\n * @param {object} opts (see Plotly.toImage in ../plot_api/to_image)\n * @return {promise}\n */\nfunction downloadImage(gd, opts) {\n var _gd;\n if(!Lib.isPlainObject(gd)) _gd = Lib.getGraphDiv(gd);\n\n opts = opts || {};\n opts.format = opts.format || 'png';\n opts.imageDataOnly = true;\n\n return new Promise(function(resolve, reject) {\n if(_gd && _gd._snapshotInProgress) {\n reject(new Error('Snapshotting already in progress.'));\n }\n\n // see comments within svgtoimg for additional\n // discussion of problems with IE\n // can now draw to canvas, but CORS tainted canvas\n // does not allow toDataURL\n // svg format will work though\n if(Lib.isIE() && opts.format !== 'svg') {\n reject(new Error(helpers.MSG_IE_BAD_FORMAT));\n }\n\n if(_gd) _gd._snapshotInProgress = true;\n var promise = toImage(gd, opts);\n\n var filename = opts.filename || gd.fn || 'newplot';\n filename += '.' + opts.format;\n\n promise.then(function(result) {\n if(_gd) _gd._snapshotInProgress = false;\n return fileSaver(result, filename, opts.format);\n }).then(function(name) {\n resolve(name);\n }).catch(function(err) {\n if(_gd) _gd._snapshotInProgress = false;\n reject(err);\n });\n });\n}\n\nmodule.exports = downloadImage;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/snapshot/download.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/snapshot/filesaver.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/snapshot/filesaver.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/snapshot/helpers.js\");\n\n/*\n* substantial portions of this code from FileSaver.js\n* https://github.com/eligrey/FileSaver.js\n* License: https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md\n* FileSaver.js\n* A saveAs() FileSaver implementation.\n* 1.1.20160328\n*\n* By Eli Grey, http://eligrey.com\n* License: MIT\n* See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md\n*/\nfunction fileSaver(url, name, format) {\n var saveLink = document.createElement('a');\n var canUseSaveLink = 'download' in saveLink;\n\n var promise = new Promise(function(resolve, reject) {\n var blob;\n var objectUrl;\n\n if(Lib.isIE9orBelow()) {\n reject(new Error('IE < 10 unsupported'));\n }\n\n // Safari doesn't allow downloading of blob urls\n if(Lib.isSafari()) {\n var prefix = format === 'svg' ? ',' : ';base64,';\n helpers.octetStream(prefix + encodeURIComponent(url));\n return resolve(name);\n }\n\n // IE 10+ (native saveAs)\n if(Lib.isIE()) {\n // At this point we are only dealing with a decoded SVG as\n // a data URL (since IE only supports SVG)\n blob = helpers.createBlob(url, 'svg');\n window.navigator.msSaveBlob(blob, name);\n blob = null;\n return resolve(name);\n }\n\n if(canUseSaveLink) {\n blob = helpers.createBlob(url, format);\n objectUrl = helpers.createObjectURL(blob);\n\n saveLink.href = objectUrl;\n saveLink.download = name;\n document.body.appendChild(saveLink);\n saveLink.click();\n\n document.body.removeChild(saveLink);\n helpers.revokeObjectURL(objectUrl);\n blob = null;\n\n return resolve(name);\n }\n\n reject(new Error('download error'));\n });\n\n return promise;\n}\n\n\nmodule.exports = fileSaver;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/snapshot/filesaver.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/snapshot/helpers.js":
-/*!********************************************************!*\
- !*** ./node_modules/plotly.js/src/snapshot/helpers.js ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Registry = __webpack_require__(/*! ../registry */ \"./node_modules/plotly.js/src/registry.js\");\n\nexports.getDelay = function(fullLayout) {\n if(!fullLayout._has) return 0;\n\n return (\n fullLayout._has('gl3d') ||\n fullLayout._has('gl2d') ||\n fullLayout._has('mapbox')\n ) ? 500 : 0;\n};\n\nexports.getRedrawFunc = function(gd) {\n return function() {\n var fullLayout = gd._fullLayout || {};\n var hasPolar = fullLayout._has && fullLayout._has('polar');\n var hasLegacyPolar = !hasPolar && gd.data && gd.data[0] && gd.data[0].r;\n\n if(!hasLegacyPolar) {\n Registry.getComponentMethod('colorbar', 'draw')(gd);\n }\n };\n};\n\nexports.encodeSVG = function(svg) {\n return 'data:image/svg+xml,' + encodeURIComponent(svg);\n};\n\nvar DOM_URL = window.URL || window.webkitURL;\n\nexports.createObjectURL = function(blob) {\n return DOM_URL.createObjectURL(blob);\n};\n\nexports.revokeObjectURL = function(url) {\n return DOM_URL.revokeObjectURL(url);\n};\n\nexports.createBlob = function(url, format) {\n if(format === 'svg') {\n return new window.Blob([url], {type: 'image/svg+xml;charset=utf-8'});\n } else {\n var binary = fixBinary(window.atob(url));\n return new window.Blob([binary], {type: 'image/' + format});\n }\n};\n\nexports.octetStream = function(s) {\n document.location.href = 'data:application/octet-stream' + s;\n};\n\n// Taken from https://bl.ocks.org/nolanlawson/0eac306e4dac2114c752\nfunction fixBinary(b) {\n var len = b.length;\n var buf = new ArrayBuffer(len);\n var arr = new Uint8Array(buf);\n for(var i = 0; i < len; i++) {\n arr[i] = b.charCodeAt(i);\n }\n return buf;\n}\n\nexports.IMAGE_URL_PREFIX = /^data:image\\/\\w+;base64,/;\n\nexports.MSG_IE_BAD_FORMAT = 'Sorry IE does not support downloading from canvas. Try {format:\\'svg\\'} instead.';\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/snapshot/helpers.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/snapshot/index.js":
-/*!******************************************************!*\
- !*** ./node_modules/plotly.js/src/snapshot/index.js ***!
- \******************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/snapshot/helpers.js\");\n\nvar Snapshot = {\n getDelay: helpers.getDelay,\n getRedrawFunc: helpers.getRedrawFunc,\n clone: __webpack_require__(/*! ./cloneplot */ \"./node_modules/plotly.js/src/snapshot/cloneplot.js\"),\n toSVG: __webpack_require__(/*! ./tosvg */ \"./node_modules/plotly.js/src/snapshot/tosvg.js\"),\n svgToImg: __webpack_require__(/*! ./svgtoimg */ \"./node_modules/plotly.js/src/snapshot/svgtoimg.js\"),\n toImage: __webpack_require__(/*! ./toimage */ \"./node_modules/plotly.js/src/snapshot/toimage.js\"),\n downloadImage: __webpack_require__(/*! ./download */ \"./node_modules/plotly.js/src/snapshot/download.js\")\n};\n\nmodule.exports = Snapshot;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/snapshot/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/snapshot/svgtoimg.js":
-/*!*********************************************************!*\
- !*** ./node_modules/plotly.js/src/snapshot/svgtoimg.js ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar EventEmitter = __webpack_require__(/*! events */ \"./node_modules/node-libs-browser/node_modules/events/events.js\").EventEmitter;\n\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/snapshot/helpers.js\");\n\nfunction svgToImg(opts) {\n var ev = opts.emitter || new EventEmitter();\n\n var promise = new Promise(function(resolve, reject) {\n var Image = window.Image;\n var svg = opts.svg;\n var format = opts.format || 'png';\n\n // IE only support svg\n if(Lib.isIE() && format !== 'svg') {\n var ieSvgError = new Error(helpers.MSG_IE_BAD_FORMAT);\n reject(ieSvgError);\n // eventually remove the ev\n // in favor of promises\n if(!opts.promise) {\n return ev.emit('error', ieSvgError);\n } else {\n return promise;\n }\n }\n\n var canvas = opts.canvas;\n var scale = opts.scale || 1;\n var w0 = opts.width || 300;\n var h0 = opts.height || 150;\n var w1 = scale * w0;\n var h1 = scale * h0;\n\n var ctx = canvas.getContext('2d');\n var img = new Image();\n var svgBlob, url;\n\n if(format === 'svg' || Lib.isIE9orBelow() || Lib.isSafari()) {\n url = helpers.encodeSVG(svg);\n } else {\n svgBlob = helpers.createBlob(svg, 'svg');\n url = helpers.createObjectURL(svgBlob);\n }\n\n canvas.width = w1;\n canvas.height = h1;\n\n img.onload = function() {\n var imgData;\n\n svgBlob = null;\n helpers.revokeObjectURL(url);\n\n // don't need to draw to canvas if svg\n // save some time and also avoid failure on IE\n if(format !== 'svg') {\n ctx.drawImage(img, 0, 0, w1, h1);\n }\n\n switch(format) {\n case 'jpeg':\n imgData = canvas.toDataURL('image/jpeg');\n break;\n case 'png':\n imgData = canvas.toDataURL('image/png');\n break;\n case 'webp':\n imgData = canvas.toDataURL('image/webp');\n break;\n case 'svg':\n imgData = url;\n break;\n default:\n var errorMsg = 'Image format is not jpeg, png, svg or webp.';\n reject(new Error(errorMsg));\n // eventually remove the ev\n // in favor of promises\n if(!opts.promise) {\n return ev.emit('error', errorMsg);\n }\n }\n resolve(imgData);\n // eventually remove the ev\n // in favor of promises\n if(!opts.promise) {\n ev.emit('success', imgData);\n }\n };\n\n img.onerror = function(err) {\n svgBlob = null;\n helpers.revokeObjectURL(url);\n\n reject(err);\n // eventually remove the ev\n // in favor of promises\n if(!opts.promise) {\n return ev.emit('error', err);\n }\n };\n\n img.src = url;\n });\n\n // temporary for backward compatibility\n // move to only Promise in 2.0.0\n // and eliminate the EventEmitter\n if(opts.promise) {\n return promise;\n }\n\n return ev;\n}\n\nmodule.exports = svgToImg;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/snapshot/svgtoimg.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/snapshot/toimage.js":
-/*!********************************************************!*\
- !*** ./node_modules/plotly.js/src/snapshot/toimage.js ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar EventEmitter = __webpack_require__(/*! events */ \"./node_modules/node-libs-browser/node_modules/events/events.js\").EventEmitter;\n\nvar Registry = __webpack_require__(/*! ../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Lib = __webpack_require__(/*! ../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/snapshot/helpers.js\");\nvar clonePlot = __webpack_require__(/*! ./cloneplot */ \"./node_modules/plotly.js/src/snapshot/cloneplot.js\");\nvar toSVG = __webpack_require__(/*! ./tosvg */ \"./node_modules/plotly.js/src/snapshot/tosvg.js\");\nvar svgToImg = __webpack_require__(/*! ./svgtoimg */ \"./node_modules/plotly.js/src/snapshot/svgtoimg.js\");\n\n/**\n * @param {object} gd figure Object\n * @param {object} opts option object\n * @param opts.format 'jpeg' | 'png' | 'webp' | 'svg'\n */\nfunction toImage(gd, opts) {\n // first clone the GD so we can operate in a clean environment\n var ev = new EventEmitter();\n\n var clone = clonePlot(gd, {format: 'png'});\n var clonedGd = clone.gd;\n\n // put the cloned div somewhere off screen before attaching to DOM\n clonedGd.style.position = 'absolute';\n clonedGd.style.left = '-5000px';\n document.body.appendChild(clonedGd);\n\n function wait() {\n var delay = helpers.getDelay(clonedGd._fullLayout);\n\n setTimeout(function() {\n var svg = toSVG(clonedGd);\n\n var canvas = document.createElement('canvas');\n canvas.id = Lib.randstr();\n\n ev = svgToImg({\n format: opts.format,\n width: clonedGd._fullLayout.width,\n height: clonedGd._fullLayout.height,\n canvas: canvas,\n emitter: ev,\n svg: svg\n });\n\n ev.clean = function() {\n if(clonedGd) document.body.removeChild(clonedGd);\n };\n }, delay);\n }\n\n var redrawFunc = helpers.getRedrawFunc(clonedGd);\n\n Registry.call('plot', clonedGd, clone.data, clone.layout, clone.config)\n .then(redrawFunc)\n .then(wait)\n .catch(function(err) {\n ev.emit('error', err);\n });\n\n\n return ev;\n}\n\nmodule.exports = toImage;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/snapshot/toimage.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/snapshot/tosvg.js":
-/*!******************************************************!*\
- !*** ./node_modules/plotly.js/src/snapshot/tosvg.js ***!
- \******************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar Lib = __webpack_require__(/*! ../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Drawing = __webpack_require__(/*! ../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar Color = __webpack_require__(/*! ../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\n\nvar xmlnsNamespaces = __webpack_require__(/*! ../constants/xmlns_namespaces */ \"./node_modules/plotly.js/src/constants/xmlns_namespaces.js\");\nvar DOUBLEQUOTE_REGEX = /\"/g;\nvar DUMMY_SUB = 'TOBESTRIPPED';\nvar DUMMY_REGEX = new RegExp('(\"' + DUMMY_SUB + ')|(' + DUMMY_SUB + '\")', 'g');\n\nfunction htmlEntityDecode(s) {\n var hiddenDiv = d3.select('body').append('div').style({display: 'none'}).html('');\n var replaced = s.replace(/(&[^;]*;)/gi, function(d) {\n if(d === '<') { return '<'; } // special handling for brackets\n if(d === '&rt;') { return '>'; }\n if(d.indexOf('<') !== -1 || d.indexOf('>') !== -1) { return ''; }\n return hiddenDiv.html(d).text(); // everything else, let the browser decode it to unicode\n });\n hiddenDiv.remove();\n return replaced;\n}\n\nfunction xmlEntityEncode(str) {\n return str.replace(/&(?!\\w+;|\\#[0-9]+;| \\#x[0-9A-F]+;)/g, '&');\n}\n\nmodule.exports = function toSVG(gd, format, scale) {\n var fullLayout = gd._fullLayout;\n var svg = fullLayout._paper;\n var toppaper = fullLayout._toppaper;\n var width = fullLayout.width;\n var height = fullLayout.height;\n var i;\n\n // make background color a rect in the svg, then revert after scraping\n // all other alterations have been dealt with by properly preparing the svg\n // in the first place... like setting cursors with css classes so we don't\n // have to remove them, and providing the right namespaces in the svg to\n // begin with\n svg.insert('rect', ':first-child')\n .call(Drawing.setRect, 0, 0, width, height)\n .call(Color.fill, fullLayout.paper_bgcolor);\n\n // subplot-specific to-SVG methods\n // which notably add the contents of the gl-container\n // into the main svg node\n var basePlotModules = fullLayout._basePlotModules || [];\n for(i = 0; i < basePlotModules.length; i++) {\n var _module = basePlotModules[i];\n\n if(_module.toSVG) _module.toSVG(gd);\n }\n\n // add top items above them assumes everything in toppaper is either\n // a group or a defs, and if it's empty (like hoverlayer) we can ignore it.\n if(toppaper) {\n var nodes = toppaper.node().childNodes;\n\n // make copy of nodes as childNodes prop gets mutated in loop below\n var topGroups = Array.prototype.slice.call(nodes);\n\n for(i = 0; i < topGroups.length; i++) {\n var topGroup = topGroups[i];\n\n if(topGroup.childNodes.length) svg.node().appendChild(topGroup);\n }\n }\n\n // remove draglayer for Adobe Illustrator compatibility\n if(fullLayout._draggers) {\n fullLayout._draggers.remove();\n }\n\n // in case the svg element had an explicit background color, remove this\n // we want the rect to get the color so it's the right size; svg bg will\n // fill whatever container it's displayed in regardless of plot size.\n svg.node().style.background = '';\n\n svg.selectAll('text')\n .attr({'data-unformatted': null, 'data-math': null})\n .each(function() {\n var txt = d3.select(this);\n\n // hidden text is pre-formatting mathjax, the browser ignores it\n // but in a static plot it's useless and it can confuse batik\n // we've tried to standardize on display:none but make sure we still\n // catch visibility:hidden if it ever arises\n if(this.style.visibility === 'hidden' || this.style.display === 'none') {\n txt.remove();\n return;\n } else {\n // clear other visibility/display values to default\n // to not potentially confuse non-browser SVG implementations\n txt.style({visibility: null, display: null});\n }\n\n // Font family styles break things because of quotation marks,\n // so we must remove them *after* the SVG DOM has been serialized\n // to a string (browsers convert singles back)\n var ff = this.style.fontFamily;\n if(ff && ff.indexOf('\"') !== -1) {\n txt.style('font-family', ff.replace(DOUBLEQUOTE_REGEX, DUMMY_SUB));\n }\n });\n\n\n if(fullLayout._gradientUrlQueryParts) {\n var queryParts = [];\n for(var k in fullLayout._gradientUrlQueryParts) queryParts.push(k);\n\n if(queryParts.length) {\n svg.selectAll(queryParts.join(',')).each(function() {\n var pt = d3.select(this);\n\n // similar to font family styles above,\n // we must remove \" after the SVG DOM has been serialized\n var fill = this.style.fill;\n if(fill && fill.indexOf('url(') !== -1) {\n pt.style('fill', fill.replace(DOUBLEQUOTE_REGEX, DUMMY_SUB));\n }\n\n var stroke = this.style.stroke;\n if(stroke && stroke.indexOf('url(') !== -1) {\n pt.style('stroke', stroke.replace(DOUBLEQUOTE_REGEX, DUMMY_SUB));\n }\n });\n }\n }\n\n if(format === 'pdf' || format === 'eps') {\n // these formats make the extra line MathJax adds around symbols look super thick in some cases\n // it looks better if this is removed entirely.\n svg.selectAll('#MathJax_SVG_glyphs path')\n .attr('stroke-width', 0);\n }\n\n // fix for IE namespacing quirk?\n // http://stackoverflow.com/questions/19610089/unwanted-namespaces-on-svg-markup-when-using-xmlserializer-in-javascript-with-ie\n svg.node().setAttributeNS(xmlnsNamespaces.xmlns, 'xmlns', xmlnsNamespaces.svg);\n svg.node().setAttributeNS(xmlnsNamespaces.xmlns, 'xmlns:xlink', xmlnsNamespaces.xlink);\n\n if(format === 'svg' && scale) {\n svg.attr('width', scale * width);\n svg.attr('height', scale * height);\n svg.attr('viewBox', '0 0 ' + width + ' ' + height);\n }\n\n var s = new window.XMLSerializer().serializeToString(svg.node());\n s = htmlEntityDecode(s);\n s = xmlEntityEncode(s);\n\n // Fix quotations around font strings and gradient URLs\n s = s.replace(DUMMY_REGEX, '\\'');\n\n // IE is very strict, so we will need to clean\n // svg with the following regex\n // yes this is messy, but do not know a better way\n // Even with this IE will not work due to tainted canvas\n // see https://github.com/kangax/fabric.js/issues/1957\n // http://stackoverflow.com/questions/18112047/canvas-todataurl-working-in-all-browsers-except-ie10\n // Leave here just in case the CORS/tainted IE issue gets resolved\n if(Lib.isIE()) {\n // replace double quote with single quote\n s = s.replace(/\"/gi, '\\'');\n // url in svg are single quoted\n // since we changed double to single\n // we'll need to change these to double-quoted\n s = s.replace(/(\\('#)([^']*)('\\))/gi, '(\\\"#$2\\\")');\n // font names with spaces will be escaped single-quoted\n // we'll need to change these to double-quoted\n s = s.replace(/(\\\\')/gi, '\\\"');\n }\n\n return s;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/snapshot/tosvg.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/arrays_to_calcdata.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/arrays_to_calcdata.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\n// arrayOk attributes, merge them into calcdata array\nmodule.exports = function arraysToCalcdata(cd, trace) {\n for(var i = 0; i < cd.length; i++) cd[i].i = i;\n\n Lib.mergeArray(trace.text, cd, 'tx');\n Lib.mergeArray(trace.hovertext, cd, 'htx');\n\n var marker = trace.marker;\n if(marker) {\n Lib.mergeArray(marker.opacity, cd, 'mo', true);\n Lib.mergeArray(marker.color, cd, 'mc');\n\n var markerLine = marker.line;\n if(markerLine) {\n Lib.mergeArray(markerLine.color, cd, 'mlc');\n Lib.mergeArrayCastPositive(markerLine.width, cd, 'mlw');\n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/arrays_to_calcdata.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/attributes.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/attributes.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar scatterAttrs = __webpack_require__(/*! ../scatter/attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar texttemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").texttemplateAttrs;\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar fontAttrs = __webpack_require__(/*! ../../plots/font_attributes */ \"./node_modules/plotly.js/src/plots/font_attributes.js\");\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/bar/constants.js\");\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nvar textFontAttrs = fontAttrs({\n editType: 'calc',\n arrayOk: true,\n colorEditType: 'style',\n \n});\n\nvar scatterMarkerAttrs = scatterAttrs.marker;\nvar scatterMarkerLineAttrs = scatterMarkerAttrs.line;\n\nvar markerLineWidth = extendFlat({},\n scatterMarkerLineAttrs.width, { dflt: 0 });\n\nvar markerLine = extendFlat({\n width: markerLineWidth,\n editType: 'calc'\n}, colorScaleAttrs('marker.line'));\n\nvar marker = extendFlat({\n line: markerLine,\n editType: 'calc'\n}, colorScaleAttrs('marker'), {\n opacity: {\n valType: 'number',\n arrayOk: true,\n dflt: 1,\n min: 0,\n max: 1,\n \n editType: 'style',\n \n }\n});\n\nmodule.exports = {\n x: scatterAttrs.x,\n x0: scatterAttrs.x0,\n dx: scatterAttrs.dx,\n y: scatterAttrs.y,\n y0: scatterAttrs.y0,\n dy: scatterAttrs.dy,\n\n text: scatterAttrs.text,\n texttemplate: texttemplateAttrs({editType: 'plot'}, {\n keys: constants.eventDataKeys\n }),\n hovertext: scatterAttrs.hovertext,\n hovertemplate: hovertemplateAttrs({}, {\n keys: constants.eventDataKeys\n }),\n\n textposition: {\n valType: 'enumerated',\n \n values: ['inside', 'outside', 'auto', 'none'],\n dflt: 'none',\n arrayOk: true,\n editType: 'calc',\n \n },\n\n insidetextanchor: {\n valType: 'enumerated',\n values: ['end', 'middle', 'start'],\n dflt: 'end',\n \n editType: 'plot',\n \n },\n\n textangle: {\n valType: 'angle',\n dflt: 'auto',\n \n editType: 'plot',\n \n },\n\n textfont: extendFlat({}, textFontAttrs, {\n \n }),\n\n insidetextfont: extendFlat({}, textFontAttrs, {\n \n }),\n\n outsidetextfont: extendFlat({}, textFontAttrs, {\n \n }),\n\n constraintext: {\n valType: 'enumerated',\n values: ['inside', 'outside', 'both', 'none'],\n \n dflt: 'both',\n editType: 'calc',\n \n },\n\n cliponaxis: extendFlat({}, scatterAttrs.cliponaxis, {\n \n }),\n\n orientation: {\n valType: 'enumerated',\n \n values: ['v', 'h'],\n editType: 'calc+clearAxisTypes',\n \n },\n\n base: {\n valType: 'any',\n dflt: null,\n arrayOk: true,\n \n editType: 'calc',\n \n },\n\n offset: {\n valType: 'number',\n dflt: null,\n arrayOk: true,\n \n editType: 'calc',\n \n },\n\n width: {\n valType: 'number',\n dflt: null,\n min: 0,\n arrayOk: true,\n \n editType: 'calc',\n \n },\n\n marker: marker,\n\n offsetgroup: {\n valType: 'string',\n \n dflt: '',\n editType: 'calc',\n \n },\n alignmentgroup: {\n valType: 'string',\n \n dflt: '',\n editType: 'calc',\n \n },\n\n selected: {\n marker: {\n opacity: scatterAttrs.selected.marker.opacity,\n color: scatterAttrs.selected.marker.color,\n editType: 'style'\n },\n textfont: scatterAttrs.selected.textfont,\n editType: 'style'\n },\n unselected: {\n marker: {\n opacity: scatterAttrs.unselected.marker.opacity,\n color: scatterAttrs.unselected.marker.color,\n editType: 'style'\n },\n textfont: scatterAttrs.unselected.textfont,\n editType: 'style'\n },\n\n r: scatterAttrs.r,\n t: scatterAttrs.t,\n\n _deprecated: {\n bardir: {\n valType: 'enumerated',\n \n editType: 'calc',\n values: ['v', 'h'],\n \n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/calc.js":
-/*!*******************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/calc.js ***!
- \*******************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar hasColorscale = __webpack_require__(/*! ../../components/colorscale/helpers */ \"./node_modules/plotly.js/src/components/colorscale/helpers.js\").hasColorscale;\nvar colorscaleCalc = __webpack_require__(/*! ../../components/colorscale/calc */ \"./node_modules/plotly.js/src/components/colorscale/calc.js\");\nvar arraysToCalcdata = __webpack_require__(/*! ./arrays_to_calcdata */ \"./node_modules/plotly.js/src/traces/bar/arrays_to_calcdata.js\");\nvar calcSelection = __webpack_require__(/*! ../scatter/calc_selection */ \"./node_modules/plotly.js/src/traces/scatter/calc_selection.js\");\n\nmodule.exports = function calc(gd, trace) {\n var xa = Axes.getFromId(gd, trace.xaxis || 'x');\n var ya = Axes.getFromId(gd, trace.yaxis || 'y');\n var size, pos;\n\n if(trace.orientation === 'h') {\n size = xa.makeCalcdata(trace, 'x');\n pos = ya.makeCalcdata(trace, 'y');\n } else {\n size = ya.makeCalcdata(trace, 'y');\n pos = xa.makeCalcdata(trace, 'x');\n }\n\n // create the \"calculated data\" to plot\n var serieslen = Math.min(pos.length, size.length);\n var cd = new Array(serieslen);\n\n // set position and size\n for(var i = 0; i < serieslen; i++) {\n cd[i] = { p: pos[i], s: size[i] };\n\n if(trace.ids) {\n cd[i].id = String(trace.ids[i]);\n }\n }\n\n // auto-z and autocolorscale if applicable\n if(hasColorscale(trace, 'marker')) {\n colorscaleCalc(gd, trace, {\n vals: trace.marker.color,\n containerStr: 'marker',\n cLetter: 'c'\n });\n }\n if(hasColorscale(trace, 'marker.line')) {\n colorscaleCalc(gd, trace, {\n vals: trace.marker.line.color,\n containerStr: 'marker.line',\n cLetter: 'c'\n });\n }\n\n arraysToCalcdata(cd, trace);\n calcSelection(cd, trace);\n\n return cd;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/constants.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/constants.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nmodule.exports = {\n // padding in pixels around text\n TEXTPAD: 3,\n // 'value' and 'label' are not really necessary for bar traces,\n // but they were made available to `texttemplate` (maybe by accident)\n // via tokens `%{value}` and `%{label}` starting in 1.50.0,\n // so let's include them in the event data also.\n eventDataKeys: ['value', 'label']\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/constants.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/cross_trace_calc.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/cross_trace_calc.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\nvar isArrayOrTypedArray = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").isArrayOrTypedArray;\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar getAxisGroup = __webpack_require__(/*! ../../plots/cartesian/axis_ids */ \"./node_modules/plotly.js/src/plots/cartesian/axis_ids.js\").getAxisGroup;\nvar Sieve = __webpack_require__(/*! ./sieve.js */ \"./node_modules/plotly.js/src/traces/bar/sieve.js\");\n\n/*\n * Bar chart stacking/grouping positioning and autoscaling calculations\n * for each direction separately calculate the ranges and positions\n * note that this handles histograms too\n * now doing this one subplot at a time\n */\n\nfunction crossTraceCalc(gd, plotinfo) {\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n\n var fullLayout = gd._fullLayout;\n var fullTraces = gd._fullData;\n var calcTraces = gd.calcdata;\n var calcTracesHorz = [];\n var calcTracesVert = [];\n\n for(var i = 0; i < fullTraces.length; i++) {\n var fullTrace = fullTraces[i];\n if(\n fullTrace.visible === true &&\n Registry.traceIs(fullTrace, 'bar') &&\n fullTrace.xaxis === xa._id &&\n fullTrace.yaxis === ya._id\n ) {\n if(fullTrace.orientation === 'h') {\n calcTracesHorz.push(calcTraces[i]);\n } else {\n calcTracesVert.push(calcTraces[i]);\n }\n }\n }\n\n var opts = {\n mode: fullLayout.barmode,\n norm: fullLayout.barnorm,\n gap: fullLayout.bargap,\n groupgap: fullLayout.bargroupgap\n };\n\n setGroupPositions(gd, xa, ya, calcTracesVert, opts);\n setGroupPositions(gd, ya, xa, calcTracesHorz, opts);\n}\n\nfunction setGroupPositions(gd, pa, sa, calcTraces, opts) {\n if(!calcTraces.length) return;\n\n var excluded;\n var included;\n var i, calcTrace, fullTrace;\n\n initBase(sa, calcTraces);\n\n switch(opts.mode) {\n case 'overlay':\n setGroupPositionsInOverlayMode(pa, sa, calcTraces, opts);\n break;\n\n case 'group':\n // exclude from the group those traces for which the user set an offset\n excluded = [];\n included = [];\n for(i = 0; i < calcTraces.length; i++) {\n calcTrace = calcTraces[i];\n fullTrace = calcTrace[0].trace;\n\n if(fullTrace.offset === undefined) included.push(calcTrace);\n else excluded.push(calcTrace);\n }\n\n if(included.length) {\n setGroupPositionsInGroupMode(gd, pa, sa, included, opts);\n }\n if(excluded.length) {\n setGroupPositionsInOverlayMode(pa, sa, excluded, opts);\n }\n break;\n\n case 'stack':\n case 'relative':\n // exclude from the stack those traces for which the user set a base\n excluded = [];\n included = [];\n for(i = 0; i < calcTraces.length; i++) {\n calcTrace = calcTraces[i];\n fullTrace = calcTrace[0].trace;\n\n if(fullTrace.base === undefined) included.push(calcTrace);\n else excluded.push(calcTrace);\n }\n\n if(included.length) {\n setGroupPositionsInStackOrRelativeMode(gd, pa, sa, included, opts);\n }\n if(excluded.length) {\n setGroupPositionsInOverlayMode(pa, sa, excluded, opts);\n }\n break;\n }\n\n collectExtents(calcTraces, pa);\n}\n\nfunction initBase(sa, calcTraces) {\n var i, j;\n\n for(i = 0; i < calcTraces.length; i++) {\n var cd = calcTraces[i];\n var trace = cd[0].trace;\n var base = (trace.type === 'funnel') ? trace._base : trace.base;\n var b;\n\n // not sure if it really makes sense to have dates for bar size data...\n // ideally if we want to make gantt charts or something we'd treat\n // the actual size (trace.x or y) as time delta but base as absolute\n // time. But included here for completeness.\n var scalendar = trace.orientation === 'h' ? trace.xcalendar : trace.ycalendar;\n\n // 'base' on categorical axes makes no sense\n var d2c = sa.type === 'category' || sa.type === 'multicategory' ?\n function() { return null; } :\n sa.d2c;\n\n if(isArrayOrTypedArray(base)) {\n for(j = 0; j < Math.min(base.length, cd.length); j++) {\n b = d2c(base[j], 0, scalendar);\n if(isNumeric(b)) {\n cd[j].b = +b;\n cd[j].hasB = 1;\n } else cd[j].b = 0;\n }\n for(; j < cd.length; j++) {\n cd[j].b = 0;\n }\n } else {\n b = d2c(base, 0, scalendar);\n var hasBase = isNumeric(b);\n b = hasBase ? b : 0;\n for(j = 0; j < cd.length; j++) {\n cd[j].b = b;\n if(hasBase) cd[j].hasB = 1;\n }\n }\n }\n}\n\nfunction setGroupPositionsInOverlayMode(pa, sa, calcTraces, opts) {\n // update position axis and set bar offsets and widths\n for(var i = 0; i < calcTraces.length; i++) {\n var calcTrace = calcTraces[i];\n\n var sieve = new Sieve([calcTrace], {\n sepNegVal: false,\n overlapNoMerge: !opts.norm\n });\n\n // set bar offsets and widths, and update position axis\n setOffsetAndWidth(pa, sieve, opts);\n\n // set bar bases and sizes, and update size axis\n //\n // (note that `setGroupPositionsInOverlayMode` handles the case barnorm\n // is defined, because this function is also invoked for traces that\n // can't be grouped or stacked)\n if(opts.norm) {\n sieveBars(sieve);\n normalizeBars(sa, sieve, opts);\n } else {\n setBaseAndTop(sa, sieve);\n }\n }\n}\n\nfunction setGroupPositionsInGroupMode(gd, pa, sa, calcTraces, opts) {\n var sieve = new Sieve(calcTraces, {\n sepNegVal: false,\n overlapNoMerge: !opts.norm\n });\n\n // set bar offsets and widths, and update position axis\n setOffsetAndWidthInGroupMode(gd, pa, sieve, opts);\n\n // relative-stack bars within the same trace that would otherwise\n // be hidden\n unhideBarsWithinTrace(sieve);\n\n // set bar bases and sizes, and update size axis\n if(opts.norm) {\n sieveBars(sieve);\n normalizeBars(sa, sieve, opts);\n } else {\n setBaseAndTop(sa, sieve);\n }\n}\n\nfunction setGroupPositionsInStackOrRelativeMode(gd, pa, sa, calcTraces, opts) {\n var sieve = new Sieve(calcTraces, {\n sepNegVal: opts.mode === 'relative',\n overlapNoMerge: !(opts.norm || opts.mode === 'stack' || opts.mode === 'relative')\n });\n\n // set bar offsets and widths, and update position axis\n setOffsetAndWidth(pa, sieve, opts);\n\n // set bar bases and sizes, and update size axis\n stackBars(sa, sieve, opts);\n\n // flag the outmost bar (for text display purposes)\n for(var i = 0; i < calcTraces.length; i++) {\n var calcTrace = calcTraces[i];\n\n for(var j = 0; j < calcTrace.length; j++) {\n var bar = calcTrace[j];\n\n if(bar.s !== BADNUM) {\n var isOutmostBar = ((bar.b + bar.s) === sieve.get(bar.p, bar.s));\n if(isOutmostBar) bar._outmost = true;\n }\n }\n }\n\n // Note that marking the outmost bars has to be done\n // before `normalizeBars` changes `bar.b` and `bar.s`.\n if(opts.norm) normalizeBars(sa, sieve, opts);\n}\n\nfunction setOffsetAndWidth(pa, sieve, opts) {\n var minDiff = sieve.minDiff;\n var calcTraces = sieve.traces;\n\n // set bar offsets and widths\n var barGroupWidth = minDiff * (1 - opts.gap);\n var barWidthPlusGap = barGroupWidth;\n var barWidth = barWidthPlusGap * (1 - (opts.groupgap || 0));\n\n // computer bar group center and bar offset\n var offsetFromCenter = -barWidth / 2;\n\n for(var i = 0; i < calcTraces.length; i++) {\n var calcTrace = calcTraces[i];\n var t = calcTrace[0].t;\n\n // store bar width and offset for this trace\n t.barwidth = barWidth;\n t.poffset = offsetFromCenter;\n t.bargroupwidth = barGroupWidth;\n t.bardelta = minDiff;\n }\n\n // stack bars that only differ by rounding\n sieve.binWidth = calcTraces[0][0].t.barwidth / 100;\n\n // if defined, apply trace offset and width\n applyAttributes(sieve);\n\n // store the bar center in each calcdata item\n setBarCenterAndWidth(pa, sieve);\n\n // update position axes\n updatePositionAxis(pa, sieve);\n}\n\nfunction setOffsetAndWidthInGroupMode(gd, pa, sieve, opts) {\n var fullLayout = gd._fullLayout;\n var positions = sieve.positions;\n var distinctPositions = sieve.distinctPositions;\n var minDiff = sieve.minDiff;\n var calcTraces = sieve.traces;\n var nTraces = calcTraces.length;\n\n // if there aren't any overlapping positions,\n // let them have full width even if mode is group\n var overlap = (positions.length !== distinctPositions.length);\n var barGroupWidth = minDiff * (1 - opts.gap);\n\n var groupId = getAxisGroup(fullLayout, pa._id) + calcTraces[0][0].trace.orientation;\n var alignmentGroups = fullLayout._alignmentOpts[groupId] || {};\n\n for(var i = 0; i < nTraces; i++) {\n var calcTrace = calcTraces[i];\n var trace = calcTrace[0].trace;\n\n var alignmentGroupOpts = alignmentGroups[trace.alignmentgroup] || {};\n var nOffsetGroups = Object.keys(alignmentGroupOpts.offsetGroups || {}).length;\n\n var barWidthPlusGap;\n if(nOffsetGroups) {\n barWidthPlusGap = barGroupWidth / nOffsetGroups;\n } else {\n barWidthPlusGap = overlap ? barGroupWidth / nTraces : barGroupWidth;\n }\n\n var barWidth = barWidthPlusGap * (1 - (opts.groupgap || 0));\n\n var offsetFromCenter;\n if(nOffsetGroups) {\n offsetFromCenter = ((2 * trace._offsetIndex + 1 - nOffsetGroups) * barWidthPlusGap - barWidth) / 2;\n } else {\n offsetFromCenter = overlap ?\n ((2 * i + 1 - nTraces) * barWidthPlusGap - barWidth) / 2 :\n -barWidth / 2;\n }\n\n var t = calcTrace[0].t;\n t.barwidth = barWidth;\n t.poffset = offsetFromCenter;\n t.bargroupwidth = barGroupWidth;\n t.bardelta = minDiff;\n }\n\n // stack bars that only differ by rounding\n sieve.binWidth = calcTraces[0][0].t.barwidth / 100;\n\n // if defined, apply trace width\n applyAttributes(sieve);\n\n // store the bar center in each calcdata item\n setBarCenterAndWidth(pa, sieve);\n\n // update position axes\n updatePositionAxis(pa, sieve, overlap);\n}\n\nfunction applyAttributes(sieve) {\n var calcTraces = sieve.traces;\n var i, j;\n\n for(i = 0; i < calcTraces.length; i++) {\n var calcTrace = calcTraces[i];\n var calcTrace0 = calcTrace[0];\n var fullTrace = calcTrace0.trace;\n var t = calcTrace0.t;\n var offset = fullTrace._offset || fullTrace.offset;\n var initialPoffset = t.poffset;\n var newPoffset;\n\n if(isArrayOrTypedArray(offset)) {\n // if offset is an array, then clone it into t.poffset.\n newPoffset = Array.prototype.slice.call(offset, 0, calcTrace.length);\n\n // guard against non-numeric items\n for(j = 0; j < newPoffset.length; j++) {\n if(!isNumeric(newPoffset[j])) {\n newPoffset[j] = initialPoffset;\n }\n }\n\n // if the length of the array is too short,\n // then extend it with the initial value of t.poffset\n for(j = newPoffset.length; j < calcTrace.length; j++) {\n newPoffset.push(initialPoffset);\n }\n\n t.poffset = newPoffset;\n } else if(offset !== undefined) {\n t.poffset = offset;\n }\n\n var width = fullTrace._width || fullTrace.width;\n var initialBarwidth = t.barwidth;\n\n if(isArrayOrTypedArray(width)) {\n // if width is an array, then clone it into t.barwidth.\n var newBarwidth = Array.prototype.slice.call(width, 0, calcTrace.length);\n\n // guard against non-numeric items\n for(j = 0; j < newBarwidth.length; j++) {\n if(!isNumeric(newBarwidth[j])) newBarwidth[j] = initialBarwidth;\n }\n\n // if the length of the array is too short,\n // then extend it with the initial value of t.barwidth\n for(j = newBarwidth.length; j < calcTrace.length; j++) {\n newBarwidth.push(initialBarwidth);\n }\n\n t.barwidth = newBarwidth;\n\n // if user didn't set offset,\n // then correct t.poffset to ensure bars remain centered\n if(offset === undefined) {\n newPoffset = [];\n for(j = 0; j < calcTrace.length; j++) {\n newPoffset.push(\n initialPoffset + (initialBarwidth - newBarwidth[j]) / 2\n );\n }\n t.poffset = newPoffset;\n }\n } else if(width !== undefined) {\n t.barwidth = width;\n\n // if user didn't set offset,\n // then correct t.poffset to ensure bars remain centered\n if(offset === undefined) {\n t.poffset = initialPoffset + (initialBarwidth - width) / 2;\n }\n }\n }\n}\n\nfunction setBarCenterAndWidth(pa, sieve) {\n var calcTraces = sieve.traces;\n var pLetter = getAxisLetter(pa);\n\n for(var i = 0; i < calcTraces.length; i++) {\n var calcTrace = calcTraces[i];\n var t = calcTrace[0].t;\n var poffset = t.poffset;\n var poffsetIsArray = Array.isArray(poffset);\n var barwidth = t.barwidth;\n var barwidthIsArray = Array.isArray(barwidth);\n\n for(var j = 0; j < calcTrace.length; j++) {\n var calcBar = calcTrace[j];\n\n // store the actual bar width and position, for use by hover\n var width = calcBar.w = barwidthIsArray ? barwidth[j] : barwidth;\n calcBar[pLetter] = calcBar.p + (poffsetIsArray ? poffset[j] : poffset) + width / 2;\n }\n }\n}\n\nfunction updatePositionAxis(pa, sieve, allowMinDtick) {\n var calcTraces = sieve.traces;\n var minDiff = sieve.minDiff;\n var vpad = minDiff / 2;\n\n Axes.minDtick(pa, sieve.minDiff, sieve.distinctPositions[0], allowMinDtick);\n\n for(var i = 0; i < calcTraces.length; i++) {\n var calcTrace = calcTraces[i];\n var calcTrace0 = calcTrace[0];\n var fullTrace = calcTrace0.trace;\n var pts = [];\n var bar, l, r, j;\n\n for(j = 0; j < calcTrace.length; j++) {\n bar = calcTrace[j];\n l = bar.p - vpad;\n r = bar.p + vpad;\n pts.push(l, r);\n }\n\n if(fullTrace.width || fullTrace.offset) {\n var t = calcTrace0.t;\n var poffset = t.poffset;\n var barwidth = t.barwidth;\n var poffsetIsArray = Array.isArray(poffset);\n var barwidthIsArray = Array.isArray(barwidth);\n\n for(j = 0; j < calcTrace.length; j++) {\n bar = calcTrace[j];\n var calcBarOffset = poffsetIsArray ? poffset[j] : poffset;\n var calcBarWidth = barwidthIsArray ? barwidth[j] : barwidth;\n l = bar.p + calcBarOffset;\n r = l + calcBarWidth;\n pts.push(l, r);\n }\n }\n\n fullTrace._extremes[pa._id] = Axes.findExtremes(pa, pts, {padded: false});\n }\n}\n\n// store these bar bases and tops in calcdata\n// and make sure the size axis includes zero,\n// along with the bases and tops of each bar.\nfunction setBaseAndTop(sa, sieve) {\n var calcTraces = sieve.traces;\n var sLetter = getAxisLetter(sa);\n\n for(var i = 0; i < calcTraces.length; i++) {\n var calcTrace = calcTraces[i];\n var fullTrace = calcTrace[0].trace;\n var pts = [];\n var allBaseAboveZero = true;\n\n for(var j = 0; j < calcTrace.length; j++) {\n var bar = calcTrace[j];\n var base = bar.b;\n var top = base + bar.s;\n\n bar[sLetter] = top;\n pts.push(top);\n if(bar.hasB) pts.push(base);\n\n if(!bar.hasB || !(bar.b > 0 && bar.s > 0)) {\n allBaseAboveZero = false;\n }\n }\n\n fullTrace._extremes[sa._id] = Axes.findExtremes(sa, pts, {\n tozero: !allBaseAboveZero,\n padded: true\n });\n }\n}\n\nfunction stackBars(sa, sieve, opts) {\n var sLetter = getAxisLetter(sa);\n var calcTraces = sieve.traces;\n var calcTrace;\n var fullTrace;\n var isFunnel;\n var i, j;\n var bar;\n\n for(i = 0; i < calcTraces.length; i++) {\n calcTrace = calcTraces[i];\n fullTrace = calcTrace[0].trace;\n\n if(fullTrace.type === 'funnel') {\n for(j = 0; j < calcTrace.length; j++) {\n bar = calcTrace[j];\n\n if(bar.s !== BADNUM) {\n // create base of funnels\n sieve.put(bar.p, -0.5 * bar.s);\n }\n }\n }\n }\n\n for(i = 0; i < calcTraces.length; i++) {\n calcTrace = calcTraces[i];\n fullTrace = calcTrace[0].trace;\n\n isFunnel = (fullTrace.type === 'funnel');\n\n var pts = [];\n\n for(j = 0; j < calcTrace.length; j++) {\n bar = calcTrace[j];\n\n if(bar.s !== BADNUM) {\n // stack current bar and get previous sum\n var value;\n if(isFunnel) {\n value = bar.s;\n } else {\n value = bar.s + bar.b;\n }\n\n var base = sieve.put(bar.p, value);\n\n var top = base + value;\n\n // store the bar base and top in each calcdata item\n bar.b = base;\n bar[sLetter] = top;\n\n if(!opts.norm) {\n pts.push(top);\n if(bar.hasB) {\n pts.push(base);\n }\n }\n }\n }\n\n // if barnorm is set, let normalizeBars update the axis range\n if(!opts.norm) {\n fullTrace._extremes[sa._id] = Axes.findExtremes(sa, pts, {\n // N.B. we don't stack base with 'base',\n // so set tozero:true always!\n tozero: true,\n padded: true\n });\n }\n }\n}\n\nfunction sieveBars(sieve) {\n var calcTraces = sieve.traces;\n\n for(var i = 0; i < calcTraces.length; i++) {\n var calcTrace = calcTraces[i];\n\n for(var j = 0; j < calcTrace.length; j++) {\n var bar = calcTrace[j];\n\n if(bar.s !== BADNUM) {\n sieve.put(bar.p, bar.b + bar.s);\n }\n }\n }\n}\n\nfunction unhideBarsWithinTrace(sieve) {\n var calcTraces = sieve.traces;\n\n for(var i = 0; i < calcTraces.length; i++) {\n var calcTrace = calcTraces[i];\n var fullTrace = calcTrace[0].trace;\n\n if(fullTrace.base === undefined) {\n var inTraceSieve = new Sieve([calcTrace], {\n sepNegVal: true,\n overlapNoMerge: true\n });\n\n for(var j = 0; j < calcTrace.length; j++) {\n var bar = calcTrace[j];\n\n if(bar.p !== BADNUM) {\n // stack current bar and get previous sum\n var base = inTraceSieve.put(bar.p, bar.b + bar.s);\n\n // if previous sum if non-zero, this means:\n // multiple bars have same starting point are potentially hidden,\n // shift them vertically so that all bars are visible by default\n if(base) bar.b = base;\n }\n }\n }\n }\n}\n\n// Note:\n//\n// normalizeBars requires that either sieveBars or stackBars has been\n// previously invoked.\nfunction normalizeBars(sa, sieve, opts) {\n var calcTraces = sieve.traces;\n var sLetter = getAxisLetter(sa);\n var sTop = opts.norm === 'fraction' ? 1 : 100;\n var sTiny = sTop / 1e9; // in case of rounding error in sum\n var sMin = sa.l2c(sa.c2l(0));\n var sMax = opts.mode === 'stack' ? sTop : sMin;\n\n function needsPadding(v) {\n return (\n isNumeric(sa.c2l(v)) &&\n ((v < sMin - sTiny) || (v > sMax + sTiny) || !isNumeric(sMin))\n );\n }\n\n for(var i = 0; i < calcTraces.length; i++) {\n var calcTrace = calcTraces[i];\n var fullTrace = calcTrace[0].trace;\n var pts = [];\n var allBaseAboveZero = true;\n var padded = false;\n\n for(var j = 0; j < calcTrace.length; j++) {\n var bar = calcTrace[j];\n\n if(bar.s !== BADNUM) {\n var scale = Math.abs(sTop / sieve.get(bar.p, bar.s));\n bar.b *= scale;\n bar.s *= scale;\n\n var base = bar.b;\n var top = base + bar.s;\n\n bar[sLetter] = top;\n pts.push(top);\n padded = padded || needsPadding(top);\n\n if(bar.hasB) {\n pts.push(base);\n padded = padded || needsPadding(base);\n }\n\n if(!bar.hasB || !(bar.b > 0 && bar.s > 0)) {\n allBaseAboveZero = false;\n }\n }\n }\n\n fullTrace._extremes[sa._id] = Axes.findExtremes(sa, pts, {\n tozero: !allBaseAboveZero,\n padded: padded\n });\n }\n}\n\n// find the full position span of bars at each position\n// for use by hover, to ensure labels move in if bars are\n// narrower than the space they're in.\n// run once per trace group (subplot & direction) and\n// the same mapping is attached to all calcdata traces\nfunction collectExtents(calcTraces, pa) {\n var pLetter = getAxisLetter(pa);\n var extents = {};\n var i, j, cd;\n\n var pMin = Infinity;\n var pMax = -Infinity;\n\n for(i = 0; i < calcTraces.length; i++) {\n cd = calcTraces[i];\n for(j = 0; j < cd.length; j++) {\n var p = cd[j].p;\n if(isNumeric(p)) {\n pMin = Math.min(pMin, p);\n pMax = Math.max(pMax, p);\n }\n }\n }\n\n // this is just for positioning of hover labels, and nobody will care if\n // the label is 1px too far out; so round positions to 1/10K in case\n // position values don't exactly match from trace to trace\n var roundFactor = 10000 / (pMax - pMin);\n var round = extents.round = function(p) {\n return String(Math.round(roundFactor * (p - pMin)));\n };\n\n for(i = 0; i < calcTraces.length; i++) {\n cd = calcTraces[i];\n cd[0].t.extents = extents;\n\n var poffset = cd[0].t.poffset;\n var poffsetIsArray = Array.isArray(poffset);\n\n for(j = 0; j < cd.length; j++) {\n var di = cd[j];\n var p0 = di[pLetter] - di.w / 2;\n\n if(isNumeric(p0)) {\n var p1 = di[pLetter] + di.w / 2;\n var pVal = round(di.p);\n if(extents[pVal]) {\n extents[pVal] = [Math.min(p0, extents[pVal][0]), Math.max(p1, extents[pVal][1])];\n } else {\n extents[pVal] = [p0, p1];\n }\n }\n\n di.p0 = di.p + (poffsetIsArray ? poffset[j] : poffset);\n di.p1 = di.p0 + di.w;\n di.s0 = di.b;\n di.s1 = di.s0 + di.s;\n }\n }\n}\n\nfunction getAxisLetter(ax) {\n return ax._id.charAt(0);\n}\n\nmodule.exports = {\n crossTraceCalc: crossTraceCalc,\n setGroupPositions: setGroupPositions\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/cross_trace_calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/defaults.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/defaults.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\n\nvar handleXYDefaults = __webpack_require__(/*! ../scatter/xy_defaults */ \"./node_modules/plotly.js/src/traces/scatter/xy_defaults.js\");\nvar handleStyleDefaults = __webpack_require__(/*! ./style_defaults */ \"./node_modules/plotly.js/src/traces/bar/style_defaults.js\");\nvar getAxisGroup = __webpack_require__(/*! ../../plots/cartesian/axis_ids */ \"./node_modules/plotly.js/src/plots/cartesian/axis_ids.js\").getAxisGroup;\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/bar/attributes.js\");\n\nvar coerceFont = Lib.coerceFont;\n\nfunction supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var len = handleXYDefaults(traceIn, traceOut, layout, coerce);\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n coerce('orientation', (traceOut.x && !traceOut.y) ? 'h' : 'v');\n coerce('base');\n coerce('offset');\n coerce('width');\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n\n var textposition = coerce('textposition');\n handleText(traceIn, traceOut, layout, coerce, textposition, {\n moduleHasSelected: true,\n moduleHasUnselected: true,\n moduleHasConstrain: true,\n moduleHasCliponaxis: true,\n moduleHasTextangle: true,\n moduleHasInsideanchor: true\n });\n\n handleStyleDefaults(traceIn, traceOut, coerce, defaultColor, layout);\n\n var lineColor = (traceOut.marker.line || {}).color;\n\n // override defaultColor for error bars with defaultLine\n var errorBarsSupplyDefaults = Registry.getComponentMethod('errorbars', 'supplyDefaults');\n errorBarsSupplyDefaults(traceIn, traceOut, lineColor || Color.defaultLine, {axis: 'y'});\n errorBarsSupplyDefaults(traceIn, traceOut, lineColor || Color.defaultLine, {axis: 'x', inherit: 'y'});\n\n Lib.coerceSelectionMarkerOpacity(traceOut, coerce);\n}\n\nfunction handleGroupingDefaults(traceIn, traceOut, fullLayout, coerce) {\n var orientation = traceOut.orientation;\n // N.B. grouping is done across all trace types that support it\n var posAxId = traceOut[{v: 'x', h: 'y'}[orientation] + 'axis'];\n var groupId = getAxisGroup(fullLayout, posAxId) + orientation;\n\n var alignmentOpts = fullLayout._alignmentOpts || {};\n var alignmentgroup = coerce('alignmentgroup');\n\n var alignmentGroups = alignmentOpts[groupId];\n if(!alignmentGroups) alignmentGroups = alignmentOpts[groupId] = {};\n\n var alignmentGroupOpts = alignmentGroups[alignmentgroup];\n\n if(alignmentGroupOpts) {\n alignmentGroupOpts.traces.push(traceOut);\n } else {\n alignmentGroupOpts = alignmentGroups[alignmentgroup] = {\n traces: [traceOut],\n alignmentIndex: Object.keys(alignmentGroups).length,\n offsetGroups: {}\n };\n }\n\n var offsetgroup = coerce('offsetgroup');\n var offsetGroups = alignmentGroupOpts.offsetGroups;\n var offsetGroupOpts = offsetGroups[offsetgroup];\n\n if(offsetgroup) {\n if(!offsetGroupOpts) {\n offsetGroupOpts = offsetGroups[offsetgroup] = {\n offsetIndex: Object.keys(offsetGroups).length\n };\n }\n\n traceOut._offsetIndex = offsetGroupOpts.offsetIndex;\n }\n}\n\nfunction crossTraceDefaults(fullData, fullLayout) {\n var traceIn, traceOut;\n\n function coerce(attr) {\n return Lib.coerce(traceOut._input, traceOut, attributes, attr);\n }\n\n if(fullLayout.barmode === 'group') {\n for(var i = 0; i < fullData.length; i++) {\n traceOut = fullData[i];\n\n if(traceOut.type === 'bar') {\n traceIn = traceOut._input;\n handleGroupingDefaults(traceIn, traceOut, fullLayout, coerce);\n }\n }\n }\n}\n\nfunction handleText(traceIn, traceOut, layout, coerce, textposition, opts) {\n opts = opts || {};\n var moduleHasSelected = !(opts.moduleHasSelected === false);\n var moduleHasUnselected = !(opts.moduleHasUnselected === false);\n var moduleHasConstrain = !(opts.moduleHasConstrain === false);\n var moduleHasCliponaxis = !(opts.moduleHasCliponaxis === false);\n var moduleHasTextangle = !(opts.moduleHasTextangle === false);\n var moduleHasInsideanchor = !(opts.moduleHasInsideanchor === false);\n var hasPathbar = !!opts.hasPathbar;\n\n var hasBoth = Array.isArray(textposition) || textposition === 'auto';\n var hasInside = hasBoth || textposition === 'inside';\n var hasOutside = hasBoth || textposition === 'outside';\n\n if(hasInside || hasOutside) {\n var dfltFont = coerceFont(coerce, 'textfont', layout.font);\n\n // Note that coercing `insidetextfont` is always needed –\n // even if `textposition` is `outside` for each trace – since\n // an outside label can become an inside one, for example because\n // of a bar being stacked on top of it.\n var insideTextFontDefault = Lib.extendFlat({}, dfltFont);\n var isTraceTextfontColorSet = traceIn.textfont && traceIn.textfont.color;\n var isColorInheritedFromLayoutFont = !isTraceTextfontColorSet;\n if(isColorInheritedFromLayoutFont) {\n delete insideTextFontDefault.color;\n }\n coerceFont(coerce, 'insidetextfont', insideTextFontDefault);\n\n if(hasPathbar) {\n var pathbarTextFontDefault = Lib.extendFlat({}, dfltFont);\n if(isColorInheritedFromLayoutFont) {\n delete pathbarTextFontDefault.color;\n }\n coerceFont(coerce, 'pathbar.textfont', pathbarTextFontDefault);\n }\n\n if(hasOutside) coerceFont(coerce, 'outsidetextfont', dfltFont);\n\n if(moduleHasSelected) coerce('selected.textfont.color');\n if(moduleHasUnselected) coerce('unselected.textfont.color');\n if(moduleHasConstrain) coerce('constraintext');\n if(moduleHasCliponaxis) coerce('cliponaxis');\n if(moduleHasTextangle) coerce('textangle');\n\n coerce('texttemplate');\n }\n\n if(hasInside) {\n if(moduleHasInsideanchor) coerce('insidetextanchor');\n }\n}\n\nmodule.exports = {\n supplyDefaults: supplyDefaults,\n crossTraceDefaults: crossTraceDefaults,\n handleGroupingDefaults: handleGroupingDefaults,\n handleText: handleText\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/event_data.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/event_data.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function eventData(out, pt, trace) {\n // standard cartesian event data\n out.x = 'xVal' in pt ? pt.xVal : pt.x;\n out.y = 'yVal' in pt ? pt.yVal : pt.y;\n if(pt.xa) out.xaxis = pt.xa;\n if(pt.ya) out.yaxis = pt.ya;\n\n if(trace.orientation === 'h') {\n out.label = out.y;\n out.value = out.x;\n } else {\n out.label = out.x;\n out.value = out.y;\n }\n\n return out;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/event_data.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/helpers.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/helpers.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\nvar tinycolor = __webpack_require__(/*! tinycolor2 */ \"./node_modules/tinycolor2/tinycolor.js\");\nvar isArrayOrTypedArray = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").isArrayOrTypedArray;\n\nexports.coerceString = function(attributeDefinition, value, defaultValue) {\n if(typeof value === 'string') {\n if(value || !attributeDefinition.noBlank) return value;\n } else if(typeof value === 'number' || value === true) {\n if(!attributeDefinition.strict) return String(value);\n }\n\n return (defaultValue !== undefined) ?\n defaultValue :\n attributeDefinition.dflt;\n};\n\nexports.coerceNumber = function(attributeDefinition, value, defaultValue) {\n if(isNumeric(value)) {\n value = +value;\n\n var min = attributeDefinition.min;\n var max = attributeDefinition.max;\n var isOutOfBounds = (min !== undefined && value < min) ||\n (max !== undefined && value > max);\n\n if(!isOutOfBounds) return value;\n }\n\n return (defaultValue !== undefined) ?\n defaultValue :\n attributeDefinition.dflt;\n};\n\nexports.coerceColor = function(attributeDefinition, value, defaultValue) {\n if(tinycolor(value).isValid()) return value;\n\n return (defaultValue !== undefined) ?\n defaultValue :\n attributeDefinition.dflt;\n};\n\nexports.coerceEnumerated = function(attributeDefinition, value, defaultValue) {\n if(attributeDefinition.coerceNumber) value = +value;\n\n if(attributeDefinition.values.indexOf(value) !== -1) return value;\n\n return (defaultValue !== undefined) ?\n defaultValue :\n attributeDefinition.dflt;\n};\n\nexports.getValue = function(arrayOrScalar, index) {\n var value;\n if(!Array.isArray(arrayOrScalar)) value = arrayOrScalar;\n else if(index < arrayOrScalar.length) value = arrayOrScalar[index];\n return value;\n};\n\nexports.getLineWidth = function(trace, di) {\n var w =\n (0 < di.mlw) ? di.mlw :\n !isArrayOrTypedArray(trace.marker.line.width) ? trace.marker.line.width :\n 0;\n\n return w;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/helpers.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/hover.js":
-/*!********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/hover.js ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Fx = __webpack_require__(/*! ../../components/fx */ \"./node_modules/plotly.js/src/components/fx/index.js\");\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\n\nvar fillText = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").fillText;\nvar getLineWidth = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/traces/bar/helpers.js\").getLineWidth;\nvar hoverLabelText = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\").hoverLabelText;\n\nfunction hoverPoints(pointData, xval, yval, hovermode) {\n var barPointData = hoverOnBars(pointData, xval, yval, hovermode);\n\n if(barPointData) {\n var cd = barPointData.cd;\n var trace = cd[0].trace;\n var di = cd[barPointData.index];\n\n barPointData.color = getTraceColor(trace, di);\n Registry.getComponentMethod('errorbars', 'hoverInfo')(di, trace, barPointData);\n\n return [barPointData];\n }\n}\n\nfunction hoverOnBars(pointData, xval, yval, hovermode) {\n var cd = pointData.cd;\n var trace = cd[0].trace;\n var t = cd[0].t;\n var isClosest = (hovermode === 'closest');\n var isWaterfall = (trace.type === 'waterfall');\n var maxHoverDistance = pointData.maxHoverDistance;\n var maxSpikeDistance = pointData.maxSpikeDistance;\n\n var posVal, sizeVal, posLetter, sizeLetter, dx, dy, pRangeCalc;\n\n function thisBarMinPos(di) { return di[posLetter] - di.w / 2; }\n function thisBarMaxPos(di) { return di[posLetter] + di.w / 2; }\n\n var minPos = isClosest ?\n thisBarMinPos :\n function(di) {\n /*\n * In compare mode, accept a bar if you're on it *or* its group.\n * Nearly always it's the group that matters, but in case the bar\n * was explicitly set wider than its group we'd better accept the\n * whole bar.\n *\n * use `bardelta` instead of `bargroupwidth` so we accept hover\n * in the gap. That way hover doesn't flash on and off as you\n * mouse over the plot in compare modes.\n * In 'closest' mode though the flashing seems inevitable,\n * without far more complex logic\n */\n return Math.min(thisBarMinPos(di), di.p - t.bardelta / 2);\n };\n\n var maxPos = isClosest ?\n thisBarMaxPos :\n function(di) {\n return Math.max(thisBarMaxPos(di), di.p + t.bardelta / 2);\n };\n\n function _positionFn(_minPos, _maxPos) {\n // add a little to the pseudo-distance for wider bars, so that like scatter,\n // if you are over two overlapping bars, the narrower one wins.\n return Fx.inbox(_minPos - posVal, _maxPos - posVal,\n maxHoverDistance + Math.min(1, Math.abs(_maxPos - _minPos) / pRangeCalc) - 1);\n }\n\n function positionFn(di) {\n return _positionFn(minPos(di), maxPos(di));\n }\n\n function thisBarPositionFn(di) {\n return _positionFn(thisBarMinPos(di), thisBarMaxPos(di));\n }\n\n function sizeFn(di) {\n var v = sizeVal;\n var b = di.b;\n var s = di[sizeLetter];\n\n if(isWaterfall) {\n s += Math.abs(di.rawS || 0);\n }\n\n // add a gradient so hovering near the end of a\n // bar makes it a little closer match\n return Fx.inbox(b - v, s - v, maxHoverDistance + (s - v) / (s - b) - 1);\n }\n\n if(trace.orientation === 'h') {\n posVal = yval;\n sizeVal = xval;\n posLetter = 'y';\n sizeLetter = 'x';\n dx = sizeFn;\n dy = positionFn;\n } else {\n posVal = xval;\n sizeVal = yval;\n posLetter = 'x';\n sizeLetter = 'y';\n dy = sizeFn;\n dx = positionFn;\n }\n\n var pa = pointData[posLetter + 'a'];\n var sa = pointData[sizeLetter + 'a'];\n\n pRangeCalc = Math.abs(pa.r2c(pa.range[1]) - pa.r2c(pa.range[0]));\n\n function dxy(di) { return (dx(di) + dy(di)) / 2; }\n var distfn = Fx.getDistanceFunction(hovermode, dx, dy, dxy);\n Fx.getClosest(cd, distfn, pointData);\n\n // skip the rest (for this trace) if we didn't find a close point\n if(pointData.index === false) return;\n\n // if we get here and we're not in 'closest' mode, push min/max pos back\n // onto the group - even though that means occasionally the mouse will be\n // over the hover label.\n if(!isClosest) {\n minPos = function(di) {\n return Math.min(thisBarMinPos(di), di.p - t.bargroupwidth / 2);\n };\n maxPos = function(di) {\n return Math.max(thisBarMaxPos(di), di.p + t.bargroupwidth / 2);\n };\n }\n\n // the closest data point\n var index = pointData.index;\n var di = cd[index];\n\n var size = (trace.base) ? di.b + di.s : di.s;\n pointData[sizeLetter + '0'] = pointData[sizeLetter + '1'] = sa.c2p(di[sizeLetter], true);\n pointData[sizeLetter + 'LabelVal'] = size;\n\n var extent = t.extents[t.extents.round(di.p)];\n pointData[posLetter + '0'] = pa.c2p(isClosest ? minPos(di) : extent[0], true);\n pointData[posLetter + '1'] = pa.c2p(isClosest ? maxPos(di) : extent[1], true);\n pointData[posLetter + 'LabelVal'] = di.p;\n\n pointData.labelLabel = hoverLabelText(pa, pointData[posLetter + 'LabelVal']);\n pointData.valueLabel = hoverLabelText(sa, pointData[sizeLetter + 'LabelVal']);\n\n // spikelines always want \"closest\" distance regardless of hovermode\n pointData.spikeDistance = (sizeFn(di) + thisBarPositionFn(di)) / 2 + maxSpikeDistance - maxHoverDistance;\n // they also want to point to the data value, regardless of where the label goes\n // in case of bars shifted within groups\n pointData[posLetter + 'Spike'] = pa.c2p(di.p, true);\n\n fillText(di, trace, pointData);\n pointData.hovertemplate = trace.hovertemplate;\n\n return pointData;\n}\n\nfunction getTraceColor(trace, di) {\n var mc = di.mcc || trace.marker.color;\n var mlc = di.mlcc || trace.marker.line.color;\n var mlw = getLineWidth(trace, di);\n\n if(Color.opacity(mc)) return mc;\n else if(Color.opacity(mlc) && mlw) return mlc;\n}\n\nmodule.exports = {\n hoverPoints: hoverPoints,\n hoverOnBars: hoverOnBars,\n getTraceColor: getTraceColor\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/index.js":
-/*!********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/index.js ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/bar/attributes.js\"),\n layoutAttributes: __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/bar/layout_attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/bar/defaults.js\").supplyDefaults,\n crossTraceDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/bar/defaults.js\").crossTraceDefaults,\n supplyLayoutDefaults: __webpack_require__(/*! ./layout_defaults */ \"./node_modules/plotly.js/src/traces/bar/layout_defaults.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/bar/calc.js\"),\n crossTraceCalc: __webpack_require__(/*! ./cross_trace_calc */ \"./node_modules/plotly.js/src/traces/bar/cross_trace_calc.js\").crossTraceCalc,\n colorbar: __webpack_require__(/*! ../scatter/marker_colorbar */ \"./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js\"),\n arraysToCalcdata: __webpack_require__(/*! ./arrays_to_calcdata */ \"./node_modules/plotly.js/src/traces/bar/arrays_to_calcdata.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/bar/plot.js\").plot,\n style: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/bar/style.js\").style,\n styleOnSelect: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/bar/style.js\").styleOnSelect,\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/bar/hover.js\").hoverPoints,\n eventData: __webpack_require__(/*! ./event_data */ \"./node_modules/plotly.js/src/traces/bar/event_data.js\"),\n selectPoints: __webpack_require__(/*! ./select */ \"./node_modules/plotly.js/src/traces/bar/select.js\"),\n\n moduleType: 'trace',\n name: 'bar',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['bar-like', 'cartesian', 'svg', 'bar', 'oriented', 'errorBarsOK', 'showLegend', 'zoomScale'],\n animatable: true,\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/layout_attributes.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/layout_attributes.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nmodule.exports = {\n barmode: {\n valType: 'enumerated',\n values: ['stack', 'group', 'overlay', 'relative'],\n dflt: 'group',\n \n editType: 'calc',\n \n },\n barnorm: {\n valType: 'enumerated',\n values: ['', 'fraction', 'percent'],\n dflt: '',\n \n editType: 'calc',\n \n },\n bargap: {\n valType: 'number',\n min: 0,\n max: 1,\n \n editType: 'calc',\n \n },\n bargroupgap: {\n valType: 'number',\n min: 0,\n max: 1,\n dflt: 0,\n \n editType: 'calc',\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/layout_attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/layout_defaults.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/layout_defaults.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar layoutAttributes = __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/bar/layout_attributes.js\");\n\nmodule.exports = function(layoutIn, layoutOut, fullData) {\n function coerce(attr, dflt) {\n return Lib.coerce(layoutIn, layoutOut, layoutAttributes, attr, dflt);\n }\n\n var hasBars = false;\n var shouldBeGapless = false;\n var gappedAnyway = false;\n var usedSubplots = {};\n\n var mode = coerce('barmode');\n\n for(var i = 0; i < fullData.length; i++) {\n var trace = fullData[i];\n if(Registry.traceIs(trace, 'bar') && trace.visible) hasBars = true;\n else continue;\n\n // if we have at least 2 grouped bar traces on the same subplot,\n // we should default to a gap anyway, even if the data is histograms\n if(mode === 'group') {\n var subploti = trace.xaxis + trace.yaxis;\n if(usedSubplots[subploti]) gappedAnyway = true;\n usedSubplots[subploti] = true;\n }\n\n if(trace.visible && trace.type === 'histogram') {\n var pa = Axes.getFromId({_fullLayout: layoutOut},\n trace[trace.orientation === 'v' ? 'xaxis' : 'yaxis']);\n if(pa.type !== 'category') shouldBeGapless = true;\n }\n }\n\n if(!hasBars) {\n delete layoutOut.barmode;\n return;\n }\n\n if(mode !== 'overlay') coerce('barnorm');\n\n coerce('bargap', (shouldBeGapless && !gappedAnyway) ? 0 : 0.2);\n coerce('bargroupgap');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/layout_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/plot.js":
-/*!*******************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/plot.js ***!
- \*******************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar svgTextUtils = __webpack_require__(/*! ../../lib/svg_text_utils */ \"./node_modules/plotly.js/src/lib/svg_text_utils.js\");\n\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar tickText = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\").tickText;\n\nvar uniformText = __webpack_require__(/*! ./uniform_text */ \"./node_modules/plotly.js/src/traces/bar/uniform_text.js\");\nvar recordMinTextSize = uniformText.recordMinTextSize;\nvar clearMinTextSize = uniformText.clearMinTextSize;\n\nvar style = __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/bar/style.js\");\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/traces/bar/helpers.js\");\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/bar/constants.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/bar/attributes.js\");\n\nvar attributeText = attributes.text;\nvar attributeTextPosition = attributes.textposition;\n\nvar appendArrayPointValue = __webpack_require__(/*! ../../components/fx/helpers */ \"./node_modules/plotly.js/src/components/fx/helpers.js\").appendArrayPointValue;\n\nvar TEXTPAD = constants.TEXTPAD;\n\nfunction keyFunc(d) {return d.id;}\nfunction getKeyFunc(trace) {\n if(trace.ids) {\n return keyFunc;\n }\n}\n\nfunction dirSign(a, b) {\n return (a < b) ? 1 : -1;\n}\n\nfunction getXY(di, xa, ya, isHorizontal) {\n var s = [];\n var p = [];\n\n var sAxis = isHorizontal ? xa : ya;\n var pAxis = isHorizontal ? ya : xa;\n\n s[0] = sAxis.c2p(di.s0, true);\n p[0] = pAxis.c2p(di.p0, true);\n\n s[1] = sAxis.c2p(di.s1, true);\n p[1] = pAxis.c2p(di.p1, true);\n\n return isHorizontal ? [s, p] : [p, s];\n}\n\nfunction transition(selection, fullLayout, opts, makeOnCompleteCallback) {\n if(!fullLayout.uniformtext.mode && hasTransition(opts)) {\n var onComplete;\n if(makeOnCompleteCallback) {\n onComplete = makeOnCompleteCallback();\n }\n return selection\n .transition()\n .duration(opts.duration)\n .ease(opts.easing)\n .each('end', function() { onComplete && onComplete(); })\n .each('interrupt', function() { onComplete && onComplete(); });\n } else {\n return selection;\n }\n}\n\nfunction hasTransition(transitionOpts) {\n return transitionOpts && transitionOpts.duration > 0;\n}\n\nfunction plot(gd, plotinfo, cdModule, traceLayer, opts, makeOnCompleteCallback) {\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n var fullLayout = gd._fullLayout;\n\n if(!opts) {\n opts = {\n mode: fullLayout.barmode,\n norm: fullLayout.barmode,\n gap: fullLayout.bargap,\n groupgap: fullLayout.bargroupgap\n };\n\n // don't clear bar when this is called from waterfall or funnel\n clearMinTextSize('bar', fullLayout);\n }\n\n var bartraces = Lib.makeTraceGroups(traceLayer, cdModule, 'trace bars').each(function(cd) {\n var plotGroup = d3.select(this);\n var trace = cd[0].trace;\n var isWaterfall = (trace.type === 'waterfall');\n var isFunnel = (trace.type === 'funnel');\n var isBar = (trace.type === 'bar');\n var shouldDisplayZeros = (isBar || isFunnel);\n\n var adjustPixel = 0;\n if(isWaterfall && trace.connector.visible && trace.connector.mode === 'between') {\n adjustPixel = trace.connector.line.width / 2;\n }\n\n var isHorizontal = (trace.orientation === 'h');\n\n var pointGroup = Lib.ensureSingle(plotGroup, 'g', 'points');\n\n var keyFunc = getKeyFunc(trace);\n var bars = pointGroup.selectAll('g.point').data(Lib.identity, keyFunc);\n\n bars.enter().append('g')\n .classed('point', true);\n\n bars.exit().remove();\n\n bars.each(function(di, i) {\n var bar = d3.select(this);\n\n // now display the bar\n // clipped xf/yf (2nd arg true): non-positive\n // log values go off-screen by plotwidth\n // so you see them continue if you drag the plot\n var xy = getXY(di, xa, ya, isHorizontal);\n\n var x0 = xy[0][0];\n var x1 = xy[0][1];\n var y0 = xy[1][0];\n var y1 = xy[1][1];\n\n var isBlank = (\n x0 === x1 ||\n y0 === y1 ||\n !isNumeric(x0) ||\n !isNumeric(x1) ||\n !isNumeric(y0) ||\n !isNumeric(y1)\n );\n // display zeros if line.width > 0\n if(isBlank && shouldDisplayZeros && helpers.getLineWidth(trace, di) && (isHorizontal ? x1 - x0 === 0 : y1 - y0 === 0)) {\n isBlank = false;\n }\n di.isBlank = isBlank;\n\n if(isBlank && isHorizontal) x1 = x0;\n if(isBlank && !isHorizontal) y1 = y0;\n\n // in waterfall mode `between` we need to adjust bar end points to match the connector width\n if(adjustPixel && !isBlank) {\n if(isHorizontal) {\n x0 -= dirSign(x0, x1) * adjustPixel;\n x1 += dirSign(x0, x1) * adjustPixel;\n } else {\n y0 -= dirSign(y0, y1) * adjustPixel;\n y1 += dirSign(y0, y1) * adjustPixel;\n }\n }\n\n var lw;\n var mc;\n\n if(trace.type === 'waterfall') {\n if(!isBlank) {\n var cont = trace[di.dir].marker;\n lw = cont.line.width;\n mc = cont.color;\n }\n } else {\n lw = helpers.getLineWidth(trace, di);\n mc = di.mc || trace.marker.color;\n }\n\n var offset = d3.round((lw / 2) % 1, 2);\n\n function roundWithLine(v) {\n // if there are explicit gaps, don't round,\n // it can make the gaps look crappy\n return (opts.gap === 0 && opts.groupgap === 0) ?\n d3.round(Math.round(v) - offset, 2) : v;\n }\n\n function expandToVisible(v, vc) {\n // if it's not in danger of disappearing entirely,\n // round more precisely\n return Math.abs(v - vc) >= 2 ? roundWithLine(v) :\n // but if it's very thin, expand it so it's\n // necessarily visible, even if it might overlap\n // its neighbor\n (v > vc ? Math.ceil(v) : Math.floor(v));\n }\n\n if(!gd._context.staticPlot) {\n // if bars are not fully opaque or they have a line\n // around them, round to integer pixels, mainly for\n // safari so we prevent overlaps from its expansive\n // pixelation. if the bars ARE fully opaque and have\n // no line, expand to a full pixel to make sure we\n // can see them\n\n var op = Color.opacity(mc);\n var fixpx = (op < 1 || lw > 0.01) ? roundWithLine : expandToVisible;\n x0 = fixpx(x0, x1);\n x1 = fixpx(x1, x0);\n y0 = fixpx(y0, y1);\n y1 = fixpx(y1, y0);\n }\n\n var sel = transition(Lib.ensureSingle(bar, 'path'), fullLayout, opts, makeOnCompleteCallback);\n sel\n .style('vector-effect', 'non-scaling-stroke')\n .attr('d', 'M' + x0 + ',' + y0 + 'V' + y1 + 'H' + x1 + 'V' + y0 + 'Z')\n .call(Drawing.setClipUrl, plotinfo.layerClipId, gd);\n\n if(!fullLayout.uniformtext.mode && hasTransition(opts)) {\n var styleFns = Drawing.makePointStyleFns(trace);\n Drawing.singlePointStyle(di, sel, trace, styleFns, gd);\n }\n\n appendBarText(gd, plotinfo, bar, cd, i, x0, x1, y0, y1, opts, makeOnCompleteCallback);\n\n if(plotinfo.layerClipId) {\n Drawing.hideOutsideRangePoint(di, bar.select('text'), xa, ya, trace.xcalendar, trace.ycalendar);\n }\n });\n\n // lastly, clip points groups of `cliponaxis !== false` traces\n // on `plotinfo._hasClipOnAxisFalse === true` subplots\n var hasClipOnAxisFalse = trace.cliponaxis === false;\n Drawing.setClipUrl(plotGroup, hasClipOnAxisFalse ? null : plotinfo.layerClipId, gd);\n });\n\n // error bars are on the top\n Registry.getComponentMethod('errorbars', 'plot')(gd, bartraces, plotinfo, opts);\n}\n\nfunction appendBarText(gd, plotinfo, bar, cd, i, x0, x1, y0, y1, opts, makeOnCompleteCallback) {\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n\n var fullLayout = gd._fullLayout;\n var textPosition;\n\n function appendTextNode(bar, text, font) {\n var textSelection = Lib.ensureSingle(bar, 'text')\n .text(text)\n .attr({\n 'class': 'bartext bartext-' + textPosition,\n 'text-anchor': 'middle',\n // prohibit tex interpretation until we can handle\n // tex and regular text together\n 'data-notex': 1\n })\n .call(Drawing.font, font)\n .call(svgTextUtils.convertToTspans, gd);\n\n return textSelection;\n }\n\n // get trace attributes\n var trace = cd[0].trace;\n var isHorizontal = (trace.orientation === 'h');\n\n var text = getText(fullLayout, cd, i, xa, ya);\n textPosition = getTextPosition(trace, i);\n\n // compute text position\n var inStackOrRelativeMode =\n opts.mode === 'stack' ||\n opts.mode === 'relative';\n\n var calcBar = cd[i];\n var isOutmostBar = !inStackOrRelativeMode || calcBar._outmost;\n\n if(!text ||\n textPosition === 'none' ||\n ((calcBar.isBlank || x0 === x1 || y0 === y1) && (\n textPosition === 'auto' ||\n textPosition === 'inside'))) {\n bar.select('text').remove();\n return;\n }\n\n var layoutFont = fullLayout.font;\n var barColor = style.getBarColor(cd[i], trace);\n var insideTextFont = style.getInsideTextFont(trace, i, layoutFont, barColor);\n var outsideTextFont = style.getOutsideTextFont(trace, i, layoutFont);\n\n // Special case: don't use the c2p(v, true) value on log size axes,\n // so that we can get correctly inside text scaling\n var di = bar.datum();\n if(isHorizontal) {\n if(xa.type === 'log' && di.s0 <= 0) {\n if(xa.range[0] < xa.range[1]) {\n x0 = 0;\n } else {\n x0 = xa._length;\n }\n }\n } else {\n if(ya.type === 'log' && di.s0 <= 0) {\n if(ya.range[0] < ya.range[1]) {\n y0 = ya._length;\n } else {\n y0 = 0;\n }\n }\n }\n\n // padding excluded\n var barWidth = Math.abs(x1 - x0) - 2 * TEXTPAD;\n var barHeight = Math.abs(y1 - y0) - 2 * TEXTPAD;\n\n var textSelection;\n var textBB;\n var textWidth;\n var textHeight;\n var font;\n\n if(textPosition === 'outside') {\n if(!isOutmostBar && !calcBar.hasB) textPosition = 'inside';\n }\n\n if(textPosition === 'auto') {\n if(isOutmostBar) {\n // draw text using insideTextFont and check if it fits inside bar\n textPosition = 'inside';\n\n font = Lib.ensureUniformFontSize(gd, insideTextFont);\n\n textSelection = appendTextNode(bar, text, font);\n\n textBB = Drawing.bBox(textSelection.node()),\n textWidth = textBB.width,\n textHeight = textBB.height;\n\n var textHasSize = (textWidth > 0 && textHeight > 0);\n var fitsInside = (textWidth <= barWidth && textHeight <= barHeight);\n var fitsInsideIfRotated = (textWidth <= barHeight && textHeight <= barWidth);\n var fitsInsideIfShrunk = (isHorizontal) ?\n (barWidth >= textWidth * (barHeight / textHeight)) :\n (barHeight >= textHeight * (barWidth / textWidth));\n\n if(textHasSize && (\n fitsInside ||\n fitsInsideIfRotated ||\n fitsInsideIfShrunk)\n ) {\n textPosition = 'inside';\n } else {\n textPosition = 'outside';\n textSelection.remove();\n textSelection = null;\n }\n } else {\n textPosition = 'inside';\n }\n }\n\n if(!textSelection) {\n font = Lib.ensureUniformFontSize(gd, (textPosition === 'outside') ? outsideTextFont : insideTextFont);\n\n textSelection = appendTextNode(bar, text, font);\n\n var currentTransform = textSelection.attr('transform');\n textSelection.attr('transform', '');\n textBB = Drawing.bBox(textSelection.node()),\n textWidth = textBB.width,\n textHeight = textBB.height;\n textSelection.attr('transform', currentTransform);\n\n if(textWidth <= 0 || textHeight <= 0) {\n textSelection.remove();\n return;\n }\n }\n\n var angle = trace.textangle;\n\n // compute text transform\n var transform, constrained;\n if(textPosition === 'outside') {\n constrained =\n trace.constraintext === 'both' ||\n trace.constraintext === 'outside';\n\n transform = toMoveOutsideBar(x0, x1, y0, y1, textBB, {\n isHorizontal: isHorizontal,\n constrained: constrained,\n angle: angle\n });\n } else {\n constrained =\n trace.constraintext === 'both' ||\n trace.constraintext === 'inside';\n\n transform = toMoveInsideBar(x0, x1, y0, y1, textBB, {\n isHorizontal: isHorizontal,\n constrained: constrained,\n angle: angle,\n anchor: trace.insidetextanchor\n });\n }\n\n transform.fontSize = font.size;\n recordMinTextSize(trace.type, transform, fullLayout);\n calcBar.transform = transform;\n\n transition(textSelection, fullLayout, opts, makeOnCompleteCallback)\n .attr('transform', Lib.getTextTransform(transform));\n}\n\nfunction getRotateFromAngle(angle) {\n return (angle === 'auto') ? 0 : angle;\n}\n\nfunction getRotatedTextSize(textBB, rotate) {\n var a = Math.PI / 180 * rotate;\n var absSin = Math.abs(Math.sin(a));\n var absCos = Math.abs(Math.cos(a));\n\n return {\n x: textBB.width * absCos + textBB.height * absSin,\n y: textBB.width * absSin + textBB.height * absCos\n };\n}\n\nfunction toMoveInsideBar(x0, x1, y0, y1, textBB, opts) {\n var isHorizontal = !!opts.isHorizontal;\n var constrained = !!opts.constrained;\n var angle = opts.angle || 0;\n var anchor = opts.anchor || 'end';\n var isEnd = anchor === 'end';\n var isStart = anchor === 'start';\n var leftToRight = opts.leftToRight || 0; // left: -1, center: 0, right: 1\n var toRight = (leftToRight + 1) / 2;\n var toLeft = 1 - toRight;\n\n var textWidth = textBB.width;\n var textHeight = textBB.height;\n var lx = Math.abs(x1 - x0);\n var ly = Math.abs(y1 - y0);\n\n // compute remaining space\n var textpad = (\n lx > (2 * TEXTPAD) &&\n ly > (2 * TEXTPAD)\n ) ? TEXTPAD : 0;\n\n lx -= 2 * textpad;\n ly -= 2 * textpad;\n\n var rotate = getRotateFromAngle(angle);\n if((angle === 'auto') &&\n !(textWidth <= lx && textHeight <= ly) &&\n (textWidth > lx || textHeight > ly) && (\n !(textWidth > ly || textHeight > lx) ||\n ((textWidth < textHeight) !== (lx < ly))\n )) {\n rotate += 90;\n }\n\n var t = getRotatedTextSize(textBB, rotate);\n\n var scale = 1;\n if(constrained) {\n scale = Math.min(\n 1,\n lx / t.x,\n ly / t.y\n );\n }\n\n // compute text and target positions\n var textX = (\n textBB.left * toLeft +\n textBB.right * toRight\n );\n var textY = (textBB.top + textBB.bottom) / 2;\n var targetX = (\n (x0 + TEXTPAD) * toLeft +\n (x1 - TEXTPAD) * toRight\n );\n var targetY = (y0 + y1) / 2;\n var anchorX = 0;\n var anchorY = 0;\n if(isStart || isEnd) {\n var extrapad = (isHorizontal ? t.x : t.y) / 2;\n var dir = isHorizontal ? dirSign(x0, x1) : dirSign(y0, y1);\n\n if(isHorizontal) {\n if(isStart) {\n targetX = x0 + dir * textpad;\n anchorX = -dir * extrapad;\n } else {\n targetX = x1 - dir * textpad;\n anchorX = dir * extrapad;\n }\n } else {\n if(isStart) {\n targetY = y0 + dir * textpad;\n anchorY = -dir * extrapad;\n } else {\n targetY = y1 - dir * textpad;\n anchorY = dir * extrapad;\n }\n }\n }\n\n return {\n textX: textX,\n textY: textY,\n targetX: targetX,\n targetY: targetY,\n anchorX: anchorX,\n anchorY: anchorY,\n scale: scale,\n rotate: rotate\n };\n}\n\nfunction toMoveOutsideBar(x0, x1, y0, y1, textBB, opts) {\n var isHorizontal = !!opts.isHorizontal;\n var constrained = !!opts.constrained;\n var angle = opts.angle || 0;\n\n var textWidth = textBB.width;\n var textHeight = textBB.height;\n var lx = Math.abs(x1 - x0);\n var ly = Math.abs(y1 - y0);\n\n var textpad;\n // Keep the padding so the text doesn't sit right against\n // the bars, but don't factor it into barWidth\n if(isHorizontal) {\n textpad = (ly > 2 * TEXTPAD) ? TEXTPAD : 0;\n } else {\n textpad = (lx > 2 * TEXTPAD) ? TEXTPAD : 0;\n }\n\n // compute rotate and scale\n var scale = 1;\n if(constrained) {\n scale = (isHorizontal) ?\n Math.min(1, ly / textHeight) :\n Math.min(1, lx / textWidth);\n }\n\n var rotate = getRotateFromAngle(angle);\n var t = getRotatedTextSize(textBB, rotate);\n\n // compute text and target positions\n var extrapad = (isHorizontal ? t.x : t.y) / 2;\n var textX = (textBB.left + textBB.right) / 2;\n var textY = (textBB.top + textBB.bottom) / 2;\n var targetX = (x0 + x1) / 2;\n var targetY = (y0 + y1) / 2;\n var anchorX = 0;\n var anchorY = 0;\n\n var dir = isHorizontal ? dirSign(x1, x0) : dirSign(y0, y1);\n if(isHorizontal) {\n targetX = x1 - dir * textpad;\n anchorX = dir * extrapad;\n } else {\n targetY = y1 + dir * textpad;\n anchorY = -dir * extrapad;\n }\n\n return {\n textX: textX,\n textY: textY,\n targetX: targetX,\n targetY: targetY,\n anchorX: anchorX,\n anchorY: anchorY,\n scale: scale,\n rotate: rotate\n };\n}\n\nfunction getText(fullLayout, cd, index, xa, ya) {\n var trace = cd[0].trace;\n var texttemplate = trace.texttemplate;\n\n var value;\n if(texttemplate) {\n value = calcTexttemplate(fullLayout, cd, index, xa, ya);\n } else if(trace.textinfo) {\n value = calcTextinfo(cd, index, xa, ya);\n } else {\n value = helpers.getValue(trace.text, index);\n }\n\n return helpers.coerceString(attributeText, value);\n}\n\nfunction getTextPosition(trace, index) {\n var value = helpers.getValue(trace.textposition, index);\n return helpers.coerceEnumerated(attributeTextPosition, value);\n}\n\nfunction calcTexttemplate(fullLayout, cd, index, xa, ya) {\n var trace = cd[0].trace;\n var texttemplate = Lib.castOption(trace, index, 'texttemplate');\n if(!texttemplate) return '';\n var isWaterfall = (trace.type === 'waterfall');\n var isFunnel = (trace.type === 'funnel');\n\n var pLetter, pAxis;\n var vLetter, vAxis;\n if(trace.orientation === 'h') {\n pLetter = 'y';\n pAxis = ya;\n vLetter = 'x';\n vAxis = xa;\n } else {\n pLetter = 'x';\n pAxis = xa;\n vLetter = 'y';\n vAxis = ya;\n }\n\n function formatLabel(u) {\n return tickText(pAxis, u, true).text;\n }\n\n function formatNumber(v) {\n return tickText(vAxis, +v, true).text;\n }\n\n var cdi = cd[index];\n var obj = {};\n\n obj.label = cdi.p;\n obj.labelLabel = obj[pLetter + 'Label'] = formatLabel(cdi.p);\n\n var tx = Lib.castOption(trace, cdi.i, 'text');\n if(tx === 0 || tx) obj.text = tx;\n\n obj.value = cdi.s;\n obj.valueLabel = obj[vLetter + 'Label'] = formatNumber(cdi.s);\n\n var pt = {};\n appendArrayPointValue(pt, trace, cdi.i);\n\n if(isWaterfall) {\n obj.delta = +cdi.rawS || cdi.s;\n obj.deltaLabel = formatNumber(obj.delta);\n obj.final = cdi.v;\n obj.finalLabel = formatNumber(obj.final);\n obj.initial = obj.final - obj.delta;\n obj.initialLabel = formatNumber(obj.initial);\n }\n\n if(isFunnel) {\n obj.value = cdi.s;\n obj.valueLabel = formatNumber(obj.value);\n\n obj.percentInitial = cdi.begR;\n obj.percentInitialLabel = Lib.formatPercent(cdi.begR);\n obj.percentPrevious = cdi.difR;\n obj.percentPreviousLabel = Lib.formatPercent(cdi.difR);\n obj.percentTotal = cdi.sumR;\n obj.percenTotalLabel = Lib.formatPercent(cdi.sumR);\n }\n\n var customdata = Lib.castOption(trace, cdi.i, 'customdata');\n if(customdata) obj.customdata = customdata;\n return Lib.texttemplateString(texttemplate, obj, fullLayout._d3locale, pt, obj, trace._meta || {});\n}\n\nfunction calcTextinfo(cd, index, xa, ya) {\n var trace = cd[0].trace;\n var isHorizontal = (trace.orientation === 'h');\n var isWaterfall = (trace.type === 'waterfall');\n var isFunnel = (trace.type === 'funnel');\n\n function formatLabel(u) {\n var pAxis = isHorizontal ? ya : xa;\n return tickText(pAxis, u, true).text;\n }\n\n function formatNumber(v) {\n var sAxis = isHorizontal ? xa : ya;\n return tickText(sAxis, +v, true).text;\n }\n\n var textinfo = trace.textinfo;\n var cdi = cd[index];\n\n var parts = textinfo.split('+');\n var text = [];\n var tx;\n\n var hasFlag = function(flag) { return parts.indexOf(flag) !== -1; };\n\n if(hasFlag('label')) {\n text.push(formatLabel(cd[index].p));\n }\n\n if(hasFlag('text')) {\n tx = Lib.castOption(trace, cdi.i, 'text');\n if(tx === 0 || tx) text.push(tx);\n }\n\n if(isWaterfall) {\n var delta = +cdi.rawS || cdi.s;\n var final = cdi.v;\n var initial = final - delta;\n\n if(hasFlag('initial')) text.push(formatNumber(initial));\n if(hasFlag('delta')) text.push(formatNumber(delta));\n if(hasFlag('final')) text.push(formatNumber(final));\n }\n\n if(isFunnel) {\n if(hasFlag('value')) text.push(formatNumber(cdi.s));\n\n var nPercent = 0;\n if(hasFlag('percent initial')) nPercent++;\n if(hasFlag('percent previous')) nPercent++;\n if(hasFlag('percent total')) nPercent++;\n\n var hasMultiplePercents = nPercent > 1;\n\n if(hasFlag('percent initial')) {\n tx = Lib.formatPercent(cdi.begR);\n if(hasMultiplePercents) tx += ' of initial';\n text.push(tx);\n }\n if(hasFlag('percent previous')) {\n tx = Lib.formatPercent(cdi.difR);\n if(hasMultiplePercents) tx += ' of previous';\n text.push(tx);\n }\n if(hasFlag('percent total')) {\n tx = Lib.formatPercent(cdi.sumR);\n if(hasMultiplePercents) tx += ' of total';\n text.push(tx);\n }\n }\n\n return text.join('
');\n}\n\nmodule.exports = {\n plot: plot,\n toMoveInsideBar: toMoveInsideBar\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/select.js":
-/*!*********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/select.js ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function selectPoints(searchInfo, selectionTester) {\n var cd = searchInfo.cd;\n var xa = searchInfo.xaxis;\n var ya = searchInfo.yaxis;\n var trace = cd[0].trace;\n var isFunnel = (trace.type === 'funnel');\n var isHorizontal = (trace.orientation === 'h');\n var selection = [];\n var i;\n\n if(selectionTester === false) {\n // clear selection\n for(i = 0; i < cd.length; i++) {\n cd[i].selected = 0;\n }\n } else {\n for(i = 0; i < cd.length; i++) {\n var di = cd[i];\n var ct = 'ct' in di ? di.ct : getCentroid(di, xa, ya, isHorizontal, isFunnel);\n\n if(selectionTester.contains(ct, false, i, searchInfo)) {\n selection.push({\n pointNumber: i,\n x: xa.c2d(di.x),\n y: ya.c2d(di.y)\n });\n di.selected = 1;\n } else {\n di.selected = 0;\n }\n }\n }\n\n return selection;\n};\n\nfunction getCentroid(d, xa, ya, isHorizontal, isFunnel) {\n var x0 = xa.c2p(isHorizontal ? d.s0 : d.p0, true);\n var x1 = xa.c2p(isHorizontal ? d.s1 : d.p1, true);\n var y0 = ya.c2p(isHorizontal ? d.p0 : d.s0, true);\n var y1 = ya.c2p(isHorizontal ? d.p1 : d.s1, true);\n\n if(isFunnel) {\n return [(x0 + x1) / 2, (y0 + y1) / 2];\n } else {\n if(isHorizontal) {\n return [x1, (y0 + y1) / 2];\n } else {\n return [(x0 + x1) / 2, y1];\n }\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/select.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/sieve.js":
-/*!********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/sieve.js ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = Sieve;\n\nvar distinctVals = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").distinctVals;\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\n/**\n * Helper class to sieve data from traces into bins\n *\n * @class\n *\n * @param {Array} traces\n* Array of calculated traces\n * @param {object} opts\n * - @param {boolean} [sepNegVal]\n * If true, then split data at the same position into a bar\n * for positive values and another for negative values\n * - @param {boolean} [overlapNoMerge]\n * If true, then don't merge overlapping bars into a single bar\n */\nfunction Sieve(traces, opts) {\n this.traces = traces;\n this.sepNegVal = opts.sepNegVal;\n this.overlapNoMerge = opts.overlapNoMerge;\n\n // for single-bin histograms - see histogram/calc\n var width1 = Infinity;\n\n var positions = [];\n for(var i = 0; i < traces.length; i++) {\n var trace = traces[i];\n for(var j = 0; j < trace.length; j++) {\n var bar = trace[j];\n if(bar.p !== BADNUM) positions.push(bar.p);\n }\n if(trace[0] && trace[0].width1) {\n width1 = Math.min(trace[0].width1, width1);\n }\n }\n this.positions = positions;\n\n var dv = distinctVals(positions);\n this.distinctPositions = dv.vals;\n if(dv.vals.length === 1 && width1 !== Infinity) this.minDiff = width1;\n else this.minDiff = Math.min(dv.minDiff, width1);\n\n this.binWidth = this.minDiff;\n\n this.bins = {};\n}\n\n/**\n * Sieve datum\n *\n * @method\n * @param {number} position\n * @param {number} value\n * @returns {number} Previous bin value\n */\nSieve.prototype.put = function put(position, value) {\n var label = this.getLabel(position, value);\n var oldValue = this.bins[label] || 0;\n\n this.bins[label] = oldValue + value;\n\n return oldValue;\n};\n\n/**\n * Get current bin value for a given datum\n *\n * @method\n * @param {number} position Position of datum\n * @param {number} [value] Value of datum\n * (required if this.sepNegVal is true)\n * @returns {number} Current bin value\n */\nSieve.prototype.get = function get(position, value) {\n var label = this.getLabel(position, value);\n return this.bins[label] || 0;\n};\n\n/**\n * Get bin label for a given datum\n *\n * @method\n * @param {number} position Position of datum\n * @param {number} [value] Value of datum\n * (required if this.sepNegVal is true)\n * @returns {string} Bin label\n * (prefixed with a 'v' if value is negative and this.sepNegVal is\n * true; otherwise prefixed with '^')\n */\nSieve.prototype.getLabel = function getLabel(position, value) {\n var prefix = (value < 0 && this.sepNegVal) ? 'v' : '^';\n var label = (this.overlapNoMerge) ?\n position :\n Math.round(position / this.binWidth);\n return prefix + label;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/sieve.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/style.js":
-/*!********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/style.js ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\n\nvar resizeText = __webpack_require__(/*! ./uniform_text */ \"./node_modules/plotly.js/src/traces/bar/uniform_text.js\").resizeText;\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/bar/attributes.js\");\nvar attributeTextFont = attributes.textfont;\nvar attributeInsideTextFont = attributes.insidetextfont;\nvar attributeOutsideTextFont = attributes.outsidetextfont;\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/traces/bar/helpers.js\");\n\nfunction style(gd) {\n var s = d3.select(gd).selectAll('g.barlayer').selectAll('g.trace');\n resizeText(gd, s, 'bar');\n\n var barcount = s.size();\n var fullLayout = gd._fullLayout;\n\n // trace styling\n s.style('opacity', function(d) { return d[0].trace.opacity; })\n\n // for gapless (either stacked or neighboring grouped) bars use\n // crispEdges to turn off antialiasing so an artificial gap\n // isn't introduced.\n .each(function(d) {\n if((fullLayout.barmode === 'stack' && barcount > 1) ||\n (fullLayout.bargap === 0 &&\n fullLayout.bargroupgap === 0 &&\n !d[0].trace.marker.line.width)) {\n d3.select(this).attr('shape-rendering', 'crispEdges');\n }\n });\n\n s.selectAll('g.points').each(function(d) {\n var sel = d3.select(this);\n var trace = d[0].trace;\n stylePoints(sel, trace, gd);\n });\n\n Registry.getComponentMethod('errorbars', 'style')(s);\n}\n\nfunction stylePoints(sel, trace, gd) {\n Drawing.pointStyle(sel.selectAll('path'), trace, gd);\n styleTextPoints(sel, trace, gd);\n}\n\nfunction styleTextPoints(sel, trace, gd) {\n sel.selectAll('text').each(function(d) {\n var tx = d3.select(this);\n var font = Lib.ensureUniformFontSize(gd, determineFont(tx, d, trace, gd));\n\n Drawing.font(tx, font);\n });\n}\n\nfunction styleOnSelect(gd, cd, sel) {\n var trace = cd[0].trace;\n\n if(trace.selectedpoints) {\n stylePointsInSelectionMode(sel, trace, gd);\n } else {\n stylePoints(sel, trace, gd);\n Registry.getComponentMethod('errorbars', 'style')(sel);\n }\n}\n\nfunction stylePointsInSelectionMode(s, trace, gd) {\n Drawing.selectedPointStyle(s.selectAll('path'), trace);\n styleTextInSelectionMode(s.selectAll('text'), trace, gd);\n}\n\nfunction styleTextInSelectionMode(txs, trace, gd) {\n txs.each(function(d) {\n var tx = d3.select(this);\n var font;\n\n if(d.selected) {\n font = Lib.ensureUniformFontSize(gd, determineFont(tx, d, trace, gd));\n\n var selectedFontColor = trace.selected.textfont && trace.selected.textfont.color;\n if(selectedFontColor) {\n font.color = selectedFontColor;\n }\n\n Drawing.font(tx, font);\n } else {\n Drawing.selectedTextStyle(tx, trace);\n }\n });\n}\n\nfunction determineFont(tx, d, trace, gd) {\n var layoutFont = gd._fullLayout.font;\n var textFont = trace.textfont;\n\n if(tx.classed('bartext-inside')) {\n var barColor = getBarColor(d, trace);\n textFont = getInsideTextFont(trace, d.i, layoutFont, barColor);\n } else if(tx.classed('bartext-outside')) {\n textFont = getOutsideTextFont(trace, d.i, layoutFont);\n }\n\n return textFont;\n}\n\nfunction getTextFont(trace, index, defaultValue) {\n return getFontValue(\n attributeTextFont, trace.textfont, index, defaultValue);\n}\n\nfunction getInsideTextFont(trace, index, layoutFont, barColor) {\n var defaultFont = getTextFont(trace, index, layoutFont);\n\n var wouldFallBackToLayoutFont =\n (trace._input.textfont === undefined || trace._input.textfont.color === undefined) ||\n (Array.isArray(trace.textfont.color) && trace.textfont.color[index] === undefined);\n if(wouldFallBackToLayoutFont) {\n defaultFont = {\n color: Color.contrast(barColor),\n family: defaultFont.family,\n size: defaultFont.size\n };\n }\n\n return getFontValue(\n attributeInsideTextFont, trace.insidetextfont, index, defaultFont);\n}\n\nfunction getOutsideTextFont(trace, index, layoutFont) {\n var defaultFont = getTextFont(trace, index, layoutFont);\n return getFontValue(\n attributeOutsideTextFont, trace.outsidetextfont, index, defaultFont);\n}\n\nfunction getFontValue(attributeDefinition, attributeValue, index, defaultValue) {\n attributeValue = attributeValue || {};\n\n var familyValue = helpers.getValue(attributeValue.family, index);\n var sizeValue = helpers.getValue(attributeValue.size, index);\n var colorValue = helpers.getValue(attributeValue.color, index);\n\n return {\n family: helpers.coerceString(\n attributeDefinition.family, familyValue, defaultValue.family),\n size: helpers.coerceNumber(\n attributeDefinition.size, sizeValue, defaultValue.size),\n color: helpers.coerceColor(\n attributeDefinition.color, colorValue, defaultValue.color)\n };\n}\n\nfunction getBarColor(cd, trace) {\n if(trace.type === 'waterfall') {\n return trace[cd.dir].marker.color;\n }\n return cd.mc || trace.marker.color;\n}\n\nmodule.exports = {\n style: style,\n styleTextPoints: styleTextPoints,\n styleOnSelect: styleOnSelect,\n getInsideTextFont: getInsideTextFont,\n getOutsideTextFont: getOutsideTextFont,\n getBarColor: getBarColor,\n resizeText: resizeText\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/style_defaults.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/style_defaults.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar hasColorscale = __webpack_require__(/*! ../../components/colorscale/helpers */ \"./node_modules/plotly.js/src/components/colorscale/helpers.js\").hasColorscale;\nvar colorscaleDefaults = __webpack_require__(/*! ../../components/colorscale/defaults */ \"./node_modules/plotly.js/src/components/colorscale/defaults.js\");\n\nmodule.exports = function handleStyleDefaults(traceIn, traceOut, coerce, defaultColor, layout) {\n coerce('marker.color', defaultColor);\n\n if(hasColorscale(traceIn, 'marker')) {\n colorscaleDefaults(\n traceIn, traceOut, layout, coerce, {prefix: 'marker.', cLetter: 'c'}\n );\n }\n\n coerce('marker.line.color', Color.defaultLine);\n\n if(hasColorscale(traceIn, 'marker.line')) {\n colorscaleDefaults(\n traceIn, traceOut, layout, coerce, {prefix: 'marker.line.', cLetter: 'c'}\n );\n }\n\n coerce('marker.line.width');\n coerce('marker.opacity');\n coerce('selected.marker.color');\n coerce('unselected.marker.color');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/style_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/bar/uniform_text.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/bar/uniform_text.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nfunction resizeText(gd, gTrace, traceType) {\n var fullLayout = gd._fullLayout;\n var minSize = fullLayout['_' + traceType + 'Text_minsize'];\n if(minSize) {\n var shouldHide = fullLayout.uniformtext.mode === 'hide';\n\n var selector;\n switch(traceType) {\n case 'funnelarea' :\n case 'pie' :\n case 'sunburst' :\n selector = 'g.slice';\n break;\n case 'treemap' :\n selector = 'g.slice, g.pathbar';\n break;\n default :\n selector = 'g.points > g.point';\n }\n\n gTrace.selectAll(selector).each(function(d) {\n var transform = d.transform;\n if(transform) {\n transform.scale = (shouldHide && transform.hide) ? 0 : minSize / transform.fontSize;\n\n var el = d3.select(this).select('text');\n el.attr('transform', Lib.getTextTransform(transform));\n }\n });\n }\n}\n\nfunction recordMinTextSize(\n traceType, // in\n transform, // inout\n fullLayout // inout\n) {\n if(fullLayout.uniformtext.mode) {\n var minKey = getMinKey(traceType);\n var minSize = fullLayout.uniformtext.minsize;\n var size = transform.scale * transform.fontSize;\n\n transform.hide = size < minSize;\n\n fullLayout[minKey] = fullLayout[minKey] || Infinity;\n if(!transform.hide) {\n fullLayout[minKey] = Math.min(\n fullLayout[minKey],\n Math.max(size, minSize)\n );\n }\n }\n}\n\nfunction clearMinTextSize(\n traceType, // in\n fullLayout // inout\n) {\n var minKey = getMinKey(traceType);\n fullLayout[minKey] = undefined;\n}\n\nfunction getMinKey(traceType) {\n return '_' + traceType + 'Text_minsize';\n}\n\nmodule.exports = {\n recordMinTextSize: recordMinTextSize,\n clearMinTextSize: clearMinTextSize,\n resizeText: resizeText\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/bar/uniform_text.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/barpolar/attributes.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/barpolar/attributes.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar scatterPolarAttrs = __webpack_require__(/*! ../scatterpolar/attributes */ \"./node_modules/plotly.js/src/traces/scatterpolar/attributes.js\");\nvar barAttrs = __webpack_require__(/*! ../bar/attributes */ \"./node_modules/plotly.js/src/traces/bar/attributes.js\");\n\nmodule.exports = {\n r: scatterPolarAttrs.r,\n theta: scatterPolarAttrs.theta,\n r0: scatterPolarAttrs.r0,\n dr: scatterPolarAttrs.dr,\n theta0: scatterPolarAttrs.theta0,\n dtheta: scatterPolarAttrs.dtheta,\n thetaunit: scatterPolarAttrs.thetaunit,\n\n // orientation: {\n // valType: 'enumerated',\n // \n // values: ['radial', 'angular'],\n // editType: 'calc+clearAxisTypes',\n // \n // },\n\n base: extendFlat({}, barAttrs.base, {\n \n }),\n offset: extendFlat({}, barAttrs.offset, {\n \n }),\n width: extendFlat({}, barAttrs.width, {\n \n }),\n\n text: extendFlat({}, barAttrs.text, {\n \n }),\n hovertext: extendFlat({}, barAttrs.hovertext, {\n \n }),\n\n // textposition: {},\n // textfont: {},\n // insidetextfont: {},\n // outsidetextfont: {},\n // constraintext: {},\n // cliponaxis: extendFlat({}, barAttrs.cliponaxis, {dflt: false}),\n\n marker: barAttrs.marker,\n\n hoverinfo: scatterPolarAttrs.hoverinfo,\n hovertemplate: hovertemplateAttrs(),\n\n selected: barAttrs.selected,\n unselected: barAttrs.unselected\n\n // error_x (error_r, error_theta)\n // error_y\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/barpolar/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/barpolar/calc.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/barpolar/calc.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar hasColorscale = __webpack_require__(/*! ../../components/colorscale/helpers */ \"./node_modules/plotly.js/src/components/colorscale/helpers.js\").hasColorscale;\nvar colorscaleCalc = __webpack_require__(/*! ../../components/colorscale/calc */ \"./node_modules/plotly.js/src/components/colorscale/calc.js\");\nvar arraysToCalcdata = __webpack_require__(/*! ../bar/arrays_to_calcdata */ \"./node_modules/plotly.js/src/traces/bar/arrays_to_calcdata.js\");\nvar setGroupPositions = __webpack_require__(/*! ../bar/cross_trace_calc */ \"./node_modules/plotly.js/src/traces/bar/cross_trace_calc.js\").setGroupPositions;\nvar calcSelection = __webpack_require__(/*! ../scatter/calc_selection */ \"./node_modules/plotly.js/src/traces/scatter/calc_selection.js\");\nvar traceIs = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\").traceIs;\nvar extendFlat = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").extendFlat;\n\nfunction calc(gd, trace) {\n var fullLayout = gd._fullLayout;\n var subplotId = trace.subplot;\n var radialAxis = fullLayout[subplotId].radialaxis;\n var angularAxis = fullLayout[subplotId].angularaxis;\n var rArray = radialAxis.makeCalcdata(trace, 'r');\n var thetaArray = angularAxis.makeCalcdata(trace, 'theta');\n var len = trace._length;\n var cd = new Array(len);\n\n // 'size' axis variables\n var sArray = rArray;\n // 'pos' axis variables\n var pArray = thetaArray;\n\n for(var i = 0; i < len; i++) {\n cd[i] = {p: pArray[i], s: sArray[i]};\n }\n\n // convert width and offset in 'c' coordinate,\n // set 'c' value(s) in trace._width and trace._offset,\n // to make Bar.crossTraceCalc \"just work\"\n function d2c(attr) {\n var val = trace[attr];\n if(val !== undefined) {\n trace['_' + attr] = Array.isArray(val) ?\n angularAxis.makeCalcdata(trace, attr) :\n angularAxis.d2c(val, trace.thetaunit);\n }\n }\n\n if(angularAxis.type === 'linear') {\n d2c('width');\n d2c('offset');\n }\n\n if(hasColorscale(trace, 'marker')) {\n colorscaleCalc(gd, trace, {\n vals: trace.marker.color,\n containerStr: 'marker',\n cLetter: 'c'\n });\n }\n if(hasColorscale(trace, 'marker.line')) {\n colorscaleCalc(gd, trace, {\n vals: trace.marker.line.color,\n containerStr: 'marker.line',\n cLetter: 'c'\n });\n }\n\n arraysToCalcdata(cd, trace);\n calcSelection(cd, trace);\n\n return cd;\n}\n\nfunction crossTraceCalc(gd, polarLayout, subplotId) {\n var calcdata = gd.calcdata;\n var barPolarCd = [];\n\n for(var i = 0; i < calcdata.length; i++) {\n var cdi = calcdata[i];\n var trace = cdi[0].trace;\n\n if(trace.visible === true && traceIs(trace, 'bar') &&\n trace.subplot === subplotId\n ) {\n barPolarCd.push(cdi);\n }\n }\n\n // to make _extremes is filled in correctly so that\n // polar._subplot.radialAxis can get auotrange'd\n // TODO clean up!\n // I think we want to call getAutorange on polar.radialaxis\n // NOT on polar._subplot.radialAxis\n var rAxis = extendFlat({}, polarLayout.radialaxis, {_id: 'x'});\n var aAxis = polarLayout.angularaxis;\n\n setGroupPositions(gd, aAxis, rAxis, barPolarCd, {\n mode: polarLayout.barmode,\n norm: polarLayout.barnorm,\n gap: polarLayout.bargap,\n groupgap: polarLayout.bargroupgap\n });\n}\n\nmodule.exports = {\n calc: calc,\n crossTraceCalc: crossTraceCalc\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/barpolar/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/barpolar/defaults.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/barpolar/defaults.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar handleRThetaDefaults = __webpack_require__(/*! ../scatterpolar/defaults */ \"./node_modules/plotly.js/src/traces/scatterpolar/defaults.js\").handleRThetaDefaults;\nvar handleStyleDefaults = __webpack_require__(/*! ../bar/style_defaults */ \"./node_modules/plotly.js/src/traces/bar/style_defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/barpolar/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var len = handleRThetaDefaults(traceIn, traceOut, layout, coerce);\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n // coerce('orientation', (traceOut.theta && !traceOut.r) ? 'angular' : 'radial');\n\n coerce('thetaunit');\n coerce('base');\n coerce('offset');\n coerce('width');\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n\n // var textPosition = coerce('textposition');\n // var hasBoth = Array.isArray(textPosition) || textPosition === 'auto';\n // var hasInside = hasBoth || textPosition === 'inside';\n // var hasOutside = hasBoth || textPosition === 'outside';\n\n // if(hasInside || hasOutside) {\n // var textFont = coerceFont(coerce, 'textfont', layout.font);\n // if(hasInside) coerceFont(coerce, 'insidetextfont', textFont);\n // if(hasOutside) coerceFont(coerce, 'outsidetextfont', textFont);\n // coerce('constraintext');\n // coerce('selected.textfont.color');\n // coerce('unselected.textfont.color');\n // coerce('cliponaxis');\n // }\n\n handleStyleDefaults(traceIn, traceOut, coerce, defaultColor, layout);\n\n Lib.coerceSelectionMarkerOpacity(traceOut, coerce);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/barpolar/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/barpolar/hover.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/barpolar/hover.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Fx = __webpack_require__(/*! ../../components/fx */ \"./node_modules/plotly.js/src/components/fx/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar getTraceColor = __webpack_require__(/*! ../bar/hover */ \"./node_modules/plotly.js/src/traces/bar/hover.js\").getTraceColor;\nvar fillText = Lib.fillText;\nvar makeHoverPointText = __webpack_require__(/*! ../scatterpolar/hover */ \"./node_modules/plotly.js/src/traces/scatterpolar/hover.js\").makeHoverPointText;\nvar isPtInsidePolygon = __webpack_require__(/*! ../../plots/polar/helpers */ \"./node_modules/plotly.js/src/plots/polar/helpers.js\").isPtInsidePolygon;\n\nmodule.exports = function hoverPoints(pointData, xval, yval) {\n var cd = pointData.cd;\n var trace = cd[0].trace;\n\n var subplot = pointData.subplot;\n var radialAxis = subplot.radialAxis;\n var angularAxis = subplot.angularAxis;\n var vangles = subplot.vangles;\n var inboxFn = vangles ? isPtInsidePolygon : Lib.isPtInsideSector;\n var maxHoverDistance = pointData.maxHoverDistance;\n var period = angularAxis._period || 2 * Math.PI;\n\n var rVal = Math.abs(radialAxis.g2p(Math.sqrt(xval * xval + yval * yval)));\n var thetaVal = Math.atan2(yval, xval);\n\n // polar.(x|y)axis.p2c doesn't get the reversed radial axis range case right\n if(radialAxis.range[0] > radialAxis.range[1]) {\n thetaVal += Math.PI;\n }\n\n var distFn = function(di) {\n if(inboxFn(rVal, thetaVal, [di.rp0, di.rp1], [di.thetag0, di.thetag1], vangles)) {\n return maxHoverDistance +\n // add a little to the pseudo-distance for wider bars, so that like scatter,\n // if you are over two overlapping bars, the narrower one wins.\n Math.min(1, Math.abs(di.thetag1 - di.thetag0) / period) - 1 +\n // add a gradient so hovering near the end of a\n // bar makes it a little closer match\n (di.rp1 - rVal) / (di.rp1 - di.rp0) - 1;\n } else {\n return Infinity;\n }\n };\n\n Fx.getClosest(cd, distFn, pointData);\n if(pointData.index === false) return;\n\n var index = pointData.index;\n var cdi = cd[index];\n\n pointData.x0 = pointData.x1 = cdi.ct[0];\n pointData.y0 = pointData.y1 = cdi.ct[1];\n\n var _cdi = Lib.extendFlat({}, cdi, {r: cdi.s, theta: cdi.p});\n fillText(cdi, trace, pointData);\n makeHoverPointText(_cdi, trace, subplot, pointData);\n pointData.hovertemplate = trace.hovertemplate;\n pointData.color = getTraceColor(trace, cdi);\n pointData.xLabelVal = pointData.yLabelVal = undefined;\n\n if(cdi.s < 0) {\n pointData.idealAlign = 'left';\n }\n\n return [pointData];\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/barpolar/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/barpolar/index.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/barpolar/index.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n moduleType: 'trace',\n name: 'barpolar',\n basePlotModule: __webpack_require__(/*! ../../plots/polar */ \"./node_modules/plotly.js/src/plots/polar/index.js\"),\n categories: ['polar', 'bar', 'showLegend'],\n\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/barpolar/attributes.js\"),\n layoutAttributes: __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/barpolar/layout_attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/barpolar/defaults.js\"),\n supplyLayoutDefaults: __webpack_require__(/*! ./layout_defaults */ \"./node_modules/plotly.js/src/traces/barpolar/layout_defaults.js\"),\n\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/barpolar/calc.js\").calc,\n crossTraceCalc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/barpolar/calc.js\").crossTraceCalc,\n\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/barpolar/plot.js\"),\n colorbar: __webpack_require__(/*! ../scatter/marker_colorbar */ \"./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js\"),\n formatLabels: __webpack_require__(/*! ../scatterpolar/format_labels */ \"./node_modules/plotly.js/src/traces/scatterpolar/format_labels.js\"),\n\n style: __webpack_require__(/*! ../bar/style */ \"./node_modules/plotly.js/src/traces/bar/style.js\").style,\n styleOnSelect: __webpack_require__(/*! ../bar/style */ \"./node_modules/plotly.js/src/traces/bar/style.js\").styleOnSelect,\n\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/barpolar/hover.js\"),\n selectPoints: __webpack_require__(/*! ../bar/select */ \"./node_modules/plotly.js/src/traces/bar/select.js\"),\n\n meta: {\n \n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/barpolar/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/barpolar/layout_attributes.js":
-/*!*************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/barpolar/layout_attributes.js ***!
- \*************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n barmode: {\n valType: 'enumerated',\n values: ['stack', 'overlay'],\n dflt: 'stack',\n \n editType: 'calc',\n \n },\n bargap: {\n valType: 'number',\n dflt: 0.1,\n min: 0,\n max: 1,\n \n editType: 'calc',\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/barpolar/layout_attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/barpolar/layout_defaults.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/barpolar/layout_defaults.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar attrs = __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/barpolar/layout_attributes.js\");\n\nmodule.exports = function(layoutIn, layoutOut, fullData) {\n var subplotsDone = {};\n var sp;\n\n function coerce(attr, dflt) {\n return Lib.coerce(layoutIn[sp] || {}, layoutOut[sp], attrs, attr, dflt);\n }\n\n for(var i = 0; i < fullData.length; i++) {\n var trace = fullData[i];\n if(trace.type === 'barpolar' && trace.visible === true) {\n sp = trace.subplot;\n if(!subplotsDone[sp]) {\n coerce('barmode');\n coerce('bargap');\n subplotsDone[sp] = 1;\n }\n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/barpolar/layout_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/barpolar/plot.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/barpolar/plot.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar helpers = __webpack_require__(/*! ../../plots/polar/helpers */ \"./node_modules/plotly.js/src/plots/polar/helpers.js\");\n\nmodule.exports = function plot(gd, subplot, cdbar) {\n var xa = subplot.xaxis;\n var ya = subplot.yaxis;\n var radialAxis = subplot.radialAxis;\n var angularAxis = subplot.angularAxis;\n var pathFn = makePathFn(subplot);\n var barLayer = subplot.layers.frontplot.select('g.barlayer');\n\n Lib.makeTraceGroups(barLayer, cdbar, 'trace bars').each(function() {\n var plotGroup = d3.select(this);\n var pointGroup = Lib.ensureSingle(plotGroup, 'g', 'points');\n var bars = pointGroup.selectAll('g.point').data(Lib.identity);\n\n bars.enter().append('g')\n .style('vector-effect', 'non-scaling-stroke')\n .style('stroke-miterlimit', 2)\n .classed('point', true);\n\n bars.exit().remove();\n\n bars.each(function(di) {\n var bar = d3.select(this);\n\n var rp0 = di.rp0 = radialAxis.c2p(di.s0);\n var rp1 = di.rp1 = radialAxis.c2p(di.s1);\n var thetag0 = di.thetag0 = angularAxis.c2g(di.p0);\n var thetag1 = di.thetag1 = angularAxis.c2g(di.p1);\n\n var dPath;\n\n if(!isNumeric(rp0) || !isNumeric(rp1) ||\n !isNumeric(thetag0) || !isNumeric(thetag1) ||\n rp0 === rp1 || thetag0 === thetag1\n ) {\n // do not remove blank bars, to keep data-to-node\n // mapping intact during radial drag, that we\n // can skip calling _module.style during interactions\n dPath = 'M0,0Z';\n } else {\n // this 'center' pt is used for selections and hover labels\n var rg1 = radialAxis.c2g(di.s1);\n var thetagMid = (thetag0 + thetag1) / 2;\n di.ct = [\n xa.c2p(rg1 * Math.cos(thetagMid)),\n ya.c2p(rg1 * Math.sin(thetagMid))\n ];\n\n dPath = pathFn(rp0, rp1, thetag0, thetag1);\n }\n\n Lib.ensureSingle(bar, 'path').attr('d', dPath);\n });\n\n // clip plotGroup, when trace layer isn't clipped\n Drawing.setClipUrl(\n plotGroup,\n subplot._hasClipOnAxisFalse ? subplot.clipIds.forTraces : null,\n gd\n );\n });\n};\n\nfunction makePathFn(subplot) {\n var cxx = subplot.cxx;\n var cyy = subplot.cyy;\n\n if(subplot.vangles) {\n return function(r0, r1, _a0, _a1) {\n var a0, a1;\n\n if(Lib.angleDelta(_a0, _a1) > 0) {\n a0 = _a0;\n a1 = _a1;\n } else {\n a0 = _a1;\n a1 = _a0;\n }\n\n var va0 = helpers.findEnclosingVertexAngles(a0, subplot.vangles)[0];\n var va1 = helpers.findEnclosingVertexAngles(a1, subplot.vangles)[1];\n var vaBar = [va0, (a0 + a1) / 2, va1];\n return helpers.pathPolygonAnnulus(r0, r1, a0, a1, vaBar, cxx, cyy);\n };\n }\n\n return function(r0, r1, a0, a1) {\n return Lib.pathAnnulus(r0, r1, a0, a1, cxx, cyy);\n };\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/barpolar/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/box/attributes.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/box/attributes.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar scatterAttrs = __webpack_require__(/*! ../scatter/attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\");\nvar barAttrs = __webpack_require__(/*! ../bar/attributes */ \"./node_modules/plotly.js/src/traces/bar/attributes.js\");\nvar colorAttrs = __webpack_require__(/*! ../../components/color/attributes */ \"./node_modules/plotly.js/src/components/color/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nvar scatterMarkerAttrs = scatterAttrs.marker;\nvar scatterMarkerLineAttrs = scatterMarkerAttrs.line;\n\nmodule.exports = {\n y: {\n valType: 'data_array',\n editType: 'calc+clearAxisTypes',\n \n },\n x: {\n valType: 'data_array',\n editType: 'calc+clearAxisTypes',\n \n },\n x0: {\n valType: 'any',\n \n editType: 'calc+clearAxisTypes',\n \n },\n y0: {\n valType: 'any',\n \n editType: 'calc+clearAxisTypes',\n \n },\n\n dx: {\n valType: 'number',\n \n editType: 'calc',\n \n },\n dy: {\n valType: 'number',\n \n editType: 'calc',\n \n },\n\n name: {\n valType: 'string',\n \n editType: 'calc+clearAxisTypes',\n \n },\n\n q1: {\n valType: 'data_array',\n \n editType: 'calc+clearAxisTypes',\n \n },\n median: {\n valType: 'data_array',\n \n editType: 'calc+clearAxisTypes',\n \n },\n q3: {\n valType: 'data_array',\n \n editType: 'calc+clearAxisTypes',\n \n },\n lowerfence: {\n valType: 'data_array',\n \n editType: 'calc',\n \n },\n upperfence: {\n valType: 'data_array',\n \n editType: 'calc',\n \n },\n\n notched: {\n valType: 'boolean',\n \n editType: 'calc',\n \n },\n notchwidth: {\n valType: 'number',\n min: 0,\n max: 0.5,\n dflt: 0.25,\n \n editType: 'calc',\n \n },\n notchspan: {\n valType: 'data_array',\n \n editType: 'calc',\n \n },\n\n // TODO\n // maybe add\n // - loweroutlierbound / upperoutlierbound\n // - lowersuspectedoutlierbound / uppersuspectedoutlierbound\n\n boxpoints: {\n valType: 'enumerated',\n values: ['all', 'outliers', 'suspectedoutliers', false],\n \n editType: 'calc',\n \n },\n jitter: {\n valType: 'number',\n min: 0,\n max: 1,\n \n editType: 'calc',\n \n },\n pointpos: {\n valType: 'number',\n min: -2,\n max: 2,\n \n editType: 'calc',\n \n },\n\n boxmean: {\n valType: 'enumerated',\n values: [true, 'sd', false],\n \n editType: 'calc',\n \n },\n mean: {\n valType: 'data_array',\n \n editType: 'calc',\n \n },\n sd: {\n valType: 'data_array',\n \n editType: 'calc',\n \n },\n\n orientation: {\n valType: 'enumerated',\n values: ['v', 'h'],\n \n editType: 'calc+clearAxisTypes',\n \n },\n\n quartilemethod: {\n valType: 'enumerated',\n values: ['linear', 'exclusive', 'inclusive'],\n dflt: 'linear',\n \n editType: 'calc',\n \n },\n\n width: {\n valType: 'number',\n min: 0,\n \n dflt: 0,\n editType: 'calc',\n \n },\n\n marker: {\n outliercolor: {\n valType: 'color',\n dflt: 'rgba(0, 0, 0, 0)',\n \n editType: 'style',\n \n },\n symbol: extendFlat({}, scatterMarkerAttrs.symbol,\n {arrayOk: false, editType: 'plot'}),\n opacity: extendFlat({}, scatterMarkerAttrs.opacity,\n {arrayOk: false, dflt: 1, editType: 'style'}),\n size: extendFlat({}, scatterMarkerAttrs.size,\n {arrayOk: false, editType: 'calc'}),\n color: extendFlat({}, scatterMarkerAttrs.color,\n {arrayOk: false, editType: 'style'}),\n line: {\n color: extendFlat({}, scatterMarkerLineAttrs.color,\n {arrayOk: false, dflt: colorAttrs.defaultLine, editType: 'style'}\n ),\n width: extendFlat({}, scatterMarkerLineAttrs.width,\n {arrayOk: false, dflt: 0, editType: 'style'}\n ),\n outliercolor: {\n valType: 'color',\n \n editType: 'style',\n \n },\n outlierwidth: {\n valType: 'number',\n min: 0,\n dflt: 1,\n \n editType: 'style',\n \n },\n editType: 'style'\n },\n editType: 'plot'\n },\n\n line: {\n color: {\n valType: 'color',\n \n editType: 'style',\n \n },\n width: {\n valType: 'number',\n \n min: 0,\n dflt: 2,\n editType: 'style',\n \n },\n editType: 'plot'\n },\n\n fillcolor: scatterAttrs.fillcolor,\n\n whiskerwidth: {\n valType: 'number',\n min: 0,\n max: 1,\n dflt: 0.5,\n \n editType: 'calc',\n \n },\n\n offsetgroup: barAttrs.offsetgroup,\n alignmentgroup: barAttrs.alignmentgroup,\n\n selected: {\n marker: scatterAttrs.selected.marker,\n editType: 'style'\n },\n unselected: {\n marker: scatterAttrs.unselected.marker,\n editType: 'style'\n },\n\n text: extendFlat({}, scatterAttrs.text, {\n \n }),\n hovertext: extendFlat({}, scatterAttrs.hovertext, {\n \n }),\n hovertemplate: hovertemplateAttrs({\n \n }),\n\n hoveron: {\n valType: 'flaglist',\n flags: ['boxes', 'points'],\n dflt: 'boxes+points',\n \n editType: 'style',\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/box/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/box/calc.js":
-/*!*******************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/box/calc.js ***!
- \*******************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\nvar _ = Lib._;\n\nmodule.exports = function calc(gd, trace) {\n var fullLayout = gd._fullLayout;\n var xa = Axes.getFromId(gd, trace.xaxis || 'x');\n var ya = Axes.getFromId(gd, trace.yaxis || 'y');\n var cd = [];\n\n // N.B. violin reuses same Box.calc\n var numKey = trace.type === 'violin' ? '_numViolins' : '_numBoxes';\n\n var i, j;\n var valAxis, valLetter;\n var posAxis, posLetter;\n\n if(trace.orientation === 'h') {\n valAxis = xa;\n valLetter = 'x';\n posAxis = ya;\n posLetter = 'y';\n } else {\n valAxis = ya;\n valLetter = 'y';\n posAxis = xa;\n posLetter = 'x';\n }\n\n var posArray = getPos(trace, posLetter, posAxis, fullLayout[numKey]);\n var dv = Lib.distinctVals(posArray);\n var posDistinct = dv.vals;\n var dPos = dv.minDiff / 2;\n\n // item in trace calcdata\n var cdi;\n // array of {v: v, i, i} sample pts\n var pts;\n // values of the `pts` array of objects\n var boxVals;\n // length of sample\n var N;\n // single sample point\n var pt;\n // single sample value\n var v;\n\n // filter function for outlier pts\n // outlier definition based on http://www.physics.csbsju.edu/stats/box2.html\n var ptFilterFn = (trace.boxpoints || trace.points) === 'all' ?\n Lib.identity :\n function(pt) { return (pt.v < cdi.lf || pt.v > cdi.uf); };\n\n if(trace._hasPreCompStats) {\n var valArrayRaw = trace[valLetter];\n var d2c = function(k) { return valAxis.d2c((trace[k] || [])[i]); };\n var minVal = Infinity;\n var maxVal = -Infinity;\n\n for(i = 0; i < trace._length; i++) {\n var posi = posArray[i];\n if(!isNumeric(posi)) continue;\n\n cdi = {};\n cdi.pos = cdi[posLetter] = posi;\n\n cdi.q1 = d2c('q1');\n cdi.med = d2c('median');\n cdi.q3 = d2c('q3');\n\n pts = [];\n if(valArrayRaw && Lib.isArrayOrTypedArray(valArrayRaw[i])) {\n for(j = 0; j < valArrayRaw[i].length; j++) {\n v = valAxis.d2c(valArrayRaw[i][j]);\n if(v !== BADNUM) {\n pt = {v: v, i: [i, j]};\n arraysToCalcdata(pt, trace, [i, j]);\n pts.push(pt);\n }\n }\n }\n cdi.pts = pts.sort(sortByVal);\n boxVals = cdi[valLetter] = pts.map(extractVal);\n N = boxVals.length;\n\n if(cdi.med !== BADNUM && cdi.q1 !== BADNUM && cdi.q3 !== BADNUM &&\n cdi.med >= cdi.q1 && cdi.q3 >= cdi.med\n ) {\n var lf = d2c('lowerfence');\n cdi.lf = (lf !== BADNUM && lf <= cdi.q1) ?\n lf :\n computeLowerFence(cdi, boxVals, N);\n\n var uf = d2c('upperfence');\n cdi.uf = (uf !== BADNUM && uf >= cdi.q3) ?\n uf :\n computeUpperFence(cdi, boxVals, N);\n\n var mean = d2c('mean');\n cdi.mean = (mean !== BADNUM) ?\n mean :\n (N ? Lib.mean(boxVals, N) : (cdi.q1 + cdi.q3) / 2);\n\n var sd = d2c('sd');\n cdi.sd = (mean !== BADNUM && sd >= 0) ?\n sd :\n (N ? Lib.stdev(boxVals, N, cdi.mean) : (cdi.q3 - cdi.q1));\n\n cdi.lo = computeLowerOutlierBound(cdi);\n cdi.uo = computeUpperOutlierBound(cdi);\n\n var ns = d2c('notchspan');\n ns = (ns !== BADNUM && ns > 0) ? ns : computeNotchSpan(cdi, N);\n cdi.ln = cdi.med - ns;\n cdi.un = cdi.med + ns;\n\n var imin = cdi.lf;\n var imax = cdi.uf;\n if(trace.boxpoints && boxVals.length) {\n imin = Math.min(imin, boxVals[0]);\n imax = Math.max(imax, boxVals[N - 1]);\n }\n if(trace.notched) {\n imin = Math.min(imin, cdi.ln);\n imax = Math.max(imax, cdi.un);\n }\n cdi.min = imin;\n cdi.max = imax;\n } else {\n Lib.warn([\n 'Invalid input - make sure that q1 <= median <= q3',\n 'q1 = ' + cdi.q1,\n 'median = ' + cdi.med,\n 'q3 = ' + cdi.q3\n ].join('\\n'));\n\n var v0;\n if(cdi.med !== BADNUM) {\n v0 = cdi.med;\n } else if(cdi.q1 !== BADNUM) {\n if(cdi.q3 !== BADNUM) v0 = (cdi.q1 + cdi.q3) / 2;\n else v0 = cdi.q1;\n } else if(cdi.q3 !== BADNUM) {\n v0 = cdi.q3;\n } else {\n v0 = 0;\n }\n\n // draw box as line segment\n cdi.med = v0;\n cdi.q1 = cdi.q3 = v0;\n cdi.lf = cdi.uf = v0;\n cdi.mean = cdi.sd = v0;\n cdi.ln = cdi.un = v0;\n cdi.min = cdi.max = v0;\n }\n\n minVal = Math.min(minVal, cdi.min);\n maxVal = Math.max(maxVal, cdi.max);\n\n cdi.pts2 = pts.filter(ptFilterFn);\n\n cd.push(cdi);\n }\n\n trace._extremes[valAxis._id] = Axes.findExtremes(valAxis,\n [minVal, maxVal],\n {padded: true}\n );\n } else {\n var valArray = valAxis.makeCalcdata(trace, valLetter);\n var posBins = makeBins(posDistinct, dPos);\n var pLen = posDistinct.length;\n var ptsPerBin = initNestedArray(pLen);\n\n // bin pts info per position bins\n for(i = 0; i < trace._length; i++) {\n v = valArray[i];\n if(!isNumeric(v)) continue;\n\n var n = Lib.findBin(posArray[i], posBins);\n if(n >= 0 && n < pLen) {\n pt = {v: v, i: i};\n arraysToCalcdata(pt, trace, i);\n ptsPerBin[n].push(pt);\n }\n }\n\n var minLowerNotch = Infinity;\n var maxUpperNotch = -Infinity;\n\n var quartilemethod = trace.quartilemethod;\n var usesExclusive = quartilemethod === 'exclusive';\n var usesInclusive = quartilemethod === 'inclusive';\n\n // build calcdata trace items, one item per distinct position\n for(i = 0; i < pLen; i++) {\n if(ptsPerBin[i].length > 0) {\n cdi = {};\n cdi.pos = cdi[posLetter] = posDistinct[i];\n\n pts = cdi.pts = ptsPerBin[i].sort(sortByVal);\n boxVals = cdi[valLetter] = pts.map(extractVal);\n N = boxVals.length;\n\n cdi.min = boxVals[0];\n cdi.max = boxVals[N - 1];\n cdi.mean = Lib.mean(boxVals, N);\n cdi.sd = Lib.stdev(boxVals, N, cdi.mean);\n cdi.med = Lib.interp(boxVals, 0.5);\n\n if((N % 2) && (usesExclusive || usesInclusive)) {\n var lower;\n var upper;\n\n if(usesExclusive) {\n // do NOT include the median in either half\n lower = boxVals.slice(0, N / 2);\n upper = boxVals.slice(N / 2 + 1);\n } else if(usesInclusive) {\n // include the median in either half\n lower = boxVals.slice(0, N / 2 + 1);\n upper = boxVals.slice(N / 2);\n }\n\n cdi.q1 = Lib.interp(lower, 0.5);\n cdi.q3 = Lib.interp(upper, 0.5);\n } else {\n cdi.q1 = Lib.interp(boxVals, 0.25);\n cdi.q3 = Lib.interp(boxVals, 0.75);\n }\n\n // lower and upper fences\n cdi.lf = computeLowerFence(cdi, boxVals, N);\n cdi.uf = computeUpperFence(cdi, boxVals, N);\n\n // lower and upper outliers bounds\n cdi.lo = computeLowerOutlierBound(cdi);\n cdi.uo = computeUpperOutlierBound(cdi);\n\n // lower and upper notches\n var mci = computeNotchSpan(cdi, N);\n cdi.ln = cdi.med - mci;\n cdi.un = cdi.med + mci;\n minLowerNotch = Math.min(minLowerNotch, cdi.ln);\n maxUpperNotch = Math.max(maxUpperNotch, cdi.un);\n\n cdi.pts2 = pts.filter(ptFilterFn);\n\n cd.push(cdi);\n }\n }\n\n trace._extremes[valAxis._id] = Axes.findExtremes(valAxis,\n trace.notched ? valArray.concat([minLowerNotch, maxUpperNotch]) : valArray,\n {padded: true}\n );\n }\n\n calcSelection(cd, trace);\n\n if(cd.length > 0) {\n cd[0].t = {\n num: fullLayout[numKey],\n dPos: dPos,\n posLetter: posLetter,\n valLetter: valLetter,\n labels: {\n med: _(gd, 'median:'),\n min: _(gd, 'min:'),\n q1: _(gd, 'q1:'),\n q3: _(gd, 'q3:'),\n max: _(gd, 'max:'),\n mean: trace.boxmean === 'sd' ? _(gd, 'mean ± σ:') : _(gd, 'mean:'),\n lf: _(gd, 'lower fence:'),\n uf: _(gd, 'upper fence:')\n }\n };\n\n fullLayout[numKey]++;\n return cd;\n } else {\n return [{t: {empty: true}}];\n }\n};\n\n// In vertical (horizontal) box plots:\n// if no x (y) data, use x0 (y0), or name\n// so if you want one box\n// per trace, set x0 (y0) to the x (y) value or category for this trace\n// (or set x (y) to a constant array matching y (x))\nfunction getPos(trace, posLetter, posAxis, num) {\n var hasPosArray = posLetter in trace;\n var hasPos0 = posLetter + '0' in trace;\n var hasPosStep = 'd' + posLetter in trace;\n\n if(hasPosArray || (hasPos0 && hasPosStep)) {\n return posAxis.makeCalcdata(trace, posLetter);\n }\n\n var pos0;\n if(hasPos0) {\n pos0 = trace[posLetter + '0'];\n } else if('name' in trace && (\n posAxis.type === 'category' || (\n isNumeric(trace.name) &&\n ['linear', 'log'].indexOf(posAxis.type) !== -1\n ) || (\n Lib.isDateTime(trace.name) &&\n posAxis.type === 'date'\n )\n )) {\n pos0 = trace.name;\n } else {\n pos0 = num;\n }\n\n var pos0c = posAxis.type === 'multicategory' ?\n posAxis.r2c_just_indices(pos0) :\n posAxis.d2c(pos0, 0, trace[posLetter + 'calendar']);\n\n var len = trace._length;\n var out = new Array(len);\n for(var i = 0; i < len; i++) out[i] = pos0c;\n\n return out;\n}\n\nfunction makeBins(x, dx) {\n var len = x.length;\n var bins = new Array(len + 1);\n\n for(var i = 0; i < len; i++) {\n bins[i] = x[i] - dx;\n }\n bins[len] = x[len - 1] + dx;\n\n return bins;\n}\n\nfunction initNestedArray(len) {\n var arr = new Array(len);\n for(var i = 0; i < len; i++) {\n arr[i] = [];\n }\n return arr;\n}\n\nvar TRACE_TO_CALC = {\n text: 'tx',\n hovertext: 'htx'\n};\n\nfunction arraysToCalcdata(pt, trace, ptNumber) {\n for(var k in TRACE_TO_CALC) {\n if(Lib.isArrayOrTypedArray(trace[k])) {\n if(Array.isArray(ptNumber)) {\n if(Lib.isArrayOrTypedArray(trace[k][ptNumber[0]])) {\n pt[TRACE_TO_CALC[k]] = trace[k][ptNumber[0]][ptNumber[1]];\n }\n } else {\n pt[TRACE_TO_CALC[k]] = trace[k][ptNumber];\n }\n }\n }\n}\n\nfunction calcSelection(cd, trace) {\n if(Lib.isArrayOrTypedArray(trace.selectedpoints)) {\n for(var i = 0; i < cd.length; i++) {\n var pts = cd[i].pts || [];\n var ptNumber2cdIndex = {};\n\n for(var j = 0; j < pts.length; j++) {\n ptNumber2cdIndex[pts[j].i] = j;\n }\n\n Lib.tagSelected(pts, trace, ptNumber2cdIndex);\n }\n }\n}\n\nfunction sortByVal(a, b) { return a.v - b.v; }\n\nfunction extractVal(o) { return o.v; }\n\n// last point below 1.5 * IQR\nfunction computeLowerFence(cdi, boxVals, N) {\n if(N === 0) return cdi.q1;\n return Math.min(\n cdi.q1,\n boxVals[Math.min(\n Lib.findBin(2.5 * cdi.q1 - 1.5 * cdi.q3, boxVals, true) + 1,\n N - 1\n )]\n );\n}\n\n// last point above 1.5 * IQR\nfunction computeUpperFence(cdi, boxVals, N) {\n if(N === 0) return cdi.q3;\n return Math.max(\n cdi.q3,\n boxVals[Math.max(\n Lib.findBin(2.5 * cdi.q3 - 1.5 * cdi.q1, boxVals),\n 0\n )]\n );\n}\n\n// 3 IQR below (don't clip to max/min,\n// this is only for discriminating suspected & far outliers)\nfunction computeLowerOutlierBound(cdi) {\n return 4 * cdi.q1 - 3 * cdi.q3;\n}\n\n// 3 IQR above (don't clip to max/min,\n// this is only for discriminating suspected & far outliers)\nfunction computeUpperOutlierBound(cdi) {\n return 4 * cdi.q3 - 3 * cdi.q1;\n}\n\n// 95% confidence intervals for median\nfunction computeNotchSpan(cdi, N) {\n if(N === 0) return 0;\n return 1.57 * (cdi.q3 - cdi.q1) / Math.sqrt(N);\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/box/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/box/cross_trace_calc.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/box/cross_trace_calc.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar getAxisGroup = __webpack_require__(/*! ../../plots/cartesian/axis_ids */ \"./node_modules/plotly.js/src/plots/cartesian/axis_ids.js\").getAxisGroup;\n\nvar orientations = ['v', 'h'];\n\nfunction crossTraceCalc(gd, plotinfo) {\n var calcdata = gd.calcdata;\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n\n for(var i = 0; i < orientations.length; i++) {\n var orientation = orientations[i];\n var posAxis = orientation === 'h' ? ya : xa;\n var boxList = [];\n\n // make list of boxes / candlesticks\n // For backward compatibility, candlesticks are treated as if they *are* box traces here\n for(var j = 0; j < calcdata.length; j++) {\n var cd = calcdata[j];\n var t = cd[0].t;\n var trace = cd[0].trace;\n\n if(trace.visible === true &&\n (trace.type === 'box' || trace.type === 'candlestick') &&\n !t.empty &&\n (trace.orientation || 'v') === orientation &&\n trace.xaxis === xa._id &&\n trace.yaxis === ya._id\n ) {\n boxList.push(j);\n }\n }\n\n setPositionOffset('box', gd, boxList, posAxis);\n }\n}\n\nfunction setPositionOffset(traceType, gd, boxList, posAxis) {\n var calcdata = gd.calcdata;\n var fullLayout = gd._fullLayout;\n var axId = posAxis._id;\n var axLetter = axId.charAt(0);\n\n var i, j, calcTrace;\n var pointList = [];\n var shownPts = 0;\n\n // make list of box points\n for(i = 0; i < boxList.length; i++) {\n calcTrace = calcdata[boxList[i]];\n for(j = 0; j < calcTrace.length; j++) {\n pointList.push(posAxis.c2l(calcTrace[j].pos, true));\n shownPts += (calcTrace[j].pts2 || []).length;\n }\n }\n\n if(!pointList.length) return;\n\n // box plots - update dPos based on multiple traces\n var boxdv = Lib.distinctVals(pointList);\n var dPos0 = boxdv.minDiff / 2;\n\n // check for forced minimum dtick\n Axes.minDtick(posAxis, boxdv.minDiff, boxdv.vals[0], true);\n\n var numKey = traceType === 'violin' ? '_numViolins' : '_numBoxes';\n var numTotal = fullLayout[numKey];\n var group = fullLayout[traceType + 'mode'] === 'group' && numTotal > 1;\n var groupFraction = 1 - fullLayout[traceType + 'gap'];\n var groupGapFraction = 1 - fullLayout[traceType + 'groupgap'];\n\n for(i = 0; i < boxList.length; i++) {\n calcTrace = calcdata[boxList[i]];\n\n var trace = calcTrace[0].trace;\n var t = calcTrace[0].t;\n var width = trace.width;\n var side = trace.side;\n\n // position coordinate delta\n var dPos;\n // box half width;\n var bdPos;\n // box center offset\n var bPos;\n // half-width within which to accept hover for this box/violin\n // always split the distance to the closest box/violin\n var wHover;\n\n if(width) {\n dPos = bdPos = wHover = width / 2;\n bPos = 0;\n } else {\n dPos = dPos0;\n\n if(group) {\n var groupId = getAxisGroup(fullLayout, posAxis._id) + trace.orientation;\n var alignmentGroups = fullLayout._alignmentOpts[groupId] || {};\n var alignmentGroupOpts = alignmentGroups[trace.alignmentgroup] || {};\n var nOffsetGroups = Object.keys(alignmentGroupOpts.offsetGroups || {}).length;\n var num = nOffsetGroups || numTotal;\n var shift = nOffsetGroups ? trace._offsetIndex : t.num;\n\n bdPos = dPos * groupFraction * groupGapFraction / num;\n bPos = 2 * dPos * (-0.5 + (shift + 0.5) / num) * groupFraction;\n wHover = dPos * groupFraction / num;\n } else {\n bdPos = dPos * groupFraction * groupGapFraction;\n bPos = 0;\n wHover = dPos;\n }\n }\n t.dPos = dPos;\n t.bPos = bPos;\n t.bdPos = bdPos;\n t.wHover = wHover;\n\n // box/violin-only value-space push value\n var pushplus;\n var pushminus;\n // edge of box/violin\n var edge = bPos + bdPos;\n var edgeplus;\n var edgeminus;\n // value-space padding\n var vpadplus;\n var vpadminus;\n // pixel-space padding\n var ppadplus;\n var ppadminus;\n // do we add 5% of both sides (more logic for points beyond box/violin below)\n var padded = Boolean(width);\n // does this trace show points?\n var hasPts = (trace.boxpoints || trace.points) && (shownPts > 0);\n\n if(side === 'positive') {\n pushplus = dPos * (width ? 1 : 0.5);\n edgeplus = edge;\n pushminus = edgeplus = bPos;\n } else if(side === 'negative') {\n pushplus = edgeplus = bPos;\n pushminus = dPos * (width ? 1 : 0.5);\n edgeminus = edge;\n } else {\n pushplus = pushminus = dPos;\n edgeplus = edgeminus = edge;\n }\n\n if(hasPts) {\n var pointpos = trace.pointpos;\n var jitter = trace.jitter;\n var ms = trace.marker.size / 2;\n\n var pp = 0;\n if((pointpos + jitter) >= 0) {\n pp = edge * (pointpos + jitter);\n if(pp > pushplus) {\n // (++) beyond plus-value, use pp\n padded = true;\n ppadplus = ms;\n vpadplus = pp;\n } else if(pp > edgeplus) {\n // (+), use push-value (it's bigger), but add px-pad\n ppadplus = ms;\n vpadplus = pushplus;\n }\n }\n if(pp <= pushplus) {\n // (->) fallback to push value\n vpadplus = pushplus;\n }\n\n var pm = 0;\n if((pointpos - jitter) <= 0) {\n pm = -edge * (pointpos - jitter);\n if(pm > pushminus) {\n // (--) beyond plus-value, use pp\n padded = true;\n ppadminus = ms;\n vpadminus = pm;\n } else if(pm > edgeminus) {\n // (-), use push-value (it's bigger), but add px-pad\n ppadminus = ms;\n vpadminus = pushminus;\n }\n }\n if(pm <= pushminus) {\n // (<-) fallback to push value\n vpadminus = pushminus;\n }\n } else {\n vpadplus = pushplus;\n vpadminus = pushminus;\n }\n\n var pos = new Array(calcTrace.length);\n for(j = 0; j < calcTrace.length; j++) {\n pos[j] = calcTrace[j].pos;\n }\n\n trace._extremes[axId] = Axes.findExtremes(posAxis, pos, {\n padded: padded,\n vpadminus: vpadminus,\n vpadplus: vpadplus,\n vpadLinearized: true,\n // N.B. SVG px-space positive/negative\n ppadminus: {x: ppadminus, y: ppadplus}[axLetter],\n ppadplus: {x: ppadplus, y: ppadminus}[axLetter],\n });\n }\n}\n\nmodule.exports = {\n crossTraceCalc: crossTraceCalc,\n setPositionOffset: setPositionOffset\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/box/cross_trace_calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/box/defaults.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/box/defaults.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar handleGroupingDefaults = __webpack_require__(/*! ../bar/defaults */ \"./node_modules/plotly.js/src/traces/bar/defaults.js\").handleGroupingDefaults;\nvar autoType = __webpack_require__(/*! ../../plots/cartesian/axis_autotype */ \"./node_modules/plotly.js/src/plots/cartesian/axis_autotype.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/box/attributes.js\");\n\nfunction supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n handleSampleDefaults(traceIn, traceOut, coerce, layout);\n if(traceOut.visible === false) return;\n\n var hasPreCompStats = traceOut._hasPreCompStats;\n\n if(hasPreCompStats) {\n coerce('lowerfence');\n coerce('upperfence');\n }\n\n coerce('line.color', (traceIn.marker || {}).color || defaultColor);\n coerce('line.width');\n coerce('fillcolor', Color.addOpacity(traceOut.line.color, 0.5));\n\n var boxmeanDflt = false;\n if(hasPreCompStats) {\n var mean = coerce('mean');\n var sd = coerce('sd');\n if(mean && mean.length) {\n boxmeanDflt = true;\n if(sd && sd.length) boxmeanDflt = 'sd';\n }\n }\n coerce('boxmean', boxmeanDflt);\n\n coerce('whiskerwidth');\n coerce('width');\n coerce('quartilemethod');\n\n var notchedDflt = false;\n if(hasPreCompStats) {\n var notchspan = coerce('notchspan');\n if(notchspan && notchspan.length) {\n notchedDflt = true;\n }\n } else if(Lib.validate(traceIn.notchwidth, attributes.notchwidth)) {\n notchedDflt = true;\n }\n var notched = coerce('notched', notchedDflt);\n if(notched) coerce('notchwidth');\n\n handlePointsDefaults(traceIn, traceOut, coerce, {prefix: 'box'});\n}\n\nfunction handleSampleDefaults(traceIn, traceOut, coerce, layout) {\n function getDims(arr) {\n var dims = 0;\n if(arr && arr.length) {\n dims += 1;\n if(Lib.isArrayOrTypedArray(arr[0]) && arr[0].length) {\n dims += 1;\n }\n }\n return dims;\n }\n\n function valid(astr) {\n return Lib.validate(traceIn[astr], attributes[astr]);\n }\n\n var y = coerce('y');\n var x = coerce('x');\n\n var sLen;\n if(traceOut.type === 'box') {\n var q1 = coerce('q1');\n var median = coerce('median');\n var q3 = coerce('q3');\n\n traceOut._hasPreCompStats = (\n q1 && q1.length &&\n median && median.length &&\n q3 && q3.length\n );\n sLen = Math.min(\n Lib.minRowLength(q1),\n Lib.minRowLength(median),\n Lib.minRowLength(q3)\n );\n }\n\n var yDims = getDims(y);\n var xDims = getDims(x);\n var yLen = yDims && Lib.minRowLength(y);\n var xLen = xDims && Lib.minRowLength(x);\n\n var defaultOrientation, len;\n if(traceOut._hasPreCompStats) {\n switch(String(xDims) + String(yDims)) {\n // no x / no y\n case '00':\n var setInX = valid('x0') || valid('dx');\n var setInY = valid('y0') || valid('dy');\n\n if(setInY && !setInX) {\n defaultOrientation = 'h';\n } else {\n defaultOrientation = 'v';\n }\n\n len = sLen;\n break;\n // just x\n case '10':\n defaultOrientation = 'v';\n len = Math.min(sLen, xLen);\n break;\n case '20':\n defaultOrientation = 'h';\n len = Math.min(sLen, x.length);\n break;\n // just y\n case '01':\n defaultOrientation = 'h';\n len = Math.min(sLen, yLen);\n break;\n case '02':\n defaultOrientation = 'v';\n len = Math.min(sLen, y.length);\n break;\n // both\n case '12':\n defaultOrientation = 'v';\n len = Math.min(sLen, xLen, y.length);\n break;\n case '21':\n defaultOrientation = 'h';\n len = Math.min(sLen, x.length, yLen);\n break;\n case '11':\n // this one is ill-defined\n len = 0;\n break;\n case '22':\n var hasCategories = false;\n var i;\n for(i = 0; i < x.length; i++) {\n if(autoType(x[i]) === 'category') {\n hasCategories = true;\n break;\n }\n }\n\n if(hasCategories) {\n defaultOrientation = 'v';\n len = Math.min(sLen, xLen, y.length);\n } else {\n for(i = 0; i < y.length; i++) {\n if(autoType(y[i]) === 'category') {\n hasCategories = true;\n break;\n }\n }\n\n if(hasCategories) {\n defaultOrientation = 'h';\n len = Math.min(sLen, x.length, yLen);\n } else {\n defaultOrientation = 'v';\n len = Math.min(sLen, xLen, y.length);\n }\n }\n break;\n }\n } else if(yDims > 0) {\n defaultOrientation = 'v';\n if(xDims > 0) {\n len = Math.min(xLen, yLen);\n } else {\n len = Math.min(yLen);\n }\n } else if(xDims > 0) {\n defaultOrientation = 'h';\n len = Math.min(xLen);\n } else {\n len = 0;\n }\n\n if(!len) {\n traceOut.visible = false;\n return;\n }\n traceOut._length = len;\n\n var orientation = coerce('orientation', defaultOrientation);\n\n // these are just used for positioning, they never define the sample\n if(traceOut._hasPreCompStats) {\n if(orientation === 'v' && xDims === 0) {\n coerce('x0', 0);\n coerce('dx', 1);\n } else if(orientation === 'h' && yDims === 0) {\n coerce('y0', 0);\n coerce('dy', 1);\n }\n } else {\n if(orientation === 'v' && xDims === 0) {\n coerce('x0');\n } else if(orientation === 'h' && yDims === 0) {\n coerce('y0');\n }\n }\n\n var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleTraceDefaults');\n handleCalendarDefaults(traceIn, traceOut, ['x', 'y'], layout);\n}\n\nfunction handlePointsDefaults(traceIn, traceOut, coerce, opts) {\n var prefix = opts.prefix;\n\n var outlierColorDflt = Lib.coerce2(traceIn, traceOut, attributes, 'marker.outliercolor');\n var lineoutliercolor = coerce('marker.line.outliercolor');\n\n var modeDflt = 'outliers';\n if(traceOut._hasPreCompStats) {\n modeDflt = 'all';\n } else if(outlierColorDflt || lineoutliercolor) {\n modeDflt = 'suspectedoutliers';\n }\n\n var mode = coerce(prefix + 'points', modeDflt);\n\n if(mode) {\n coerce('jitter', mode === 'all' ? 0.3 : 0);\n coerce('pointpos', mode === 'all' ? -1.5 : 0);\n\n coerce('marker.symbol');\n coerce('marker.opacity');\n coerce('marker.size');\n coerce('marker.color', traceOut.line.color);\n coerce('marker.line.color');\n coerce('marker.line.width');\n\n if(mode === 'suspectedoutliers') {\n coerce('marker.line.outliercolor', traceOut.marker.color);\n coerce('marker.line.outlierwidth');\n }\n\n coerce('selected.marker.color');\n coerce('unselected.marker.color');\n coerce('selected.marker.size');\n coerce('unselected.marker.size');\n\n coerce('text');\n coerce('hovertext');\n } else {\n delete traceOut.marker;\n }\n\n var hoveron = coerce('hoveron');\n if(hoveron === 'all' || hoveron.indexOf('points') !== -1) {\n coerce('hovertemplate');\n }\n\n Lib.coerceSelectionMarkerOpacity(traceOut, coerce);\n}\n\nfunction crossTraceDefaults(fullData, fullLayout) {\n var traceIn, traceOut;\n\n function coerce(attr) {\n return Lib.coerce(traceOut._input, traceOut, attributes, attr);\n }\n\n for(var i = 0; i < fullData.length; i++) {\n traceOut = fullData[i];\n var traceType = traceOut.type;\n\n if(traceType === 'box' || traceType === 'violin') {\n traceIn = traceOut._input;\n if(fullLayout[traceType + 'mode'] === 'group') {\n handleGroupingDefaults(traceIn, traceOut, fullLayout, coerce);\n }\n }\n }\n}\n\nmodule.exports = {\n supplyDefaults: supplyDefaults,\n crossTraceDefaults: crossTraceDefaults,\n\n handleSampleDefaults: handleSampleDefaults,\n handlePointsDefaults: handlePointsDefaults\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/box/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/box/event_data.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/box/event_data.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function eventData(out, pt) {\n // Note: hoverOnBox property is needed for click-to-select\n // to ignore when a box was clicked. This is the reason box\n // implements this custom eventData function.\n if(pt.hoverOnBox) out.hoverOnBox = pt.hoverOnBox;\n\n if('xVal' in pt) out.x = pt.xVal;\n if('yVal' in pt) out.y = pt.yVal;\n if(pt.xa) out.xaxis = pt.xa;\n if(pt.ya) out.yaxis = pt.ya;\n\n return out;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/box/event_data.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/box/hover.js":
-/*!********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/box/hover.js ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Fx = __webpack_require__(/*! ../../components/fx */ \"./node_modules/plotly.js/src/components/fx/index.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar fillText = Lib.fillText;\n\nfunction hoverPoints(pointData, xval, yval, hovermode) {\n var cd = pointData.cd;\n var trace = cd[0].trace;\n var hoveron = trace.hoveron;\n var closeBoxData = [];\n var closePtData;\n\n if(hoveron.indexOf('boxes') !== -1) {\n closeBoxData = closeBoxData.concat(hoverOnBoxes(pointData, xval, yval, hovermode));\n }\n\n if(hoveron.indexOf('points') !== -1) {\n closePtData = hoverOnPoints(pointData, xval, yval);\n }\n\n // If there's a point in range and hoveron has points, show the best single point only.\n // If hoveron has boxes and there's no point in range (or hoveron doesn't have points), show the box stats.\n if(hovermode === 'closest') {\n if(closePtData) return [closePtData];\n return closeBoxData;\n }\n\n // Otherwise in compare mode, allow a point AND the box stats to be labeled\n // If there are multiple boxes in range (ie boxmode = 'overlay') we'll see stats for all of them.\n if(closePtData) {\n closeBoxData.push(closePtData);\n return closeBoxData;\n }\n return closeBoxData;\n}\n\nfunction hoverOnBoxes(pointData, xval, yval, hovermode) {\n var cd = pointData.cd;\n var xa = pointData.xa;\n var ya = pointData.ya;\n var trace = cd[0].trace;\n var t = cd[0].t;\n var isViolin = trace.type === 'violin';\n var closeBoxData = [];\n\n var pLetter, vLetter, pAxis, vAxis, vVal, pVal, dx, dy, dPos,\n hoverPseudoDistance, spikePseudoDistance;\n\n var boxDelta = t.bdPos;\n var boxDeltaPos, boxDeltaNeg;\n var posAcceptance = t.wHover;\n var shiftPos = function(di) { return pAxis.c2l(di.pos) + t.bPos - pAxis.c2l(pVal); };\n\n if(isViolin && trace.side !== 'both') {\n if(trace.side === 'positive') {\n dPos = function(di) {\n var pos = shiftPos(di);\n return Fx.inbox(pos, pos + posAcceptance, hoverPseudoDistance);\n };\n boxDeltaPos = boxDelta;\n boxDeltaNeg = 0;\n }\n if(trace.side === 'negative') {\n dPos = function(di) {\n var pos = shiftPos(di);\n return Fx.inbox(pos - posAcceptance, pos, hoverPseudoDistance);\n };\n boxDeltaPos = 0;\n boxDeltaNeg = boxDelta;\n }\n } else {\n dPos = function(di) {\n var pos = shiftPos(di);\n return Fx.inbox(pos - posAcceptance, pos + posAcceptance, hoverPseudoDistance);\n };\n boxDeltaPos = boxDeltaNeg = boxDelta;\n }\n\n var dVal;\n\n if(isViolin) {\n dVal = function(di) {\n return Fx.inbox(di.span[0] - vVal, di.span[1] - vVal, hoverPseudoDistance);\n };\n } else {\n dVal = function(di) {\n return Fx.inbox(di.min - vVal, di.max - vVal, hoverPseudoDistance);\n };\n }\n\n if(trace.orientation === 'h') {\n vVal = xval;\n pVal = yval;\n dx = dVal;\n dy = dPos;\n pLetter = 'y';\n pAxis = ya;\n vLetter = 'x';\n vAxis = xa;\n } else {\n vVal = yval;\n pVal = xval;\n dx = dPos;\n dy = dVal;\n pLetter = 'x';\n pAxis = xa;\n vLetter = 'y';\n vAxis = ya;\n }\n\n // if two boxes are overlaying, let the narrowest one win\n var pseudoDistance = Math.min(1, boxDelta / Math.abs(pAxis.r2c(pAxis.range[1]) - pAxis.r2c(pAxis.range[0])));\n hoverPseudoDistance = pointData.maxHoverDistance - pseudoDistance;\n spikePseudoDistance = pointData.maxSpikeDistance - pseudoDistance;\n\n function dxy(di) { return (dx(di) + dy(di)) / 2; }\n var distfn = Fx.getDistanceFunction(hovermode, dx, dy, dxy);\n Fx.getClosest(cd, distfn, pointData);\n\n // skip the rest (for this trace) if we didn't find a close point\n // and create the item(s) in closedata for this point\n if(pointData.index === false) return [];\n\n var di = cd[pointData.index];\n var lc = trace.line.color;\n var mc = (trace.marker || {}).color;\n\n if(Color.opacity(lc) && trace.line.width) pointData.color = lc;\n else if(Color.opacity(mc) && trace.boxpoints) pointData.color = mc;\n else pointData.color = trace.fillcolor;\n\n pointData[pLetter + '0'] = pAxis.c2p(di.pos + t.bPos - boxDeltaNeg, true);\n pointData[pLetter + '1'] = pAxis.c2p(di.pos + t.bPos + boxDeltaPos, true);\n\n pointData[pLetter + 'LabelVal'] = di.pos;\n\n var spikePosAttr = pLetter + 'Spike';\n pointData.spikeDistance = dxy(di) * spikePseudoDistance / hoverPseudoDistance;\n pointData[spikePosAttr] = pAxis.c2p(di.pos, true);\n\n // box plots: each \"point\" gets many labels\n var usedVals = {};\n var attrs = ['med', 'q1', 'q3', 'min', 'max'];\n\n if(trace.boxmean || (trace.meanline || {}).visible) {\n attrs.push('mean');\n }\n if(trace.boxpoints || trace.points) {\n attrs.push('lf', 'uf');\n }\n\n for(var i = 0; i < attrs.length; i++) {\n var attr = attrs[i];\n\n if(!(attr in di) || (di[attr] in usedVals)) continue;\n usedVals[di[attr]] = true;\n\n // copy out to a new object for each value to label\n var val = di[attr];\n var valPx = vAxis.c2p(val, true);\n var pointData2 = Lib.extendFlat({}, pointData);\n\n pointData2.attr = attr;\n pointData2[vLetter + '0'] = pointData2[vLetter + '1'] = valPx;\n pointData2[vLetter + 'LabelVal'] = val;\n pointData2[vLetter + 'Label'] = (t.labels ? t.labels[attr] + ' ' : '') + Axes.hoverLabelText(vAxis, val);\n\n // Note: introduced to be able to distinguish a\n // clicked point from a box during click-to-select\n pointData2.hoverOnBox = true;\n\n if(attr === 'mean' && ('sd' in di) && trace.boxmean === 'sd') {\n pointData2[vLetter + 'err'] = di.sd;\n }\n\n // only keep name and spikes on the first item (median)\n pointData.name = '';\n pointData.spikeDistance = undefined;\n pointData[spikePosAttr] = undefined;\n\n // no hovertemplate support yet\n pointData2.hovertemplate = false;\n\n closeBoxData.push(pointData2);\n }\n\n return closeBoxData;\n}\n\nfunction hoverOnPoints(pointData, xval, yval) {\n var cd = pointData.cd;\n var xa = pointData.xa;\n var ya = pointData.ya;\n var trace = cd[0].trace;\n var xPx = xa.c2p(xval);\n var yPx = ya.c2p(yval);\n var closePtData;\n\n var dx = function(di) {\n var rad = Math.max(3, di.mrc || 0);\n return Math.max(Math.abs(xa.c2p(di.x) - xPx) - rad, 1 - 3 / rad);\n };\n var dy = function(di) {\n var rad = Math.max(3, di.mrc || 0);\n return Math.max(Math.abs(ya.c2p(di.y) - yPx) - rad, 1 - 3 / rad);\n };\n var distfn = Fx.quadrature(dx, dy);\n\n // show one point per trace\n var ijClosest = false;\n var di, pt;\n\n for(var i = 0; i < cd.length; i++) {\n di = cd[i];\n\n for(var j = 0; j < (di.pts || []).length; j++) {\n pt = di.pts[j];\n\n var newDistance = distfn(pt);\n if(newDistance <= pointData.distance) {\n pointData.distance = newDistance;\n ijClosest = [i, j];\n }\n }\n }\n\n if(!ijClosest) return false;\n\n di = cd[ijClosest[0]];\n pt = di.pts[ijClosest[1]];\n\n var xc = xa.c2p(pt.x, true);\n var yc = ya.c2p(pt.y, true);\n var rad = pt.mrc || 1;\n\n closePtData = Lib.extendFlat({}, pointData, {\n // corresponds to index in x/y input data array\n index: pt.i,\n color: (trace.marker || {}).color,\n name: trace.name,\n x0: xc - rad,\n x1: xc + rad,\n y0: yc - rad,\n y1: yc + rad,\n spikeDistance: pointData.distance,\n hovertemplate: trace.hovertemplate\n });\n\n var pa;\n if(trace.orientation === 'h') {\n pa = ya;\n closePtData.xLabelVal = pt.x;\n closePtData.yLabelVal = di.pos;\n } else {\n pa = xa;\n closePtData.xLabelVal = di.pos;\n closePtData.yLabelVal = pt.y;\n }\n\n var pLetter = pa._id.charAt(0);\n closePtData[pLetter + 'Spike'] = pa.c2p(di.pos, true);\n\n fillText(pt, trace, closePtData);\n\n return closePtData;\n}\n\nmodule.exports = {\n hoverPoints: hoverPoints,\n hoverOnBoxes: hoverOnBoxes,\n hoverOnPoints: hoverOnPoints\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/box/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/box/index.js":
-/*!********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/box/index.js ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/box/attributes.js\"),\n layoutAttributes: __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/box/layout_attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/box/defaults.js\").supplyDefaults,\n crossTraceDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/box/defaults.js\").crossTraceDefaults,\n supplyLayoutDefaults: __webpack_require__(/*! ./layout_defaults */ \"./node_modules/plotly.js/src/traces/box/layout_defaults.js\").supplyLayoutDefaults,\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/box/calc.js\"),\n crossTraceCalc: __webpack_require__(/*! ./cross_trace_calc */ \"./node_modules/plotly.js/src/traces/box/cross_trace_calc.js\").crossTraceCalc,\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/box/plot.js\").plot,\n style: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/box/style.js\").style,\n styleOnSelect: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/box/style.js\").styleOnSelect,\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/box/hover.js\").hoverPoints,\n eventData: __webpack_require__(/*! ./event_data */ \"./node_modules/plotly.js/src/traces/box/event_data.js\"),\n selectPoints: __webpack_require__(/*! ./select */ \"./node_modules/plotly.js/src/traces/box/select.js\"),\n\n moduleType: 'trace',\n name: 'box',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['cartesian', 'svg', 'symbols', 'oriented', 'box-violin', 'showLegend', 'boxLayout', 'zoomScale'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/box/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/box/layout_attributes.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/box/layout_attributes.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nmodule.exports = {\n boxmode: {\n valType: 'enumerated',\n values: ['group', 'overlay'],\n dflt: 'overlay',\n \n editType: 'calc',\n \n },\n boxgap: {\n valType: 'number',\n min: 0,\n max: 1,\n dflt: 0.3,\n \n editType: 'calc',\n \n },\n boxgroupgap: {\n valType: 'number',\n min: 0,\n max: 1,\n dflt: 0.3,\n \n editType: 'calc',\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/box/layout_attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/box/layout_defaults.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/box/layout_defaults.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar layoutAttributes = __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/box/layout_attributes.js\");\n\nfunction _supply(layoutIn, layoutOut, fullData, coerce, traceType) {\n var category = traceType + 'Layout';\n var hasTraceType = false;\n\n for(var i = 0; i < fullData.length; i++) {\n var trace = fullData[i];\n\n if(Registry.traceIs(trace, category)) {\n hasTraceType = true;\n break;\n }\n }\n if(!hasTraceType) return;\n\n coerce(traceType + 'mode');\n coerce(traceType + 'gap');\n coerce(traceType + 'groupgap');\n}\n\nfunction supplyLayoutDefaults(layoutIn, layoutOut, fullData) {\n function coerce(attr, dflt) {\n return Lib.coerce(layoutIn, layoutOut, layoutAttributes, attr, dflt);\n }\n _supply(layoutIn, layoutOut, fullData, coerce, 'box');\n}\n\nmodule.exports = {\n supplyLayoutDefaults: supplyLayoutDefaults,\n _supply: _supply\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/box/layout_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/box/plot.js":
-/*!*******************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/box/plot.js ***!
- \*******************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\n\n// constants for dynamic jitter (ie less jitter for sparser points)\nvar JITTERCOUNT = 5; // points either side of this to include\nvar JITTERSPREAD = 0.01; // fraction of IQR to count as \"dense\"\n\nfunction plot(gd, plotinfo, cdbox, boxLayer) {\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n\n Lib.makeTraceGroups(boxLayer, cdbox, 'trace boxes').each(function(cd) {\n var plotGroup = d3.select(this);\n var cd0 = cd[0];\n var t = cd0.t;\n var trace = cd0.trace;\n\n // whisker width\n t.wdPos = t.bdPos * trace.whiskerwidth;\n\n if(trace.visible !== true || t.empty) {\n plotGroup.remove();\n return;\n }\n\n var posAxis, valAxis;\n\n if(trace.orientation === 'h') {\n posAxis = ya;\n valAxis = xa;\n } else {\n posAxis = xa;\n valAxis = ya;\n }\n\n plotBoxAndWhiskers(plotGroup, {pos: posAxis, val: valAxis}, trace, t);\n plotPoints(plotGroup, {x: xa, y: ya}, trace, t);\n plotBoxMean(plotGroup, {pos: posAxis, val: valAxis}, trace, t);\n });\n}\n\nfunction plotBoxAndWhiskers(sel, axes, trace, t) {\n var posAxis = axes.pos;\n var valAxis = axes.val;\n var bPos = t.bPos;\n var wdPos = t.wdPos || 0;\n var bPosPxOffset = t.bPosPxOffset || 0;\n var whiskerWidth = trace.whiskerwidth || 0;\n var notched = trace.notched || false;\n var nw = notched ? 1 - 2 * trace.notchwidth : 1;\n\n // to support for one-sided box\n var bdPos0;\n var bdPos1;\n if(Array.isArray(t.bdPos)) {\n bdPos0 = t.bdPos[0];\n bdPos1 = t.bdPos[1];\n } else {\n bdPos0 = t.bdPos;\n bdPos1 = t.bdPos;\n }\n\n var paths = sel.selectAll('path.box').data((\n trace.type !== 'violin' ||\n trace.box.visible\n ) ? Lib.identity : []);\n\n paths.enter().append('path')\n .style('vector-effect', 'non-scaling-stroke')\n .attr('class', 'box');\n\n paths.exit().remove();\n\n paths.each(function(d) {\n if(d.empty) return 'M0,0Z';\n\n var lcenter = posAxis.c2l(d.pos + bPos, true);\n var posc = posAxis.l2p(lcenter) + bPosPxOffset;\n var pos0 = posAxis.l2p(lcenter - bdPos0) + bPosPxOffset;\n var pos1 = posAxis.l2p(lcenter + bdPos1) + bPosPxOffset;\n var posw0 = posAxis.l2p(lcenter - wdPos) + bPosPxOffset;\n var posw1 = posAxis.l2p(lcenter + wdPos) + bPosPxOffset;\n var posm0 = posAxis.l2p(lcenter - bdPos0 * nw) + bPosPxOffset;\n var posm1 = posAxis.l2p(lcenter + bdPos1 * nw) + bPosPxOffset;\n var q1 = valAxis.c2p(d.q1, true);\n var q3 = valAxis.c2p(d.q3, true);\n // make sure median isn't identical to either of the\n // quartiles, so we can see it\n var m = Lib.constrain(\n valAxis.c2p(d.med, true),\n Math.min(q1, q3) + 1, Math.max(q1, q3) - 1\n );\n\n // for compatibility with box, violin, and candlestick\n // perhaps we should put this into cd0.t instead so it's more explicit,\n // but what we have now is:\n // - box always has d.lf, but boxpoints can be anything\n // - violin has d.lf and should always use it (boxpoints is undefined)\n // - candlestick has only min/max\n var useExtremes = (d.lf === undefined) || (trace.boxpoints === false);\n var lf = valAxis.c2p(useExtremes ? d.min : d.lf, true);\n var uf = valAxis.c2p(useExtremes ? d.max : d.uf, true);\n var ln = valAxis.c2p(d.ln, true);\n var un = valAxis.c2p(d.un, true);\n\n if(trace.orientation === 'h') {\n d3.select(this).attr('d',\n 'M' + m + ',' + posm0 + 'V' + posm1 + // median line\n 'M' + q1 + ',' + pos0 + 'V' + pos1 + // left edge\n (notched ? 'H' + ln + 'L' + m + ',' + posm1 + 'L' + un + ',' + pos1 : '') + // top notched edge\n 'H' + q3 + // end of the top edge\n 'V' + pos0 + // right edge\n (notched ? 'H' + un + 'L' + m + ',' + posm0 + 'L' + ln + ',' + pos0 : '') + // bottom notched edge\n 'Z' + // end of the box\n 'M' + q1 + ',' + posc + 'H' + lf + 'M' + q3 + ',' + posc + 'H' + uf + // whiskers\n ((whiskerWidth === 0) ? '' : // whisker caps\n 'M' + lf + ',' + posw0 + 'V' + posw1 + 'M' + uf + ',' + posw0 + 'V' + posw1));\n } else {\n d3.select(this).attr('d',\n 'M' + posm0 + ',' + m + 'H' + posm1 + // median line\n 'M' + pos0 + ',' + q1 + 'H' + pos1 + // top of the box\n (notched ? 'V' + ln + 'L' + posm1 + ',' + m + 'L' + pos1 + ',' + un : '') + // notched right edge\n 'V' + q3 + // end of the right edge\n 'H' + pos0 + // bottom of the box\n (notched ? 'V' + un + 'L' + posm0 + ',' + m + 'L' + pos0 + ',' + ln : '') + // notched left edge\n 'Z' + // end of the box\n 'M' + posc + ',' + q1 + 'V' + lf + 'M' + posc + ',' + q3 + 'V' + uf + // whiskers\n ((whiskerWidth === 0) ? '' : // whisker caps\n 'M' + posw0 + ',' + lf + 'H' + posw1 + 'M' + posw0 + ',' + uf + 'H' + posw1));\n }\n });\n}\n\nfunction plotPoints(sel, axes, trace, t) {\n var xa = axes.x;\n var ya = axes.y;\n var bdPos = t.bdPos;\n var bPos = t.bPos;\n\n // to support violin points\n var mode = trace.boxpoints || trace.points;\n\n // repeatable pseudo-random number generator\n Lib.seedPseudoRandom();\n\n // since box plot points get an extra level of nesting, each\n // box needs the trace styling info\n var fn = function(d) {\n d.forEach(function(v) {\n v.t = t;\n v.trace = trace;\n });\n return d;\n };\n\n var gPoints = sel.selectAll('g.points')\n .data(mode ? fn : []);\n\n gPoints.enter().append('g')\n .attr('class', 'points');\n\n gPoints.exit().remove();\n\n var paths = gPoints.selectAll('path')\n .data(function(d) {\n var i;\n var pts = d.pts2;\n\n // normally use IQR, but if this is 0 or too small, use max-min\n var typicalSpread = Math.max((d.max - d.min) / 10, d.q3 - d.q1);\n var minSpread = typicalSpread * 1e-9;\n var spreadLimit = typicalSpread * JITTERSPREAD;\n var jitterFactors = [];\n var maxJitterFactor = 0;\n var newJitter;\n\n // dynamic jitter\n if(trace.jitter) {\n if(typicalSpread === 0) {\n // edge case of no spread at all: fall back to max jitter\n maxJitterFactor = 1;\n jitterFactors = new Array(pts.length);\n for(i = 0; i < pts.length; i++) {\n jitterFactors[i] = 1;\n }\n } else {\n for(i = 0; i < pts.length; i++) {\n var i0 = Math.max(0, i - JITTERCOUNT);\n var pmin = pts[i0].v;\n var i1 = Math.min(pts.length - 1, i + JITTERCOUNT);\n var pmax = pts[i1].v;\n\n if(mode !== 'all') {\n if(pts[i].v < d.lf) pmax = Math.min(pmax, d.lf);\n else pmin = Math.max(pmin, d.uf);\n }\n\n var jitterFactor = Math.sqrt(spreadLimit * (i1 - i0) / (pmax - pmin + minSpread)) || 0;\n jitterFactor = Lib.constrain(Math.abs(jitterFactor), 0, 1);\n\n jitterFactors.push(jitterFactor);\n maxJitterFactor = Math.max(jitterFactor, maxJitterFactor);\n }\n }\n newJitter = trace.jitter * 2 / (maxJitterFactor || 1);\n }\n\n // fills in 'x' and 'y' in calcdata 'pts' item\n for(i = 0; i < pts.length; i++) {\n var pt = pts[i];\n var v = pt.v;\n\n var jitterOffset = trace.jitter ?\n (newJitter * jitterFactors[i] * (Lib.pseudoRandom() - 0.5)) :\n 0;\n\n var posPx = d.pos + bPos + bdPos * (trace.pointpos + jitterOffset);\n\n if(trace.orientation === 'h') {\n pt.y = posPx;\n pt.x = v;\n } else {\n pt.x = posPx;\n pt.y = v;\n }\n\n // tag suspected outliers\n if(mode === 'suspectedoutliers' && v < d.uo && v > d.lo) {\n pt.so = true;\n }\n }\n\n return pts;\n });\n\n paths.enter().append('path')\n .classed('point', true);\n\n paths.exit().remove();\n\n paths.call(Drawing.translatePoints, xa, ya);\n}\n\nfunction plotBoxMean(sel, axes, trace, t) {\n var posAxis = axes.pos;\n var valAxis = axes.val;\n var bPos = t.bPos;\n var bPosPxOffset = t.bPosPxOffset || 0;\n\n // to support violin mean lines\n var mode = trace.boxmean || (trace.meanline || {}).visible;\n\n // to support for one-sided box\n var bdPos0;\n var bdPos1;\n if(Array.isArray(t.bdPos)) {\n bdPos0 = t.bdPos[0];\n bdPos1 = t.bdPos[1];\n } else {\n bdPos0 = t.bdPos;\n bdPos1 = t.bdPos;\n }\n\n var paths = sel.selectAll('path.mean').data((\n (trace.type === 'box' && trace.boxmean) ||\n (trace.type === 'violin' && trace.box.visible && trace.meanline.visible)\n ) ? Lib.identity : []);\n\n paths.enter().append('path')\n .attr('class', 'mean')\n .style({\n fill: 'none',\n 'vector-effect': 'non-scaling-stroke'\n });\n\n paths.exit().remove();\n\n paths.each(function(d) {\n var lcenter = posAxis.c2l(d.pos + bPos, true);\n var posc = posAxis.l2p(lcenter) + bPosPxOffset;\n var pos0 = posAxis.l2p(lcenter - bdPos0) + bPosPxOffset;\n var pos1 = posAxis.l2p(lcenter + bdPos1) + bPosPxOffset;\n var m = valAxis.c2p(d.mean, true);\n var sl = valAxis.c2p(d.mean - d.sd, true);\n var sh = valAxis.c2p(d.mean + d.sd, true);\n\n if(trace.orientation === 'h') {\n d3.select(this).attr('d',\n 'M' + m + ',' + pos0 + 'V' + pos1 +\n (mode === 'sd' ?\n 'm0,0L' + sl + ',' + posc + 'L' + m + ',' + pos0 + 'L' + sh + ',' + posc + 'Z' :\n '')\n );\n } else {\n d3.select(this).attr('d',\n 'M' + pos0 + ',' + m + 'H' + pos1 +\n (mode === 'sd' ?\n 'm0,0L' + posc + ',' + sl + 'L' + pos0 + ',' + m + 'L' + posc + ',' + sh + 'Z' :\n '')\n );\n }\n });\n}\n\nmodule.exports = {\n plot: plot,\n plotBoxAndWhiskers: plotBoxAndWhiskers,\n plotPoints: plotPoints,\n plotBoxMean: plotBoxMean\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/box/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/box/select.js":
-/*!*********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/box/select.js ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function selectPoints(searchInfo, selectionTester) {\n var cd = searchInfo.cd;\n var xa = searchInfo.xaxis;\n var ya = searchInfo.yaxis;\n var selection = [];\n var i, j;\n\n if(selectionTester === false) {\n for(i = 0; i < cd.length; i++) {\n for(j = 0; j < (cd[i].pts || []).length; j++) {\n // clear selection\n cd[i].pts[j].selected = 0;\n }\n }\n } else {\n for(i = 0; i < cd.length; i++) {\n for(j = 0; j < (cd[i].pts || []).length; j++) {\n var pt = cd[i].pts[j];\n var x = xa.c2p(pt.x);\n var y = ya.c2p(pt.y);\n\n if(selectionTester.contains([x, y], null, pt.i, searchInfo)) {\n selection.push({\n pointNumber: pt.i,\n x: xa.c2d(pt.x),\n y: ya.c2d(pt.y)\n });\n pt.selected = 1;\n } else {\n pt.selected = 0;\n }\n }\n }\n }\n\n return selection;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/box/select.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/box/style.js":
-/*!********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/box/style.js ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\n\nfunction style(gd, cd, sel) {\n var s = sel ? sel : d3.select(gd).selectAll('g.trace.boxes');\n\n s.style('opacity', function(d) { return d[0].trace.opacity; });\n\n s.each(function(d) {\n var el = d3.select(this);\n var trace = d[0].trace;\n var lineWidth = trace.line.width;\n\n function styleBox(boxSel, lineWidth, lineColor, fillColor) {\n boxSel.style('stroke-width', lineWidth + 'px')\n .call(Color.stroke, lineColor)\n .call(Color.fill, fillColor);\n }\n\n var allBoxes = el.selectAll('path.box');\n\n if(trace.type === 'candlestick') {\n allBoxes.each(function(boxData) {\n if(boxData.empty) return;\n\n var thisBox = d3.select(this);\n var container = trace[boxData.dir]; // dir = 'increasing' or 'decreasing'\n styleBox(thisBox, container.line.width, container.line.color, container.fillcolor);\n // TODO: custom selection style for candlesticks\n thisBox.style('opacity', trace.selectedpoints && !boxData.selected ? 0.3 : 1);\n });\n } else {\n styleBox(allBoxes, lineWidth, trace.line.color, trace.fillcolor);\n el.selectAll('path.mean')\n .style({\n 'stroke-width': lineWidth,\n 'stroke-dasharray': (2 * lineWidth) + 'px,' + lineWidth + 'px'\n })\n .call(Color.stroke, trace.line.color);\n\n var pts = el.selectAll('path.point');\n Drawing.pointStyle(pts, trace, gd);\n }\n });\n}\n\nfunction styleOnSelect(gd, cd, sel) {\n var trace = cd[0].trace;\n var pts = sel.selectAll('path.point');\n\n if(trace.selectedpoints) {\n Drawing.selectedPointStyle(pts, trace);\n } else {\n Drawing.pointStyle(pts, trace, gd);\n }\n}\n\nmodule.exports = {\n style: style,\n styleOnSelect: styleOnSelect\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/box/style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/candlestick/attributes.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/candlestick/attributes.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar extendFlat = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").extendFlat;\nvar OHLCattrs = __webpack_require__(/*! ../ohlc/attributes */ \"./node_modules/plotly.js/src/traces/ohlc/attributes.js\");\nvar boxAttrs = __webpack_require__(/*! ../box/attributes */ \"./node_modules/plotly.js/src/traces/box/attributes.js\");\n\nfunction directionAttrs(lineColorDefault) {\n return {\n line: {\n color: extendFlat({}, boxAttrs.line.color, {dflt: lineColorDefault}),\n width: boxAttrs.line.width,\n editType: 'style'\n },\n\n fillcolor: boxAttrs.fillcolor,\n editType: 'style'\n };\n}\n\nmodule.exports = {\n x: OHLCattrs.x,\n open: OHLCattrs.open,\n high: OHLCattrs.high,\n low: OHLCattrs.low,\n close: OHLCattrs.close,\n\n line: {\n width: extendFlat({}, boxAttrs.line.width, {\n \n }),\n editType: 'style'\n },\n\n increasing: directionAttrs(OHLCattrs.increasing.line.color.dflt),\n\n decreasing: directionAttrs(OHLCattrs.decreasing.line.color.dflt),\n\n text: OHLCattrs.text,\n hovertext: OHLCattrs.hovertext,\n whiskerwidth: extendFlat({}, boxAttrs.whiskerwidth, { dflt: 0 }),\n\n hoverlabel: OHLCattrs.hoverlabel,\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/candlestick/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/candlestick/calc.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/candlestick/calc.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\n\nvar calcCommon = __webpack_require__(/*! ../ohlc/calc */ \"./node_modules/plotly.js/src/traces/ohlc/calc.js\").calcCommon;\n\nmodule.exports = function(gd, trace) {\n var fullLayout = gd._fullLayout;\n var xa = Axes.getFromId(gd, trace.xaxis);\n var ya = Axes.getFromId(gd, trace.yaxis);\n\n var x = xa.makeCalcdata(trace, 'x');\n\n var cd = calcCommon(gd, trace, x, ya, ptFunc);\n\n if(cd.length) {\n Lib.extendFlat(cd[0].t, {\n num: fullLayout._numBoxes,\n dPos: Lib.distinctVals(x).minDiff / 2,\n posLetter: 'x',\n valLetter: 'y',\n });\n\n fullLayout._numBoxes++;\n return cd;\n } else {\n return [{t: {empty: true}}];\n }\n};\n\nfunction ptFunc(o, h, l, c) {\n return {\n min: l,\n q1: Math.min(o, c),\n med: c,\n q3: Math.max(o, c),\n max: h,\n };\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/candlestick/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/candlestick/defaults.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/candlestick/defaults.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar handleOHLC = __webpack_require__(/*! ../ohlc/ohlc_defaults */ \"./node_modules/plotly.js/src/traces/ohlc/ohlc_defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/candlestick/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var len = handleOHLC(traceIn, traceOut, coerce, layout);\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n coerce('line.width');\n\n handleDirection(traceIn, traceOut, coerce, 'increasing');\n handleDirection(traceIn, traceOut, coerce, 'decreasing');\n\n coerce('text');\n coerce('hovertext');\n coerce('whiskerwidth');\n\n layout._requestRangeslider[traceOut.xaxis] = true;\n};\n\nfunction handleDirection(traceIn, traceOut, coerce, direction) {\n var lineColor = coerce(direction + '.line.color');\n coerce(direction + '.line.width', traceOut.line.width);\n coerce(direction + '.fillcolor', Color.addOpacity(lineColor, 0.5));\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/candlestick/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/candlestick/index.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/candlestick/index.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n moduleType: 'trace',\n name: 'candlestick',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['cartesian', 'svg', 'showLegend', 'candlestick', 'boxLayout'],\n meta: {\n \n },\n\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/candlestick/attributes.js\"),\n layoutAttributes: __webpack_require__(/*! ../box/layout_attributes */ \"./node_modules/plotly.js/src/traces/box/layout_attributes.js\"),\n supplyLayoutDefaults: __webpack_require__(/*! ../box/layout_defaults */ \"./node_modules/plotly.js/src/traces/box/layout_defaults.js\").supplyLayoutDefaults,\n crossTraceCalc: __webpack_require__(/*! ../box/cross_trace_calc */ \"./node_modules/plotly.js/src/traces/box/cross_trace_calc.js\").crossTraceCalc,\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/candlestick/defaults.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/candlestick/calc.js\"),\n plot: __webpack_require__(/*! ../box/plot */ \"./node_modules/plotly.js/src/traces/box/plot.js\").plot,\n layerName: 'boxlayer',\n style: __webpack_require__(/*! ../box/style */ \"./node_modules/plotly.js/src/traces/box/style.js\").style,\n hoverPoints: __webpack_require__(/*! ../ohlc/hover */ \"./node_modules/plotly.js/src/traces/ohlc/hover.js\").hoverPoints,\n selectPoints: __webpack_require__(/*! ../ohlc/select */ \"./node_modules/plotly.js/src/traces/ohlc/select.js\")\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/candlestick/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/ab_defaults.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/ab_defaults.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar handleAxisDefaults = __webpack_require__(/*! ./axis_defaults */ \"./node_modules/plotly.js/src/traces/carpet/axis_defaults.js\");\nvar Template = __webpack_require__(/*! ../../plot_api/plot_template */ \"./node_modules/plotly.js/src/plot_api/plot_template.js\");\n\nmodule.exports = function handleABDefaults(traceIn, traceOut, fullLayout, coerce, dfltColor) {\n var a = coerce('a');\n\n if(!a) {\n coerce('da');\n coerce('a0');\n }\n\n var b = coerce('b');\n\n if(!b) {\n coerce('db');\n coerce('b0');\n }\n\n mimickAxisDefaults(traceIn, traceOut, fullLayout, dfltColor);\n};\n\nfunction mimickAxisDefaults(traceIn, traceOut, fullLayout, dfltColor) {\n var axesList = ['aaxis', 'baxis'];\n\n axesList.forEach(function(axName) {\n var axLetter = axName.charAt(0);\n var axIn = traceIn[axName] || {};\n var axOut = Template.newContainer(traceOut, axName);\n\n var defaultOptions = {\n tickfont: 'x',\n id: axLetter + 'axis',\n letter: axLetter,\n font: traceOut.font,\n name: axName,\n data: traceIn[axLetter],\n calendar: traceOut.calendar,\n dfltColor: dfltColor,\n bgColor: fullLayout.paper_bgcolor,\n fullLayout: fullLayout\n };\n\n handleAxisDefaults(axIn, axOut, defaultOptions);\n axOut._categories = axOut._categories || [];\n\n // so we don't have to repeat autotype unnecessarily,\n // copy an autotype back to traceIn\n if(!traceIn[axName] && axIn.type !== '-') {\n traceIn[axName] = {type: axIn.type};\n }\n });\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/ab_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/array_minmax.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/array_minmax.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isArrayOrTypedArray = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").isArrayOrTypedArray;\n\nmodule.exports = function(a) {\n return minMax(a, 0);\n};\n\nfunction minMax(a, depth) {\n // Limit to ten dimensional datasets. This seems *exceedingly* unlikely to\n // ever cause problems or even be a concern. It's include strictly so that\n // circular arrays could never cause this to loop.\n if(!isArrayOrTypedArray(a) || depth >= 10) {\n return null;\n }\n\n var min = Infinity;\n var max = -Infinity;\n var n = a.length;\n for(var i = 0; i < n; i++) {\n var datum = a[i];\n\n if(isArrayOrTypedArray(datum)) {\n var result = minMax(datum, depth + 1);\n\n if(result) {\n min = Math.min(result[0], min);\n max = Math.max(result[1], max);\n }\n } else {\n min = Math.min(datum, min);\n max = Math.max(datum, max);\n }\n }\n\n return [min, max];\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/array_minmax.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/attributes.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/attributes.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar fontAttrs = __webpack_require__(/*! ../../plots/font_attributes */ \"./node_modules/plotly.js/src/plots/font_attributes.js\");\nvar axisAttrs = __webpack_require__(/*! ./axis_attributes */ \"./node_modules/plotly.js/src/traces/carpet/axis_attributes.js\");\nvar colorAttrs = __webpack_require__(/*! ../../components/color/attributes */ \"./node_modules/plotly.js/src/components/color/attributes.js\");\n\nvar carpetFont = fontAttrs({\n editType: 'calc',\n \n});\n// TODO: inherit from global font\ncarpetFont.family.dflt = '\"Open Sans\", verdana, arial, sans-serif';\ncarpetFont.size.dflt = 12;\ncarpetFont.color.dflt = colorAttrs.defaultLine;\n\nmodule.exports = {\n carpet: {\n valType: 'string',\n \n editType: 'calc',\n \n },\n x: {\n valType: 'data_array',\n editType: 'calc+clearAxisTypes',\n \n },\n y: {\n valType: 'data_array',\n editType: 'calc+clearAxisTypes',\n \n },\n a: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n a0: {\n valType: 'number',\n dflt: 0,\n \n editType: 'calc',\n \n },\n da: {\n valType: 'number',\n dflt: 1,\n \n editType: 'calc',\n \n },\n b: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n b0: {\n valType: 'number',\n dflt: 0,\n \n editType: 'calc',\n \n },\n db: {\n valType: 'number',\n dflt: 1,\n \n editType: 'calc',\n \n },\n cheaterslope: {\n valType: 'number',\n \n dflt: 1,\n editType: 'calc',\n \n },\n aaxis: axisAttrs,\n baxis: axisAttrs,\n font: carpetFont,\n color: {\n valType: 'color',\n dflt: colorAttrs.defaultLine,\n \n editType: 'plot',\n \n },\n transforms: undefined\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/axis_aligned_line.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/axis_aligned_line.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isArrayOrTypedArray = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").isArrayOrTypedArray;\n\n/* This function retrns a set of control points that define a curve aligned along\n * either the a or b axis. Exactly one of a or b must be an array defining the range\n * spanned.\n *\n * Honestly this is the most complicated function I've implemente here so far because\n * of the way it handles knot insertion and direction/axis-agnostic slices.\n */\nmodule.exports = function(carpet, carpetcd, a, b) {\n var idx, tangent, tanIsoIdx, tanIsoPar, segment, refidx;\n var p0, p1, v0, v1, start, end, range;\n\n var axis = isArrayOrTypedArray(a) ? 'a' : 'b';\n var ax = axis === 'a' ? carpet.aaxis : carpet.baxis;\n var smoothing = ax.smoothing;\n var toIdx = axis === 'a' ? carpet.a2i : carpet.b2j;\n var pt = axis === 'a' ? a : b;\n var iso = axis === 'a' ? b : a;\n var n = axis === 'a' ? carpetcd.a.length : carpetcd.b.length;\n var m = axis === 'a' ? carpetcd.b.length : carpetcd.a.length;\n var isoIdx = Math.floor(axis === 'a' ? carpet.b2j(iso) : carpet.a2i(iso));\n\n var xy = axis === 'a' ? function(value) {\n return carpet.evalxy([], value, isoIdx);\n } : function(value) {\n return carpet.evalxy([], isoIdx, value);\n };\n\n if(smoothing) {\n tanIsoIdx = Math.max(0, Math.min(m - 2, isoIdx));\n tanIsoPar = isoIdx - tanIsoIdx;\n tangent = axis === 'a' ? function(i, ti) {\n return carpet.dxydi([], i, tanIsoIdx, ti, tanIsoPar);\n } : function(j, tj) {\n return carpet.dxydj([], tanIsoIdx, j, tanIsoPar, tj);\n };\n }\n\n var vstart = toIdx(pt[0]);\n var vend = toIdx(pt[1]);\n\n // So that we can make this work in two directions, flip all of the\n // math functions if the direction is from higher to lower indices:\n //\n // Note that the tolerance is directional!\n var dir = vstart < vend ? 1 : -1;\n var tol = (vend - vstart) * 1e-8;\n var dirfloor = dir > 0 ? Math.floor : Math.ceil;\n var dirceil = dir > 0 ? Math.ceil : Math.floor;\n var dirmin = dir > 0 ? Math.min : Math.max;\n var dirmax = dir > 0 ? Math.max : Math.min;\n\n var idx0 = dirfloor(vstart + tol);\n var idx1 = dirceil(vend - tol);\n\n p0 = xy(vstart);\n var segments = [[p0]];\n\n for(idx = idx0; idx * dir < idx1 * dir; idx += dir) {\n segment = [];\n start = dirmax(vstart, idx);\n end = dirmin(vend, idx + dir);\n range = end - start;\n\n // In order to figure out which cell we're in for the derivative (remember,\n // the derivatives are *not* constant across grid lines), let's just average\n // the start and end points. This cuts out just a tiny bit of logic and\n // there's really no computational difference:\n refidx = Math.max(0, Math.min(n - 2, Math.floor(0.5 * (start + end))));\n\n p1 = xy(end);\n if(smoothing) {\n v0 = tangent(refidx, start - refidx);\n v1 = tangent(refidx, end - refidx);\n\n segment.push([\n p0[0] + v0[0] / 3 * range,\n p0[1] + v0[1] / 3 * range\n ]);\n\n segment.push([\n p1[0] - v1[0] / 3 * range,\n p1[1] - v1[1] / 3 * range\n ]);\n }\n\n segment.push(p1);\n\n segments.push(segment);\n p0 = p1;\n }\n\n return segments;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/axis_aligned_line.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/axis_attributes.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/axis_attributes.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar fontAttrs = __webpack_require__(/*! ../../plots/font_attributes */ \"./node_modules/plotly.js/src/plots/font_attributes.js\");\nvar colorAttrs = __webpack_require__(/*! ../../components/color/attributes */ \"./node_modules/plotly.js/src/components/color/attributes.js\");\nvar axesAttrs = __webpack_require__(/*! ../../plots/cartesian/layout_attributes */ \"./node_modules/plotly.js/src/plots/cartesian/layout_attributes.js\");\nvar overrideAll = __webpack_require__(/*! ../../plot_api/edit_types */ \"./node_modules/plotly.js/src/plot_api/edit_types.js\").overrideAll;\n\nvar FORMAT_LINK = __webpack_require__(/*! ../../constants/docs */ \"./node_modules/plotly.js/src/constants/docs.js\").FORMAT_LINK;\nvar DATE_FORMAT_LINK = __webpack_require__(/*! ../../constants/docs */ \"./node_modules/plotly.js/src/constants/docs.js\").TIME_FORMAT_LINK;\n\nmodule.exports = {\n color: {\n valType: 'color',\n \n editType: 'calc',\n \n },\n smoothing: {\n valType: 'number',\n dflt: 1,\n min: 0,\n max: 1.3,\n \n editType: 'calc'\n },\n title: {\n text: {\n valType: 'string',\n dflt: '',\n \n editType: 'calc',\n \n },\n font: fontAttrs({\n editType: 'calc',\n \n }),\n // TODO how is this different than `title.standoff`\n offset: {\n valType: 'number',\n \n dflt: 10,\n editType: 'calc',\n \n },\n editType: 'calc',\n },\n type: {\n valType: 'enumerated',\n // '-' means we haven't yet run autotype or couldn't find any data\n // it gets turned into linear in gd._fullLayout but not copied back\n // to gd.data like the others are.\n values: ['-', 'linear', 'date', 'category'],\n dflt: '-',\n \n editType: 'calc',\n \n },\n autorange: {\n valType: 'enumerated',\n values: [true, false, 'reversed'],\n dflt: true,\n \n editType: 'calc',\n \n },\n rangemode: {\n valType: 'enumerated',\n values: ['normal', 'tozero', 'nonnegative'],\n dflt: 'normal',\n \n editType: 'calc',\n \n },\n range: {\n valType: 'info_array',\n \n editType: 'calc',\n items: [\n {valType: 'any', editType: 'calc'},\n {valType: 'any', editType: 'calc'}\n ],\n \n },\n\n fixedrange: {\n valType: 'boolean',\n dflt: false,\n \n editType: 'calc',\n \n },\n cheatertype: {\n valType: 'enumerated',\n values: ['index', 'value'],\n dflt: 'value',\n \n editType: 'calc'\n },\n tickmode: {\n valType: 'enumerated',\n values: ['linear', 'array'],\n dflt: 'array',\n \n editType: 'calc'\n },\n nticks: {\n valType: 'integer',\n min: 0,\n dflt: 0,\n \n editType: 'calc',\n \n },\n tickvals: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n ticktext: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n showticklabels: {\n valType: 'enumerated',\n values: ['start', 'end', 'both', 'none'],\n dflt: 'start',\n \n editType: 'calc',\n \n },\n tickfont: fontAttrs({\n editType: 'calc',\n \n }),\n tickangle: {\n valType: 'angle',\n dflt: 'auto',\n \n editType: 'calc',\n \n },\n tickprefix: {\n valType: 'string',\n dflt: '',\n \n editType: 'calc',\n \n },\n showtickprefix: {\n valType: 'enumerated',\n values: ['all', 'first', 'last', 'none'],\n dflt: 'all',\n \n editType: 'calc',\n \n },\n ticksuffix: {\n valType: 'string',\n dflt: '',\n \n editType: 'calc',\n \n },\n showticksuffix: {\n valType: 'enumerated',\n values: ['all', 'first', 'last', 'none'],\n dflt: 'all',\n \n editType: 'calc',\n \n },\n showexponent: {\n valType: 'enumerated',\n values: ['all', 'first', 'last', 'none'],\n dflt: 'all',\n \n editType: 'calc',\n \n },\n exponentformat: {\n valType: 'enumerated',\n values: ['none', 'e', 'E', 'power', 'SI', 'B'],\n dflt: 'B',\n \n editType: 'calc',\n \n },\n separatethousands: {\n valType: 'boolean',\n dflt: false,\n \n editType: 'calc',\n \n },\n tickformat: {\n valType: 'string',\n dflt: '',\n \n editType: 'calc',\n \n },\n tickformatstops: overrideAll(axesAttrs.tickformatstops, 'calc', 'from-root'),\n categoryorder: {\n valType: 'enumerated',\n values: [\n 'trace', 'category ascending', 'category descending', 'array'\n /* , 'value ascending', 'value descending'*/ // value ascending / descending to be implemented later\n ],\n dflt: 'trace',\n \n editType: 'calc',\n \n },\n categoryarray: {\n valType: 'data_array',\n \n editType: 'calc',\n \n },\n labelpadding: {\n valType: 'integer',\n \n dflt: 10,\n editType: 'calc',\n \n },\n labelprefix: {\n valType: 'string',\n \n editType: 'calc',\n \n },\n labelsuffix: {\n valType: 'string',\n dflt: '',\n \n editType: 'calc',\n \n },\n // lines and grids\n showline: {\n valType: 'boolean',\n dflt: false,\n \n editType: 'calc',\n \n },\n linecolor: {\n valType: 'color',\n dflt: colorAttrs.defaultLine,\n \n editType: 'calc',\n \n },\n linewidth: {\n valType: 'number',\n min: 0,\n dflt: 1,\n \n editType: 'calc',\n \n },\n gridcolor: {\n valType: 'color',\n \n editType: 'calc',\n \n },\n gridwidth: {\n valType: 'number',\n min: 0,\n dflt: 1,\n \n editType: 'calc',\n \n },\n showgrid: {\n valType: 'boolean',\n \n dflt: true,\n editType: 'calc',\n \n },\n minorgridcount: {\n valType: 'integer',\n min: 0,\n dflt: 0,\n \n editType: 'calc',\n \n },\n minorgridwidth: {\n valType: 'number',\n min: 0,\n dflt: 1,\n \n editType: 'calc',\n \n },\n minorgridcolor: {\n valType: 'color',\n dflt: colorAttrs.lightLine,\n \n editType: 'calc',\n \n },\n startline: {\n valType: 'boolean',\n \n editType: 'calc',\n \n },\n startlinecolor: {\n valType: 'color',\n \n editType: 'calc',\n \n },\n startlinewidth: {\n valType: 'number',\n dflt: 1,\n \n editType: 'calc',\n \n },\n endline: {\n valType: 'boolean',\n \n editType: 'calc',\n \n },\n endlinewidth: {\n valType: 'number',\n dflt: 1,\n \n editType: 'calc',\n \n },\n endlinecolor: {\n valType: 'color',\n \n editType: 'calc',\n \n },\n tick0: {\n valType: 'number',\n min: 0,\n dflt: 0,\n \n editType: 'calc',\n \n },\n dtick: {\n valType: 'number',\n min: 0,\n dflt: 1,\n \n editType: 'calc',\n \n },\n arraytick0: {\n valType: 'integer',\n min: 0,\n dflt: 0,\n \n editType: 'calc',\n \n },\n arraydtick: {\n valType: 'integer',\n min: 1,\n dflt: 1,\n \n editType: 'calc',\n \n },\n\n _deprecated: {\n title: {\n valType: 'string',\n \n editType: 'calc',\n \n },\n titlefont: fontAttrs({\n editType: 'calc',\n \n }),\n titleoffset: {\n valType: 'number',\n \n dflt: 10,\n editType: 'calc',\n \n }\n },\n\n editType: 'calc'\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/axis_attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/axis_defaults.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/axis_defaults.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar carpetAttrs = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/carpet/attributes.js\");\n\nvar addOpacity = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\").addOpacity;\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar handleTickValueDefaults = __webpack_require__(/*! ../../plots/cartesian/tick_value_defaults */ \"./node_modules/plotly.js/src/plots/cartesian/tick_value_defaults.js\");\nvar handleTickLabelDefaults = __webpack_require__(/*! ../../plots/cartesian/tick_label_defaults */ \"./node_modules/plotly.js/src/plots/cartesian/tick_label_defaults.js\");\nvar handleCategoryOrderDefaults = __webpack_require__(/*! ../../plots/cartesian/category_order_defaults */ \"./node_modules/plotly.js/src/plots/cartesian/category_order_defaults.js\");\nvar setConvert = __webpack_require__(/*! ../../plots/cartesian/set_convert */ \"./node_modules/plotly.js/src/plots/cartesian/set_convert.js\");\nvar autoType = __webpack_require__(/*! ../../plots/cartesian/axis_autotype */ \"./node_modules/plotly.js/src/plots/cartesian/axis_autotype.js\");\n\n/**\n * options: object containing:\n *\n * letter: 'a' or 'b'\n * title: name of the axis (ie 'Colorbar') to go in default title\n * name: axis object name (ie 'xaxis') if one should be stored\n * font: the default font to inherit\n * outerTicks: boolean, should ticks default to outside?\n * showGrid: boolean, should gridlines be shown by default?\n * data: the plot data to use in choosing auto type\n * bgColor: the plot background color, to calculate default gridline colors\n */\nmodule.exports = function handleAxisDefaults(containerIn, containerOut, options) {\n var letter = options.letter;\n var font = options.font || {};\n var attributes = carpetAttrs[letter + 'axis'];\n\n function coerce(attr, dflt) {\n return Lib.coerce(containerIn, containerOut, attributes, attr, dflt);\n }\n\n function coerce2(attr, dflt) {\n return Lib.coerce2(containerIn, containerOut, attributes, attr, dflt);\n }\n\n // set up some private properties\n if(options.name) {\n containerOut._name = options.name;\n containerOut._id = options.name;\n }\n\n // now figure out type and do some more initialization\n var axType = coerce('type');\n if(axType === '-') {\n if(options.data) setAutoType(containerOut, options.data);\n\n if(containerOut.type === '-') {\n containerOut.type = 'linear';\n } else {\n // copy autoType back to input axis\n // note that if this object didn't exist\n // in the input layout, we have to put it in\n // this happens in the main supplyDefaults function\n axType = containerIn.type = containerOut.type;\n }\n }\n\n coerce('smoothing');\n coerce('cheatertype');\n\n coerce('showticklabels');\n coerce('labelprefix', letter + ' = ');\n coerce('labelsuffix');\n coerce('showtickprefix');\n coerce('showticksuffix');\n\n coerce('separatethousands');\n coerce('tickformat');\n coerce('exponentformat');\n coerce('showexponent');\n coerce('categoryorder');\n\n coerce('tickmode');\n coerce('tickvals');\n coerce('ticktext');\n coerce('tick0');\n coerce('dtick');\n\n if(containerOut.tickmode === 'array') {\n coerce('arraytick0');\n coerce('arraydtick');\n }\n\n coerce('labelpadding');\n\n containerOut._hovertitle = letter;\n\n\n if(axType === 'date') {\n var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleDefaults');\n handleCalendarDefaults(containerIn, containerOut, 'calendar', options.calendar);\n }\n\n // we need some of the other functions setConvert attaches, but for\n // path finding, override pixel scaling to simple passthrough (identity)\n setConvert(containerOut, options.fullLayout);\n containerOut.c2p = Lib.identity;\n\n var dfltColor = coerce('color', options.dfltColor);\n // if axis.color was provided, use it for fonts too; otherwise,\n // inherit from global font color in case that was provided.\n var dfltFontColor = (dfltColor === containerIn.color) ? dfltColor : font.color;\n\n var title = coerce('title.text');\n if(title) {\n Lib.coerceFont(coerce, 'title.font', {\n family: font.family,\n size: Math.round(font.size * 1.2),\n color: dfltFontColor\n });\n coerce('title.offset');\n }\n\n coerce('tickangle');\n\n var autoRange = coerce('autorange', !containerOut.isValidRange(containerIn.range));\n\n if(autoRange) coerce('rangemode');\n\n coerce('range');\n containerOut.cleanRange();\n\n coerce('fixedrange');\n\n handleTickValueDefaults(containerIn, containerOut, coerce, axType);\n handleTickLabelDefaults(containerIn, containerOut, coerce, axType, options);\n handleCategoryOrderDefaults(containerIn, containerOut, coerce, {\n data: options.data,\n dataAttr: letter\n });\n\n var gridColor = coerce2('gridcolor', addOpacity(dfltColor, 0.3));\n var gridWidth = coerce2('gridwidth');\n var showGrid = coerce('showgrid');\n\n if(!showGrid) {\n delete containerOut.gridcolor;\n delete containerOut.gridwidth;\n }\n\n var startLineColor = coerce2('startlinecolor', dfltColor);\n var startLineWidth = coerce2('startlinewidth', gridWidth);\n var showStartLine = coerce('startline', containerOut.showgrid || !!startLineColor || !!startLineWidth);\n\n if(!showStartLine) {\n delete containerOut.startlinecolor;\n delete containerOut.startlinewidth;\n }\n\n var endLineColor = coerce2('endlinecolor', dfltColor);\n var endLineWidth = coerce2('endlinewidth', gridWidth);\n var showEndLine = coerce('endline', containerOut.showgrid || !!endLineColor || !!endLineWidth);\n\n if(!showEndLine) {\n delete containerOut.endlinecolor;\n delete containerOut.endlinewidth;\n }\n\n if(!showGrid) {\n delete containerOut.gridcolor;\n delete containerOut.gridWidth;\n } else {\n coerce('minorgridcount');\n coerce('minorgridwidth', gridWidth);\n coerce('minorgridcolor', addOpacity(gridColor, 0.06));\n\n if(!containerOut.minorgridcount) {\n delete containerOut.minorgridwidth;\n delete containerOut.minorgridcolor;\n }\n }\n\n if(containerOut.showticklabels === 'none') {\n delete containerOut.tickfont;\n delete containerOut.tickangle;\n delete containerOut.showexponent;\n delete containerOut.exponentformat;\n delete containerOut.tickformat;\n delete containerOut.showticksuffix;\n delete containerOut.showtickprefix;\n }\n\n if(!containerOut.showticksuffix) {\n delete containerOut.ticksuffix;\n }\n\n if(!containerOut.showtickprefix) {\n delete containerOut.tickprefix;\n }\n\n // It needs to be coerced, then something above overrides this deep in the axis code,\n // but no, we *actually* want to coerce this.\n coerce('tickmode');\n\n return containerOut;\n};\n\nfunction setAutoType(ax, data) {\n // new logic: let people specify any type they want,\n // only autotype if type is '-'\n if(ax.type !== '-') return;\n\n var id = ax._id;\n var axLetter = id.charAt(0);\n\n var calAttr = axLetter + 'calendar';\n var calendar = ax[calAttr];\n\n ax.type = autoType(data, calendar);\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/axis_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/calc.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/calc.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar isArray1D = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").isArray1D;\nvar cheaterBasis = __webpack_require__(/*! ./cheater_basis */ \"./node_modules/plotly.js/src/traces/carpet/cheater_basis.js\");\nvar arrayMinmax = __webpack_require__(/*! ./array_minmax */ \"./node_modules/plotly.js/src/traces/carpet/array_minmax.js\");\nvar calcGridlines = __webpack_require__(/*! ./calc_gridlines */ \"./node_modules/plotly.js/src/traces/carpet/calc_gridlines.js\");\nvar calcLabels = __webpack_require__(/*! ./calc_labels */ \"./node_modules/plotly.js/src/traces/carpet/calc_labels.js\");\nvar calcClipPath = __webpack_require__(/*! ./calc_clippath */ \"./node_modules/plotly.js/src/traces/carpet/calc_clippath.js\");\nvar clean2dArray = __webpack_require__(/*! ../heatmap/clean_2d_array */ \"./node_modules/plotly.js/src/traces/heatmap/clean_2d_array.js\");\nvar smoothFill2dArray = __webpack_require__(/*! ./smooth_fill_2d_array */ \"./node_modules/plotly.js/src/traces/carpet/smooth_fill_2d_array.js\");\nvar convertColumnData = __webpack_require__(/*! ../heatmap/convert_column_xyz */ \"./node_modules/plotly.js/src/traces/heatmap/convert_column_xyz.js\");\nvar setConvert = __webpack_require__(/*! ./set_convert */ \"./node_modules/plotly.js/src/traces/carpet/set_convert.js\");\n\nmodule.exports = function calc(gd, trace) {\n var xa = Axes.getFromId(gd, trace.xaxis);\n var ya = Axes.getFromId(gd, trace.yaxis);\n var aax = trace.aaxis;\n var bax = trace.baxis;\n\n var x = trace.x;\n var y = trace.y;\n var cols = [];\n if(x && isArray1D(x)) cols.push('x');\n if(y && isArray1D(y)) cols.push('y');\n\n if(cols.length) {\n convertColumnData(trace, aax, bax, 'a', 'b', cols);\n }\n\n var a = trace._a = trace._a || trace.a;\n var b = trace._b = trace._b || trace.b;\n x = trace._x || trace.x;\n y = trace._y || trace.y;\n\n var t = {};\n\n if(trace._cheater) {\n var avals = aax.cheatertype === 'index' ? a.length : a;\n var bvals = bax.cheatertype === 'index' ? b.length : b;\n x = cheaterBasis(avals, bvals, trace.cheaterslope);\n }\n\n trace._x = x = clean2dArray(x);\n trace._y = y = clean2dArray(y);\n\n // Fill in any undefined values with elliptic smoothing. This doesn't take\n // into account the spacing of the values. That is, the derivatives should\n // be modified to use a and b values. It's not that hard, but this is already\n // moderate overkill for just filling in missing values.\n smoothFill2dArray(x, a, b);\n smoothFill2dArray(y, a, b);\n\n setConvert(trace);\n\n // create conversion functions that depend on the data\n trace.setScale();\n\n // This is a rather expensive scan. Nothing guarantees monotonicity,\n // so we need to scan through all data to get proper ranges:\n var xrange = arrayMinmax(x);\n var yrange = arrayMinmax(y);\n\n var dx = 0.5 * (xrange[1] - xrange[0]);\n var xc = 0.5 * (xrange[1] + xrange[0]);\n\n var dy = 0.5 * (yrange[1] - yrange[0]);\n var yc = 0.5 * (yrange[1] + yrange[0]);\n\n // Expand the axes to fit the plot, except just grow it by a factor of 1.3\n // because the labels should be taken into account except that's difficult\n // hence 1.3.\n var grow = 1.3;\n xrange = [xc - dx * grow, xc + dx * grow];\n yrange = [yc - dy * grow, yc + dy * grow];\n\n trace._extremes[xa._id] = Axes.findExtremes(xa, xrange, {padded: true});\n trace._extremes[ya._id] = Axes.findExtremes(ya, yrange, {padded: true});\n\n // Enumerate the gridlines, both major and minor, and store them on the trace\n // object:\n calcGridlines(trace, 'a', 'b');\n calcGridlines(trace, 'b', 'a');\n\n // Calculate the text labels for each major gridline and store them on the\n // trace object:\n calcLabels(trace, aax);\n calcLabels(trace, bax);\n\n // Tabulate points for the four segments that bound the axes so that we can\n // map to pixel coordinates in the plot function and create a clip rect:\n t.clipsegments = calcClipPath(trace._xctrl, trace._yctrl, aax, bax);\n\n t.x = x;\n t.y = y;\n t.a = a;\n t.b = b;\n\n return [t];\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/calc_clippath.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/calc_clippath.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nmodule.exports = function makeClipPath(xctrl, yctrl, aax, bax) {\n var i, x, y;\n var segments = [];\n\n var asmoothing = !!aax.smoothing;\n var bsmoothing = !!bax.smoothing;\n var nea1 = xctrl[0].length - 1;\n var neb1 = xctrl.length - 1;\n\n // Along the lower a axis:\n for(i = 0, x = [], y = []; i <= nea1; i++) {\n x[i] = xctrl[0][i];\n y[i] = yctrl[0][i];\n }\n segments.push({x: x, y: y, bicubic: asmoothing});\n\n // Along the upper b axis:\n for(i = 0, x = [], y = []; i <= neb1; i++) {\n x[i] = xctrl[i][nea1];\n y[i] = yctrl[i][nea1];\n }\n segments.push({x: x, y: y, bicubic: bsmoothing});\n\n // Backwards along the upper a axis:\n for(i = nea1, x = [], y = []; i >= 0; i--) {\n x[nea1 - i] = xctrl[neb1][i];\n y[nea1 - i] = yctrl[neb1][i];\n }\n segments.push({x: x, y: y, bicubic: asmoothing});\n\n // Backwards along the lower b axis:\n for(i = neb1, x = [], y = []; i >= 0; i--) {\n x[neb1 - i] = xctrl[i][0];\n y[neb1 - i] = yctrl[i][0];\n }\n segments.push({x: x, y: y, bicubic: bsmoothing});\n\n return segments;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/calc_clippath.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/calc_gridlines.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/calc_gridlines.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nmodule.exports = function calcGridlines(trace, axisLetter, crossAxisLetter) {\n var i, j, j0;\n var eps, bounds, n1, n2, n, value, v;\n var j1, v0, v1, d;\n\n var data = trace['_' + axisLetter];\n var axis = trace[axisLetter + 'axis'];\n\n var gridlines = axis._gridlines = [];\n var minorgridlines = axis._minorgridlines = [];\n var boundarylines = axis._boundarylines = [];\n\n var crossData = trace['_' + crossAxisLetter];\n var crossAxis = trace[crossAxisLetter + 'axis'];\n\n if(axis.tickmode === 'array') {\n axis.tickvals = data.slice();\n }\n\n var xcp = trace._xctrl;\n var ycp = trace._yctrl;\n var nea = xcp[0].length;\n var neb = xcp.length;\n var na = trace._a.length;\n var nb = trace._b.length;\n\n Axes.prepTicks(axis);\n\n // don't leave tickvals in axis looking like an attribute\n if(axis.tickmode === 'array') delete axis.tickvals;\n\n // The default is an empty array that will cause the join to remove the gridline if\n // it's just disappeared:\n // axis._startline = axis._endline = [];\n\n // If the cross axis uses bicubic interpolation, then the grid\n // lines fall once every three expanded grid row/cols:\n var stride = axis.smoothing ? 3 : 1;\n\n function constructValueGridline(value) {\n var i, j, j0, tj, pxy, i0, ti, xy, dxydi0, dxydi1, dxydj0, dxydj1;\n var xpoints = [];\n var ypoints = [];\n var ret = {};\n // Search for the fractional grid index giving this line:\n if(axisLetter === 'b') {\n // For the position we use just the i-j coordinates:\n j = trace.b2j(value);\n\n // The derivatives for catmull-rom splines are discontinuous across cell\n // boundaries though, so we need to provide both the cell and the position\n // within the cell separately:\n j0 = Math.floor(Math.max(0, Math.min(nb - 2, j)));\n tj = j - j0;\n\n ret.length = nb;\n ret.crossLength = na;\n\n ret.xy = function(i) {\n return trace.evalxy([], i, j);\n };\n\n ret.dxy = function(i0, ti) {\n return trace.dxydi([], i0, j0, ti, tj);\n };\n\n for(i = 0; i < na; i++) {\n i0 = Math.min(na - 2, i);\n ti = i - i0;\n xy = trace.evalxy([], i, j);\n\n if(crossAxis.smoothing && i > 0) {\n // First control point:\n dxydi0 = trace.dxydi([], i - 1, j0, 0, tj);\n xpoints.push(pxy[0] + dxydi0[0] / 3);\n ypoints.push(pxy[1] + dxydi0[1] / 3);\n\n // Second control point:\n dxydi1 = trace.dxydi([], i - 1, j0, 1, tj);\n xpoints.push(xy[0] - dxydi1[0] / 3);\n ypoints.push(xy[1] - dxydi1[1] / 3);\n }\n\n xpoints.push(xy[0]);\n ypoints.push(xy[1]);\n\n pxy = xy;\n }\n } else {\n i = trace.a2i(value);\n i0 = Math.floor(Math.max(0, Math.min(na - 2, i)));\n ti = i - i0;\n\n ret.length = na;\n ret.crossLength = nb;\n\n ret.xy = function(j) {\n return trace.evalxy([], i, j);\n };\n\n ret.dxy = function(j0, tj) {\n return trace.dxydj([], i0, j0, ti, tj);\n };\n\n for(j = 0; j < nb; j++) {\n j0 = Math.min(nb - 2, j);\n tj = j - j0;\n xy = trace.evalxy([], i, j);\n\n if(crossAxis.smoothing && j > 0) {\n // First control point:\n dxydj0 = trace.dxydj([], i0, j - 1, ti, 0);\n xpoints.push(pxy[0] + dxydj0[0] / 3);\n ypoints.push(pxy[1] + dxydj0[1] / 3);\n\n // Second control point:\n dxydj1 = trace.dxydj([], i0, j - 1, ti, 1);\n xpoints.push(xy[0] - dxydj1[0] / 3);\n ypoints.push(xy[1] - dxydj1[1] / 3);\n }\n\n xpoints.push(xy[0]);\n ypoints.push(xy[1]);\n\n pxy = xy;\n }\n }\n\n ret.axisLetter = axisLetter;\n ret.axis = axis;\n ret.crossAxis = crossAxis;\n ret.value = value;\n ret.constvar = crossAxisLetter;\n ret.index = n;\n ret.x = xpoints;\n ret.y = ypoints;\n ret.smoothing = crossAxis.smoothing;\n\n return ret;\n }\n\n function constructArrayGridline(idx) {\n var j, i0, j0, ti, tj;\n var xpoints = [];\n var ypoints = [];\n var ret = {};\n ret.length = data.length;\n ret.crossLength = crossData.length;\n\n if(axisLetter === 'b') {\n j0 = Math.max(0, Math.min(nb - 2, idx));\n tj = Math.min(1, Math.max(0, idx - j0));\n\n ret.xy = function(i) {\n return trace.evalxy([], i, idx);\n };\n\n ret.dxy = function(i0, ti) {\n return trace.dxydi([], i0, j0, ti, tj);\n };\n\n // In the tickmode: array case, this operation is a simple\n // transfer of data:\n for(j = 0; j < nea; j++) {\n xpoints[j] = xcp[idx * stride][j];\n ypoints[j] = ycp[idx * stride][j];\n }\n } else {\n i0 = Math.max(0, Math.min(na - 2, idx));\n ti = Math.min(1, Math.max(0, idx - i0));\n\n ret.xy = function(j) {\n return trace.evalxy([], idx, j);\n };\n\n ret.dxy = function(j0, tj) {\n return trace.dxydj([], i0, j0, ti, tj);\n };\n\n // In the tickmode: array case, this operation is a simple\n // transfer of data:\n for(j = 0; j < neb; j++) {\n xpoints[j] = xcp[j][idx * stride];\n ypoints[j] = ycp[j][idx * stride];\n }\n }\n\n ret.axisLetter = axisLetter;\n ret.axis = axis;\n ret.crossAxis = crossAxis;\n ret.value = data[idx];\n ret.constvar = crossAxisLetter;\n ret.index = idx;\n ret.x = xpoints;\n ret.y = ypoints;\n ret.smoothing = crossAxis.smoothing;\n\n return ret;\n }\n\n if(axis.tickmode === 'array') {\n // var j0 = axis.startline ? 1 : 0;\n // var j1 = data.length - (axis.endline ? 1 : 0);\n\n eps = 5e-15;\n bounds = [\n Math.floor(((data.length - 1) - axis.arraytick0) / axis.arraydtick * (1 + eps)),\n Math.ceil((- axis.arraytick0) / axis.arraydtick / (1 + eps))\n ].sort(function(a, b) {return a - b;});\n\n // Unpack sorted values so we can be sure to avoid infinite loops if something\n // is backwards:\n n1 = bounds[0] - 1;\n n2 = bounds[1] + 1;\n\n // If the axes fall along array lines, then this is a much simpler process since\n // we already have all the control points we need\n for(n = n1; n < n2; n++) {\n j = axis.arraytick0 + axis.arraydtick * n;\n if(j < 0 || j > data.length - 1) continue;\n gridlines.push(extendFlat(constructArrayGridline(j), {\n color: axis.gridcolor,\n width: axis.gridwidth\n }));\n }\n\n for(n = n1; n < n2; n++) {\n j0 = axis.arraytick0 + axis.arraydtick * n;\n j1 = Math.min(j0 + axis.arraydtick, data.length - 1);\n\n // TODO: fix the bounds computation so we don't have to do a large range and then throw\n // out unneeded numbers\n if(j0 < 0 || j0 > data.length - 1) continue;\n if(j1 < 0 || j1 > data.length - 1) continue;\n\n v0 = data[j0];\n v1 = data[j1];\n\n for(i = 0; i < axis.minorgridcount; i++) {\n d = j1 - j0;\n\n // TODO: fix the bounds computation so we don't have to do a large range and then throw\n // out unneeded numbers\n if(d <= 0) continue;\n\n // XXX: This calculation isn't quite right. Off by one somewhere?\n v = v0 + (v1 - v0) * (i + 1) / (axis.minorgridcount + 1) * (axis.arraydtick / d);\n\n // TODO: fix the bounds computation so we don't have to do a large range and then throw\n // out unneeded numbers\n if(v < data[0] || v > data[data.length - 1]) continue;\n minorgridlines.push(extendFlat(constructValueGridline(v), {\n color: axis.minorgridcolor,\n width: axis.minorgridwidth\n }));\n }\n }\n\n if(axis.startline) {\n boundarylines.push(extendFlat(constructArrayGridline(0), {\n color: axis.startlinecolor,\n width: axis.startlinewidth\n }));\n }\n\n if(axis.endline) {\n boundarylines.push(extendFlat(constructArrayGridline(data.length - 1), {\n color: axis.endlinecolor,\n width: axis.endlinewidth\n }));\n }\n } else {\n // If the lines do not fall along the axes, then we have to interpolate\n // the contro points and so some math to figure out where the lines are\n // in the first place.\n\n // Compute the integer boudns of tick0 + n * dtick that fall within the range\n // (roughly speaking):\n // Give this a nice generous epsilon. We use at as * (1 + eps) in order to make\n // inequalities a little tolerant in a more or less correct manner:\n eps = 5e-15;\n bounds = [\n Math.floor((data[data.length - 1] - axis.tick0) / axis.dtick * (1 + eps)),\n Math.ceil((data[0] - axis.tick0) / axis.dtick / (1 + eps))\n ].sort(function(a, b) {return a - b;});\n\n // Unpack sorted values so we can be sure to avoid infinite loops if something\n // is backwards:\n n1 = bounds[0];\n n2 = bounds[1];\n\n for(n = n1; n <= n2; n++) {\n value = axis.tick0 + axis.dtick * n;\n\n gridlines.push(extendFlat(constructValueGridline(value), {\n color: axis.gridcolor,\n width: axis.gridwidth\n }));\n }\n\n for(n = n1 - 1; n < n2 + 1; n++) {\n value = axis.tick0 + axis.dtick * n;\n\n for(i = 0; i < axis.minorgridcount; i++) {\n v = value + axis.dtick * (i + 1) / (axis.minorgridcount + 1);\n if(v < data[0] || v > data[data.length - 1]) continue;\n minorgridlines.push(extendFlat(constructValueGridline(v), {\n color: axis.minorgridcolor,\n width: axis.minorgridwidth\n }));\n }\n }\n\n if(axis.startline) {\n boundarylines.push(extendFlat(constructValueGridline(data[0]), {\n color: axis.startlinecolor,\n width: axis.startlinewidth\n }));\n }\n\n if(axis.endline) {\n boundarylines.push(extendFlat(constructValueGridline(data[data.length - 1]), {\n color: axis.endlinecolor,\n width: axis.endlinewidth\n }));\n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/calc_gridlines.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/calc_labels.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/calc_labels.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nmodule.exports = function calcLabels(trace, axis) {\n var i, tobj, prefix, suffix, gridline;\n\n var labels = axis._labels = [];\n var gridlines = axis._gridlines;\n\n for(i = 0; i < gridlines.length; i++) {\n gridline = gridlines[i];\n\n if(['start', 'both'].indexOf(axis.showticklabels) !== -1) {\n tobj = Axes.tickText(axis, gridline.value);\n\n extendFlat(tobj, {\n prefix: prefix,\n suffix: suffix,\n endAnchor: true,\n xy: gridline.xy(0),\n dxy: gridline.dxy(0, 0),\n axis: gridline.axis,\n length: gridline.crossAxis.length,\n font: gridline.axis.tickfont,\n isFirst: i === 0,\n isLast: i === gridlines.length - 1\n });\n\n labels.push(tobj);\n }\n\n if(['end', 'both'].indexOf(axis.showticklabels) !== -1) {\n tobj = Axes.tickText(axis, gridline.value);\n\n extendFlat(tobj, {\n endAnchor: false,\n xy: gridline.xy(gridline.crossLength - 1),\n dxy: gridline.dxy(gridline.crossLength - 2, 1),\n axis: gridline.axis,\n length: gridline.crossAxis.length,\n font: gridline.axis.tickfont,\n isFirst: i === 0,\n isLast: i === gridlines.length - 1\n });\n\n labels.push(tobj);\n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/calc_labels.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/catmull_rom.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/catmull_rom.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n/*\n * Compute the tangent vector according to catmull-rom cubic splines (centripetal,\n * I think). That differs from the control point in two ways:\n * 1. It is a vector, not a position relative to the point\n * 2. the vector is longer than the position relative to p1 by a factor of 3\n *\n * Close to the boundaries, we'll use these as *quadratic control points, so that\n * to make a nice grid, we'll need to divide the tangent by 2 instead of 3. (The\n * math works out this way if you work through the bezier derivatives)\n */\nvar CatmullRomExp = 0.5;\nmodule.exports = function makeControlPoints(p0, p1, p2, smoothness) {\n var d1x = p0[0] - p1[0];\n var d1y = p0[1] - p1[1];\n var d2x = p2[0] - p1[0];\n var d2y = p2[1] - p1[1];\n var d1a = Math.pow(d1x * d1x + d1y * d1y, CatmullRomExp / 2);\n var d2a = Math.pow(d2x * d2x + d2y * d2y, CatmullRomExp / 2);\n var numx = (d2a * d2a * d1x - d1a * d1a * d2x) * smoothness;\n var numy = (d2a * d2a * d1y - d1a * d1a * d2y) * smoothness;\n var denom1 = d2a * (d1a + d2a) * 3;\n var denom2 = d1a * (d1a + d2a) * 3;\n\n return [[\n p1[0] + (denom1 && numx / denom1),\n p1[1] + (denom1 && numy / denom1)\n ], [\n p1[0] - (denom2 && numx / denom2),\n p1[1] - (denom2 && numy / denom2)\n ]];\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/catmull_rom.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/cheater_basis.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/cheater_basis.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isArrayOrTypedArray = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").isArrayOrTypedArray;\n\n/*\n * Construct a 2D array of cheater values given a, b, and a slope.\n * If\n */\nmodule.exports = function(a, b, cheaterslope) {\n var i, j, ascal, bscal, aval, bval;\n var data = [];\n\n var na = isArrayOrTypedArray(a) ? a.length : a;\n var nb = isArrayOrTypedArray(b) ? b.length : b;\n var adata = isArrayOrTypedArray(a) ? a : null;\n var bdata = isArrayOrTypedArray(b) ? b : null;\n\n // If we're using data, scale it so that for data that's just barely\n // not evenly spaced, the switch to value-based indexing is continuous.\n // This means evenly spaced data should look the same whether value\n // or index cheatertype.\n if(adata) {\n ascal = (adata.length - 1) / (adata[adata.length - 1] - adata[0]) / (na - 1);\n }\n\n if(bdata) {\n bscal = (bdata.length - 1) / (bdata[bdata.length - 1] - bdata[0]) / (nb - 1);\n }\n\n var xval;\n var xmin = Infinity;\n var xmax = -Infinity;\n for(j = 0; j < nb; j++) {\n data[j] = [];\n bval = bdata ? (bdata[j] - bdata[0]) * bscal : j / (nb - 1);\n for(i = 0; i < na; i++) {\n aval = adata ? (adata[i] - adata[0]) * ascal : i / (na - 1);\n xval = aval - bval * cheaterslope;\n xmin = Math.min(xval, xmin);\n xmax = Math.max(xval, xmax);\n data[j][i] = xval;\n }\n }\n\n // Normalize cheater values to the 0-1 range. This comes into play when you have\n // multiple cheater plots. After careful consideration, it seems better if cheater\n // values are normalized to a consistent range. Otherwise one cheater affects the\n // layout of other cheaters on the same axis.\n var slope = 1.0 / (xmax - xmin);\n var offset = -xmin * slope;\n for(j = 0; j < nb; j++) {\n for(i = 0; i < na; i++) {\n data[j][i] = slope * data[j][i] + offset;\n }\n }\n\n return data;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/cheater_basis.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/compute_control_points.js":
-/*!****************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/compute_control_points.js ***!
- \****************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar makeControlPoints = __webpack_require__(/*! ./catmull_rom */ \"./node_modules/plotly.js/src/traces/carpet/catmull_rom.js\");\nvar ensureArray = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").ensureArray;\n\n/*\n * Turns a coarse grid into a fine grid with control points.\n *\n * Here's an ASCII representation:\n *\n * o ----- o ----- o ----- o\n * | | | |\n * | | | |\n * | | | |\n * o ----- o ----- o ----- o\n * | | | |\n * | | | |\n * ^ | | | |\n * | o ----- o ----- o ----- o\n * b | | | | |\n * | | | | |\n * | | | | |\n * o ----- o ----- o ----- o\n * ------>\n * a\n *\n * First of all, note that we want to do this in *cartesian* space. This means\n * we might run into problems when there are extreme differences in x/y scaling,\n * but the alternative is that the topology of the contours might actually be\n * view-dependent, which seems worse. As a fallback, the only parameter that\n * actually affects the result is the *aspect ratio*, so that we can at least\n * improve the situation a bit without going all the way to screen coordinates.\n *\n * This function flattens the points + tangents into a slightly denser grid of\n * *control points*. The resulting grid looks like this:\n *\n * 9 +--o-o--+ -o-o--+--o-o--+\n * 8 o o o o o o o o o o\n * | | | |\n * 7 o o o o o o o o o o\n * 6 +--o-o--+ -o-o--+--o-o--+\n * 5 o o o o o o o o o o\n * | | | |\n * ^ 4 o o o o o o o o o o\n * | 3 +--o-o--+ -o-o--+--o-o--+\n * b | 2 o o o o o o o o o o\n * | | | | |\n * | 1 o o o o o o o o o o\n * 0 +--o-o--+ -o-o--+--o-o--+\n * 0 1 2 3 4 5 6 7 8 9\n * ------>\n * a\n *\n * where `o`s represent newly-computed control points. the resulting dimension is\n *\n * (m - 1) * 3 + 1\n * = 3 * m - 2\n *\n * We could simply store the tangents separately, but that's a nightmare to organize\n * in two dimensions since we'll be slicing grid lines in both directions and since\n * that basically requires very nearly just as much storage as just storing the dense\n * grid.\n *\n * Wow!\n */\n\n\n/*\n * Catmull-rom is biased at the boundaries toward the interior and we actually\n * can't use catmull-rom to compute the control point closest to (but inside)\n * the boundary.\n *\n * A note on plotly's spline interpolation. It uses the catmull rom control point\n * closest to the boundary *as* a quadratic control point. This seems incorrect,\n * so I've elected not to follow that. Given control points 0 and 1, regular plotly\n * splines give *equivalent* cubic control points:\n *\n * Input:\n *\n * boundary\n * | |\n * p0 p2 p3 --> interior\n * 0.0 0.667 1.0\n * | |\n *\n * Cubic-equivalent of what plotly splines draw::\n *\n * boundary\n * | |\n * p0 p1 p2 p3 --> interior\n * 0.0 0.4444 0.8888 1.0\n * | |\n *\n * What this function fills in:\n *\n * boundary\n * | |\n * p0 p1 p2 p3 --> interior\n * 0.0 0.333 0.667 1.0\n * | |\n *\n * Parameters:\n * p0: boundary point\n * p2: catmull rom point based on computation at p3\n * p3: first grid point\n *\n * Of course it works whichever way it's oriented; you just need to interpret the\n * input/output accordingly.\n */\nfunction inferCubicControlPoint(p0, p2, p3) {\n // Extend p1 away from p0 by 50%. This is the equivalent quadratic point that\n // would give the same slope as catmull rom at p0.\n var p2e0 = -0.5 * p3[0] + 1.5 * p2[0];\n var p2e1 = -0.5 * p3[1] + 1.5 * p2[1];\n\n return [\n (2 * p2e0 + p0[0]) / 3,\n (2 * p2e1 + p0[1]) / 3,\n ];\n}\n\nmodule.exports = function computeControlPoints(xe, ye, x, y, asmoothing, bsmoothing) {\n var i, j, ie, je, xej, yej, xj, yj, cp, p1;\n // At this point, we know these dimensions are correct and representative of\n // the whole 2D arrays:\n var na = x[0].length;\n var nb = x.length;\n\n // (n)umber of (e)xpanded points:\n var nea = asmoothing ? 3 * na - 2 : na;\n var neb = bsmoothing ? 3 * nb - 2 : nb;\n\n xe = ensureArray(xe, neb);\n ye = ensureArray(ye, neb);\n\n for(ie = 0; ie < neb; ie++) {\n xe[ie] = ensureArray(xe[ie], nea);\n ye[ie] = ensureArray(ye[ie], nea);\n }\n\n // This loop fills in the X'd points:\n //\n // . . . .\n // . . . .\n // | | | |\n // | | | |\n // X ----- X ----- X ----- X\n // | | | |\n // | | | |\n // | | | |\n // X ----- X ----- X ----- X\n //\n //\n // ie = (i) (e)xpanded:\n for(j = 0, je = 0; j < nb; j++, je += bsmoothing ? 3 : 1) {\n xej = xe[je];\n yej = ye[je];\n xj = x[j];\n yj = y[j];\n\n // je = (j) (e)xpanded:\n for(i = 0, ie = 0; i < na; i++, ie += asmoothing ? 3 : 1) {\n xej[ie] = xj[i];\n yej[ie] = yj[i];\n }\n }\n\n if(asmoothing) {\n // If there's a-smoothing, this loop fills in the X'd points with catmull-rom\n // control points computed along the a-axis:\n // . . . .\n // . . . .\n // | | | |\n // | | | |\n // o -Y-X- o -X-X- o -X-Y- o\n // | | | |\n // | | | |\n // | | | |\n // o -Y-X- o -X-X- o -X-Y- o\n //\n // i: 0 1 2 3\n // ie: 0 1 3 3 4 5 6 7 8 9\n //\n // ------>\n // a\n //\n for(j = 0, je = 0; j < nb; j++, je += bsmoothing ? 3 : 1) {\n // Fill in the points marked X for this a-row:\n for(i = 1, ie = 3; i < na - 1; i++, ie += 3) {\n cp = makeControlPoints(\n [x[j][i - 1], y[j][i - 1]],\n [x[j][i ], y[j][i]],\n [x[j][i + 1], y[j][i + 1]],\n asmoothing\n );\n\n xe[je][ie - 1] = cp[0][0];\n ye[je][ie - 1] = cp[0][1];\n xe[je][ie + 1] = cp[1][0];\n ye[je][ie + 1] = cp[1][1];\n }\n\n // The very first cubic interpolation point (to the left for i = 1 above) is\n // used as a *quadratic* interpolation point by the spline drawing function\n // which isn't really correct. But for the sake of consistency, we'll use it\n // as such. Since we're using cubic splines, that means we need to shorten the\n // tangent by 1/3 and also construct a new cubic spline control point 1/3 from\n // the original to the i = 0 point.\n p1 = inferCubicControlPoint(\n [xe[je][0], ye[je][0]],\n [xe[je][2], ye[je][2]],\n [xe[je][3], ye[je][3]]\n );\n xe[je][1] = p1[0];\n ye[je][1] = p1[1];\n\n // Ditto last points, sans explanation:\n p1 = inferCubicControlPoint(\n [xe[je][nea - 1], ye[je][nea - 1]],\n [xe[je][nea - 3], ye[je][nea - 3]],\n [xe[je][nea - 4], ye[je][nea - 4]]\n );\n xe[je][nea - 2] = p1[0];\n ye[je][nea - 2] = p1[1];\n }\n }\n\n if(bsmoothing) {\n // If there's a-smoothing, this loop fills in the X'd points with catmull-rom\n // control points computed along the b-axis:\n // . . . .\n // X X X X X X X X X X\n // | | | |\n // X X X X X X X X X X\n // o -o-o- o -o-o- o -o-o- o\n // X X X X X X X X X X\n // | | | |\n // Y Y Y Y Y Y Y Y Y Y\n // o -o-o- o -o-o- o -o-o- o\n //\n // i: 0 1 2 3\n // ie: 0 1 3 3 4 5 6 7 8 9\n //\n // ------>\n // a\n //\n for(ie = 0; ie < nea; ie++) {\n for(je = 3; je < neb - 3; je += 3) {\n cp = makeControlPoints(\n [xe[je - 3][ie], ye[je - 3][ie]],\n [xe[je][ie], ye[je][ie]],\n [xe[je + 3][ie], ye[je + 3][ie]],\n bsmoothing\n );\n\n xe[je - 1][ie] = cp[0][0];\n ye[je - 1][ie] = cp[0][1];\n xe[je + 1][ie] = cp[1][0];\n ye[je + 1][ie] = cp[1][1];\n }\n // Do the same boundary condition magic for these control points marked Y above:\n p1 = inferCubicControlPoint(\n [xe[0][ie], ye[0][ie]],\n [xe[2][ie], ye[2][ie]],\n [xe[3][ie], ye[3][ie]]\n );\n xe[1][ie] = p1[0];\n ye[1][ie] = p1[1];\n\n p1 = inferCubicControlPoint(\n [xe[neb - 1][ie], ye[neb - 1][ie]],\n [xe[neb - 3][ie], ye[neb - 3][ie]],\n [xe[neb - 4][ie], ye[neb - 4][ie]]\n );\n xe[neb - 2][ie] = p1[0];\n ye[neb - 2][ie] = p1[1];\n }\n }\n\n if(asmoothing && bsmoothing) {\n // Do one more pass, this time recomputing exactly what we just computed.\n // It's overdetermined since we're peforming catmull-rom in two directions,\n // so we'll just average the overdetermined. These points don't lie along the\n // grid lines, so note that only grid lines will follow normal plotly spline\n // interpolation.\n //\n // Unless of course there was no b smoothing. Then these intermediate points\n // don't actually exist and this section is bypassed.\n // . . . .\n // o X X o X X o X X o\n // | | | |\n // o X X o X X o X X o\n // o -o-o- o -o-o- o -o-o- o\n // o X X o X X o X X o\n // | | | |\n // o Y Y o Y Y o Y Y o\n // o -o-o- o -o-o- o -o-o- o\n //\n // i: 0 1 2 3\n // ie: 0 1 3 3 4 5 6 7 8 9\n //\n // ------>\n // a\n //\n for(je = 1; je < neb; je += (je + 1) % 3 === 0 ? 2 : 1) {\n // Fill in the points marked X for this a-row:\n for(ie = 3; ie < nea - 3; ie += 3) {\n cp = makeControlPoints(\n [xe[je][ie - 3], ye[je][ie - 3]],\n [xe[je][ie], ye[je][ie]],\n [xe[je][ie + 3], ye[je][ie + 3]],\n asmoothing\n );\n\n xe[je][ie - 1] = 0.5 * (xe[je][ie - 1] + cp[0][0]);\n ye[je][ie - 1] = 0.5 * (ye[je][ie - 1] + cp[0][1]);\n xe[je][ie + 1] = 0.5 * (xe[je][ie + 1] + cp[1][0]);\n ye[je][ie + 1] = 0.5 * (ye[je][ie + 1] + cp[1][1]);\n }\n\n // This case is just slightly different. The computation is the same,\n // but having computed this, we'll average with the existing result.\n p1 = inferCubicControlPoint(\n [xe[je][0], ye[je][0]],\n [xe[je][2], ye[je][2]],\n [xe[je][3], ye[je][3]]\n );\n xe[je][1] = 0.5 * (xe[je][1] + p1[0]);\n ye[je][1] = 0.5 * (ye[je][1] + p1[1]);\n\n p1 = inferCubicControlPoint(\n [xe[je][nea - 1], ye[je][nea - 1]],\n [xe[je][nea - 3], ye[je][nea - 3]],\n [xe[je][nea - 4], ye[je][nea - 4]]\n );\n xe[je][nea - 2] = 0.5 * (xe[je][nea - 2] + p1[0]);\n ye[je][nea - 2] = 0.5 * (ye[je][nea - 2] + p1[1]);\n }\n }\n\n return [xe, ye];\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/compute_control_points.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/constants.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/constants.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nmodule.exports = {\n RELATIVE_CULL_TOLERANCE: 1e-6\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/constants.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/create_i_derivative_evaluator.js":
-/*!***********************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/create_i_derivative_evaluator.js ***!
- \***********************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n/*\n * Evaluates the derivative of a list of control point arrays. That is, it expects an array or arrays\n * that are expanded relative to the raw data to include the bicubic control points, if applicable. If\n * only linear interpolation is desired, then the data points correspond 1-1 along that axis to the\n * data itself. Since it's catmull-rom splines in either direction note in particular that the\n * derivatives are discontinuous across cell boundaries. That's the reason you need both the *cell*\n * and the *point within the cell*.\n *\n * Also note that the discontinuity of the derivative is in magnitude only. The direction *is*\n * continuous across cell boundaries.\n *\n * For example, to compute the derivative of the xcoordinate halfway betwen the 7 and 8th i-gridpoints\n * and the 10th and 11th j-gridpoints given bicubic smoothing in both dimensions, you'd write:\n *\n * var deriv = createIDerivativeEvaluator([x], 1, 1);\n *\n * var dxdi = deriv([], 7, 10, 0.5, 0.5);\n * // => [0.12345]\n *\n * Since there'd be a bunch of duplicate computation to compute multiple derivatives, you can double\n * this up by providing more arrays:\n *\n * var deriv = createIDerivativeEvaluator([x, y], 1, 1);\n *\n * var dxdi = deriv([], 7, 10, 0.5, 0.5);\n * // => [0.12345, 0.78910]\n *\n * NB: It's presumed that at this point all data has been sanitized and is valid numerical data arrays\n * of the correct dimension.\n */\nmodule.exports = function(arrays, asmoothing, bsmoothing) {\n if(asmoothing && bsmoothing) {\n return function(out, i0, j0, u, v) {\n if(!out) out = [];\n var f0, f1, f2, f3, ak, k;\n\n // Since it's a grid of control points, the actual indices are * 3:\n i0 *= 3;\n j0 *= 3;\n\n // Precompute some numbers:\n var u2 = u * u;\n var ou = 1 - u;\n var ou2 = ou * ou;\n var ouu2 = ou * u * 2;\n var a = -3 * ou2;\n var b = 3 * (ou2 - ouu2);\n var c = 3 * (ouu2 - u2);\n var d = 3 * u2;\n\n var v2 = v * v;\n var v3 = v2 * v;\n var ov = 1 - v;\n var ov2 = ov * ov;\n var ov3 = ov2 * ov;\n\n for(k = 0; k < arrays.length; k++) {\n ak = arrays[k];\n // Compute the derivatives in the u-direction:\n f0 = a * ak[j0 ][i0] + b * ak[j0 ][i0 + 1] + c * ak[j0 ][i0 + 2] + d * ak[j0 ][i0 + 3];\n f1 = a * ak[j0 + 1][i0] + b * ak[j0 + 1][i0 + 1] + c * ak[j0 + 1][i0 + 2] + d * ak[j0 + 1][i0 + 3];\n f2 = a * ak[j0 + 2][i0] + b * ak[j0 + 2][i0 + 1] + c * ak[j0 + 2][i0 + 2] + d * ak[j0 + 2][i0 + 3];\n f3 = a * ak[j0 + 3][i0] + b * ak[j0 + 3][i0 + 1] + c * ak[j0 + 3][i0 + 2] + d * ak[j0 + 3][i0 + 3];\n\n // Now just interpolate in the v-direction since it's all separable:\n out[k] = ov3 * f0 + 3 * (ov2 * v * f1 + ov * v2 * f2) + v3 * f3;\n }\n\n return out;\n };\n } else if(asmoothing) {\n // Handle smooth in the a-direction but linear in the b-direction by performing four\n // linear interpolations followed by one cubic interpolation of the result\n return function(out, i0, j0, u, v) {\n if(!out) out = [];\n var f0, f1, k, ak;\n i0 *= 3;\n var u2 = u * u;\n var ou = 1 - u;\n var ou2 = ou * ou;\n var ouu2 = ou * u * 2;\n var a = -3 * ou2;\n var b = 3 * (ou2 - ouu2);\n var c = 3 * (ouu2 - u2);\n var d = 3 * u2;\n var ov = 1 - v;\n for(k = 0; k < arrays.length; k++) {\n ak = arrays[k];\n f0 = a * ak[j0 ][i0] + b * ak[j0 ][i0 + 1] + c * ak[j0 ][i0 + 2] + d * ak[j0 ][i0 + 3];\n f1 = a * ak[j0 + 1][i0] + b * ak[j0 + 1][i0 + 1] + c * ak[j0 + 1][i0 + 2] + d * ak[j0 + 1][i0 + 3];\n\n out[k] = ov * f0 + v * f1;\n }\n return out;\n };\n } else if(bsmoothing) {\n // Same as the above case, except reversed. I've disabled the no-unused vars rule\n // so that this function is fully interpolation-agnostic. Otherwise it would need\n // to be called differently in different cases. Which wouldn't be the worst, but\n /* eslint-disable no-unused-vars */\n return function(out, i0, j0, u, v) {\n /* eslint-enable no-unused-vars */\n if(!out) out = [];\n var f0, f1, f2, f3, k, ak;\n j0 *= 3;\n var v2 = v * v;\n var v3 = v2 * v;\n var ov = 1 - v;\n var ov2 = ov * ov;\n var ov3 = ov2 * ov;\n for(k = 0; k < arrays.length; k++) {\n ak = arrays[k];\n f0 = ak[j0][i0 + 1] - ak[j0][i0];\n f1 = ak[j0 + 1][i0 + 1] - ak[j0 + 1][i0];\n f2 = ak[j0 + 2][i0 + 1] - ak[j0 + 2][i0];\n f3 = ak[j0 + 3][i0 + 1] - ak[j0 + 3][i0];\n\n out[k] = ov3 * f0 + 3 * (ov2 * v * f1 + ov * v2 * f2) + v3 * f3;\n }\n return out;\n };\n } else {\n // Finally, both directions are linear:\n /* eslint-disable no-unused-vars */\n return function(out, i0, j0, u, v) {\n /* eslint-enable no-unused-vars */\n if(!out) out = [];\n var f0, f1, k, ak;\n var ov = 1 - v;\n for(k = 0; k < arrays.length; k++) {\n ak = arrays[k];\n f0 = ak[j0][i0 + 1] - ak[j0][i0];\n f1 = ak[j0 + 1][i0 + 1] - ak[j0 + 1][i0];\n\n out[k] = ov * f0 + v * f1;\n }\n return out;\n };\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/create_i_derivative_evaluator.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/create_j_derivative_evaluator.js":
-/*!***********************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/create_j_derivative_evaluator.js ***!
- \***********************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function(arrays, asmoothing, bsmoothing) {\n if(asmoothing && bsmoothing) {\n return function(out, i0, j0, u, v) {\n if(!out) out = [];\n var f0, f1, f2, f3, ak, k;\n\n // Since it's a grid of control points, the actual indices are * 3:\n i0 *= 3;\n j0 *= 3;\n\n // Precompute some numbers:\n var u2 = u * u;\n var u3 = u2 * u;\n var ou = 1 - u;\n var ou2 = ou * ou;\n var ou3 = ou2 * ou;\n\n var v2 = v * v;\n var ov = 1 - v;\n var ov2 = ov * ov;\n var ovv2 = ov * v * 2;\n var a = -3 * ov2;\n var b = 3 * (ov2 - ovv2);\n var c = 3 * (ovv2 - v2);\n var d = 3 * v2;\n\n for(k = 0; k < arrays.length; k++) {\n ak = arrays[k];\n\n // Compute the derivatives in the v-direction:\n f0 = a * ak[j0][i0] + b * ak[j0 + 1][i0] + c * ak[j0 + 2][i0] + d * ak[j0 + 3][i0];\n f1 = a * ak[j0][i0 + 1] + b * ak[j0 + 1][i0 + 1] + c * ak[j0 + 2][i0 + 1] + d * ak[j0 + 3][i0 + 1];\n f2 = a * ak[j0][i0 + 2] + b * ak[j0 + 1][i0 + 2] + c * ak[j0 + 2][i0 + 2] + d * ak[j0 + 3][i0 + 2];\n f3 = a * ak[j0][i0 + 3] + b * ak[j0 + 1][i0 + 3] + c * ak[j0 + 2][i0 + 3] + d * ak[j0 + 3][i0 + 3];\n\n // Now just interpolate in the v-direction since it's all separable:\n out[k] = ou3 * f0 + 3 * (ou2 * u * f1 + ou * u2 * f2) + u3 * f3;\n }\n\n return out;\n };\n } else if(asmoothing) {\n // Handle smooth in the a-direction but linear in the b-direction by performing four\n // linear interpolations followed by one cubic interpolation of the result\n return function(out, i0, j0, v, u) {\n if(!out) out = [];\n var f0, f1, f2, f3, k, ak;\n i0 *= 3;\n var u2 = u * u;\n var u3 = u2 * u;\n var ou = 1 - u;\n var ou2 = ou * ou;\n var ou3 = ou2 * ou;\n for(k = 0; k < arrays.length; k++) {\n ak = arrays[k];\n\n f0 = ak[j0 + 1][i0] - ak[j0][i0];\n f1 = ak[j0 + 1][i0 + 1] - ak[j0][i0 + 1];\n f2 = ak[j0 + 1][i0 + 2] - ak[j0][i0 + 2];\n f3 = ak[j0 + 1][i0 + 3] - ak[j0][i0 + 3];\n\n out[k] = ou3 * f0 + 3 * (ou2 * u * f1 + ou * u2 * f2) + u3 * f3;\n\n // mathematically equivalent:\n // f0 = ou3 * ak[j0 ][i0] + 3 * (ou2 * u * ak[j0 ][i0 + 1] + ou * u2 * ak[j0 ][i0 + 2]) + u3 * ak[j0 ][i0 + 3];\n // f1 = ou3 * ak[j0 + 1][i0] + 3 * (ou2 * u * ak[j0 + 1][i0 + 1] + ou * u2 * ak[j0 + 1][i0 + 2]) + u3 * ak[j0 + 1][i0 + 3];\n // out[k] = f1 - f0;\n }\n return out;\n };\n } else if(bsmoothing) {\n // Same as the above case, except reversed:\n /* eslint-disable no-unused-vars */\n return function(out, i0, j0, u, v) {\n /* eslint-enable no-unused-vars */\n if(!out) out = [];\n var f0, f1, k, ak;\n j0 *= 3;\n var ou = 1 - u;\n var v2 = v * v;\n var ov = 1 - v;\n var ov2 = ov * ov;\n var ovv2 = ov * v * 2;\n var a = -3 * ov2;\n var b = 3 * (ov2 - ovv2);\n var c = 3 * (ovv2 - v2);\n var d = 3 * v2;\n for(k = 0; k < arrays.length; k++) {\n ak = arrays[k];\n f0 = a * ak[j0][i0] + b * ak[j0 + 1][i0] + c * ak[j0 + 2][i0] + d * ak[j0 + 3][i0];\n f1 = a * ak[j0][i0 + 1] + b * ak[j0 + 1][i0 + 1] + c * ak[j0 + 2][i0 + 1] + d * ak[j0 + 3][i0 + 1];\n\n out[k] = ou * f0 + u * f1;\n }\n return out;\n };\n } else {\n // Finally, both directions are linear:\n /* eslint-disable no-unused-vars */\n return function(out, i0, j0, v, u) {\n /* eslint-enable no-unused-vars */\n if(!out) out = [];\n var f0, f1, k, ak;\n var ov = 1 - v;\n for(k = 0; k < arrays.length; k++) {\n ak = arrays[k];\n f0 = ak[j0 + 1][i0] - ak[j0][i0];\n f1 = ak[j0 + 1][i0 + 1] - ak[j0][i0 + 1];\n\n out[k] = ov * f0 + v * f1;\n }\n return out;\n };\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/create_j_derivative_evaluator.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/create_spline_evaluator.js":
-/*!*****************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/create_spline_evaluator.js ***!
- \*****************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n/*\n * Return a function that evaluates a set of linear or bicubic control points.\n * This will get evaluated a lot, so we'll at least do a bit of extra work to\n * flatten some of the choices. In particular, we'll unroll the linear/bicubic\n * combinations and we'll allow computing results in parallel to cut down\n * on repeated arithmetic.\n *\n * Take note that we don't search for the correct range in this function. The\n * reason is for consistency due to the corrresponding derivative function. In\n * particular, the derivatives aren't continuous across cells, so it's important\n * to be able control whether the derivative at a cell boundary is approached\n * from one side or the other.\n */\nmodule.exports = function(arrays, na, nb, asmoothing, bsmoothing) {\n var imax = na - 2;\n var jmax = nb - 2;\n\n if(asmoothing && bsmoothing) {\n return function(out, i, j) {\n if(!out) out = [];\n var f0, f1, f2, f3, ak, k;\n\n var i0 = Math.max(0, Math.min(Math.floor(i), imax));\n var j0 = Math.max(0, Math.min(Math.floor(j), jmax));\n var u = Math.max(0, Math.min(1, i - i0));\n var v = Math.max(0, Math.min(1, j - j0));\n\n // Since it's a grid of control points, the actual indices are * 3:\n i0 *= 3;\n j0 *= 3;\n\n // Precompute some numbers:\n var u2 = u * u;\n var u3 = u2 * u;\n var ou = 1 - u;\n var ou2 = ou * ou;\n var ou3 = ou2 * ou;\n\n var v2 = v * v;\n var v3 = v2 * v;\n var ov = 1 - v;\n var ov2 = ov * ov;\n var ov3 = ov2 * ov;\n\n for(k = 0; k < arrays.length; k++) {\n ak = arrays[k];\n f0 = ou3 * ak[j0][i0] + 3 * (ou2 * u * ak[j0][i0 + 1] + ou * u2 * ak[j0][i0 + 2]) + u3 * ak[j0][i0 + 3];\n f1 = ou3 * ak[j0 + 1][i0] + 3 * (ou2 * u * ak[j0 + 1][i0 + 1] + ou * u2 * ak[j0 + 1][i0 + 2]) + u3 * ak[j0 + 1][i0 + 3];\n f2 = ou3 * ak[j0 + 2][i0] + 3 * (ou2 * u * ak[j0 + 2][i0 + 1] + ou * u2 * ak[j0 + 2][i0 + 2]) + u3 * ak[j0 + 2][i0 + 3];\n f3 = ou3 * ak[j0 + 3][i0] + 3 * (ou2 * u * ak[j0 + 3][i0 + 1] + ou * u2 * ak[j0 + 3][i0 + 2]) + u3 * ak[j0 + 3][i0 + 3];\n out[k] = ov3 * f0 + 3 * (ov2 * v * f1 + ov * v2 * f2) + v3 * f3;\n }\n\n return out;\n };\n } else if(asmoothing) {\n // Handle smooth in the a-direction but linear in the b-direction by performing four\n // linear interpolations followed by one cubic interpolation of the result\n return function(out, i, j) {\n if(!out) out = [];\n\n var i0 = Math.max(0, Math.min(Math.floor(i), imax));\n var j0 = Math.max(0, Math.min(Math.floor(j), jmax));\n var u = Math.max(0, Math.min(1, i - i0));\n var v = Math.max(0, Math.min(1, j - j0));\n\n var f0, f1, f2, f3, k, ak;\n i0 *= 3;\n var u2 = u * u;\n var u3 = u2 * u;\n var ou = 1 - u;\n var ou2 = ou * ou;\n var ou3 = ou2 * ou;\n var ov = 1 - v;\n for(k = 0; k < arrays.length; k++) {\n ak = arrays[k];\n f0 = ov * ak[j0][i0] + v * ak[j0 + 1][i0];\n f1 = ov * ak[j0][i0 + 1] + v * ak[j0 + 1][i0 + 1];\n f2 = ov * ak[j0][i0 + 2] + v * ak[j0 + 1][i0 + 1];\n f3 = ov * ak[j0][i0 + 3] + v * ak[j0 + 1][i0 + 1];\n\n out[k] = ou3 * f0 + 3 * (ou2 * u * f1 + ou * u2 * f2) + u3 * f3;\n }\n return out;\n };\n } else if(bsmoothing) {\n // Same as the above case, except reversed:\n return function(out, i, j) {\n if(!out) out = [];\n\n var i0 = Math.max(0, Math.min(Math.floor(i), imax));\n var j0 = Math.max(0, Math.min(Math.floor(j), jmax));\n var u = Math.max(0, Math.min(1, i - i0));\n var v = Math.max(0, Math.min(1, j - j0));\n\n var f0, f1, f2, f3, k, ak;\n j0 *= 3;\n var v2 = v * v;\n var v3 = v2 * v;\n var ov = 1 - v;\n var ov2 = ov * ov;\n var ov3 = ov2 * ov;\n var ou = 1 - u;\n for(k = 0; k < arrays.length; k++) {\n ak = arrays[k];\n f0 = ou * ak[j0][i0] + u * ak[j0][i0 + 1];\n f1 = ou * ak[j0 + 1][i0] + u * ak[j0 + 1][i0 + 1];\n f2 = ou * ak[j0 + 2][i0] + u * ak[j0 + 2][i0 + 1];\n f3 = ou * ak[j0 + 3][i0] + u * ak[j0 + 3][i0 + 1];\n\n out[k] = ov3 * f0 + 3 * (ov2 * v * f1 + ov * v2 * f2) + v3 * f3;\n }\n return out;\n };\n } else {\n // Finally, both directions are linear:\n return function(out, i, j) {\n if(!out) out = [];\n\n var i0 = Math.max(0, Math.min(Math.floor(i), imax));\n var j0 = Math.max(0, Math.min(Math.floor(j), jmax));\n var u = Math.max(0, Math.min(1, i - i0));\n var v = Math.max(0, Math.min(1, j - j0));\n\n var f0, f1, k, ak;\n var ov = 1 - v;\n var ou = 1 - u;\n for(k = 0; k < arrays.length; k++) {\n ak = arrays[k];\n f0 = ou * ak[j0][i0] + u * ak[j0][i0 + 1];\n f1 = ou * ak[j0 + 1][i0] + u * ak[j0 + 1][i0 + 1];\n\n out[k] = ov * f0 + v * f1;\n }\n return out;\n };\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/create_spline_evaluator.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/defaults.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/defaults.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar handleXYDefaults = __webpack_require__(/*! ./xy_defaults */ \"./node_modules/plotly.js/src/traces/carpet/xy_defaults.js\");\nvar handleABDefaults = __webpack_require__(/*! ./ab_defaults */ \"./node_modules/plotly.js/src/traces/carpet/ab_defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/carpet/attributes.js\");\nvar colorAttrs = __webpack_require__(/*! ../../components/color/attributes */ \"./node_modules/plotly.js/src/components/color/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, dfltColor, fullLayout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n traceOut._clipPathId = 'clip' + traceOut.uid + 'carpet';\n\n var defaultColor = coerce('color', colorAttrs.defaultLine);\n Lib.coerceFont(coerce, 'font');\n\n coerce('carpet');\n\n handleABDefaults(traceIn, traceOut, fullLayout, coerce, defaultColor);\n\n if(!traceOut.a || !traceOut.b) {\n traceOut.visible = false;\n return;\n }\n\n if(traceOut.a.length < 3) {\n traceOut.aaxis.smoothing = 0;\n }\n\n if(traceOut.b.length < 3) {\n traceOut.baxis.smoothing = 0;\n }\n\n // NB: the input is x/y arrays. You should know that the *first* dimension of x and y\n // corresponds to b and the second to a. This sounds backwards but ends up making sense\n // the important part to know is that when you write y[j][i], j goes from 0 to b.length - 1\n // and i goes from 0 to a.length - 1.\n var validData = handleXYDefaults(traceIn, traceOut, coerce);\n if(!validData) {\n traceOut.visible = false;\n }\n\n if(traceOut._cheater) {\n coerce('cheaterslope');\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/index.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/index.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/carpet/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/carpet/defaults.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/carpet/plot.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/carpet/calc.js\"),\n animatable: true,\n isContainer: true, // so carpet traces get `calc` before other traces\n\n moduleType: 'trace',\n name: 'carpet',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['cartesian', 'svg', 'carpet', 'carpetAxis', 'notLegendIsolatable', 'noMultiCategory', 'noHover', 'noSortingByValue'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/lookup_carpetid.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/lookup_carpetid.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n/*\n * Given a trace, look up the carpet axis by carpet.\n */\nmodule.exports = function(gd, trace) {\n var n = gd._fullData.length;\n var firstAxis;\n for(var i = 0; i < n; i++) {\n var maybeCarpet = gd._fullData[i];\n\n if(maybeCarpet.index === trace.index) continue;\n\n if(maybeCarpet.type === 'carpet') {\n if(!firstAxis) {\n firstAxis = maybeCarpet;\n }\n\n if(maybeCarpet.carpet === trace.carpet) {\n return maybeCarpet;\n }\n }\n }\n\n return firstAxis;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/lookup_carpetid.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/makepath.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/makepath.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function makePath(xp, yp, isBicubic) {\n // Prevent d3 errors that would result otherwise:\n if(xp.length === 0) return '';\n\n var i;\n var path = [];\n var stride = isBicubic ? 3 : 1;\n for(i = 0; i < xp.length; i += stride) {\n path.push(xp[i] + ',' + yp[i]);\n\n if(isBicubic && i < xp.length - stride) {\n path.push('C');\n path.push([\n xp[i + 1] + ',' + yp[i + 1],\n xp[i + 2] + ',' + yp[i + 2] + ' ',\n ].join(' '));\n }\n }\n return path.join(isBicubic ? '' : 'L');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/makepath.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/map_1d_array.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/map_1d_array.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isArrayOrTypedArray = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").isArrayOrTypedArray;\n\n/*\n * Map an array of x or y coordinates (c) to screen-space pixel coordinates (p).\n * The output array is optional, but if provided, it will be reused without\n * reallocation to the extent possible.\n */\nmodule.exports = function mapArray(out, data, func) {\n var i;\n\n if(!isArrayOrTypedArray(out)) {\n // If not an array, make it an array:\n out = [];\n } else if(out.length > data.length) {\n // If too long, truncate. (If too short, it will grow\n // automatically so we don't care about that case)\n out = out.slice(0, data.length);\n }\n\n for(i = 0; i < data.length; i++) {\n out[i] = func(data[i]);\n }\n\n return out;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/map_1d_array.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/orient_text.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/orient_text.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nmodule.exports = function orientText(trace, xaxis, yaxis, xy, dxy, refDxy) {\n var dx = dxy[0] * trace.dpdx(xaxis);\n var dy = dxy[1] * trace.dpdy(yaxis);\n var flip = 1;\n\n var offsetMultiplier = 1.0;\n if(refDxy) {\n var l1 = Math.sqrt(dxy[0] * dxy[0] + dxy[1] * dxy[1]);\n var l2 = Math.sqrt(refDxy[0] * refDxy[0] + refDxy[1] * refDxy[1]);\n var dot = (dxy[0] * refDxy[0] + dxy[1] * refDxy[1]) / l1 / l2;\n offsetMultiplier = Math.max(0.0, dot);\n }\n\n var angle = Math.atan2(dy, dx) * 180 / Math.PI;\n if(angle < -90) {\n angle += 180;\n flip = -flip;\n } else if(angle > 90) {\n angle -= 180;\n flip = -flip;\n }\n\n return {\n angle: angle,\n flip: flip,\n p: trace.c2p(xy, xaxis, yaxis),\n offsetMultplier: offsetMultiplier\n };\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/orient_text.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/plot.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/plot.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar map1dArray = __webpack_require__(/*! ./map_1d_array */ \"./node_modules/plotly.js/src/traces/carpet/map_1d_array.js\");\nvar makepath = __webpack_require__(/*! ./makepath */ \"./node_modules/plotly.js/src/traces/carpet/makepath.js\");\nvar orientText = __webpack_require__(/*! ./orient_text */ \"./node_modules/plotly.js/src/traces/carpet/orient_text.js\");\nvar svgTextUtils = __webpack_require__(/*! ../../lib/svg_text_utils */ \"./node_modules/plotly.js/src/lib/svg_text_utils.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar alignmentConstants = __webpack_require__(/*! ../../constants/alignment */ \"./node_modules/plotly.js/src/constants/alignment.js\");\n\nmodule.exports = function plot(gd, plotinfo, cdcarpet, carpetLayer) {\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n var fullLayout = gd._fullLayout;\n var clipLayer = fullLayout._clips;\n\n Lib.makeTraceGroups(carpetLayer, cdcarpet, 'trace').each(function(cd) {\n var axisLayer = d3.select(this);\n var cd0 = cd[0];\n var trace = cd0.trace;\n var aax = trace.aaxis;\n var bax = trace.baxis;\n\n var minorLayer = Lib.ensureSingle(axisLayer, 'g', 'minorlayer');\n var majorLayer = Lib.ensureSingle(axisLayer, 'g', 'majorlayer');\n var boundaryLayer = Lib.ensureSingle(axisLayer, 'g', 'boundarylayer');\n var labelLayer = Lib.ensureSingle(axisLayer, 'g', 'labellayer');\n\n axisLayer.style('opacity', trace.opacity);\n\n drawGridLines(xa, ya, majorLayer, aax, 'a', aax._gridlines, true);\n drawGridLines(xa, ya, majorLayer, bax, 'b', bax._gridlines, true);\n drawGridLines(xa, ya, minorLayer, aax, 'a', aax._minorgridlines, true);\n drawGridLines(xa, ya, minorLayer, bax, 'b', bax._minorgridlines, true);\n\n // NB: These are not ommitted if the lines are not active. The joins must be executed\n // in order for them to get cleaned up without a full redraw\n drawGridLines(xa, ya, boundaryLayer, aax, 'a-boundary', aax._boundarylines);\n drawGridLines(xa, ya, boundaryLayer, bax, 'b-boundary', bax._boundarylines);\n\n var labelOrientationA = drawAxisLabels(gd, xa, ya, trace, cd0, labelLayer, aax._labels, 'a-label');\n var labelOrientationB = drawAxisLabels(gd, xa, ya, trace, cd0, labelLayer, bax._labels, 'b-label');\n\n drawAxisTitles(gd, labelLayer, trace, cd0, xa, ya, labelOrientationA, labelOrientationB);\n\n drawClipPath(trace, cd0, clipLayer, xa, ya);\n });\n};\n\nfunction drawClipPath(trace, t, layer, xaxis, yaxis) {\n var seg, xp, yp, i;\n\n var clip = layer.select('#' + trace._clipPathId);\n\n if(!clip.size()) {\n clip = layer.append('clipPath')\n .classed('carpetclip', true);\n }\n\n var path = Lib.ensureSingle(clip, 'path', 'carpetboundary');\n var segments = t.clipsegments;\n var segs = [];\n\n for(i = 0; i < segments.length; i++) {\n seg = segments[i];\n xp = map1dArray([], seg.x, xaxis.c2p);\n yp = map1dArray([], seg.y, yaxis.c2p);\n segs.push(makepath(xp, yp, seg.bicubic));\n }\n\n // This could be optimized ever so slightly to avoid no-op L segments\n // at the corners, but it's so negligible that I don't think it's worth\n // the extra complexity\n var clipPathData = 'M' + segs.join('L') + 'Z';\n clip.attr('id', trace._clipPathId);\n path.attr('d', clipPathData);\n}\n\nfunction drawGridLines(xaxis, yaxis, layer, axis, axisLetter, gridlines) {\n var lineClass = 'const-' + axisLetter + '-lines';\n var gridJoin = layer.selectAll('.' + lineClass).data(gridlines);\n\n gridJoin.enter().append('path')\n .classed(lineClass, true)\n .style('vector-effect', 'non-scaling-stroke');\n\n gridJoin.each(function(d) {\n var gridline = d;\n var x = gridline.x;\n var y = gridline.y;\n\n var xp = map1dArray([], x, xaxis.c2p);\n var yp = map1dArray([], y, yaxis.c2p);\n\n var path = 'M' + makepath(xp, yp, gridline.smoothing);\n\n var el = d3.select(this);\n\n el.attr('d', path)\n .style('stroke-width', gridline.width)\n .style('stroke', gridline.color)\n .style('fill', 'none');\n });\n\n gridJoin.exit().remove();\n}\n\nfunction drawAxisLabels(gd, xaxis, yaxis, trace, t, layer, labels, labelClass) {\n var labelJoin = layer.selectAll('text.' + labelClass).data(labels);\n\n labelJoin.enter().append('text')\n .classed(labelClass, true);\n\n var maxExtent = 0;\n var labelOrientation = {};\n\n labelJoin.each(function(label, i) {\n // Most of the positioning is done in calc_labels. Only the parts that depend upon\n // the screen space representation of the x and y axes are here:\n var orientation;\n if(label.axis.tickangle === 'auto') {\n orientation = orientText(trace, xaxis, yaxis, label.xy, label.dxy);\n } else {\n var angle = (label.axis.tickangle + 180.0) * Math.PI / 180.0;\n orientation = orientText(trace, xaxis, yaxis, label.xy, [Math.cos(angle), Math.sin(angle)]);\n }\n\n if(!i) {\n // TODO: offsetMultiplier? Not currently used anywhere...\n labelOrientation = {angle: orientation.angle, flip: orientation.flip};\n }\n var direction = (label.endAnchor ? -1 : 1) * orientation.flip;\n\n var labelEl = d3.select(this)\n .attr({\n 'text-anchor': direction > 0 ? 'start' : 'end',\n 'data-notex': 1\n })\n .call(Drawing.font, label.font)\n .text(label.text)\n .call(svgTextUtils.convertToTspans, gd);\n\n var bbox = Drawing.bBox(this);\n\n labelEl.attr('transform',\n // Translate to the correct point:\n 'translate(' + orientation.p[0] + ',' + orientation.p[1] + ') ' +\n // Rotate to line up with grid line tangent:\n 'rotate(' + orientation.angle + ')' +\n // Adjust the baseline and indentation:\n 'translate(' + label.axis.labelpadding * direction + ',' + bbox.height * 0.3 + ')'\n );\n\n maxExtent = Math.max(maxExtent, bbox.width + label.axis.labelpadding);\n });\n\n labelJoin.exit().remove();\n\n labelOrientation.maxExtent = maxExtent;\n return labelOrientation;\n}\n\nfunction drawAxisTitles(gd, layer, trace, t, xa, ya, labelOrientationA, labelOrientationB) {\n var a, b, xy, dxy;\n\n var aMin = Lib.aggNums(Math.min, null, trace.a);\n var aMax = Lib.aggNums(Math.max, null, trace.a);\n var bMin = Lib.aggNums(Math.min, null, trace.b);\n var bMax = Lib.aggNums(Math.max, null, trace.b);\n\n a = 0.5 * (aMin + aMax);\n b = bMin;\n xy = trace.ab2xy(a, b, true);\n dxy = trace.dxyda_rough(a, b);\n if(labelOrientationA.angle === undefined) {\n Lib.extendFlat(labelOrientationA, orientText(trace, xa, ya, xy, trace.dxydb_rough(a, b)));\n }\n drawAxisTitle(gd, layer, trace, t, xy, dxy, trace.aaxis, xa, ya, labelOrientationA, 'a-title');\n\n a = aMin;\n b = 0.5 * (bMin + bMax);\n xy = trace.ab2xy(a, b, true);\n dxy = trace.dxydb_rough(a, b);\n if(labelOrientationB.angle === undefined) {\n Lib.extendFlat(labelOrientationB, orientText(trace, xa, ya, xy, trace.dxyda_rough(a, b)));\n }\n drawAxisTitle(gd, layer, trace, t, xy, dxy, trace.baxis, xa, ya, labelOrientationB, 'b-title');\n}\n\nvar lineSpacing = alignmentConstants.LINE_SPACING;\nvar midShift = ((1 - alignmentConstants.MID_SHIFT) / lineSpacing) + 1;\n\nfunction drawAxisTitle(gd, layer, trace, t, xy, dxy, axis, xa, ya, labelOrientation, labelClass) {\n var data = [];\n if(axis.title.text) data.push(axis.title.text);\n var titleJoin = layer.selectAll('text.' + labelClass).data(data);\n var offset = labelOrientation.maxExtent;\n\n titleJoin.enter().append('text')\n .classed(labelClass, true);\n\n // There's only one, but we'll do it as a join so it's updated nicely:\n titleJoin.each(function() {\n var orientation = orientText(trace, xa, ya, xy, dxy);\n\n if(['start', 'both'].indexOf(axis.showticklabels) === -1) {\n offset = 0;\n }\n\n // In addition to the size of the labels, add on some extra padding:\n var titleSize = axis.title.font.size;\n offset += titleSize + axis.title.offset;\n\n var labelNorm = labelOrientation.angle + (labelOrientation.flip < 0 ? 180 : 0);\n var angleDiff = (labelNorm - orientation.angle + 450) % 360;\n var reverseTitle = angleDiff > 90 && angleDiff < 270;\n\n var el = d3.select(this);\n\n el.text(axis.title.text)\n .call(svgTextUtils.convertToTspans, gd);\n\n if(reverseTitle) {\n offset = (-svgTextUtils.lineCount(el) + midShift) * lineSpacing * titleSize - offset;\n }\n\n el.attr('transform',\n 'translate(' + orientation.p[0] + ',' + orientation.p[1] + ') ' +\n 'rotate(' + orientation.angle + ') ' +\n 'translate(0,' + offset + ')'\n )\n .classed('user-select-none', true)\n .attr('text-anchor', 'middle')\n .call(Drawing.font, axis.title.font);\n });\n\n titleJoin.exit().remove();\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/set_convert.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/set_convert.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/carpet/constants.js\");\nvar search = __webpack_require__(/*! ../../lib/search */ \"./node_modules/plotly.js/src/lib/search.js\").findBin;\nvar computeControlPoints = __webpack_require__(/*! ./compute_control_points */ \"./node_modules/plotly.js/src/traces/carpet/compute_control_points.js\");\nvar createSplineEvaluator = __webpack_require__(/*! ./create_spline_evaluator */ \"./node_modules/plotly.js/src/traces/carpet/create_spline_evaluator.js\");\nvar createIDerivativeEvaluator = __webpack_require__(/*! ./create_i_derivative_evaluator */ \"./node_modules/plotly.js/src/traces/carpet/create_i_derivative_evaluator.js\");\nvar createJDerivativeEvaluator = __webpack_require__(/*! ./create_j_derivative_evaluator */ \"./node_modules/plotly.js/src/traces/carpet/create_j_derivative_evaluator.js\");\n\n/*\n * Create conversion functions to go from one basis to another. In particular the letter\n * abbreviations are:\n *\n * i: i/j coordinates along the grid. Integer values correspond to data points\n * a: real-valued coordinates along the a/b axes\n * c: cartesian x-y coordinates\n * p: screen-space pixel coordinates\n */\nmodule.exports = function setConvert(trace) {\n var a = trace._a;\n var b = trace._b;\n var na = a.length;\n var nb = b.length;\n var aax = trace.aaxis;\n var bax = trace.baxis;\n\n // Grab the limits once rather than recomputing the bounds for every point\n // independently:\n var amin = a[0];\n var amax = a[na - 1];\n var bmin = b[0];\n var bmax = b[nb - 1];\n var arange = a[a.length - 1] - a[0];\n var brange = b[b.length - 1] - b[0];\n\n // Compute the tolerance so that points are visible slightly outside the\n // defined carpet axis:\n var atol = arange * constants.RELATIVE_CULL_TOLERANCE;\n var btol = brange * constants.RELATIVE_CULL_TOLERANCE;\n\n // Expand the limits to include the relative tolerance:\n amin -= atol;\n amax += atol;\n bmin -= btol;\n bmax += btol;\n\n trace.isVisible = function(a, b) {\n return a > amin && a < amax && b > bmin && b < bmax;\n };\n\n trace.isOccluded = function(a, b) {\n return a < amin || a > amax || b < bmin || b > bmax;\n };\n\n trace.setScale = function() {\n var x = trace._x;\n var y = trace._y;\n\n // This is potentially a very expensive step! It does the bulk of the work of constructing\n // an expanded basis of control points. Note in particular that it overwrites the existing\n // basis without creating a new array since that would potentially thrash the garbage\n // collector.\n var result = computeControlPoints(trace._xctrl, trace._yctrl, x, y, aax.smoothing, bax.smoothing);\n trace._xctrl = result[0];\n trace._yctrl = result[1];\n\n // This step is the second step in the process, but it's somewhat simpler. It just unrolls\n // some logic since it would be unnecessarily expensive to compute both interpolations\n // nearly identically but separately and to include a bunch of linear vs. bicubic logic in\n // every single call.\n trace.evalxy = createSplineEvaluator([trace._xctrl, trace._yctrl], na, nb, aax.smoothing, bax.smoothing);\n\n trace.dxydi = createIDerivativeEvaluator([trace._xctrl, trace._yctrl], aax.smoothing, bax.smoothing);\n trace.dxydj = createJDerivativeEvaluator([trace._xctrl, trace._yctrl], aax.smoothing, bax.smoothing);\n };\n\n /*\n * Convert from i/j data grid coordinates to a/b values. Note in particular that this\n * is *linear* interpolation, even if the data is interpolated bicubically.\n */\n trace.i2a = function(i) {\n var i0 = Math.max(0, Math.floor(i[0]), na - 2);\n var ti = i[0] - i0;\n return (1 - ti) * a[i0] + ti * a[i0 + 1];\n };\n\n trace.j2b = function(j) {\n var j0 = Math.max(0, Math.floor(j[1]), na - 2);\n var tj = j[1] - j0;\n return (1 - tj) * b[j0] + tj * b[j0 + 1];\n };\n\n trace.ij2ab = function(ij) {\n return [trace.i2a(ij[0]), trace.j2b(ij[1])];\n };\n\n /*\n * Convert from a/b coordinates to i/j grid-numbered coordinates. This requires searching\n * through the a/b data arrays and assumes they are monotonic, which is presumed to have\n * been enforced already.\n */\n trace.a2i = function(aval) {\n var i0 = Math.max(0, Math.min(search(aval, a), na - 2));\n var a0 = a[i0];\n var a1 = a[i0 + 1];\n return Math.max(0, Math.min(na - 1, i0 + (aval - a0) / (a1 - a0)));\n };\n\n trace.b2j = function(bval) {\n var j0 = Math.max(0, Math.min(search(bval, b), nb - 2));\n var b0 = b[j0];\n var b1 = b[j0 + 1];\n return Math.max(0, Math.min(nb - 1, j0 + (bval - b0) / (b1 - b0)));\n };\n\n trace.ab2ij = function(ab) {\n return [trace.a2i(ab[0]), trace.b2j(ab[1])];\n };\n\n /*\n * Convert from i/j coordinates to x/y caretesian coordinates. This means either bilinear\n * or bicubic spline evaluation, but the hard part is already done at this point.\n */\n trace.i2c = function(i, j) {\n return trace.evalxy([], i, j);\n };\n\n trace.ab2xy = function(aval, bval, extrapolate) {\n if(!extrapolate && (aval < a[0] || aval > a[na - 1] | bval < b[0] || bval > b[nb - 1])) {\n return [false, false];\n }\n var i = trace.a2i(aval);\n var j = trace.b2j(bval);\n\n var pt = trace.evalxy([], i, j);\n\n if(extrapolate) {\n // This section uses the boundary derivatives to extrapolate linearly outside\n // the defined range. Consider a scatter line with one point inside the carpet\n // axis and one point outside. If we don't extrapolate, we can't draw the line\n // at all.\n var iex = 0;\n var jex = 0;\n var der = [];\n\n var i0, ti, j0, tj;\n if(aval < a[0]) {\n i0 = 0;\n ti = 0;\n iex = (aval - a[0]) / (a[1] - a[0]);\n } else if(aval > a[na - 1]) {\n i0 = na - 2;\n ti = 1;\n iex = (aval - a[na - 1]) / (a[na - 1] - a[na - 2]);\n } else {\n i0 = Math.max(0, Math.min(na - 2, Math.floor(i)));\n ti = i - i0;\n }\n\n if(bval < b[0]) {\n j0 = 0;\n tj = 0;\n jex = (bval - b[0]) / (b[1] - b[0]);\n } else if(bval > b[nb - 1]) {\n j0 = nb - 2;\n tj = 1;\n jex = (bval - b[nb - 1]) / (b[nb - 1] - b[nb - 2]);\n } else {\n j0 = Math.max(0, Math.min(nb - 2, Math.floor(j)));\n tj = j - j0;\n }\n\n if(iex) {\n trace.dxydi(der, i0, j0, ti, tj);\n pt[0] += der[0] * iex;\n pt[1] += der[1] * iex;\n }\n\n if(jex) {\n trace.dxydj(der, i0, j0, ti, tj);\n pt[0] += der[0] * jex;\n pt[1] += der[1] * jex;\n }\n }\n\n return pt;\n };\n\n\n trace.c2p = function(xy, xa, ya) {\n return [xa.c2p(xy[0]), ya.c2p(xy[1])];\n };\n\n trace.p2x = function(p, xa, ya) {\n return [xa.p2c(p[0]), ya.p2c(p[1])];\n };\n\n trace.dadi = function(i /* , u*/) {\n // Right now only a piecewise linear a or b basis is permitted since smoother interpolation\n // would cause monotonicity problems. As a retult, u is entirely disregarded in this\n // computation, though we'll specify it as a parameter for the sake of completeness and\n // future-proofing. It would be possible to use monotonic cubic interpolation, for example.\n //\n // See: https://en.wikipedia.org/wiki/Monotone_cubic_interpolation\n\n // u = u || 0;\n\n var i0 = Math.max(0, Math.min(a.length - 2, i));\n\n // The step (demoninator) is implicitly 1 since that's the grid spacing.\n return a[i0 + 1] - a[i0];\n };\n\n trace.dbdj = function(j /* , v*/) {\n // See above caveats for dadi which also apply here\n var j0 = Math.max(0, Math.min(b.length - 2, j));\n\n // The step (demoninator) is implicitly 1 since that's the grid spacing.\n return b[j0 + 1] - b[j0];\n };\n\n // Takes: grid cell coordinate (i, j) and fractional grid cell coordinates (u, v)\n // Returns: (dx/da, dy/db)\n //\n // NB: separate grid cell + fractional grid cell coordinate format is due to the discontinuous\n // derivative, as described better in create_i_derivative_evaluator.js\n trace.dxyda = function(i0, j0, u, v) {\n var dxydi = trace.dxydi(null, i0, j0, u, v);\n var dadi = trace.dadi(i0, u);\n\n return [dxydi[0] / dadi, dxydi[1] / dadi];\n };\n\n trace.dxydb = function(i0, j0, u, v) {\n var dxydj = trace.dxydj(null, i0, j0, u, v);\n var dbdj = trace.dbdj(j0, v);\n\n return [dxydj[0] / dbdj, dxydj[1] / dbdj];\n };\n\n // Sometimes we don't care about precision and all we really want is decent rough\n // directions (as is the case with labels). In that case, we can do a very rough finite\n // difference and spare having to worry about precise grid coordinates:\n trace.dxyda_rough = function(a, b, reldiff) {\n var h = arange * (reldiff || 0.1);\n var plus = trace.ab2xy(a + h, b, true);\n var minus = trace.ab2xy(a - h, b, true);\n\n return [\n (plus[0] - minus[0]) * 0.5 / h,\n (plus[1] - minus[1]) * 0.5 / h\n ];\n };\n\n trace.dxydb_rough = function(a, b, reldiff) {\n var h = brange * (reldiff || 0.1);\n var plus = trace.ab2xy(a, b + h, true);\n var minus = trace.ab2xy(a, b - h, true);\n\n return [\n (plus[0] - minus[0]) * 0.5 / h,\n (plus[1] - minus[1]) * 0.5 / h\n ];\n };\n\n trace.dpdx = function(xa) {\n return xa._m;\n };\n\n trace.dpdy = function(ya) {\n return ya._m;\n };\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/set_convert.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/smooth_fill_2d_array.js":
-/*!**************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/smooth_fill_2d_array.js ***!
- \**************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\n/*\n * Given a 2D array as well as a basis in either direction, this function fills in the\n * 2D array using a combination of smoothing and extrapolation. This is rather important\n * for carpet plots since it's used for layout so that we can't simply omit or blank out\n * points. We need a reasonable guess so that the interpolation puts points somewhere\n * even if we were to somehow represent that the data was missing later on.\n *\n * input:\n * - data: 2D array of arrays\n * - a: array such that a.length === data[0].length\n * - b: array such that b.length === data.length\n */\nmodule.exports = function smoothFill2dArray(data, a, b) {\n var i, j, k;\n var ip = [];\n var jp = [];\n // var neighborCnts = [];\n\n var ni = data[0].length;\n var nj = data.length;\n\n function avgSurrounding(i, j) {\n // As a low-quality start, we can simply average surrounding points (in a not\n // non-uniform grid aware manner):\n var sum = 0.0;\n var val;\n var cnt = 0;\n if(i > 0 && (val = data[j][i - 1]) !== undefined) {\n cnt++;\n sum += val;\n }\n if(i < ni - 1 && (val = data[j][i + 1]) !== undefined) {\n cnt++;\n sum += val;\n }\n if(j > 0 && (val = data[j - 1][i]) !== undefined) {\n cnt++;\n sum += val;\n }\n if(j < nj - 1 && (val = data[j + 1][i]) !== undefined) {\n cnt++;\n sum += val;\n }\n return sum / Math.max(1, cnt);\n }\n\n // This loop iterates over all cells. Any cells that are null will be noted and those\n // are the only points we will loop over and update via laplace's equation. Points with\n // any neighbors will receive the average. If there are no neighboring points, then they\n // will be set to zero. Also as we go, track the maximum magnitude so that we can scale\n // our tolerance accordingly.\n var dmax = 0.0;\n for(i = 0; i < ni; i++) {\n for(j = 0; j < nj; j++) {\n if(data[j][i] === undefined) {\n ip.push(i);\n jp.push(j);\n\n data[j][i] = avgSurrounding(i, j);\n // neighborCnts.push(result.neighbors);\n }\n dmax = Math.max(dmax, Math.abs(data[j][i]));\n }\n }\n\n if(!ip.length) return data;\n\n // The tolerance doesn't need to be excessive. It's just for display positioning\n var dxp, dxm, dap, dam, dbp, dbm, c, d, diff, reldiff, overrelaxation;\n var tol = 1e-5;\n var resid = 0;\n var itermax = 100;\n var iter = 0;\n var n = ip.length;\n do {\n resid = 0;\n // Normally we'd loop in two dimensions, but not all points are blank and need\n // an update, so we instead loop only over the points that were tabulated above\n for(k = 0; k < n; k++) {\n i = ip[k];\n j = jp[k];\n // neighborCnt = neighborCnts[k];\n\n // Track a counter for how many contributions there are. We'll use this counter\n // to average at the end, which reduces to laplace's equation with neumann boundary\n // conditions on the first derivative (second derivative is zero so that we get\n // a nice linear extrapolation at the boundaries).\n var boundaryCnt = 0;\n var newVal = 0;\n\n var d0, d1, x0, x1, i0, j0;\n if(i === 0) {\n // If this lies along the i = 0 boundary, extrapolate from the two points\n // to the right of this point. Note that the finite differences take into\n // account non-uniform grid spacing:\n i0 = Math.min(ni - 1, 2);\n x0 = a[i0];\n x1 = a[1];\n d0 = data[j][i0];\n d1 = data[j][1];\n newVal += d1 + (d1 - d0) * (a[0] - x1) / (x1 - x0);\n boundaryCnt++;\n } else if(i === ni - 1) {\n // If along the high i boundary, extrapolate from the two points to the\n // left of this point\n i0 = Math.max(0, ni - 3);\n x0 = a[i0];\n x1 = a[ni - 2];\n d0 = data[j][i0];\n d1 = data[j][ni - 2];\n newVal += d1 + (d1 - d0) * (a[ni - 1] - x1) / (x1 - x0);\n boundaryCnt++;\n }\n\n if((i === 0 || i === ni - 1) && (j > 0 && j < nj - 1)) {\n // If along the min(i) or max(i) boundaries, also smooth vertically as long\n // as we're not in a corner. Note that the finite differences used here\n // are also aware of nonuniform grid spacing:\n dxp = b[j + 1] - b[j];\n dxm = b[j] - b[j - 1];\n newVal += (dxm * data[j + 1][i] + dxp * data[j - 1][i]) / (dxm + dxp);\n boundaryCnt++;\n }\n\n if(j === 0) {\n // If along the j = 0 boundary, extrpolate this point from the two points\n // above it\n j0 = Math.min(nj - 1, 2);\n x0 = b[j0];\n x1 = b[1];\n d0 = data[j0][i];\n d1 = data[1][i];\n newVal += d1 + (d1 - d0) * (b[0] - x1) / (x1 - x0);\n boundaryCnt++;\n } else if(j === nj - 1) {\n // Same for the max j boundary from the cells below it:\n j0 = Math.max(0, nj - 3);\n x0 = b[j0];\n x1 = b[nj - 2];\n d0 = data[j0][i];\n d1 = data[nj - 2][i];\n newVal += d1 + (d1 - d0) * (b[nj - 1] - x1) / (x1 - x0);\n boundaryCnt++;\n }\n\n if((j === 0 || j === nj - 1) && (i > 0 && i < ni - 1)) {\n // Now average points to the left/right as long as not in a corner:\n dxp = a[i + 1] - a[i];\n dxm = a[i] - a[i - 1];\n newVal += (dxm * data[j][i + 1] + dxp * data[j][i - 1]) / (dxm + dxp);\n boundaryCnt++;\n }\n\n if(!boundaryCnt) {\n // If none of the above conditions were triggered, then this is an interior\n // point and we can just do a laplace equation update. As above, these differences\n // are aware of nonuniform grid spacing:\n dap = a[i + 1] - a[i];\n dam = a[i] - a[i - 1];\n dbp = b[j + 1] - b[j];\n dbm = b[j] - b[j - 1];\n\n // These are just some useful constants for the iteration, which is perfectly\n // straightforward but a little long to derive from f_xx + f_yy = 0.\n c = dap * dam * (dap + dam);\n d = dbp * dbm * (dbp + dbm);\n\n newVal = (c * (dbm * data[j + 1][i] + dbp * data[j - 1][i]) +\n d * (dam * data[j][i + 1] + dap * data[j][i - 1])) /\n (d * (dam + dap) + c * (dbm + dbp));\n } else {\n // If we did have contributions from the boundary conditions, then average\n // the result from the various contributions:\n newVal /= boundaryCnt;\n }\n\n // Jacobi updates are ridiculously slow to converge, so this approach uses a\n // Gauss-seidel iteration which is dramatically faster.\n diff = newVal - data[j][i];\n reldiff = diff / dmax;\n resid += reldiff * reldiff;\n\n // Gauss-Seidel-ish iteration, omega chosen based on heuristics and some\n // quick tests.\n //\n // NB: Don't overrelax the boundarie. Otherwise set an overrelaxation factor\n // which is a little low but safely optimal-ish:\n overrelaxation = boundaryCnt ? 0 : 0.85;\n\n // If there are four non-null neighbors, then we want a simple average without\n // overrelaxation. If all the surrouding points are null, then we want the full\n // overrelaxation\n //\n // Based on experiments, this actually seems to slow down convergence just a bit.\n // I'll leave it here for reference in case this needs to be revisited, but\n // it seems to work just fine without this.\n // if (overrelaxation) overrelaxation *= (4 - neighborCnt) / 4;\n\n data[j][i] += diff * (1 + overrelaxation);\n }\n\n resid = Math.sqrt(resid);\n } while(iter++ < itermax && resid > tol);\n\n Lib.log('Smoother converged to', resid, 'after', iter, 'iterations');\n\n return data;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/smooth_fill_2d_array.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/carpet/xy_defaults.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/carpet/xy_defaults.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar isArray1D = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").isArray1D;\n\nmodule.exports = function handleXYDefaults(traceIn, traceOut, coerce) {\n var x = coerce('x');\n var hasX = x && x.length;\n var y = coerce('y');\n var hasY = y && y.length;\n if(!hasX && !hasY) return false;\n\n traceOut._cheater = !x;\n\n if((!hasX || isArray1D(x)) && (!hasY || isArray1D(y))) {\n var len = hasX ? x.length : Infinity;\n if(hasY) len = Math.min(len, y.length);\n if(traceOut.a && traceOut.a.length) len = Math.min(len, traceOut.a.length);\n if(traceOut.b && traceOut.b.length) len = Math.min(len, traceOut.b.length);\n traceOut._length = len;\n } else traceOut._length = null;\n\n return true;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/carpet/xy_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/choropleth/attributes.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/choropleth/attributes.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar scatterGeoAttrs = __webpack_require__(/*! ../scattergeo/attributes */ \"./node_modules/plotly.js/src/traces/scattergeo/attributes.js\");\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar defaultLine = __webpack_require__(/*! ../../components/color/attributes */ \"./node_modules/plotly.js/src/components/color/attributes.js\").defaultLine;\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nvar scatterGeoMarkerLineAttrs = scatterGeoAttrs.marker.line;\n\nmodule.exports = extendFlat({\n locations: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n locationmode: scatterGeoAttrs.locationmode,\n z: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n geojson: extendFlat({}, scatterGeoAttrs.geojson, {\n \n }),\n featureidkey: scatterGeoAttrs.featureidkey,\n\n text: extendFlat({}, scatterGeoAttrs.text, {\n \n }),\n hovertext: extendFlat({}, scatterGeoAttrs.hovertext, {\n \n }),\n marker: {\n line: {\n color: extendFlat({}, scatterGeoMarkerLineAttrs.color, {dflt: defaultLine}),\n width: extendFlat({}, scatterGeoMarkerLineAttrs.width, {dflt: 1}),\n editType: 'calc'\n },\n opacity: {\n valType: 'number',\n arrayOk: true,\n min: 0,\n max: 1,\n dflt: 1,\n \n editType: 'style',\n \n },\n editType: 'calc'\n },\n\n selected: {\n marker: {\n opacity: scatterGeoAttrs.selected.marker.opacity,\n editType: 'plot'\n },\n editType: 'plot'\n },\n unselected: {\n marker: {\n opacity: scatterGeoAttrs.unselected.marker.opacity,\n editType: 'plot'\n },\n editType: 'plot'\n },\n\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {\n editType: 'calc',\n flags: ['location', 'z', 'text', 'name']\n }),\n hovertemplate: hovertemplateAttrs(),\n showlegend: extendFlat({}, baseAttrs.showlegend, {dflt: false})\n},\n\n colorScaleAttrs('', {\n cLetter: 'z',\n editTypeOverride: 'calc'\n })\n);\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/choropleth/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/choropleth/calc.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/choropleth/calc.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nvar colorscaleCalc = __webpack_require__(/*! ../../components/colorscale/calc */ \"./node_modules/plotly.js/src/components/colorscale/calc.js\");\nvar arraysToCalcdata = __webpack_require__(/*! ../scatter/arrays_to_calcdata */ \"./node_modules/plotly.js/src/traces/scatter/arrays_to_calcdata.js\");\nvar calcSelection = __webpack_require__(/*! ../scatter/calc_selection */ \"./node_modules/plotly.js/src/traces/scatter/calc_selection.js\");\n\nfunction isNonBlankString(v) {\n return v && typeof v === 'string';\n}\n\nmodule.exports = function calc(gd, trace) {\n var len = trace._length;\n var calcTrace = new Array(len);\n\n var isValidLoc;\n\n if(trace.geojson) {\n isValidLoc = function(v) { return isNonBlankString(v) || isNumeric(v); };\n } else {\n isValidLoc = isNonBlankString;\n }\n\n for(var i = 0; i < len; i++) {\n var calcPt = calcTrace[i] = {};\n var loc = trace.locations[i];\n var z = trace.z[i];\n\n if(isValidLoc(loc) && isNumeric(z)) {\n calcPt.loc = loc;\n calcPt.z = z;\n } else {\n calcPt.loc = null;\n calcPt.z = BADNUM;\n }\n\n calcPt.index = i;\n }\n\n arraysToCalcdata(calcTrace, trace);\n colorscaleCalc(gd, trace, {\n vals: trace.z,\n containerStr: '',\n cLetter: 'z'\n });\n calcSelection(calcTrace, trace);\n\n return calcTrace;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/choropleth/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/choropleth/defaults.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/choropleth/defaults.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar colorscaleDefaults = __webpack_require__(/*! ../../components/colorscale/defaults */ \"./node_modules/plotly.js/src/components/colorscale/defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/choropleth/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var locations = coerce('locations');\n var z = coerce('z');\n\n if(!(locations && locations.length && Lib.isArrayOrTypedArray(z) && z.length)) {\n traceOut.visible = false;\n return;\n }\n\n traceOut._length = Math.min(locations.length, z.length);\n\n var geojson = coerce('geojson');\n\n var locationmodeDflt;\n if((typeof geojson === 'string' && geojson !== '') || Lib.isPlainObject(geojson)) {\n locationmodeDflt = 'geojson-id';\n }\n\n var locationMode = coerce('locationmode', locationmodeDflt);\n\n if(locationMode === 'geojson-id') {\n coerce('featureidkey');\n }\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n\n var mlw = coerce('marker.line.width');\n if(mlw) coerce('marker.line.color');\n coerce('marker.opacity');\n\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'z'});\n\n Lib.coerceSelectionMarkerOpacity(traceOut, coerce);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/choropleth/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/choropleth/event_data.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/choropleth/event_data.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function eventData(out, pt, trace, cd, pointNumber) {\n out.location = pt.location;\n out.z = pt.z;\n\n // include feature properties from input geojson\n var cdi = cd[pointNumber];\n if(cdi.fIn && cdi.fIn.properties) {\n out.properties = cdi.fIn.properties;\n }\n out.ct = cdi.ct;\n\n return out;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/choropleth/event_data.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/choropleth/hover.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/choropleth/hover.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/choropleth/attributes.js\");\nvar fillText = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").fillText;\n\nmodule.exports = function hoverPoints(pointData, xval, yval) {\n var cd = pointData.cd;\n var trace = cd[0].trace;\n var geo = pointData.subplot;\n\n var pt, i, j, isInside;\n\n for(i = 0; i < cd.length; i++) {\n pt = cd[i];\n isInside = false;\n\n if(pt._polygons) {\n for(j = 0; j < pt._polygons.length; j++) {\n if(pt._polygons[j].contains([xval, yval])) {\n isInside = !isInside;\n }\n // for polygons that cross antimeridian as xval is in [-180, 180]\n if(pt._polygons[j].contains([xval + 360, yval])) {\n isInside = !isInside;\n }\n }\n\n if(isInside) break;\n }\n }\n\n if(!isInside || !pt) return;\n\n pointData.x0 = pointData.x1 = pointData.xa.c2p(pt.ct);\n pointData.y0 = pointData.y1 = pointData.ya.c2p(pt.ct);\n\n pointData.index = pt.index;\n pointData.location = pt.loc;\n pointData.z = pt.z;\n pointData.zLabel = Axes.tickText(geo.mockAxis, geo.mockAxis.c2l(pt.z), 'hover').text;\n pointData.hovertemplate = pt.hovertemplate;\n\n makeHoverInfo(pointData, trace, pt, geo.mockAxis);\n\n return [pointData];\n};\n\nfunction makeHoverInfo(pointData, trace, pt) {\n if(trace.hovertemplate) return;\n\n var hoverinfo = pt.hi || trace.hoverinfo;\n var loc = String(pt.loc);\n\n var parts = (hoverinfo === 'all') ?\n attributes.hoverinfo.flags :\n hoverinfo.split('+');\n\n var hasName = (parts.indexOf('name') !== -1);\n var hasLocation = (parts.indexOf('location') !== -1);\n var hasZ = (parts.indexOf('z') !== -1);\n var hasText = (parts.indexOf('text') !== -1);\n var hasIdAsNameLabel = !hasName && hasLocation;\n\n var text = [];\n\n if(hasIdAsNameLabel) {\n pointData.nameOverride = loc;\n } else {\n if(hasName) pointData.nameOverride = trace.name;\n if(hasLocation) text.push(loc);\n }\n\n if(hasZ) {\n text.push(pointData.zLabel);\n }\n if(hasText) {\n fillText(pt, trace, text);\n }\n\n pointData.extraText = text.join('
');\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/choropleth/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/choropleth/index.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/choropleth/index.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/choropleth/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/choropleth/defaults.js\"),\n colorbar: __webpack_require__(/*! ../heatmap/colorbar */ \"./node_modules/plotly.js/src/traces/heatmap/colorbar.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/choropleth/calc.js\"),\n calcGeoJSON: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/choropleth/plot.js\").calcGeoJSON,\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/choropleth/plot.js\").plot,\n style: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/choropleth/style.js\").style,\n styleOnSelect: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/choropleth/style.js\").styleOnSelect,\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/choropleth/hover.js\"),\n eventData: __webpack_require__(/*! ./event_data */ \"./node_modules/plotly.js/src/traces/choropleth/event_data.js\"),\n selectPoints: __webpack_require__(/*! ./select */ \"./node_modules/plotly.js/src/traces/choropleth/select.js\"),\n\n moduleType: 'trace',\n name: 'choropleth',\n basePlotModule: __webpack_require__(/*! ../../plots/geo */ \"./node_modules/plotly.js/src/plots/geo/index.js\"),\n categories: ['geo', 'noOpacity', 'showLegend'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/choropleth/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/choropleth/plot.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/choropleth/plot.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar geoUtils = __webpack_require__(/*! ../../lib/geo_location_utils */ \"./node_modules/plotly.js/src/lib/geo_location_utils.js\");\nvar getTopojsonFeatures = __webpack_require__(/*! ../../lib/topojson_utils */ \"./node_modules/plotly.js/src/lib/topojson_utils.js\").getTopojsonFeatures;\nvar findExtremes = __webpack_require__(/*! ../../plots/cartesian/autorange */ \"./node_modules/plotly.js/src/plots/cartesian/autorange.js\").findExtremes;\n\nvar style = __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/choropleth/style.js\").style;\n\nfunction plot(gd, geo, calcData) {\n var choroplethLayer = geo.layers.backplot.select('.choroplethlayer');\n\n Lib.makeTraceGroups(choroplethLayer, calcData, 'trace choropleth').each(function(calcTrace) {\n var sel = d3.select(this);\n\n var paths = sel.selectAll('path.choroplethlocation')\n .data(Lib.identity);\n\n paths.enter().append('path')\n .classed('choroplethlocation', true);\n\n paths.exit().remove();\n\n // call style here within topojson request callback\n style(gd, calcTrace);\n });\n}\n\nfunction calcGeoJSON(calcTrace, fullLayout) {\n var trace = calcTrace[0].trace;\n var geoLayout = fullLayout[trace.geo];\n var geo = geoLayout._subplot;\n var locationmode = trace.locationmode;\n var len = trace._length;\n\n var features = locationmode === 'geojson-id' ?\n geoUtils.extractTraceFeature(calcTrace) :\n getTopojsonFeatures(trace, geo.topojson);\n\n var lonArray = [];\n var latArray = [];\n\n for(var i = 0; i < len; i++) {\n var calcPt = calcTrace[i];\n var feature = locationmode === 'geojson-id' ?\n calcPt.fOut :\n geoUtils.locationToFeature(locationmode, calcPt.loc, features);\n\n if(feature) {\n calcPt.geojson = feature;\n calcPt.ct = feature.properties.ct;\n calcPt._polygons = geoUtils.feature2polygons(feature);\n\n var bboxFeature = geoUtils.computeBbox(feature);\n lonArray.push(bboxFeature[0], bboxFeature[2]);\n latArray.push(bboxFeature[1], bboxFeature[3]);\n } else {\n calcPt.geojson = null;\n }\n }\n\n if(geoLayout.fitbounds === 'geojson' && locationmode === 'geojson-id') {\n var bboxGeojson = geoUtils.computeBbox(geoUtils.getTraceGeojson(trace));\n lonArray = [bboxGeojson[0], bboxGeojson[2]];\n latArray = [bboxGeojson[1], bboxGeojson[3]];\n }\n\n var opts = {padded: true};\n trace._extremes.lon = findExtremes(geoLayout.lonaxis._ax, lonArray, opts);\n trace._extremes.lat = findExtremes(geoLayout.lataxis._ax, latArray, opts);\n}\n\nmodule.exports = {\n calcGeoJSON: calcGeoJSON,\n plot: plot\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/choropleth/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/choropleth/select.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/choropleth/select.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function selectPoints(searchInfo, selectionTester) {\n var cd = searchInfo.cd;\n var xa = searchInfo.xaxis;\n var ya = searchInfo.yaxis;\n var selection = [];\n\n var i, di, ct, x, y;\n\n if(selectionTester === false) {\n for(i = 0; i < cd.length; i++) {\n cd[i].selected = 0;\n }\n } else {\n for(i = 0; i < cd.length; i++) {\n di = cd[i];\n ct = di.ct;\n\n if(!ct) continue;\n\n x = xa.c2p(ct);\n y = ya.c2p(ct);\n\n if(selectionTester.contains([x, y], null, i, searchInfo)) {\n selection.push({\n pointNumber: i,\n lon: ct[0],\n lat: ct[1]\n });\n di.selected = 1;\n } else {\n di.selected = 0;\n }\n }\n }\n\n return selection;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/choropleth/select.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/choropleth/style.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/choropleth/style.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar Colorscale = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\");\n\nfunction style(gd, calcTrace) {\n if(calcTrace) styleTrace(gd, calcTrace);\n}\n\nfunction styleTrace(gd, calcTrace) {\n var trace = calcTrace[0].trace;\n var s = calcTrace[0].node3;\n var locs = s.selectAll('.choroplethlocation');\n var marker = trace.marker || {};\n var markerLine = marker.line || {};\n\n var sclFunc = Colorscale.makeColorScaleFuncFromTrace(trace);\n\n locs.each(function(d) {\n d3.select(this)\n .attr('fill', sclFunc(d.z))\n .call(Color.stroke, d.mlc || markerLine.color)\n .call(Drawing.dashLine, '', d.mlw || markerLine.width || 0)\n .style('opacity', marker.opacity);\n });\n\n Drawing.selectedPointStyle(locs, trace, gd);\n}\n\nfunction styleOnSelect(gd, calcTrace) {\n var s = calcTrace[0].node3;\n var trace = calcTrace[0].trace;\n\n if(trace.selectedpoints) {\n Drawing.selectedPointStyle(s.selectAll('.choroplethlocation'), trace, gd);\n } else {\n styleTrace(gd, calcTrace);\n }\n}\n\nmodule.exports = {\n style: style,\n styleOnSelect: styleOnSelect\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/choropleth/style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/choroplethmapbox/attributes.js":
-/*!**************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/choroplethmapbox/attributes.js ***!
- \**************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar choroplethAttrs = __webpack_require__(/*! ../choropleth/attributes */ \"./node_modules/plotly.js/src/traces/choropleth/attributes.js\");\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nmodule.exports = extendFlat({\n locations: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n\n // TODO\n // Maybe start with only one value (that we could name e.g. 'geojson-id'),\n // but eventually:\n // - we could also support for our own dist/topojson/*\n // .. and locationmode: choroplethAttrs.locationmode,\n\n z: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n\n // TODO maybe we could also set a \"key\" to dig out values out of the\n // GeoJSON feature `properties` fields?\n\n geojson: {\n valType: 'any',\n \n editType: 'calc',\n \n },\n featureidkey: extendFlat({}, choroplethAttrs.featureidkey, {\n \n }),\n\n // TODO agree on name / behaviour\n //\n // 'below' is used currently for layout.mapbox.layers,\n // even though it's not very plotly-esque.\n //\n // Note also, that the mapbox-gl style don't all have the same layers,\n // see https://codepen.io/etpinard/pen/ydVMwM for full list\n below: {\n valType: 'string',\n \n editType: 'plot',\n \n },\n\n text: choroplethAttrs.text,\n hovertext: choroplethAttrs.hovertext,\n\n marker: {\n line: {\n color: extendFlat({}, choroplethAttrs.marker.line.color, {editType: 'plot'}),\n width: extendFlat({}, choroplethAttrs.marker.line.width, {editType: 'plot'}),\n editType: 'calc'\n },\n // TODO maybe having a dflt less than 1, together with `below:''` would be better?\n opacity: extendFlat({}, choroplethAttrs.marker.opacity, {editType: 'plot'}),\n editType: 'calc'\n },\n\n selected: {\n marker: {\n opacity: extendFlat({}, choroplethAttrs.selected.marker.opacity, {editType: 'plot'}),\n editType: 'plot'\n },\n editType: 'plot'\n },\n unselected: {\n marker: {\n opacity: extendFlat({}, choroplethAttrs.unselected.marker.opacity, {editType: 'plot'}),\n editType: 'plot'\n },\n editType: 'plot'\n },\n\n hoverinfo: choroplethAttrs.hoverinfo,\n hovertemplate: hovertemplateAttrs({}, {keys: ['properties']}),\n showlegend: extendFlat({}, baseAttrs.showlegend, {dflt: false})\n},\n\n colorScaleAttrs('', {\n cLetter: 'z',\n editTypeOverride: 'calc'\n })\n);\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/choroplethmapbox/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/choroplethmapbox/convert.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/choroplethmapbox/convert.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Colorscale = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\n\nvar makeBlank = __webpack_require__(/*! ../../lib/geojson_utils */ \"./node_modules/plotly.js/src/lib/geojson_utils.js\").makeBlank;\nvar geoUtils = __webpack_require__(/*! ../../lib/geo_location_utils */ \"./node_modules/plotly.js/src/lib/geo_location_utils.js\");\n\n/* N.B.\n *\n * We fetch the GeoJSON files \"ourselves\" (during\n * mapbox.prototype.fetchMapData) where they are stored in a global object\n * named `PlotlyGeoAssets` (same as for topojson files in `geo` subplots).\n *\n * Mapbox does allow using URLs as geojson sources, but does NOT allow filtering\n * features by feature `id` that are not numbers (more info in:\n * https://github.com/mapbox/mapbox-gl-js/issues/8088).\n */\n\nfunction convert(calcTrace) {\n var trace = calcTrace[0].trace;\n var isVisible = trace.visible === true && trace._length !== 0;\n\n var fill = {\n layout: {visibility: 'none'},\n paint: {}\n };\n\n var line = {\n layout: {visibility: 'none'},\n paint: {}\n };\n\n var opts = trace._opts = {\n fill: fill,\n line: line,\n geojson: makeBlank()\n };\n\n if(!isVisible) return opts;\n\n var features = geoUtils.extractTraceFeature(calcTrace);\n\n if(!features) return opts;\n\n var sclFunc = Colorscale.makeColorScaleFuncFromTrace(trace);\n var marker = trace.marker;\n var markerLine = marker.line || {};\n\n var opacityFn;\n if(Lib.isArrayOrTypedArray(marker.opacity)) {\n opacityFn = function(d) {\n var mo = d.mo;\n return isNumeric(mo) ? +Lib.constrain(mo, 0, 1) : 0;\n };\n }\n\n var lineColorFn;\n if(Lib.isArrayOrTypedArray(markerLine.color)) {\n lineColorFn = function(d) { return d.mlc; };\n }\n\n var lineWidthFn;\n if(Lib.isArrayOrTypedArray(markerLine.width)) {\n lineWidthFn = function(d) { return d.mlw; };\n }\n\n for(var i = 0; i < calcTrace.length; i++) {\n var cdi = calcTrace[i];\n var fOut = cdi.fOut;\n\n if(fOut) {\n var props = fOut.properties;\n props.fc = sclFunc(cdi.z);\n if(opacityFn) props.mo = opacityFn(cdi);\n if(lineColorFn) props.mlc = lineColorFn(cdi);\n if(lineWidthFn) props.mlw = lineWidthFn(cdi);\n cdi.ct = props.ct;\n cdi._polygons = geoUtils.feature2polygons(fOut);\n }\n }\n\n var opacitySetting = opacityFn ?\n {type: 'identity', property: 'mo'} :\n marker.opacity;\n\n Lib.extendFlat(fill.paint, {\n 'fill-color': {type: 'identity', property: 'fc'},\n 'fill-opacity': opacitySetting\n });\n\n Lib.extendFlat(line.paint, {\n 'line-color': lineColorFn ?\n {type: 'identity', property: 'mlc'} :\n markerLine.color,\n 'line-width': lineWidthFn ?\n {type: 'identity', property: 'mlw'} :\n markerLine.width,\n 'line-opacity': opacitySetting\n });\n\n fill.layout.visibility = 'visible';\n line.layout.visibility = 'visible';\n\n opts.geojson = {type: 'FeatureCollection', features: features};\n\n convertOnSelect(calcTrace);\n\n return opts;\n}\n\nfunction convertOnSelect(calcTrace) {\n var trace = calcTrace[0].trace;\n var opts = trace._opts;\n var opacitySetting;\n\n if(trace.selectedpoints) {\n var fns = Drawing.makeSelectedPointStyleFns(trace);\n\n for(var i = 0; i < calcTrace.length; i++) {\n var cdi = calcTrace[i];\n if(cdi.fOut) {\n cdi.fOut.properties.mo2 = fns.selectedOpacityFn(cdi);\n }\n }\n\n opacitySetting = {type: 'identity', property: 'mo2'};\n } else {\n opacitySetting = Lib.isArrayOrTypedArray(trace.marker.opacity) ?\n {type: 'identity', property: 'mo'} :\n trace.marker.opacity;\n }\n\n Lib.extendFlat(opts.fill.paint, {'fill-opacity': opacitySetting});\n Lib.extendFlat(opts.line.paint, {'line-opacity': opacitySetting});\n\n return opts;\n}\n\nmodule.exports = {\n convert: convert,\n convertOnSelect: convertOnSelect\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/choroplethmapbox/convert.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/choroplethmapbox/defaults.js":
-/*!************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/choroplethmapbox/defaults.js ***!
- \************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar colorscaleDefaults = __webpack_require__(/*! ../../components/colorscale/defaults */ \"./node_modules/plotly.js/src/components/colorscale/defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/choroplethmapbox/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var locations = coerce('locations');\n var z = coerce('z');\n var geojson = coerce('geojson');\n\n if(!Lib.isArrayOrTypedArray(locations) || !locations.length ||\n !Lib.isArrayOrTypedArray(z) || !z.length ||\n !((typeof geojson === 'string' && geojson !== '') || Lib.isPlainObject(geojson))\n ) {\n traceOut.visible = false;\n return;\n }\n\n coerce('featureidkey');\n\n traceOut._length = Math.min(locations.length, z.length);\n\n coerce('below');\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n\n var mlw = coerce('marker.line.width');\n if(mlw) coerce('marker.line.color');\n coerce('marker.opacity');\n\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'z'});\n\n Lib.coerceSelectionMarkerOpacity(traceOut, coerce);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/choroplethmapbox/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/choroplethmapbox/index.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/choroplethmapbox/index.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/choroplethmapbox/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/choroplethmapbox/defaults.js\"),\n colorbar: __webpack_require__(/*! ../heatmap/colorbar */ \"./node_modules/plotly.js/src/traces/heatmap/colorbar.js\"),\n calc: __webpack_require__(/*! ../choropleth/calc */ \"./node_modules/plotly.js/src/traces/choropleth/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/choroplethmapbox/plot.js\"),\n hoverPoints: __webpack_require__(/*! ../choropleth/hover */ \"./node_modules/plotly.js/src/traces/choropleth/hover.js\"),\n eventData: __webpack_require__(/*! ../choropleth/event_data */ \"./node_modules/plotly.js/src/traces/choropleth/event_data.js\"),\n selectPoints: __webpack_require__(/*! ../choropleth/select */ \"./node_modules/plotly.js/src/traces/choropleth/select.js\"),\n\n styleOnSelect: function(_, cd) {\n if(cd) {\n var trace = cd[0].trace;\n trace._glTrace.updateOnSelect(cd);\n }\n },\n\n getBelow: function(trace, subplot) {\n var mapLayers = subplot.getMapLayers();\n\n // find layer just above top-most \"water\" layer\n // that is not a plotly layer\n for(var i = mapLayers.length - 2; i >= 0; i--) {\n var layerId = mapLayers[i].id;\n\n if(typeof layerId === 'string' &&\n layerId.indexOf('water') === 0\n ) {\n for(var j = i + 1; j < mapLayers.length; j++) {\n layerId = mapLayers[j].id;\n\n if(typeof layerId === 'string' &&\n layerId.indexOf('plotly-') === -1\n ) {\n return layerId;\n }\n }\n }\n }\n },\n\n moduleType: 'trace',\n name: 'choroplethmapbox',\n basePlotModule: __webpack_require__(/*! ../../plots/mapbox */ \"./node_modules/plotly.js/src/plots/mapbox/index.js\"),\n categories: ['mapbox', 'gl', 'noOpacity', 'showLegend'],\n meta: {\n hr_name: 'choropleth_mapbox',\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/choroplethmapbox/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/choroplethmapbox/plot.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/choroplethmapbox/plot.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar convert = __webpack_require__(/*! ./convert */ \"./node_modules/plotly.js/src/traces/choroplethmapbox/convert.js\").convert;\nvar convertOnSelect = __webpack_require__(/*! ./convert */ \"./node_modules/plotly.js/src/traces/choroplethmapbox/convert.js\").convertOnSelect;\nvar LAYER_PREFIX = __webpack_require__(/*! ../../plots/mapbox/constants */ \"./node_modules/plotly.js/src/plots/mapbox/constants.js\").traceLayerPrefix;\n\nfunction ChoroplethMapbox(subplot, uid) {\n this.type = 'choroplethmapbox';\n this.subplot = subplot;\n this.uid = uid;\n\n // N.B. fill and line layers share same source\n this.sourceId = 'source-' + uid;\n\n this.layerList = [\n ['fill', LAYER_PREFIX + uid + '-fill'],\n ['line', LAYER_PREFIX + uid + '-line']\n ];\n\n // previous 'below' value,\n // need this to update it properly\n this.below = null;\n}\n\nvar proto = ChoroplethMapbox.prototype;\n\nproto.update = function(calcTrace) {\n this._update(convert(calcTrace));\n};\n\nproto.updateOnSelect = function(calcTrace) {\n this._update(convertOnSelect(calcTrace));\n};\n\nproto._update = function(optsAll) {\n var subplot = this.subplot;\n var layerList = this.layerList;\n var below = subplot.belowLookup['trace-' + this.uid];\n\n subplot.map\n .getSource(this.sourceId)\n .setData(optsAll.geojson);\n\n if(below !== this.below) {\n this._removeLayers();\n this._addLayers(optsAll, below);\n this.below = below;\n }\n\n for(var i = 0; i < layerList.length; i++) {\n var item = layerList[i];\n var k = item[0];\n var id = item[1];\n var opts = optsAll[k];\n\n subplot.setOptions(id, 'setLayoutProperty', opts.layout);\n\n if(opts.layout.visibility === 'visible') {\n subplot.setOptions(id, 'setPaintProperty', opts.paint);\n }\n }\n};\n\nproto._addLayers = function(optsAll, below) {\n var subplot = this.subplot;\n var layerList = this.layerList;\n var sourceId = this.sourceId;\n\n for(var i = 0; i < layerList.length; i++) {\n var item = layerList[i];\n var k = item[0];\n var opts = optsAll[k];\n\n subplot.addLayer({\n type: k,\n id: item[1],\n source: sourceId,\n layout: opts.layout,\n paint: opts.paint\n }, below);\n }\n};\n\nproto._removeLayers = function() {\n var map = this.subplot.map;\n var layerList = this.layerList;\n\n for(var i = layerList.length - 1; i >= 0; i--) {\n map.removeLayer(layerList[i][1]);\n }\n};\n\nproto.dispose = function() {\n var map = this.subplot.map;\n this._removeLayers();\n map.removeSource(this.sourceId);\n};\n\nmodule.exports = function createChoroplethMapbox(subplot, calcTrace) {\n var trace = calcTrace[0].trace;\n var choroplethMapbox = new ChoroplethMapbox(subplot, trace.uid);\n var sourceId = choroplethMapbox.sourceId;\n var optsAll = convert(calcTrace);\n var below = choroplethMapbox.below = subplot.belowLookup['trace-' + trace.uid];\n\n subplot.map.addSource(sourceId, {\n type: 'geojson',\n data: optsAll.geojson\n });\n\n choroplethMapbox._addLayers(optsAll, below);\n\n // link ref for quick update during selections\n calcTrace[0].trace._glTrace = choroplethMapbox;\n\n return choroplethMapbox;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/choroplethmapbox/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/cone/attributes.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/cone/attributes.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar mesh3dAttrs = __webpack_require__(/*! ../mesh3d/attributes */ \"./node_modules/plotly.js/src/traces/mesh3d/attributes.js\");\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nvar attrs = {\n x: {\n valType: 'data_array',\n \n editType: 'calc+clearAxisTypes',\n \n },\n y: {\n valType: 'data_array',\n \n editType: 'calc+clearAxisTypes',\n \n },\n z: {\n valType: 'data_array',\n \n editType: 'calc+clearAxisTypes',\n \n },\n\n u: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n v: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n w: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n\n // TODO add way to specify cone positions independently of the vector field\n // provided, similar to MATLAB's coneplot Cx/Cy/Cz meshgrids,\n // see https://www.mathworks.com/help/matlab/ref/coneplot.html\n //\n // Alternatively, if our goal is only to 'fill in gaps' in the vector data,\n // we could try to extend the heatmap 'connectgaps' algorithm to 3D.\n // From AJ: this particular algorithm which amounts to a Poisson equation,\n // both for interpolation and extrapolation - is the right one to use for\n // cones too. It makes a field with zero divergence, which is a good\n // baseline assumption for vector fields.\n //\n // cones: {\n // // potential attributes to add:\n // //\n // // - meshmode: 'cartesian-product', 'pts', 'grid'\n // //\n // // under `meshmode: 'grid'`\n // // - (x|y|z)grid.start\n // // - (x|y|z)grid.end\n // // - (x|y|z)grid.size\n //\n // x: {\n // valType: 'data_array',\n // editType: 'calc',\n // \n // },\n // y: {\n // valType: 'data_array',\n // editType: 'calc',\n // \n // },\n // z: {\n // valType: 'data_array',\n // editType: 'calc',\n // \n // },\n //\n // editType: 'calc',\n // \n // },\n\n sizemode: {\n valType: 'enumerated',\n values: ['scaled', 'absolute'],\n \n editType: 'calc',\n dflt: 'scaled',\n \n },\n sizeref: {\n valType: 'number',\n \n editType: 'calc',\n min: 0,\n \n },\n\n anchor: {\n valType: 'enumerated',\n \n editType: 'calc',\n values: ['tip', 'tail', 'cm', 'center'],\n dflt: 'cm',\n \n },\n\n text: {\n valType: 'string',\n \n dflt: '',\n arrayOk: true,\n editType: 'calc',\n \n },\n hovertext: {\n valType: 'string',\n \n dflt: '',\n arrayOk: true,\n editType: 'calc',\n \n },\n\n hovertemplate: hovertemplateAttrs({editType: 'calc'}, {keys: ['norm']}),\n showlegend: extendFlat({}, baseAttrs.showlegend, {dflt: false})\n};\n\nextendFlat(attrs, colorScaleAttrs('', {\n colorAttr: 'u/v/w norm',\n showScaleDflt: true,\n editTypeOverride: 'calc'\n}));\n\nvar fromMesh3d = ['opacity', 'lightposition', 'lighting'];\n\nfromMesh3d.forEach(function(k) {\n attrs[k] = mesh3dAttrs[k];\n});\n\nattrs.hoverinfo = extendFlat({}, baseAttrs.hoverinfo, {\n editType: 'calc',\n flags: ['x', 'y', 'z', 'u', 'v', 'w', 'norm', 'text', 'name'],\n dflt: 'x+y+z+norm+text+name'\n});\n\nattrs.transforms = undefined;\n\nmodule.exports = attrs;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/cone/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/cone/calc.js":
-/*!********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/cone/calc.js ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar colorscaleCalc = __webpack_require__(/*! ../../components/colorscale/calc */ \"./node_modules/plotly.js/src/components/colorscale/calc.js\");\n\nmodule.exports = function calc(gd, trace) {\n var u = trace.u;\n var v = trace.v;\n var w = trace.w;\n var len = Math.min(\n trace.x.length, trace.y.length, trace.z.length,\n u.length, v.length, w.length\n );\n var normMax = -Infinity;\n var normMin = Infinity;\n\n for(var i = 0; i < len; i++) {\n var uu = u[i];\n var vv = v[i];\n var ww = w[i];\n var norm = Math.sqrt(uu * uu + vv * vv + ww * ww);\n\n normMax = Math.max(normMax, norm);\n normMin = Math.min(normMin, norm);\n }\n\n trace._len = len;\n trace._normMax = normMax;\n\n colorscaleCalc(gd, trace, {\n vals: [normMin, normMax],\n containerStr: '',\n cLetter: 'c'\n });\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/cone/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/cone/convert.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/cone/convert.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar conePlot = __webpack_require__(/*! gl-cone3d */ \"./node_modules/gl-cone3d/cone.js\");\nvar createConeMesh = __webpack_require__(/*! gl-cone3d */ \"./node_modules/gl-cone3d/cone.js\").createConeMesh;\n\nvar simpleMap = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").simpleMap;\nvar parseColorScale = __webpack_require__(/*! ../../lib/gl_format_color */ \"./node_modules/plotly.js/src/lib/gl_format_color.js\").parseColorScale;\nvar extractOpts = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\").extractOpts;\nvar zip3 = __webpack_require__(/*! ../../plots/gl3d/zip3 */ \"./node_modules/plotly.js/src/plots/gl3d/zip3.js\");\n\nfunction Cone(scene, uid) {\n this.scene = scene;\n this.uid = uid;\n this.mesh = null;\n this.data = null;\n}\n\nvar proto = Cone.prototype;\n\nproto.handlePick = function(selection) {\n if(selection.object === this.mesh) {\n var selectIndex = selection.index = selection.data.index;\n var xx = this.data.x[selectIndex];\n var yy = this.data.y[selectIndex];\n var zz = this.data.z[selectIndex];\n var uu = this.data.u[selectIndex];\n var vv = this.data.v[selectIndex];\n var ww = this.data.w[selectIndex];\n\n selection.traceCoordinate = [\n xx, yy, zz,\n uu, vv, ww,\n Math.sqrt(uu * uu + vv * vv + ww * ww)\n ];\n\n var text = this.data.hovertext || this.data.text;\n if(Array.isArray(text) && text[selectIndex] !== undefined) {\n selection.textLabel = text[selectIndex];\n } else if(text) {\n selection.textLabel = text;\n }\n\n return true;\n }\n};\n\nvar axisName2scaleIndex = {xaxis: 0, yaxis: 1, zaxis: 2};\nvar anchor2coneOffset = {tip: 1, tail: 0, cm: 0.25, center: 0.5};\nvar anchor2coneSpan = {tip: 1, tail: 1, cm: 0.75, center: 0.5};\n\nfunction convert(scene, trace) {\n var sceneLayout = scene.fullSceneLayout;\n var dataScale = scene.dataScale;\n var coneOpts = {};\n\n function toDataCoords(arr, axisName) {\n var ax = sceneLayout[axisName];\n var scale = dataScale[axisName2scaleIndex[axisName]];\n return simpleMap(arr, function(v) { return ax.d2l(v) * scale; });\n }\n\n coneOpts.vectors = zip3(\n toDataCoords(trace.u, 'xaxis'),\n toDataCoords(trace.v, 'yaxis'),\n toDataCoords(trace.w, 'zaxis'),\n trace._len\n );\n\n coneOpts.positions = zip3(\n toDataCoords(trace.x, 'xaxis'),\n toDataCoords(trace.y, 'yaxis'),\n toDataCoords(trace.z, 'zaxis'),\n trace._len\n );\n\n var cOpts = extractOpts(trace);\n coneOpts.colormap = parseColorScale(trace);\n coneOpts.vertexIntensityBounds = [cOpts.min / trace._normMax, cOpts.max / trace._normMax];\n coneOpts.coneOffset = anchor2coneOffset[trace.anchor];\n\n if(trace.sizemode === 'scaled') {\n // unitless sizeref\n coneOpts.coneSize = trace.sizeref || 0.5;\n } else {\n // sizeref here has unit of velocity\n coneOpts.coneSize = trace.sizeref && trace._normMax ?\n trace.sizeref / trace._normMax :\n 0.5;\n }\n\n var meshData = conePlot(coneOpts);\n\n // pass gl-mesh3d lighting attributes\n var lp = trace.lightposition;\n meshData.lightPosition = [lp.x, lp.y, lp.z];\n meshData.ambient = trace.lighting.ambient;\n meshData.diffuse = trace.lighting.diffuse;\n meshData.specular = trace.lighting.specular;\n meshData.roughness = trace.lighting.roughness;\n meshData.fresnel = trace.lighting.fresnel;\n meshData.opacity = trace.opacity;\n\n // stash autorange pad value\n trace._pad = anchor2coneSpan[trace.anchor] * meshData.vectorScale * meshData.coneScale * trace._normMax;\n\n return meshData;\n}\n\nproto.update = function(data) {\n this.data = data;\n\n var meshData = convert(this.scene, data);\n this.mesh.update(meshData);\n};\n\nproto.dispose = function() {\n this.scene.glplot.remove(this.mesh);\n this.mesh.dispose();\n};\n\nfunction createConeTrace(scene, data) {\n var gl = scene.glplot.gl;\n\n var meshData = convert(scene, data);\n var mesh = createConeMesh(gl, meshData);\n\n var cone = new Cone(scene, data.uid);\n cone.mesh = mesh;\n cone.data = data;\n mesh._trace = cone;\n\n scene.glplot.add(mesh);\n\n return cone;\n}\n\nmodule.exports = createConeTrace;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/cone/convert.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/cone/defaults.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/cone/defaults.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar colorscaleDefaults = __webpack_require__(/*! ../../components/colorscale/defaults */ \"./node_modules/plotly.js/src/components/colorscale/defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/cone/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var u = coerce('u');\n var v = coerce('v');\n var w = coerce('w');\n\n var x = coerce('x');\n var y = coerce('y');\n var z = coerce('z');\n\n if(\n !u || !u.length || !v || !v.length || !w || !w.length ||\n !x || !x.length || !y || !y.length || !z || !z.length\n ) {\n traceOut.visible = false;\n return;\n }\n\n coerce('sizeref');\n coerce('sizemode');\n\n coerce('anchor');\n\n coerce('lighting.ambient');\n coerce('lighting.diffuse');\n coerce('lighting.specular');\n coerce('lighting.roughness');\n coerce('lighting.fresnel');\n coerce('lightposition.x');\n coerce('lightposition.y');\n coerce('lightposition.z');\n\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'c'});\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n\n // disable 1D transforms (for now)\n traceOut._length = null;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/cone/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/cone/index.js":
-/*!*********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/cone/index.js ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n moduleType: 'trace',\n name: 'cone',\n basePlotModule: __webpack_require__(/*! ../../plots/gl3d */ \"./node_modules/plotly.js/src/plots/gl3d/index.js\"),\n categories: ['gl3d', 'showLegend'],\n\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/cone/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/cone/defaults.js\"),\n colorbar: {\n min: 'cmin',\n max: 'cmax'\n },\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/cone/calc.js\"),\n plot: __webpack_require__(/*! ./convert */ \"./node_modules/plotly.js/src/traces/cone/convert.js\"),\n eventData: function(out, pt) {\n out.norm = pt.traceCoordinate[6];\n return out;\n },\n\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/cone/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/attributes.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/attributes.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar heatmapAttrs = __webpack_require__(/*! ../heatmap/attributes */ \"./node_modules/plotly.js/src/traces/heatmap/attributes.js\");\nvar scatterAttrs = __webpack_require__(/*! ../scatter/attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\");\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar dash = __webpack_require__(/*! ../../components/drawing/attributes */ \"./node_modules/plotly.js/src/components/drawing/attributes.js\").dash;\nvar fontAttrs = __webpack_require__(/*! ../../plots/font_attributes */ \"./node_modules/plotly.js/src/plots/font_attributes.js\");\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nvar filterOps = __webpack_require__(/*! ../../constants/filter_ops */ \"./node_modules/plotly.js/src/constants/filter_ops.js\");\nvar COMPARISON_OPS2 = filterOps.COMPARISON_OPS2;\nvar INTERVAL_OPS = filterOps.INTERVAL_OPS;\n\nvar FORMAT_LINK = __webpack_require__(/*! ../../constants/docs */ \"./node_modules/plotly.js/src/constants/docs.js\").FORMAT_LINK;\n\nvar scatterLineAttrs = scatterAttrs.line;\n\nmodule.exports = extendFlat({\n z: heatmapAttrs.z,\n x: heatmapAttrs.x,\n x0: heatmapAttrs.x0,\n dx: heatmapAttrs.dx,\n y: heatmapAttrs.y,\n y0: heatmapAttrs.y0,\n dy: heatmapAttrs.dy,\n text: heatmapAttrs.text,\n hovertext: heatmapAttrs.hovertext,\n transpose: heatmapAttrs.transpose,\n xtype: heatmapAttrs.xtype,\n ytype: heatmapAttrs.ytype,\n zhoverformat: heatmapAttrs.zhoverformat,\n hovertemplate: heatmapAttrs.hovertemplate,\n hoverongaps: heatmapAttrs.hoverongaps,\n connectgaps: extendFlat({}, heatmapAttrs.connectgaps, {\n \n }),\n\n fillcolor: {\n valType: 'color',\n \n editType: 'calc',\n \n },\n\n autocontour: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'calc',\n impliedEdits: {\n 'contours.start': undefined,\n 'contours.end': undefined,\n 'contours.size': undefined\n },\n \n },\n ncontours: {\n valType: 'integer',\n dflt: 15,\n min: 1,\n \n editType: 'calc',\n \n },\n\n contours: {\n type: {\n valType: 'enumerated',\n values: ['levels', 'constraint'],\n dflt: 'levels',\n \n editType: 'calc',\n \n },\n start: {\n valType: 'number',\n dflt: null,\n \n editType: 'plot',\n impliedEdits: {'^autocontour': false},\n \n },\n end: {\n valType: 'number',\n dflt: null,\n \n editType: 'plot',\n impliedEdits: {'^autocontour': false},\n \n },\n size: {\n valType: 'number',\n dflt: null,\n min: 0,\n \n editType: 'plot',\n impliedEdits: {'^autocontour': false},\n \n },\n coloring: {\n valType: 'enumerated',\n values: ['fill', 'heatmap', 'lines', 'none'],\n dflt: 'fill',\n \n editType: 'calc',\n \n },\n showlines: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'plot',\n \n },\n showlabels: {\n valType: 'boolean',\n dflt: false,\n \n editType: 'plot',\n \n },\n labelfont: fontAttrs({\n editType: 'plot',\n colorEditType: 'style',\n \n }),\n labelformat: {\n valType: 'string',\n dflt: '',\n \n editType: 'plot',\n \n },\n operation: {\n valType: 'enumerated',\n values: [].concat(COMPARISON_OPS2).concat(INTERVAL_OPS),\n \n dflt: '=',\n editType: 'calc',\n \n },\n value: {\n valType: 'any',\n dflt: 0,\n \n editType: 'calc',\n \n },\n editType: 'calc',\n impliedEdits: {'autocontour': false}\n },\n\n line: {\n color: extendFlat({}, scatterLineAttrs.color, {\n editType: 'style+colorbars',\n \n }),\n width: {\n valType: 'number',\n min: 0,\n \n editType: 'style+colorbars',\n \n },\n dash: dash,\n smoothing: extendFlat({}, scatterLineAttrs.smoothing, {\n \n }),\n editType: 'plot'\n }\n},\n colorScaleAttrs('', {\n cLetter: 'z',\n autoColorDflt: false,\n editTypeOverride: 'calc'\n })\n);\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/calc.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/calc.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Colorscale = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\");\n\nvar heatmapCalc = __webpack_require__(/*! ../heatmap/calc */ \"./node_modules/plotly.js/src/traces/heatmap/calc.js\");\nvar setContours = __webpack_require__(/*! ./set_contours */ \"./node_modules/plotly.js/src/traces/contour/set_contours.js\");\nvar endPlus = __webpack_require__(/*! ./end_plus */ \"./node_modules/plotly.js/src/traces/contour/end_plus.js\");\n\n// most is the same as heatmap calc, then adjust it\n// though a few things inside heatmap calc still look for\n// contour maps, because the makeBoundArray calls are too entangled\nmodule.exports = function calc(gd, trace) {\n var cd = heatmapCalc(gd, trace);\n\n var zOut = cd[0].z;\n setContours(trace, zOut);\n\n var contours = trace.contours;\n var cOpts = Colorscale.extractOpts(trace);\n var cVals;\n\n if(contours.coloring === 'heatmap' && cOpts.auto && trace.autocontour === false) {\n var start = contours.start;\n var end = endPlus(contours);\n var cs = contours.size || 1;\n var nc = Math.floor((end - start) / cs) + 1;\n\n if(!isFinite(cs)) {\n cs = 1;\n nc = 1;\n }\n\n var min0 = start - cs / 2;\n var max0 = min0 + nc * cs;\n cVals = [min0, max0];\n } else {\n cVals = zOut;\n }\n\n Colorscale.calc(gd, trace, {vals: cVals, cLetter: 'z'});\n\n return cd;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/close_boundaries.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/close_boundaries.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function(pathinfo, contours) {\n var pi0 = pathinfo[0];\n var z = pi0.z;\n var i;\n\n switch(contours.type) {\n case 'levels':\n // Why (just) use z[0][0] and z[0][1]?\n //\n // N.B. using boundaryMin instead of edgeVal2 here makes the\n // `contour_scatter` mock fail\n var edgeVal2 = Math.min(z[0][0], z[0][1]);\n\n for(i = 0; i < pathinfo.length; i++) {\n var pi = pathinfo[i];\n pi.prefixBoundary = !pi.edgepaths.length &&\n (edgeVal2 > pi.level || pi.starts.length && edgeVal2 === pi.level);\n }\n break;\n case 'constraint':\n // after convertToConstraints, pathinfo has length=0\n pi0.prefixBoundary = false;\n\n // joinAllPaths does enough already when edgepaths are present\n if(pi0.edgepaths.length) return;\n\n var na = pi0.x.length;\n var nb = pi0.y.length;\n var boundaryMax = -Infinity;\n var boundaryMin = Infinity;\n\n for(i = 0; i < nb; i++) {\n boundaryMin = Math.min(boundaryMin, z[i][0]);\n boundaryMin = Math.min(boundaryMin, z[i][na - 1]);\n boundaryMax = Math.max(boundaryMax, z[i][0]);\n boundaryMax = Math.max(boundaryMax, z[i][na - 1]);\n }\n for(i = 1; i < na - 1; i++) {\n boundaryMin = Math.min(boundaryMin, z[0][i]);\n boundaryMin = Math.min(boundaryMin, z[nb - 1][i]);\n boundaryMax = Math.max(boundaryMax, z[0][i]);\n boundaryMax = Math.max(boundaryMax, z[nb - 1][i]);\n }\n\n var contoursValue = contours.value;\n var v1, v2;\n\n switch(contours._operation) {\n case '>':\n if(contoursValue > boundaryMax) {\n pi0.prefixBoundary = true;\n }\n break;\n case '<':\n if(contoursValue < boundaryMin ||\n (pi0.starts.length && contoursValue === boundaryMin)) {\n pi0.prefixBoundary = true;\n }\n break;\n case '[]':\n v1 = Math.min(contoursValue[0], contoursValue[1]);\n v2 = Math.max(contoursValue[0], contoursValue[1]);\n if(v2 < boundaryMin || v1 > boundaryMax ||\n (pi0.starts.length && v2 === boundaryMin)) {\n pi0.prefixBoundary = true;\n }\n break;\n case '][':\n v1 = Math.min(contoursValue[0], contoursValue[1]);\n v2 = Math.max(contoursValue[0], contoursValue[1]);\n if(v1 < boundaryMin && v2 > boundaryMax) {\n pi0.prefixBoundary = true;\n }\n break;\n }\n break;\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/close_boundaries.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/colorbar.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/colorbar.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Colorscale = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\");\nvar makeColorMap = __webpack_require__(/*! ./make_color_map */ \"./node_modules/plotly.js/src/traces/contour/make_color_map.js\");\nvar endPlus = __webpack_require__(/*! ./end_plus */ \"./node_modules/plotly.js/src/traces/contour/end_plus.js\");\n\nfunction calc(gd, trace, opts) {\n var contours = trace.contours;\n var line = trace.line;\n var cs = contours.size || 1;\n var coloring = contours.coloring;\n var colorMap = makeColorMap(trace, {isColorbar: true});\n\n if(coloring === 'heatmap') {\n var cOpts = Colorscale.extractOpts(trace);\n opts._fillgradient = cOpts.reversescale ?\n Colorscale.flipScale(cOpts.colorscale) :\n cOpts.colorscale;\n opts._zrange = [cOpts.min, cOpts.max];\n } else if(coloring === 'fill') {\n opts._fillcolor = colorMap;\n }\n\n opts._line = {\n color: coloring === 'lines' ? colorMap : line.color,\n width: contours.showlines !== false ? line.width : 0,\n dash: line.dash\n };\n\n opts._levels = {\n start: contours.start,\n end: endPlus(contours),\n size: cs\n };\n}\n\nmodule.exports = {\n min: 'zmin',\n max: 'zmax',\n calc: calc\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/colorbar.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/constants.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/constants.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\nmodule.exports = {\n // some constants to help with marching squares algorithm\n // where does the path start for each index?\n BOTTOMSTART: [1, 9, 13, 104, 713],\n TOPSTART: [4, 6, 7, 104, 713],\n LEFTSTART: [8, 12, 14, 208, 1114],\n RIGHTSTART: [2, 3, 11, 208, 1114],\n\n // which way [dx,dy] do we leave a given index?\n // saddles are already disambiguated\n NEWDELTA: [\n null, [-1, 0], [0, -1], [-1, 0],\n [1, 0], null, [0, -1], [-1, 0],\n [0, 1], [0, 1], null, [0, 1],\n [1, 0], [1, 0], [0, -1]\n ],\n\n // for each saddle, the first index here is used\n // for dx||dy<0, the second for dx||dy>0\n CHOOSESADDLE: {\n 104: [4, 1],\n 208: [2, 8],\n 713: [7, 13],\n 1114: [11, 14]\n },\n\n // after one index has been used for a saddle, which do we\n // substitute to be used up later?\n SADDLEREMAINDER: {1: 4, 2: 8, 4: 1, 7: 13, 8: 2, 11: 14, 13: 7, 14: 11},\n\n // length of a contour, as a multiple of the plot area diagonal, per label\n LABELDISTANCE: 2,\n\n // number of contour levels after which we start increasing the number of\n // labels we draw. Many contours means they will generally be close\n // together, so it will be harder to follow a long way to find a label\n LABELINCREASE: 10,\n\n // minimum length of a contour line, as a multiple of the label length,\n // at which we draw *any* labels\n LABELMIN: 3,\n\n // max number of labels to draw on a single contour path, no matter how long\n LABELMAX: 10,\n\n // constants for the label position cost function\n LABELOPTIMIZER: {\n // weight given to edge proximity\n EDGECOST: 1,\n // weight given to the angle off horizontal\n ANGLECOST: 1,\n // weight given to distance from already-placed labels\n NEIGHBORCOST: 5,\n // cost multiplier for labels on the same level\n SAMELEVELFACTOR: 10,\n // minimum distance (as a multiple of the label length)\n // for labels on the same level\n SAMELEVELDISTANCE: 5,\n // maximum cost before we won't even place the label\n MAXCOST: 100,\n // number of evenly spaced points to look at in the first\n // iteration of the search\n INITIALSEARCHPOINTS: 10,\n // number of binary search iterations after the initial wide search\n ITERATIONS: 5\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/constants.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/constraint_defaults.js":
-/*!**************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/constraint_defaults.js ***!
- \**************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\nvar handleLabelDefaults = __webpack_require__(/*! ./label_defaults */ \"./node_modules/plotly.js/src/traces/contour/label_defaults.js\");\n\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar addOpacity = Color.addOpacity;\nvar opacity = Color.opacity;\n\nvar filterOps = __webpack_require__(/*! ../../constants/filter_ops */ \"./node_modules/plotly.js/src/constants/filter_ops.js\");\nvar CONSTRAINT_REDUCTION = filterOps.CONSTRAINT_REDUCTION;\nvar COMPARISON_OPS2 = filterOps.COMPARISON_OPS2;\n\nmodule.exports = function handleConstraintDefaults(traceIn, traceOut, coerce, layout, defaultColor, opts) {\n var contours = traceOut.contours;\n var showLines, lineColor, fillColor;\n\n var operation = coerce('contours.operation');\n contours._operation = CONSTRAINT_REDUCTION[operation];\n\n handleConstraintValueDefaults(coerce, contours);\n\n if(operation === '=') {\n showLines = contours.showlines = true;\n } else {\n showLines = coerce('contours.showlines');\n fillColor = coerce('fillcolor', addOpacity(\n (traceIn.line || {}).color || defaultColor, 0.5\n ));\n }\n\n if(showLines) {\n var lineDfltColor = fillColor && opacity(fillColor) ?\n addOpacity(traceOut.fillcolor, 1) :\n defaultColor;\n lineColor = coerce('line.color', lineDfltColor);\n coerce('line.width', 2);\n coerce('line.dash');\n }\n\n coerce('line.smoothing');\n\n handleLabelDefaults(coerce, layout, lineColor, opts);\n};\n\nfunction handleConstraintValueDefaults(coerce, contours) {\n var zvalue;\n\n if(COMPARISON_OPS2.indexOf(contours.operation) === -1) {\n // Requires an array of two numbers:\n coerce('contours.value', [0, 1]);\n\n if(!Array.isArray(contours.value)) {\n if(isNumeric(contours.value)) {\n zvalue = parseFloat(contours.value);\n contours.value = [zvalue, zvalue + 1];\n }\n } else if(contours.value.length > 2) {\n contours.value = contours.value.slice(2);\n } else if(contours.length === 0) {\n contours.value = [0, 1];\n } else if(contours.length < 2) {\n zvalue = parseFloat(contours.value[0]);\n contours.value = [zvalue, zvalue + 1];\n } else {\n contours.value = [\n parseFloat(contours.value[0]),\n parseFloat(contours.value[1])\n ];\n }\n } else {\n // Requires a single scalar:\n coerce('contours.value', 0);\n\n if(!isNumeric(contours.value)) {\n if(Array.isArray(contours.value)) {\n contours.value = parseFloat(contours.value[0]);\n } else {\n contours.value = 0;\n }\n }\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/constraint_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/constraint_mapping.js":
-/*!*************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/constraint_mapping.js ***!
- \*************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar filterOps = __webpack_require__(/*! ../../constants/filter_ops */ \"./node_modules/plotly.js/src/constants/filter_ops.js\");\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\n// This syntax conforms to the existing filter transform syntax, but we don't care\n// about open vs. closed intervals for simply drawing contours constraints:\nmodule.exports = {\n '[]': makeRangeSettings('[]'),\n '][': makeRangeSettings(']['),\n '>': makeInequalitySettings('>'),\n '<': makeInequalitySettings('<'),\n '=': makeInequalitySettings('=')\n};\n\n// This does not in any way shape or form support calendars. It's adapted from\n// transforms/filter.js.\nfunction coerceValue(operation, value) {\n var hasArrayValue = Array.isArray(value);\n\n var coercedValue;\n\n function coerce(value) {\n return isNumeric(value) ? (+value) : null;\n }\n\n if(filterOps.COMPARISON_OPS2.indexOf(operation) !== -1) {\n coercedValue = hasArrayValue ? coerce(value[0]) : coerce(value);\n } else if(filterOps.INTERVAL_OPS.indexOf(operation) !== -1) {\n coercedValue = hasArrayValue ?\n [coerce(value[0]), coerce(value[1])] :\n [coerce(value), coerce(value)];\n } else if(filterOps.SET_OPS.indexOf(operation) !== -1) {\n coercedValue = hasArrayValue ? value.map(coerce) : [coerce(value)];\n }\n\n return coercedValue;\n}\n\n// Returns a parabola scaled so that the min/max is either +/- 1 and zero at the two values\n// provided. The data is mapped by this function when constructing intervals so that it's\n// very easy to construct contours as normal.\nfunction makeRangeSettings(operation) {\n return function(value) {\n value = coerceValue(operation, value);\n\n // Ensure proper ordering:\n var min = Math.min(value[0], value[1]);\n var max = Math.max(value[0], value[1]);\n\n return {\n start: min,\n end: max,\n size: max - min\n };\n };\n}\n\nfunction makeInequalitySettings(operation) {\n return function(value) {\n value = coerceValue(operation, value);\n\n return {\n start: value,\n end: Infinity,\n size: Infinity\n };\n };\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/constraint_mapping.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/contours_defaults.js":
-/*!************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/contours_defaults.js ***!
- \************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function handleContourDefaults(traceIn, traceOut, coerce, coerce2) {\n var contourStart = coerce2('contours.start');\n var contourEnd = coerce2('contours.end');\n var missingEnd = (contourStart === false) || (contourEnd === false);\n\n // normally we only need size if autocontour is off. But contour.calc\n // pushes its calculated contour size back to the input trace, so for\n // things like restyle that can call supplyDefaults without calc\n // after the initial draw, we can just reuse the previous calculation\n var contourSize = coerce('contours.size');\n var autoContour;\n\n if(missingEnd) autoContour = traceOut.autocontour = true;\n else autoContour = coerce('autocontour', false);\n\n if(autoContour || !contourSize) coerce('ncontours');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/contours_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/convert_to_constraints.js":
-/*!*****************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/convert_to_constraints.js ***!
- \*****************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\n// The contour extraction is great, except it totally fails for constraints because we\n// need weird range loops and flipped contours instead of the usual format. This function\n// does some weird manipulation of the extracted pathinfo data such that it magically\n// draws contours correctly *as* constraints.\n//\n// ** I do not know which \"weird range loops\" the comment above is referring to.\nmodule.exports = function(pathinfo, operation) {\n var i, pi0, pi1;\n\n var op0 = function(arr) { return arr.reverse(); };\n var op1 = function(arr) { return arr; };\n\n switch(operation) {\n case '=':\n case '<':\n return pathinfo;\n case '>':\n if(pathinfo.length !== 1) {\n Lib.warn('Contour data invalid for the specified inequality operation.');\n }\n\n // In this case there should be exactly one contour levels in pathinfo.\n // We flip all of the data. This will draw the contour as closed.\n pi0 = pathinfo[0];\n\n for(i = 0; i < pi0.edgepaths.length; i++) {\n pi0.edgepaths[i] = op0(pi0.edgepaths[i]);\n }\n for(i = 0; i < pi0.paths.length; i++) {\n pi0.paths[i] = op0(pi0.paths[i]);\n }\n for(i = 0; i < pi0.starts.length; i++) {\n pi0.starts[i] = op0(pi0.starts[i]);\n }\n\n return pathinfo;\n case '][':\n var tmp = op0;\n op0 = op1;\n op1 = tmp;\n // It's a nice rule, except this definitely *is* what's intended here.\n /* eslint-disable: no-fallthrough */\n case '[]':\n /* eslint-enable: no-fallthrough */\n if(pathinfo.length !== 2) {\n Lib.warn('Contour data invalid for the specified inequality range operation.');\n }\n\n // In this case there should be exactly two contour levels in pathinfo.\n // - We concatenate the info into one pathinfo.\n // - We must also flip all of the data in the `[]` case.\n // This will draw the contours as closed.\n pi0 = copyPathinfo(pathinfo[0]);\n pi1 = copyPathinfo(pathinfo[1]);\n\n for(i = 0; i < pi0.edgepaths.length; i++) {\n pi0.edgepaths[i] = op0(pi0.edgepaths[i]);\n }\n for(i = 0; i < pi0.paths.length; i++) {\n pi0.paths[i] = op0(pi0.paths[i]);\n }\n for(i = 0; i < pi0.starts.length; i++) {\n pi0.starts[i] = op0(pi0.starts[i]);\n }\n\n while(pi1.edgepaths.length) {\n pi0.edgepaths.push(op1(pi1.edgepaths.shift()));\n }\n while(pi1.paths.length) {\n pi0.paths.push(op1(pi1.paths.shift()));\n }\n while(pi1.starts.length) {\n pi0.starts.push(op1(pi1.starts.shift()));\n }\n\n return [pi0];\n }\n};\n\nfunction copyPathinfo(pi) {\n return Lib.extendFlat({}, pi, {\n edgepaths: Lib.extendDeep([], pi.edgepaths),\n paths: Lib.extendDeep([], pi.paths),\n starts: Lib.extendDeep([], pi.starts)\n });\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/convert_to_constraints.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/defaults.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/defaults.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar handleXYZDefaults = __webpack_require__(/*! ../heatmap/xyz_defaults */ \"./node_modules/plotly.js/src/traces/heatmap/xyz_defaults.js\");\nvar handleConstraintDefaults = __webpack_require__(/*! ./constraint_defaults */ \"./node_modules/plotly.js/src/traces/contour/constraint_defaults.js\");\nvar handleContoursDefaults = __webpack_require__(/*! ./contours_defaults */ \"./node_modules/plotly.js/src/traces/contour/contours_defaults.js\");\nvar handleStyleDefaults = __webpack_require__(/*! ./style_defaults */ \"./node_modules/plotly.js/src/traces/contour/style_defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/contour/attributes.js\");\n\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n function coerce2(attr) {\n return Lib.coerce2(traceIn, traceOut, attributes, attr);\n }\n\n var len = handleXYZDefaults(traceIn, traceOut, coerce, layout);\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n coerce('hoverongaps');\n\n var isConstraint = (coerce('contours.type') === 'constraint');\n coerce('connectgaps', Lib.isArray1D(traceOut.z));\n\n if(isConstraint) {\n handleConstraintDefaults(traceIn, traceOut, coerce, layout, defaultColor);\n } else {\n handleContoursDefaults(traceIn, traceOut, coerce, coerce2);\n handleStyleDefaults(traceIn, traceOut, coerce, layout);\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/empty_pathinfo.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/empty_pathinfo.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar constraintMapping = __webpack_require__(/*! ./constraint_mapping */ \"./node_modules/plotly.js/src/traces/contour/constraint_mapping.js\");\nvar endPlus = __webpack_require__(/*! ./end_plus */ \"./node_modules/plotly.js/src/traces/contour/end_plus.js\");\n\nmodule.exports = function emptyPathinfo(contours, plotinfo, cd0) {\n var contoursFinal = (contours.type === 'constraint') ?\n constraintMapping[contours._operation](contours.value) :\n contours;\n\n var cs = contoursFinal.size;\n var pathinfo = [];\n var end = endPlus(contoursFinal);\n\n var carpet = cd0.trace._carpetTrace;\n\n var basePathinfo = carpet ? {\n // store axes so we can convert to px\n xaxis: carpet.aaxis,\n yaxis: carpet.baxis,\n // full data arrays to use for interpolation\n x: cd0.a,\n y: cd0.b\n } : {\n xaxis: plotinfo.xaxis,\n yaxis: plotinfo.yaxis,\n x: cd0.x,\n y: cd0.y\n };\n\n for(var ci = contoursFinal.start; ci < end; ci += cs) {\n pathinfo.push(Lib.extendFlat({\n level: ci,\n // all the cells with nontrivial marching index\n crossings: {},\n // starting points on the edges of the lattice for each contour\n starts: [],\n // all unclosed paths (may have less items than starts,\n // if a path is closed by rounding)\n edgepaths: [],\n // all closed paths\n paths: [],\n z: cd0.z,\n smoothing: cd0.trace.line.smoothing\n }, basePathinfo));\n\n if(pathinfo.length > 1000) {\n Lib.warn('Too many contours, clipping at 1000', contours);\n break;\n }\n }\n return pathinfo;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/empty_pathinfo.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/end_plus.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/end_plus.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\n/*\n * tiny helper to move the end of the contours a little to prevent\n * losing the last contour to rounding errors\n */\nmodule.exports = function endPlus(contours) {\n return contours.end + contours.size / 1e6;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/end_plus.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/find_all_paths.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/find_all_paths.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/contour/constants.js\");\n\nmodule.exports = function findAllPaths(pathinfo, xtol, ytol) {\n var cnt,\n startLoc,\n i,\n pi,\n j;\n\n // Default just passes these values through as they were before:\n xtol = xtol || 0.01;\n ytol = ytol || 0.01;\n\n for(i = 0; i < pathinfo.length; i++) {\n pi = pathinfo[i];\n\n for(j = 0; j < pi.starts.length; j++) {\n startLoc = pi.starts[j];\n makePath(pi, startLoc, 'edge', xtol, ytol);\n }\n\n cnt = 0;\n while(Object.keys(pi.crossings).length && cnt < 10000) {\n cnt++;\n startLoc = Object.keys(pi.crossings)[0].split(',').map(Number);\n makePath(pi, startLoc, undefined, xtol, ytol);\n }\n if(cnt === 10000) Lib.log('Infinite loop in contour?');\n }\n};\n\nfunction equalPts(pt1, pt2, xtol, ytol) {\n return Math.abs(pt1[0] - pt2[0]) < xtol &&\n Math.abs(pt1[1] - pt2[1]) < ytol;\n}\n\n// distance in index units - uses the 3rd and 4th items in points\nfunction ptDist(pt1, pt2) {\n var dx = pt1[2] - pt2[2];\n var dy = pt1[3] - pt2[3];\n return Math.sqrt(dx * dx + dy * dy);\n}\n\nfunction makePath(pi, loc, edgeflag, xtol, ytol) {\n var locStr = loc.join(',');\n var mi = pi.crossings[locStr];\n var marchStep = getStartStep(mi, edgeflag, loc);\n // start by going backward a half step and finding the crossing point\n var pts = [getInterpPx(pi, loc, [-marchStep[0], -marchStep[1]])];\n var m = pi.z.length;\n var n = pi.z[0].length;\n var startLoc = loc.slice();\n var startStep = marchStep.slice();\n var cnt;\n\n // now follow the path\n for(cnt = 0; cnt < 10000; cnt++) { // just to avoid infinite loops\n if(mi > 20) {\n mi = constants.CHOOSESADDLE[mi][(marchStep[0] || marchStep[1]) < 0 ? 0 : 1];\n pi.crossings[locStr] = constants.SADDLEREMAINDER[mi];\n } else {\n delete pi.crossings[locStr];\n }\n\n marchStep = constants.NEWDELTA[mi];\n if(!marchStep) {\n Lib.log('Found bad marching index:', mi, loc, pi.level);\n break;\n }\n\n // find the crossing a half step forward, and then take the full step\n pts.push(getInterpPx(pi, loc, marchStep));\n loc[0] += marchStep[0];\n loc[1] += marchStep[1];\n locStr = loc.join(',');\n\n // don't include the same point multiple times\n if(equalPts(pts[pts.length - 1], pts[pts.length - 2], xtol, ytol)) pts.pop();\n\n var atEdge = (marchStep[0] && (loc[0] < 0 || loc[0] > n - 2)) ||\n (marchStep[1] && (loc[1] < 0 || loc[1] > m - 2));\n\n var closedLoop = loc[0] === startLoc[0] && loc[1] === startLoc[1] &&\n marchStep[0] === startStep[0] && marchStep[1] === startStep[1];\n\n // have we completed a loop, or reached an edge?\n if((closedLoop) || (edgeflag && atEdge)) break;\n\n mi = pi.crossings[locStr];\n }\n\n if(cnt === 10000) {\n Lib.log('Infinite loop in contour?');\n }\n var closedpath = equalPts(pts[0], pts[pts.length - 1], xtol, ytol);\n var totaldist = 0;\n var distThresholdFactor = 0.2 * pi.smoothing;\n var alldists = [];\n var cropstart = 0;\n var distgroup, cnt2, cnt3, newpt, ptcnt, ptavg, thisdist,\n i, j, edgepathi, edgepathj;\n\n /*\n * Check for points that are too close together (<1/5 the average dist\n * *in grid index units* (important for log axes and nonuniform grids),\n * less if less smoothed) and just take the center (or avg of center 2).\n * This cuts down on funny behavior when a point is very close to a\n * contour level.\n */\n for(cnt = 1; cnt < pts.length; cnt++) {\n thisdist = ptDist(pts[cnt], pts[cnt - 1]);\n totaldist += thisdist;\n alldists.push(thisdist);\n }\n\n var distThreshold = totaldist / alldists.length * distThresholdFactor;\n\n function getpt(i) { return pts[i % pts.length]; }\n\n for(cnt = pts.length - 2; cnt >= cropstart; cnt--) {\n distgroup = alldists[cnt];\n if(distgroup < distThreshold) {\n cnt3 = 0;\n for(cnt2 = cnt - 1; cnt2 >= cropstart; cnt2--) {\n if(distgroup + alldists[cnt2] < distThreshold) {\n distgroup += alldists[cnt2];\n } else break;\n }\n\n // closed path with close points wrapping around the boundary?\n if(closedpath && cnt === pts.length - 2) {\n for(cnt3 = 0; cnt3 < cnt2; cnt3++) {\n if(distgroup + alldists[cnt3] < distThreshold) {\n distgroup += alldists[cnt3];\n } else break;\n }\n }\n ptcnt = cnt - cnt2 + cnt3 + 1;\n ptavg = Math.floor((cnt + cnt2 + cnt3 + 2) / 2);\n\n // either endpoint included: keep the endpoint\n if(!closedpath && cnt === pts.length - 2) newpt = pts[pts.length - 1];\n else if(!closedpath && cnt2 === -1) newpt = pts[0];\n\n // odd # of points - just take the central one\n else if(ptcnt % 2) newpt = getpt(ptavg);\n\n // even # of pts - average central two\n else {\n newpt = [(getpt(ptavg)[0] + getpt(ptavg + 1)[0]) / 2,\n (getpt(ptavg)[1] + getpt(ptavg + 1)[1]) / 2];\n }\n\n pts.splice(cnt2 + 1, cnt - cnt2 + 1, newpt);\n cnt = cnt2 + 1;\n if(cnt3) cropstart = cnt3;\n if(closedpath) {\n if(cnt === pts.length - 2) pts[cnt3] = pts[pts.length - 1];\n else if(cnt === 0) pts[pts.length - 1] = pts[0];\n }\n }\n }\n pts.splice(0, cropstart);\n\n // done with the index parts - remove them so path generation works right\n // because it depends on only having [xpx, ypx]\n for(cnt = 0; cnt < pts.length; cnt++) pts[cnt].length = 2;\n\n // don't return single-point paths (ie all points were the same\n // so they got deleted?)\n if(pts.length < 2) return;\n else if(closedpath) {\n pts.pop();\n pi.paths.push(pts);\n } else {\n if(!edgeflag) {\n Lib.log('Unclosed interior contour?',\n pi.level, startLoc.join(','), pts.join('L'));\n }\n\n // edge path - does it start where an existing edge path ends, or vice versa?\n var merged = false;\n for(i = 0; i < pi.edgepaths.length; i++) {\n edgepathi = pi.edgepaths[i];\n if(!merged && equalPts(edgepathi[0], pts[pts.length - 1], xtol, ytol)) {\n pts.pop();\n merged = true;\n\n // now does it ALSO meet the end of another (or the same) path?\n var doublemerged = false;\n for(j = 0; j < pi.edgepaths.length; j++) {\n edgepathj = pi.edgepaths[j];\n if(equalPts(edgepathj[edgepathj.length - 1], pts[0], xtol, ytol)) {\n doublemerged = true;\n pts.shift();\n pi.edgepaths.splice(i, 1);\n if(j === i) {\n // the path is now closed\n pi.paths.push(pts.concat(edgepathj));\n } else {\n if(j > i) j--;\n pi.edgepaths[j] = edgepathj.concat(pts, edgepathi);\n }\n break;\n }\n }\n if(!doublemerged) {\n pi.edgepaths[i] = pts.concat(edgepathi);\n }\n }\n }\n for(i = 0; i < pi.edgepaths.length; i++) {\n if(merged) break;\n edgepathi = pi.edgepaths[i];\n if(equalPts(edgepathi[edgepathi.length - 1], pts[0], xtol, ytol)) {\n pts.shift();\n pi.edgepaths[i] = edgepathi.concat(pts);\n merged = true;\n }\n }\n\n if(!merged) pi.edgepaths.push(pts);\n }\n}\n\n// special function to get the marching step of the\n// first point in the path (leading to loc)\nfunction getStartStep(mi, edgeflag, loc) {\n var dx = 0;\n var dy = 0;\n if(mi > 20 && edgeflag) {\n // these saddles start at +/- x\n if(mi === 208 || mi === 1114) {\n // if we're starting at the left side, we must be going right\n dx = loc[0] === 0 ? 1 : -1;\n } else {\n // if we're starting at the bottom, we must be going up\n dy = loc[1] === 0 ? 1 : -1;\n }\n } else if(constants.BOTTOMSTART.indexOf(mi) !== -1) dy = 1;\n else if(constants.LEFTSTART.indexOf(mi) !== -1) dx = 1;\n else if(constants.TOPSTART.indexOf(mi) !== -1) dy = -1;\n else dx = -1;\n return [dx, dy];\n}\n\n/*\n * Find the pixel coordinates of a particular crossing\n *\n * @param {object} pi: the pathinfo object at this level\n * @param {array} loc: the grid index [x, y] of the crossing\n * @param {array} step: the direction [dx, dy] we're moving on the grid\n *\n * @return {array} [xpx, ypx, xi, yi]: the first two are the pixel location,\n * the next two are the interpolated grid indices, which we use for\n * distance calculations to delete points that are too close together.\n * This is important when the grid is nonuniform (and most dramatically when\n * we're on log axes and include invalid (0 or negative) values.\n * It's crucial to delete these extra two before turning an array of these\n * points into a path, because those routines require length-2 points.\n */\nfunction getInterpPx(pi, loc, step) {\n var locx = loc[0] + Math.max(step[0], 0);\n var locy = loc[1] + Math.max(step[1], 0);\n var zxy = pi.z[locy][locx];\n var xa = pi.xaxis;\n var ya = pi.yaxis;\n\n if(step[1]) {\n var dx = (pi.level - zxy) / (pi.z[locy][locx + 1] - zxy);\n\n return [xa.c2p((1 - dx) * pi.x[locx] + dx * pi.x[locx + 1], true),\n ya.c2p(pi.y[locy], true),\n locx + dx, locy];\n } else {\n var dy = (pi.level - zxy) / (pi.z[locy + 1][locx] - zxy);\n return [xa.c2p(pi.x[locx], true),\n ya.c2p((1 - dy) * pi.y[locy] + dy * pi.y[locy + 1], true),\n locx, locy + dy];\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/find_all_paths.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/hover.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/hover.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\n\nvar heatmapHoverPoints = __webpack_require__(/*! ../heatmap/hover */ \"./node_modules/plotly.js/src/traces/heatmap/hover.js\");\n\nmodule.exports = function hoverPoints(pointData, xval, yval, hovermode, hoverLayer) {\n var hoverData = heatmapHoverPoints(pointData, xval, yval, hovermode, hoverLayer, true);\n\n if(hoverData) {\n hoverData.forEach(function(hoverPt) {\n var trace = hoverPt.trace;\n if(trace.contours.type === 'constraint') {\n if(trace.fillcolor && Color.opacity(trace.fillcolor)) {\n hoverPt.color = Color.addOpacity(trace.fillcolor, 1);\n } else if(trace.contours.showlines && Color.opacity(trace.line.color)) {\n hoverPt.color = Color.addOpacity(trace.line.color, 1);\n }\n }\n });\n }\n\n return hoverData;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/index.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/index.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/contour/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/contour/defaults.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/contour/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/contour/plot.js\").plot,\n style: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/contour/style.js\"),\n colorbar: __webpack_require__(/*! ./colorbar */ \"./node_modules/plotly.js/src/traces/contour/colorbar.js\"),\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/contour/hover.js\"),\n\n moduleType: 'trace',\n name: 'contour',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['cartesian', 'svg', '2dMap', 'contour', 'showLegend'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/label_defaults.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/label_defaults.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nmodule.exports = function handleLabelDefaults(coerce, layout, lineColor, opts) {\n if(!opts) opts = {};\n var showLabels = coerce('contours.showlabels');\n if(showLabels) {\n var globalFont = layout.font;\n Lib.coerceFont(coerce, 'contours.labelfont', {\n family: globalFont.family,\n size: globalFont.size,\n color: lineColor\n });\n coerce('contours.labelformat');\n }\n\n if(opts.hasHover !== false) coerce('zhoverformat');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/label_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/make_color_map.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/make_color_map.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar Colorscale = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\");\nvar endPlus = __webpack_require__(/*! ./end_plus */ \"./node_modules/plotly.js/src/traces/contour/end_plus.js\");\n\nmodule.exports = function makeColorMap(trace) {\n var contours = trace.contours;\n var start = contours.start;\n var end = endPlus(contours);\n var cs = contours.size || 1;\n var nc = Math.floor((end - start) / cs) + 1;\n var extra = contours.coloring === 'lines' ? 0 : 1;\n var cOpts = Colorscale.extractOpts(trace);\n\n if(!isFinite(cs)) {\n cs = 1;\n nc = 1;\n }\n\n var scl = cOpts.reversescale ?\n Colorscale.flipScale(cOpts.colorscale) :\n cOpts.colorscale;\n\n var len = scl.length;\n var domain = new Array(len);\n var range = new Array(len);\n\n var si, i;\n\n if(contours.coloring === 'heatmap') {\n var zmin0 = cOpts.min;\n var zmax0 = cOpts.max;\n\n for(i = 0; i < len; i++) {\n si = scl[i];\n domain[i] = si[0] * (zmax0 - zmin0) + zmin0;\n range[i] = si[1];\n }\n\n // do the contours extend beyond the colorscale?\n // if so, extend the colorscale with constants\n var zRange = d3.extent([\n zmin0,\n zmax0,\n contours.start,\n contours.start + cs * (nc - 1)\n ]);\n var zmin = zRange[zmin0 < zmax0 ? 0 : 1];\n var zmax = zRange[zmin0 < zmax0 ? 1 : 0];\n\n if(zmin !== zmin0) {\n domain.splice(0, 0, zmin);\n range.splice(0, 0, range[0]);\n }\n\n if(zmax !== zmax0) {\n domain.push(zmax);\n range.push(range[range.length - 1]);\n }\n } else {\n for(i = 0; i < len; i++) {\n si = scl[i];\n domain[i] = (si[0] * (nc + extra - 1) - (extra / 2)) * cs + start;\n range[i] = si[1];\n }\n }\n\n return Colorscale.makeColorScaleFunc(\n {domain: domain, range: range},\n {noNumericCheck: true}\n );\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/make_color_map.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/make_crossings.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/make_crossings.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/contour/constants.js\");\n\n// Calculate all the marching indices, for ALL levels at once.\n// since we want to be exhaustive we'll check for contour crossings\n// at every intersection, rather than just following a path\n// TODO: shorten the inner loop to only the relevant levels\nmodule.exports = function makeCrossings(pathinfo) {\n var z = pathinfo[0].z;\n var m = z.length;\n var n = z[0].length; // we already made sure z isn't ragged in interp2d\n var twoWide = m === 2 || n === 2;\n var xi;\n var yi;\n var startIndices;\n var ystartIndices;\n var label;\n var corners;\n var mi;\n var pi;\n var i;\n\n for(yi = 0; yi < m - 1; yi++) {\n ystartIndices = [];\n if(yi === 0) ystartIndices = ystartIndices.concat(constants.BOTTOMSTART);\n if(yi === m - 2) ystartIndices = ystartIndices.concat(constants.TOPSTART);\n\n for(xi = 0; xi < n - 1; xi++) {\n startIndices = ystartIndices.slice();\n if(xi === 0) startIndices = startIndices.concat(constants.LEFTSTART);\n if(xi === n - 2) startIndices = startIndices.concat(constants.RIGHTSTART);\n\n label = xi + ',' + yi;\n corners = [[z[yi][xi], z[yi][xi + 1]],\n [z[yi + 1][xi], z[yi + 1][xi + 1]]];\n for(i = 0; i < pathinfo.length; i++) {\n pi = pathinfo[i];\n mi = getMarchingIndex(pi.level, corners);\n if(!mi) continue;\n\n pi.crossings[label] = mi;\n if(startIndices.indexOf(mi) !== -1) {\n pi.starts.push([xi, yi]);\n if(twoWide && startIndices.indexOf(mi,\n startIndices.indexOf(mi) + 1) !== -1) {\n // the same square has starts from opposite sides\n // it's not possible to have starts on opposite edges\n // of a corner, only a start and an end...\n // but if the array is only two points wide (either way)\n // you can have starts on opposite sides.\n pi.starts.push([xi, yi]);\n }\n }\n }\n }\n }\n};\n\n// modified marching squares algorithm,\n// so we disambiguate the saddle points from the start\n// and we ignore the cases with no crossings\n// the index I'm using is based on:\n// http://en.wikipedia.org/wiki/Marching_squares\n// except that the saddles bifurcate and I represent them\n// as the decimal combination of the two appropriate\n// non-saddle indices\nfunction getMarchingIndex(val, corners) {\n var mi = (corners[0][0] > val ? 0 : 1) +\n (corners[0][1] > val ? 0 : 2) +\n (corners[1][1] > val ? 0 : 4) +\n (corners[1][0] > val ? 0 : 8);\n if(mi === 5 || mi === 10) {\n var avg = (corners[0][0] + corners[0][1] +\n corners[1][0] + corners[1][1]) / 4;\n // two peaks with a big valley\n if(val > avg) return (mi === 5) ? 713 : 1114;\n // two valleys with a big ridge\n return (mi === 5) ? 104 : 208;\n }\n return (mi === 15) ? 0 : mi;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/make_crossings.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/plot.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/plot.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar Colorscale = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\");\nvar svgTextUtils = __webpack_require__(/*! ../../lib/svg_text_utils */ \"./node_modules/plotly.js/src/lib/svg_text_utils.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar setConvert = __webpack_require__(/*! ../../plots/cartesian/set_convert */ \"./node_modules/plotly.js/src/plots/cartesian/set_convert.js\");\n\nvar heatmapPlot = __webpack_require__(/*! ../heatmap/plot */ \"./node_modules/plotly.js/src/traces/heatmap/plot.js\");\nvar makeCrossings = __webpack_require__(/*! ./make_crossings */ \"./node_modules/plotly.js/src/traces/contour/make_crossings.js\");\nvar findAllPaths = __webpack_require__(/*! ./find_all_paths */ \"./node_modules/plotly.js/src/traces/contour/find_all_paths.js\");\nvar emptyPathinfo = __webpack_require__(/*! ./empty_pathinfo */ \"./node_modules/plotly.js/src/traces/contour/empty_pathinfo.js\");\nvar convertToConstraints = __webpack_require__(/*! ./convert_to_constraints */ \"./node_modules/plotly.js/src/traces/contour/convert_to_constraints.js\");\nvar closeBoundaries = __webpack_require__(/*! ./close_boundaries */ \"./node_modules/plotly.js/src/traces/contour/close_boundaries.js\");\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/contour/constants.js\");\nvar costConstants = constants.LABELOPTIMIZER;\n\nexports.plot = function plot(gd, plotinfo, cdcontours, contourLayer) {\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n\n Lib.makeTraceGroups(contourLayer, cdcontours, 'contour').each(function(cd) {\n var plotGroup = d3.select(this);\n var cd0 = cd[0];\n var trace = cd0.trace;\n var x = cd0.x;\n var y = cd0.y;\n var contours = trace.contours;\n var pathinfo = emptyPathinfo(contours, plotinfo, cd0);\n\n // use a heatmap to fill - draw it behind the lines\n var heatmapColoringLayer = Lib.ensureSingle(plotGroup, 'g', 'heatmapcoloring');\n var cdheatmaps = [];\n if(contours.coloring === 'heatmap') {\n cdheatmaps = [cd];\n }\n heatmapPlot(gd, plotinfo, cdheatmaps, heatmapColoringLayer);\n\n makeCrossings(pathinfo);\n findAllPaths(pathinfo);\n\n var leftedge = xa.c2p(x[0], true);\n var rightedge = xa.c2p(x[x.length - 1], true);\n var bottomedge = ya.c2p(y[0], true);\n var topedge = ya.c2p(y[y.length - 1], true);\n var perimeter = [\n [leftedge, topedge],\n [rightedge, topedge],\n [rightedge, bottomedge],\n [leftedge, bottomedge]\n ];\n\n var fillPathinfo = pathinfo;\n if(contours.type === 'constraint') {\n // N.B. this also mutates pathinfo\n fillPathinfo = convertToConstraints(pathinfo, contours._operation);\n }\n\n // draw everything\n makeBackground(plotGroup, perimeter, contours);\n makeFills(plotGroup, fillPathinfo, perimeter, contours);\n makeLinesAndLabels(plotGroup, pathinfo, gd, cd0, contours);\n clipGaps(plotGroup, plotinfo, gd, cd0, perimeter);\n });\n};\n\nfunction makeBackground(plotgroup, perimeter, contours) {\n var bggroup = Lib.ensureSingle(plotgroup, 'g', 'contourbg');\n\n var bgfill = bggroup.selectAll('path')\n .data(contours.coloring === 'fill' ? [0] : []);\n bgfill.enter().append('path');\n bgfill.exit().remove();\n bgfill\n .attr('d', 'M' + perimeter.join('L') + 'Z')\n .style('stroke', 'none');\n}\n\nfunction makeFills(plotgroup, pathinfo, perimeter, contours) {\n var hasFills = contours.coloring === 'fill' || (contours.type === 'constraint' && contours._operation !== '=');\n var boundaryPath = 'M' + perimeter.join('L') + 'Z';\n\n // fills prefixBoundary in pathinfo items\n if(hasFills) {\n closeBoundaries(pathinfo, contours);\n }\n\n var fillgroup = Lib.ensureSingle(plotgroup, 'g', 'contourfill');\n\n var fillitems = fillgroup.selectAll('path').data(hasFills ? pathinfo : []);\n fillitems.enter().append('path');\n fillitems.exit().remove();\n fillitems.each(function(pi) {\n // join all paths for this level together into a single path\n // first follow clockwise around the perimeter to close any open paths\n // if the whole perimeter is above this level, start with a path\n // enclosing the whole thing. With all that, the parity should mean\n // that we always fill everything above the contour, nothing below\n var fullpath = (pi.prefixBoundary ? boundaryPath : '') +\n joinAllPaths(pi, perimeter);\n\n if(!fullpath) {\n d3.select(this).remove();\n } else {\n d3.select(this)\n .attr('d', fullpath)\n .style('stroke', 'none');\n }\n });\n}\n\nfunction joinAllPaths(pi, perimeter) {\n var fullpath = '';\n var i = 0;\n var startsleft = pi.edgepaths.map(function(v, i) { return i; });\n var newloop = true;\n var endpt;\n var newendpt;\n var cnt;\n var nexti;\n var possiblei;\n var addpath;\n\n function istop(pt) { return Math.abs(pt[1] - perimeter[0][1]) < 0.01; }\n function isbottom(pt) { return Math.abs(pt[1] - perimeter[2][1]) < 0.01; }\n function isleft(pt) { return Math.abs(pt[0] - perimeter[0][0]) < 0.01; }\n function isright(pt) { return Math.abs(pt[0] - perimeter[2][0]) < 0.01; }\n\n while(startsleft.length) {\n addpath = Drawing.smoothopen(pi.edgepaths[i], pi.smoothing);\n fullpath += newloop ? addpath : addpath.replace(/^M/, 'L');\n startsleft.splice(startsleft.indexOf(i), 1);\n endpt = pi.edgepaths[i][pi.edgepaths[i].length - 1];\n nexti = -1;\n\n // now loop through sides, moving our endpoint until we find a new start\n for(cnt = 0; cnt < 4; cnt++) { // just to prevent infinite loops\n if(!endpt) {\n Lib.log('Missing end?', i, pi);\n break;\n }\n\n if(istop(endpt) && !isright(endpt)) newendpt = perimeter[1]; // right top\n else if(isleft(endpt)) newendpt = perimeter[0]; // left top\n else if(isbottom(endpt)) newendpt = perimeter[3]; // right bottom\n else if(isright(endpt)) newendpt = perimeter[2]; // left bottom\n\n for(possiblei = 0; possiblei < pi.edgepaths.length; possiblei++) {\n var ptNew = pi.edgepaths[possiblei][0];\n // is ptNew on the (horz. or vert.) segment from endpt to newendpt?\n if(Math.abs(endpt[0] - newendpt[0]) < 0.01) {\n if(Math.abs(endpt[0] - ptNew[0]) < 0.01 &&\n (ptNew[1] - endpt[1]) * (newendpt[1] - ptNew[1]) >= 0) {\n newendpt = ptNew;\n nexti = possiblei;\n }\n } else if(Math.abs(endpt[1] - newendpt[1]) < 0.01) {\n if(Math.abs(endpt[1] - ptNew[1]) < 0.01 &&\n (ptNew[0] - endpt[0]) * (newendpt[0] - ptNew[0]) >= 0) {\n newendpt = ptNew;\n nexti = possiblei;\n }\n } else {\n Lib.log('endpt to newendpt is not vert. or horz.',\n endpt, newendpt, ptNew);\n }\n }\n\n endpt = newendpt;\n\n if(nexti >= 0) break;\n fullpath += 'L' + newendpt;\n }\n\n if(nexti === pi.edgepaths.length) {\n Lib.log('unclosed perimeter path');\n break;\n }\n\n i = nexti;\n\n // if we closed back on a loop we already included,\n // close it and start a new loop\n newloop = (startsleft.indexOf(i) === -1);\n if(newloop) {\n i = startsleft[0];\n fullpath += 'Z';\n }\n }\n\n // finally add the interior paths\n for(i = 0; i < pi.paths.length; i++) {\n fullpath += Drawing.smoothclosed(pi.paths[i], pi.smoothing);\n }\n\n return fullpath;\n}\n\nfunction makeLinesAndLabels(plotgroup, pathinfo, gd, cd0, contours) {\n var lineContainer = Lib.ensureSingle(plotgroup, 'g', 'contourlines');\n var showLines = contours.showlines !== false;\n var showLabels = contours.showlabels;\n var clipLinesForLabels = showLines && showLabels;\n\n // Even if we're not going to show lines, we need to create them\n // if we're showing labels, because the fill paths include the perimeter\n // so can't be used to position the labels correctly.\n // In this case we'll remove the lines after making the labels.\n var linegroup = exports.createLines(lineContainer, showLines || showLabels, pathinfo);\n\n var lineClip = exports.createLineClip(lineContainer, clipLinesForLabels, gd, cd0.trace.uid);\n\n var labelGroup = plotgroup.selectAll('g.contourlabels')\n .data(showLabels ? [0] : []);\n\n labelGroup.exit().remove();\n\n labelGroup.enter().append('g')\n .classed('contourlabels', true);\n\n if(showLabels) {\n var labelClipPathData = [];\n var labelData = [];\n\n // invalidate the getTextLocation cache in case paths changed\n Lib.clearLocationCache();\n\n var contourFormat = exports.labelFormatter(gd, cd0);\n\n var dummyText = Drawing.tester.append('text')\n .attr('data-notex', 1)\n .call(Drawing.font, contours.labelfont);\n\n var xa = pathinfo[0].xaxis;\n var ya = pathinfo[0].yaxis;\n var xLen = xa._length;\n var yLen = ya._length;\n var xRng = xa.range;\n var yRng = ya.range;\n var xMin = Lib.aggNums(Math.min, null, cd0.x);\n var xMax = Lib.aggNums(Math.max, null, cd0.x);\n var yMin = Lib.aggNums(Math.min, null, cd0.y);\n var yMax = Lib.aggNums(Math.max, null, cd0.y);\n var x0 = Math.max(xa.c2p(xMin, true), 0);\n var x1 = Math.min(xa.c2p(xMax, true), xLen);\n var y0 = Math.max(ya.c2p(yMax, true), 0);\n var y1 = Math.min(ya.c2p(yMin, true), yLen);\n\n // visible bounds of the contour trace (and the midpoints, to\n // help with cost calculations)\n var bounds = {};\n\n if(xRng[0] < xRng[1]) {\n bounds.left = x0;\n bounds.right = x1;\n } else {\n bounds.left = x1;\n bounds.right = x0;\n }\n\n if(yRng[0] < yRng[1]) {\n bounds.top = y0;\n bounds.bottom = y1;\n } else {\n bounds.top = y1;\n bounds.bottom = y0;\n }\n\n bounds.middle = (bounds.top + bounds.bottom) / 2;\n bounds.center = (bounds.left + bounds.right) / 2;\n\n labelClipPathData.push([\n [bounds.left, bounds.top],\n [bounds.right, bounds.top],\n [bounds.right, bounds.bottom],\n [bounds.left, bounds.bottom]\n ]);\n\n var plotDiagonal = Math.sqrt(xLen * xLen + yLen * yLen);\n\n // the path length to use to scale the number of labels to draw:\n var normLength = constants.LABELDISTANCE * plotDiagonal /\n Math.max(1, pathinfo.length / constants.LABELINCREASE);\n\n linegroup.each(function(d) {\n var textOpts = exports.calcTextOpts(d.level, contourFormat, dummyText, gd);\n\n d3.select(this).selectAll('path').each(function() {\n var path = this;\n var pathBounds = Lib.getVisibleSegment(path, bounds, textOpts.height / 2);\n if(!pathBounds) return;\n\n if(pathBounds.len < (textOpts.width + textOpts.height) * constants.LABELMIN) return;\n\n var maxLabels = Math.min(Math.ceil(pathBounds.len / normLength),\n constants.LABELMAX);\n\n for(var i = 0; i < maxLabels; i++) {\n var loc = exports.findBestTextLocation(path, pathBounds, textOpts,\n labelData, bounds);\n\n if(!loc) break;\n\n exports.addLabelData(loc, textOpts, labelData, labelClipPathData);\n }\n });\n });\n\n dummyText.remove();\n\n exports.drawLabels(labelGroup, labelData, gd, lineClip,\n clipLinesForLabels ? labelClipPathData : null);\n }\n\n if(showLabels && !showLines) linegroup.remove();\n}\n\nexports.createLines = function(lineContainer, makeLines, pathinfo) {\n var smoothing = pathinfo[0].smoothing;\n\n var linegroup = lineContainer.selectAll('g.contourlevel')\n .data(makeLines ? pathinfo : []);\n\n linegroup.exit().remove();\n linegroup.enter().append('g')\n .classed('contourlevel', true);\n\n if(makeLines) {\n // pedgepaths / ppaths are used by contourcarpet, for the paths transformed from a/b to x/y\n // edgepaths / paths are used by contour since it's in x/y from the start\n var opencontourlines = linegroup.selectAll('path.openline')\n .data(function(d) { return d.pedgepaths || d.edgepaths; });\n\n opencontourlines.exit().remove();\n opencontourlines.enter().append('path')\n .classed('openline', true);\n\n opencontourlines\n .attr('d', function(d) {\n return Drawing.smoothopen(d, smoothing);\n })\n .style('stroke-miterlimit', 1)\n .style('vector-effect', 'non-scaling-stroke');\n\n var closedcontourlines = linegroup.selectAll('path.closedline')\n .data(function(d) { return d.ppaths || d.paths; });\n\n closedcontourlines.exit().remove();\n closedcontourlines.enter().append('path')\n .classed('closedline', true);\n\n closedcontourlines\n .attr('d', function(d) {\n return Drawing.smoothclosed(d, smoothing);\n })\n .style('stroke-miterlimit', 1)\n .style('vector-effect', 'non-scaling-stroke');\n }\n\n return linegroup;\n};\n\nexports.createLineClip = function(lineContainer, clipLinesForLabels, gd, uid) {\n var clips = gd._fullLayout._clips;\n var clipId = clipLinesForLabels ? ('clipline' + uid) : null;\n\n var lineClip = clips.selectAll('#' + clipId)\n .data(clipLinesForLabels ? [0] : []);\n lineClip.exit().remove();\n\n lineClip.enter().append('clipPath')\n .classed('contourlineclip', true)\n .attr('id', clipId);\n\n Drawing.setClipUrl(lineContainer, clipId, gd);\n\n return lineClip;\n};\n\nexports.labelFormatter = function(gd, cd0) {\n var fullLayout = gd._fullLayout;\n var trace = cd0.trace;\n var contours = trace.contours;\n\n if(contours.labelformat) {\n return fullLayout._d3locale.numberFormat(contours.labelformat);\n } else {\n var formatAxis;\n var cOpts = Colorscale.extractOpts(trace);\n if(cOpts && cOpts.colorbar && cOpts.colorbar._axis) {\n formatAxis = cOpts.colorbar._axis;\n } else {\n formatAxis = {\n type: 'linear',\n _id: 'ycontour',\n showexponent: 'all',\n exponentformat: 'B'\n };\n\n if(contours.type === 'constraint') {\n var value = contours.value;\n if(Array.isArray(value)) {\n formatAxis.range = [value[0], value[value.length - 1]];\n } else formatAxis.range = [value, value];\n } else {\n formatAxis.range = [contours.start, contours.end];\n formatAxis.nticks = (contours.end - contours.start) / contours.size;\n }\n\n if(formatAxis.range[0] === formatAxis.range[1]) {\n formatAxis.range[1] += formatAxis.range[0] || 1;\n }\n if(!formatAxis.nticks) formatAxis.nticks = 1000;\n\n setConvert(formatAxis, fullLayout);\n Axes.prepTicks(formatAxis);\n formatAxis._tmin = null;\n formatAxis._tmax = null;\n }\n return function(v) {\n return Axes.tickText(formatAxis, v).text;\n };\n }\n};\n\nexports.calcTextOpts = function(level, contourFormat, dummyText, gd) {\n var text = contourFormat(level);\n dummyText.text(text)\n .call(svgTextUtils.convertToTspans, gd);\n var bBox = Drawing.bBox(dummyText.node(), true);\n\n return {\n text: text,\n width: bBox.width,\n height: bBox.height,\n level: level,\n dy: (bBox.top + bBox.bottom) / 2\n };\n};\n\nexports.findBestTextLocation = function(path, pathBounds, textOpts, labelData, plotBounds) {\n var textWidth = textOpts.width;\n\n var p0, dp, pMax, pMin, loc;\n if(pathBounds.isClosed) {\n dp = pathBounds.len / costConstants.INITIALSEARCHPOINTS;\n p0 = pathBounds.min + dp / 2;\n pMax = pathBounds.max;\n } else {\n dp = (pathBounds.len - textWidth) / (costConstants.INITIALSEARCHPOINTS + 1);\n p0 = pathBounds.min + dp + textWidth / 2;\n pMax = pathBounds.max - (dp + textWidth) / 2;\n }\n\n var cost = Infinity;\n for(var j = 0; j < costConstants.ITERATIONS; j++) {\n for(var p = p0; p < pMax; p += dp) {\n var newLocation = Lib.getTextLocation(path, pathBounds.total, p, textWidth);\n var newCost = locationCost(newLocation, textOpts, labelData, plotBounds);\n if(newCost < cost) {\n cost = newCost;\n loc = newLocation;\n pMin = p;\n }\n }\n if(cost > costConstants.MAXCOST * 2) break;\n\n // subsequent iterations just look half steps away from the\n // best we found in the previous iteration\n if(j) dp /= 2;\n p0 = pMin - dp / 2;\n pMax = p0 + dp * 1.5;\n }\n if(cost <= costConstants.MAXCOST) return loc;\n};\n\n/*\n * locationCost: a cost function for label locations\n * composed of three kinds of penalty:\n * - for open paths, being close to the end of the path\n * - the angle away from horizontal\n * - being too close to already placed neighbors\n */\nfunction locationCost(loc, textOpts, labelData, bounds) {\n var halfWidth = textOpts.width / 2;\n var halfHeight = textOpts.height / 2;\n var x = loc.x;\n var y = loc.y;\n var theta = loc.theta;\n var dx = Math.cos(theta) * halfWidth;\n var dy = Math.sin(theta) * halfWidth;\n\n // cost for being near an edge\n var normX = ((x > bounds.center) ? (bounds.right - x) : (x - bounds.left)) /\n (dx + Math.abs(Math.sin(theta) * halfHeight));\n var normY = ((y > bounds.middle) ? (bounds.bottom - y) : (y - bounds.top)) /\n (Math.abs(dy) + Math.cos(theta) * halfHeight);\n if(normX < 1 || normY < 1) return Infinity;\n var cost = costConstants.EDGECOST * (1 / (normX - 1) + 1 / (normY - 1));\n\n // cost for not being horizontal\n cost += costConstants.ANGLECOST * theta * theta;\n\n // cost for being close to other labels\n var x1 = x - dx;\n var y1 = y - dy;\n var x2 = x + dx;\n var y2 = y + dy;\n for(var i = 0; i < labelData.length; i++) {\n var labeli = labelData[i];\n var dxd = Math.cos(labeli.theta) * labeli.width / 2;\n var dyd = Math.sin(labeli.theta) * labeli.width / 2;\n var dist = Lib.segmentDistance(\n x1, y1,\n x2, y2,\n labeli.x - dxd, labeli.y - dyd,\n labeli.x + dxd, labeli.y + dyd\n ) * 2 / (textOpts.height + labeli.height);\n\n var sameLevel = labeli.level === textOpts.level;\n var distOffset = sameLevel ? costConstants.SAMELEVELDISTANCE : 1;\n\n if(dist <= distOffset) return Infinity;\n\n var distFactor = costConstants.NEIGHBORCOST *\n (sameLevel ? costConstants.SAMELEVELFACTOR : 1);\n\n cost += distFactor / (dist - distOffset);\n }\n\n return cost;\n}\n\nexports.addLabelData = function(loc, textOpts, labelData, labelClipPathData) {\n var halfWidth = textOpts.width / 2;\n var halfHeight = textOpts.height / 2;\n\n var x = loc.x;\n var y = loc.y;\n var theta = loc.theta;\n\n var sin = Math.sin(theta);\n var cos = Math.cos(theta);\n var dxw = halfWidth * cos;\n var dxh = halfHeight * sin;\n var dyw = halfWidth * sin;\n var dyh = -halfHeight * cos;\n var bBoxPts = [\n [x - dxw - dxh, y - dyw - dyh],\n [x + dxw - dxh, y + dyw - dyh],\n [x + dxw + dxh, y + dyw + dyh],\n [x - dxw + dxh, y - dyw + dyh],\n ];\n\n labelData.push({\n text: textOpts.text,\n x: x,\n y: y,\n dy: textOpts.dy,\n theta: theta,\n level: textOpts.level,\n width: textOpts.width,\n height: textOpts.height\n });\n\n labelClipPathData.push(bBoxPts);\n};\n\nexports.drawLabels = function(labelGroup, labelData, gd, lineClip, labelClipPathData) {\n var labels = labelGroup.selectAll('text')\n .data(labelData, function(d) {\n return d.text + ',' + d.x + ',' + d.y + ',' + d.theta;\n });\n\n labels.exit().remove();\n\n labels.enter().append('text')\n .attr({\n 'data-notex': 1,\n 'text-anchor': 'middle'\n })\n .each(function(d) {\n var x = d.x + Math.sin(d.theta) * d.dy;\n var y = d.y - Math.cos(d.theta) * d.dy;\n d3.select(this)\n .text(d.text)\n .attr({\n x: x,\n y: y,\n transform: 'rotate(' + (180 * d.theta / Math.PI) + ' ' + x + ' ' + y + ')'\n })\n .call(svgTextUtils.convertToTspans, gd);\n });\n\n if(labelClipPathData) {\n var clipPath = '';\n for(var i = 0; i < labelClipPathData.length; i++) {\n clipPath += 'M' + labelClipPathData[i].join('L') + 'Z';\n }\n\n var lineClipPath = Lib.ensureSingle(lineClip, 'path', '');\n lineClipPath.attr('d', clipPath);\n }\n};\n\nfunction clipGaps(plotGroup, plotinfo, gd, cd0, perimeter) {\n var trace = cd0.trace;\n var clips = gd._fullLayout._clips;\n var clipId = 'clip' + trace.uid;\n\n var clipPath = clips.selectAll('#' + clipId)\n .data(trace.connectgaps ? [] : [0]);\n clipPath.enter().append('clipPath')\n .classed('contourclip', true)\n .attr('id', clipId);\n clipPath.exit().remove();\n\n if(trace.connectgaps === false) {\n var clipPathInfo = {\n // fraction of the way from missing to present point\n // to draw the boundary.\n // if you make this 1 (or 1-epsilon) then a point in\n // a sea of missing data will disappear entirely.\n level: 0.9,\n crossings: {},\n starts: [],\n edgepaths: [],\n paths: [],\n xaxis: plotinfo.xaxis,\n yaxis: plotinfo.yaxis,\n x: cd0.x,\n y: cd0.y,\n // 0 = no data, 1 = data\n z: makeClipMask(cd0),\n smoothing: 0\n };\n\n makeCrossings([clipPathInfo]);\n findAllPaths([clipPathInfo]);\n closeBoundaries([clipPathInfo], {type: 'levels'});\n\n var path = Lib.ensureSingle(clipPath, 'path', '');\n path.attr('d',\n (clipPathInfo.prefixBoundary ? 'M' + perimeter.join('L') + 'Z' : '') +\n joinAllPaths(clipPathInfo, perimeter)\n );\n } else clipId = null;\n\n Drawing.setClipUrl(plotGroup, clipId, gd);\n}\n\nfunction makeClipMask(cd0) {\n var empties = cd0.trace._emptypoints;\n var z = [];\n var m = cd0.z.length;\n var n = cd0.z[0].length;\n var i;\n var row = [];\n var emptyPoint;\n\n for(i = 0; i < n; i++) row.push(1);\n for(i = 0; i < m; i++) z.push(row.slice());\n for(i = 0; i < empties.length; i++) {\n emptyPoint = empties[i];\n z[emptyPoint[0]][emptyPoint[1]] = 0;\n }\n // save this mask to determine whether to show this data in hover\n cd0.zmask = z;\n return z;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/set_contours.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/set_contours.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nmodule.exports = function setContours(trace, vals) {\n var contours = trace.contours;\n\n // check if we need to auto-choose contour levels\n if(trace.autocontour) {\n // N.B. do not try to use coloraxis cmin/cmax,\n // these values here are meant to remain \"per-trace\" for now\n var zmin = trace.zmin;\n var zmax = trace.zmax;\n if(trace.zauto || zmin === undefined) {\n zmin = Lib.aggNums(Math.min, null, vals);\n }\n if(trace.zauto || zmax === undefined) {\n zmax = Lib.aggNums(Math.max, null, vals);\n }\n\n var dummyAx = autoContours(zmin, zmax, trace.ncontours);\n contours.size = dummyAx.dtick;\n contours.start = Axes.tickFirst(dummyAx);\n dummyAx.range.reverse();\n contours.end = Axes.tickFirst(dummyAx);\n\n if(contours.start === zmin) contours.start += contours.size;\n if(contours.end === zmax) contours.end -= contours.size;\n\n // if you set a small ncontours, *and* the ends are exactly on zmin/zmax\n // there's an edge case where start > end now. Make sure there's at least\n // one meaningful contour, put it midway between the crossed values\n if(contours.start > contours.end) {\n contours.start = contours.end = (contours.start + contours.end) / 2;\n }\n\n // copy auto-contour info back to the source data.\n // previously we copied the whole contours object back, but that had\n // other info (coloring, showlines) that should be left to supplyDefaults\n if(!trace._input.contours) trace._input.contours = {};\n Lib.extendFlat(trace._input.contours, {\n start: contours.start,\n end: contours.end,\n size: contours.size\n });\n trace._input.autocontour = true;\n } else if(contours.type !== 'constraint') {\n // sanity checks on manually-supplied start/end/size\n var start = contours.start;\n var end = contours.end;\n var inputContours = trace._input.contours;\n\n if(start > end) {\n contours.start = inputContours.start = end;\n end = contours.end = inputContours.end = start;\n start = contours.start;\n }\n\n if(!(contours.size > 0)) {\n var sizeOut;\n if(start === end) sizeOut = 1;\n else sizeOut = autoContours(start, end, trace.ncontours).dtick;\n\n inputContours.size = contours.size = sizeOut;\n }\n }\n};\n\n\n/*\n * autoContours: make a dummy axis object with dtick we can use\n * as contours.size, and if needed we can use Axes.tickFirst\n * with this axis object to calculate the start and end too\n *\n * start: the value to start the contours at\n * end: the value to end at (must be > start)\n * ncontours: max number of contours to make, like roughDTick\n *\n * returns: an axis object\n */\nfunction autoContours(start, end, ncontours) {\n var dummyAx = {\n type: 'linear',\n range: [start, end]\n };\n\n Axes.autoTicks(\n dummyAx,\n (end - start) / (ncontours || 15)\n );\n\n return dummyAx;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/set_contours.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/style.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/style.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar heatmapStyle = __webpack_require__(/*! ../heatmap/style */ \"./node_modules/plotly.js/src/traces/heatmap/style.js\");\n\nvar makeColorMap = __webpack_require__(/*! ./make_color_map */ \"./node_modules/plotly.js/src/traces/contour/make_color_map.js\");\n\n\nmodule.exports = function style(gd) {\n var contours = d3.select(gd).selectAll('g.contour');\n\n contours.style('opacity', function(d) {\n return d[0].trace.opacity;\n });\n\n contours.each(function(d) {\n var c = d3.select(this);\n var trace = d[0].trace;\n var contours = trace.contours;\n var line = trace.line;\n var cs = contours.size || 1;\n var start = contours.start;\n\n // for contourcarpet only - is this a constraint-type contour trace?\n var isConstraintType = contours.type === 'constraint';\n var colorLines = !isConstraintType && contours.coloring === 'lines';\n var colorFills = !isConstraintType && contours.coloring === 'fill';\n\n var colorMap = (colorLines || colorFills) ? makeColorMap(trace) : null;\n\n c.selectAll('g.contourlevel').each(function(d) {\n d3.select(this).selectAll('path')\n .call(Drawing.lineGroupStyle,\n line.width,\n colorLines ? colorMap(d.level) : line.color,\n line.dash);\n });\n\n var labelFont = contours.labelfont;\n c.selectAll('g.contourlabels text').each(function(d) {\n Drawing.font(d3.select(this), {\n family: labelFont.family,\n size: labelFont.size,\n color: labelFont.color || (colorLines ? colorMap(d.level) : line.color)\n });\n });\n\n if(isConstraintType) {\n c.selectAll('g.contourfill path')\n .style('fill', trace.fillcolor);\n } else if(colorFills) {\n var firstFill;\n\n c.selectAll('g.contourfill path')\n .style('fill', function(d) {\n if(firstFill === undefined) firstFill = d.level;\n return colorMap(d.level + 0.5 * cs);\n });\n\n if(firstFill === undefined) firstFill = start;\n\n c.selectAll('g.contourbg path')\n .style('fill', colorMap(firstFill - 0.5 * cs));\n }\n });\n\n heatmapStyle(gd);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contour/style_defaults.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contour/style_defaults.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar colorscaleDefaults = __webpack_require__(/*! ../../components/colorscale/defaults */ \"./node_modules/plotly.js/src/components/colorscale/defaults.js\");\nvar handleLabelDefaults = __webpack_require__(/*! ./label_defaults */ \"./node_modules/plotly.js/src/traces/contour/label_defaults.js\");\n\n\nmodule.exports = function handleStyleDefaults(traceIn, traceOut, coerce, layout, opts) {\n var coloring = coerce('contours.coloring');\n\n var showLines;\n var lineColor = '';\n if(coloring === 'fill') showLines = coerce('contours.showlines');\n\n if(showLines !== false) {\n if(coloring !== 'lines') lineColor = coerce('line.color', '#000');\n coerce('line.width', 0.5);\n coerce('line.dash');\n }\n\n if(coloring !== 'none') {\n // plots/plots always coerces showlegend to true, but in this case\n // we default to false and (by default) show a colorbar instead\n if(traceIn.showlegend !== true) traceOut.showlegend = false;\n traceOut._dfltShowLegend = false;\n\n colorscaleDefaults(\n traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'z'}\n );\n }\n\n coerce('line.smoothing');\n\n handleLabelDefaults(coerce, layout, lineColor, opts);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contour/style_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contourcarpet/attributes.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contourcarpet/attributes.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar heatmapAttrs = __webpack_require__(/*! ../heatmap/attributes */ \"./node_modules/plotly.js/src/traces/heatmap/attributes.js\");\nvar contourAttrs = __webpack_require__(/*! ../contour/attributes */ \"./node_modules/plotly.js/src/traces/contour/attributes.js\");\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nvar contourContourAttrs = contourAttrs.contours;\n\nmodule.exports = extendFlat({\n carpet: {\n valType: 'string',\n \n editType: 'calc',\n \n },\n z: heatmapAttrs.z,\n a: heatmapAttrs.x,\n a0: heatmapAttrs.x0,\n da: heatmapAttrs.dx,\n b: heatmapAttrs.y,\n b0: heatmapAttrs.y0,\n db: heatmapAttrs.dy,\n text: heatmapAttrs.text,\n hovertext: heatmapAttrs.hovertext,\n transpose: heatmapAttrs.transpose,\n atype: heatmapAttrs.xtype,\n btype: heatmapAttrs.ytype,\n\n fillcolor: contourAttrs.fillcolor,\n\n autocontour: contourAttrs.autocontour,\n ncontours: contourAttrs.ncontours,\n\n contours: {\n type: contourContourAttrs.type,\n start: contourContourAttrs.start,\n end: contourContourAttrs.end,\n size: contourContourAttrs.size,\n coloring: {\n // from contourAttrs.contours.coloring but no 'heatmap' option\n valType: 'enumerated',\n values: ['fill', 'lines', 'none'],\n dflt: 'fill',\n \n editType: 'calc',\n \n },\n showlines: contourContourAttrs.showlines,\n showlabels: contourContourAttrs.showlabels,\n labelfont: contourContourAttrs.labelfont,\n labelformat: contourContourAttrs.labelformat,\n operation: contourContourAttrs.operation,\n value: contourContourAttrs.value,\n editType: 'calc',\n impliedEdits: {'autocontour': false}\n },\n\n line: {\n color: contourAttrs.line.color,\n width: contourAttrs.line.width,\n dash: contourAttrs.line.dash,\n smoothing: contourAttrs.line.smoothing,\n editType: 'plot'\n },\n\n transforms: undefined\n},\n\n colorScaleAttrs('', {\n cLetter: 'z',\n autoColorDflt: false\n })\n);\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contourcarpet/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contourcarpet/calc.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contourcarpet/calc.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar colorscaleCalc = __webpack_require__(/*! ../../components/colorscale/calc */ \"./node_modules/plotly.js/src/components/colorscale/calc.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar convertColumnData = __webpack_require__(/*! ../heatmap/convert_column_xyz */ \"./node_modules/plotly.js/src/traces/heatmap/convert_column_xyz.js\");\nvar clean2dArray = __webpack_require__(/*! ../heatmap/clean_2d_array */ \"./node_modules/plotly.js/src/traces/heatmap/clean_2d_array.js\");\nvar interp2d = __webpack_require__(/*! ../heatmap/interp2d */ \"./node_modules/plotly.js/src/traces/heatmap/interp2d.js\");\nvar findEmpties = __webpack_require__(/*! ../heatmap/find_empties */ \"./node_modules/plotly.js/src/traces/heatmap/find_empties.js\");\nvar makeBoundArray = __webpack_require__(/*! ../heatmap/make_bound_array */ \"./node_modules/plotly.js/src/traces/heatmap/make_bound_array.js\");\nvar supplyDefaults = __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/contourcarpet/defaults.js\");\nvar lookupCarpet = __webpack_require__(/*! ../carpet/lookup_carpetid */ \"./node_modules/plotly.js/src/traces/carpet/lookup_carpetid.js\");\nvar setContours = __webpack_require__(/*! ../contour/set_contours */ \"./node_modules/plotly.js/src/traces/contour/set_contours.js\");\n\n// most is the same as heatmap calc, then adjust it\n// though a few things inside heatmap calc still look for\n// contour maps, because the makeBoundArray calls are too entangled\nmodule.exports = function calc(gd, trace) {\n var carpet = trace._carpetTrace = lookupCarpet(gd, trace);\n if(!carpet || !carpet.visible || carpet.visible === 'legendonly') return;\n\n if(!trace.a || !trace.b) {\n // Look up the original incoming carpet data:\n var carpetdata = gd.data[carpet.index];\n\n // Look up the incoming trace data, *except* perform a shallow\n // copy so that we're not actually modifying it when we use it\n // to supply defaults:\n var tracedata = gd.data[trace.index];\n // var tracedata = extendFlat({}, gd.data[trace.index]);\n\n // If the data is not specified\n if(!tracedata.a) tracedata.a = carpetdata.a;\n if(!tracedata.b) tracedata.b = carpetdata.b;\n\n supplyDefaults(tracedata, trace, trace._defaultColor, gd._fullLayout);\n }\n\n var cd = heatmappishCalc(gd, trace);\n setContours(trace, trace._z);\n\n return cd;\n};\n\nfunction heatmappishCalc(gd, trace) {\n // prepare the raw data\n // run makeCalcdata on x and y even for heatmaps, in case of category mappings\n var carpet = trace._carpetTrace;\n var aax = carpet.aaxis;\n var bax = carpet.baxis;\n var a,\n a0,\n da,\n b,\n b0,\n db,\n z;\n\n // cancel minimum tick spacings (only applies to bars and boxes)\n aax._minDtick = 0;\n bax._minDtick = 0;\n\n if(Lib.isArray1D(trace.z)) convertColumnData(trace, aax, bax, 'a', 'b', ['z']);\n a = trace._a = trace._a || trace.a;\n b = trace._b = trace._b || trace.b;\n\n a = a ? aax.makeCalcdata(trace, '_a') : [];\n b = b ? bax.makeCalcdata(trace, '_b') : [];\n a0 = trace.a0 || 0;\n da = trace.da || 1;\n b0 = trace.b0 || 0;\n db = trace.db || 1;\n\n z = trace._z = clean2dArray(trace._z || trace.z, trace.transpose);\n\n trace._emptypoints = findEmpties(z);\n interp2d(z, trace._emptypoints);\n\n // create arrays of brick boundaries, to be used by autorange and heatmap.plot\n var xlen = Lib.maxRowLength(z);\n var xIn = trace.xtype === 'scaled' ? '' : a;\n var xArray = makeBoundArray(trace, xIn, a0, da, xlen, aax);\n var yIn = trace.ytype === 'scaled' ? '' : b;\n var yArray = makeBoundArray(trace, yIn, b0, db, z.length, bax);\n\n var cd0 = {\n a: xArray,\n b: yArray,\n z: z,\n };\n\n if(trace.contours.type === 'levels' && trace.contours.coloring !== 'none') {\n // auto-z and autocolorscale if applicable\n colorscaleCalc(gd, trace, {\n vals: z,\n containerStr: '',\n cLetter: 'z'\n });\n }\n\n return [cd0];\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contourcarpet/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contourcarpet/defaults.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contourcarpet/defaults.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar handleXYZDefaults = __webpack_require__(/*! ../heatmap/xyz_defaults */ \"./node_modules/plotly.js/src/traces/heatmap/xyz_defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/contourcarpet/attributes.js\");\nvar handleConstraintDefaults = __webpack_require__(/*! ../contour/constraint_defaults */ \"./node_modules/plotly.js/src/traces/contour/constraint_defaults.js\");\nvar handleContoursDefaults = __webpack_require__(/*! ../contour/contours_defaults */ \"./node_modules/plotly.js/src/traces/contour/contours_defaults.js\");\nvar handleStyleDefaults = __webpack_require__(/*! ../contour/style_defaults */ \"./node_modules/plotly.js/src/traces/contour/style_defaults.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n function coerce2(attr) {\n return Lib.coerce2(traceIn, traceOut, attributes, attr);\n }\n\n coerce('carpet');\n\n // If either a or b is not present, then it's not a valid trace *unless* the carpet\n // axis has the a or b values we're looking for. So if these are not found, just defer\n // that decision until the calc step.\n //\n // NB: the calc step will modify the original data input by assigning whichever of\n // a or b are missing. This is necessary because panning goes right from supplyDefaults\n // to plot (skipping calc). That means on subsequent updates, this *will* need to be\n // able to find a and b.\n //\n // The long-term proper fix is that this should perhaps use underscored attributes to\n // at least modify the user input to a slightly lesser extent. Fully removing the\n // input mutation is challenging. The underscore approach is not currently taken since\n // it requires modification to all of the functions below that expect the coerced\n // attribute name to match the property name -- except '_a' !== 'a' so that is not\n // straightforward.\n if(traceIn.a && traceIn.b) {\n var len = handleXYZDefaults(traceIn, traceOut, coerce, layout, 'a', 'b');\n\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n coerce('text');\n var isConstraint = (coerce('contours.type') === 'constraint');\n\n if(isConstraint) {\n handleConstraintDefaults(traceIn, traceOut, coerce, layout, defaultColor, {hasHover: false});\n } else {\n handleContoursDefaults(traceIn, traceOut, coerce, coerce2);\n handleStyleDefaults(traceIn, traceOut, coerce, layout, {hasHover: false});\n }\n } else {\n traceOut._defaultColor = defaultColor;\n traceOut._length = null;\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contourcarpet/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contourcarpet/index.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contourcarpet/index.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/contourcarpet/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/contourcarpet/defaults.js\"),\n colorbar: __webpack_require__(/*! ../contour/colorbar */ \"./node_modules/plotly.js/src/traces/contour/colorbar.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/contourcarpet/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/contourcarpet/plot.js\"),\n style: __webpack_require__(/*! ../contour/style */ \"./node_modules/plotly.js/src/traces/contour/style.js\"),\n\n moduleType: 'trace',\n name: 'contourcarpet',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['cartesian', 'svg', 'carpet', 'contour', 'symbols', 'showLegend', 'hasLines', 'carpetDependent', 'noHover', 'noSortingByValue'],\n meta: {\n \n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contourcarpet/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/contourcarpet/plot.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/contourcarpet/plot.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar map1dArray = __webpack_require__(/*! ../carpet/map_1d_array */ \"./node_modules/plotly.js/src/traces/carpet/map_1d_array.js\");\nvar makepath = __webpack_require__(/*! ../carpet/makepath */ \"./node_modules/plotly.js/src/traces/carpet/makepath.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar makeCrossings = __webpack_require__(/*! ../contour/make_crossings */ \"./node_modules/plotly.js/src/traces/contour/make_crossings.js\");\nvar findAllPaths = __webpack_require__(/*! ../contour/find_all_paths */ \"./node_modules/plotly.js/src/traces/contour/find_all_paths.js\");\nvar contourPlot = __webpack_require__(/*! ../contour/plot */ \"./node_modules/plotly.js/src/traces/contour/plot.js\");\nvar constants = __webpack_require__(/*! ../contour/constants */ \"./node_modules/plotly.js/src/traces/contour/constants.js\");\nvar convertToConstraints = __webpack_require__(/*! ../contour/convert_to_constraints */ \"./node_modules/plotly.js/src/traces/contour/convert_to_constraints.js\");\nvar emptyPathinfo = __webpack_require__(/*! ../contour/empty_pathinfo */ \"./node_modules/plotly.js/src/traces/contour/empty_pathinfo.js\");\nvar closeBoundaries = __webpack_require__(/*! ../contour/close_boundaries */ \"./node_modules/plotly.js/src/traces/contour/close_boundaries.js\");\nvar lookupCarpet = __webpack_require__(/*! ../carpet/lookup_carpetid */ \"./node_modules/plotly.js/src/traces/carpet/lookup_carpetid.js\");\nvar axisAlignedLine = __webpack_require__(/*! ../carpet/axis_aligned_line */ \"./node_modules/plotly.js/src/traces/carpet/axis_aligned_line.js\");\n\nmodule.exports = function plot(gd, plotinfo, cdcontours, contourcarpetLayer) {\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n\n Lib.makeTraceGroups(contourcarpetLayer, cdcontours, 'contour').each(function(cd) {\n var plotGroup = d3.select(this);\n var cd0 = cd[0];\n var trace = cd0.trace;\n\n var carpet = trace._carpetTrace = lookupCarpet(gd, trace);\n var carpetcd = gd.calcdata[carpet.index][0];\n\n if(!carpet.visible || carpet.visible === 'legendonly') return;\n\n var a = cd0.a;\n var b = cd0.b;\n var contours = trace.contours;\n var pathinfo = emptyPathinfo(contours, plotinfo, cd0);\n var isConstraint = contours.type === 'constraint';\n var operation = contours._operation;\n var coloring = isConstraint ? (operation === '=' ? 'lines' : 'fill') : contours.coloring;\n\n // Map [a, b] (data) --> [i, j] (pixels)\n function ab2p(ab) {\n var pt = carpet.ab2xy(ab[0], ab[1], true);\n return [xa.c2p(pt[0]), ya.c2p(pt[1])];\n }\n\n // Define the perimeter in a/b coordinates:\n var perimeter = [\n [a[0], b[b.length - 1]],\n [a[a.length - 1], b[b.length - 1]],\n [a[a.length - 1], b[0]],\n [a[0], b[0]]\n ];\n\n // Extract the contour levels:\n makeCrossings(pathinfo);\n var atol = (a[a.length - 1] - a[0]) * 1e-8;\n var btol = (b[b.length - 1] - b[0]) * 1e-8;\n findAllPaths(pathinfo, atol, btol);\n\n // Constraints might need to be draw inverted, which is not something contours\n // handle by default since they're assumed fully opaque so that they can be\n // drawn overlapping. This function flips the paths as necessary so that they're\n // drawn correctly.\n //\n // TODO: Perhaps this should be generalized and *all* paths should be drawn as\n // closed regions so that translucent contour levels would be valid.\n // See: https://github.com/plotly/plotly.js/issues/1356\n var fillPathinfo = pathinfo;\n if(contours.type === 'constraint') {\n fillPathinfo = convertToConstraints(pathinfo, operation);\n }\n\n // Map the paths in a/b coordinates to pixel coordinates:\n mapPathinfo(pathinfo, ab2p);\n\n // draw everything\n\n // Compute the boundary path\n var seg, xp, yp, i;\n var segs = [];\n for(i = carpetcd.clipsegments.length - 1; i >= 0; i--) {\n seg = carpetcd.clipsegments[i];\n xp = map1dArray([], seg.x, xa.c2p);\n yp = map1dArray([], seg.y, ya.c2p);\n xp.reverse();\n yp.reverse();\n segs.push(makepath(xp, yp, seg.bicubic));\n }\n\n var boundaryPath = 'M' + segs.join('L') + 'Z';\n\n // Draw the baseline background fill that fills in the space behind any other\n // contour levels:\n makeBackground(plotGroup, carpetcd.clipsegments, xa, ya, isConstraint, coloring);\n\n // Draw the specific contour fills. As a simplification, they're assumed to be\n // fully opaque so that it's easy to draw them simply overlapping. The alternative\n // would be to flip adjacent paths and draw closed paths for each level instead.\n makeFills(trace, plotGroup, xa, ya, fillPathinfo, perimeter, ab2p, carpet, carpetcd, coloring, boundaryPath);\n\n // Draw contour lines:\n makeLinesAndLabels(plotGroup, pathinfo, gd, cd0, contours, plotinfo, carpet);\n\n // Clip the boundary of the plot\n Drawing.setClipUrl(plotGroup, carpet._clipPathId, gd);\n });\n};\n\nfunction mapPathinfo(pathinfo, map) {\n var i, j, k, pi, pedgepaths, ppaths, pedgepath, ppath, path;\n\n for(i = 0; i < pathinfo.length; i++) {\n pi = pathinfo[i];\n pedgepaths = pi.pedgepaths = [];\n ppaths = pi.ppaths = [];\n for(j = 0; j < pi.edgepaths.length; j++) {\n path = pi.edgepaths[j];\n pedgepath = [];\n for(k = 0; k < path.length; k++) {\n pedgepath[k] = map(path[k]);\n }\n pedgepaths.push(pedgepath);\n }\n for(j = 0; j < pi.paths.length; j++) {\n path = pi.paths[j];\n ppath = [];\n for(k = 0; k < path.length; k++) {\n ppath[k] = map(path[k]);\n }\n ppaths.push(ppath);\n }\n }\n}\n\nfunction makeLinesAndLabels(plotgroup, pathinfo, gd, cd0, contours, plotinfo, carpet) {\n var lineContainer = Lib.ensureSingle(plotgroup, 'g', 'contourlines');\n var showLines = contours.showlines !== false;\n var showLabels = contours.showlabels;\n var clipLinesForLabels = showLines && showLabels;\n\n // Even if we're not going to show lines, we need to create them\n // if we're showing labels, because the fill paths include the perimeter\n // so can't be used to position the labels correctly.\n // In this case we'll remove the lines after making the labels.\n var linegroup = contourPlot.createLines(lineContainer, showLines || showLabels, pathinfo);\n\n var lineClip = contourPlot.createLineClip(lineContainer, clipLinesForLabels, gd, cd0.trace.uid);\n\n var labelGroup = plotgroup.selectAll('g.contourlabels')\n .data(showLabels ? [0] : []);\n\n labelGroup.exit().remove();\n\n labelGroup.enter().append('g')\n .classed('contourlabels', true);\n\n if(showLabels) {\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n var xLen = xa._length;\n var yLen = ya._length;\n // for simplicity use the xy box for label clipping outline.\n var labelClipPathData = [[\n [0, 0],\n [xLen, 0],\n [xLen, yLen],\n [0, yLen]\n ]];\n\n\n var labelData = [];\n\n // invalidate the getTextLocation cache in case paths changed\n Lib.clearLocationCache();\n\n var contourFormat = contourPlot.labelFormatter(gd, cd0);\n\n var dummyText = Drawing.tester.append('text')\n .attr('data-notex', 1)\n .call(Drawing.font, contours.labelfont);\n\n // use `bounds` only to keep labels away from the x/y boundaries\n // `constrainToCarpet` below ensures labels don't go off the\n // carpet edges\n var bounds = {\n left: 0,\n right: xLen,\n center: xLen / 2,\n top: 0,\n bottom: yLen,\n middle: yLen / 2\n };\n\n var plotDiagonal = Math.sqrt(xLen * xLen + yLen * yLen);\n\n // the path length to use to scale the number of labels to draw:\n var normLength = constants.LABELDISTANCE * plotDiagonal /\n Math.max(1, pathinfo.length / constants.LABELINCREASE);\n\n linegroup.each(function(d) {\n var textOpts = contourPlot.calcTextOpts(d.level, contourFormat, dummyText, gd);\n\n d3.select(this).selectAll('path').each(function(pathData) {\n var path = this;\n var pathBounds = Lib.getVisibleSegment(path, bounds, textOpts.height / 2);\n if(!pathBounds) return;\n\n constrainToCarpet(path, pathData, d, pathBounds, carpet, textOpts.height);\n\n if(pathBounds.len < (textOpts.width + textOpts.height) * constants.LABELMIN) return;\n\n var maxLabels = Math.min(Math.ceil(pathBounds.len / normLength),\n constants.LABELMAX);\n\n for(var i = 0; i < maxLabels; i++) {\n var loc = contourPlot.findBestTextLocation(path, pathBounds, textOpts,\n labelData, bounds);\n\n if(!loc) break;\n\n contourPlot.addLabelData(loc, textOpts, labelData, labelClipPathData);\n }\n });\n });\n\n dummyText.remove();\n\n contourPlot.drawLabels(labelGroup, labelData, gd, lineClip,\n clipLinesForLabels ? labelClipPathData : null);\n }\n\n if(showLabels && !showLines) linegroup.remove();\n}\n\n// figure out if this path goes off the edge of the carpet\n// and shorten the part we call visible to keep labels away from the edge\nfunction constrainToCarpet(path, pathData, levelData, pathBounds, carpet, textHeight) {\n var pathABData;\n for(var i = 0; i < levelData.pedgepaths.length; i++) {\n if(pathData === levelData.pedgepaths[i]) {\n pathABData = levelData.edgepaths[i];\n }\n }\n if(!pathABData) return;\n\n var aMin = carpet.a[0];\n var aMax = carpet.a[carpet.a.length - 1];\n var bMin = carpet.b[0];\n var bMax = carpet.b[carpet.b.length - 1];\n\n function getOffset(abPt, pathVector) {\n var offset = 0;\n var edgeVector;\n var dAB = 0.1;\n if(Math.abs(abPt[0] - aMin) < dAB || Math.abs(abPt[0] - aMax) < dAB) {\n edgeVector = normalizeVector(carpet.dxydb_rough(abPt[0], abPt[1], dAB));\n offset = Math.max(offset, textHeight * vectorTan(pathVector, edgeVector) / 2);\n }\n\n if(Math.abs(abPt[1] - bMin) < dAB || Math.abs(abPt[1] - bMax) < dAB) {\n edgeVector = normalizeVector(carpet.dxyda_rough(abPt[0], abPt[1], dAB));\n offset = Math.max(offset, textHeight * vectorTan(pathVector, edgeVector) / 2);\n }\n return offset;\n }\n\n var startVector = getUnitVector(path, 0, 1);\n var endVector = getUnitVector(path, pathBounds.total, pathBounds.total - 1);\n var minStart = getOffset(pathABData[0], startVector);\n var maxEnd = pathBounds.total - getOffset(pathABData[pathABData.length - 1], endVector);\n\n if(pathBounds.min < minStart) pathBounds.min = minStart;\n if(pathBounds.max > maxEnd) pathBounds.max = maxEnd;\n\n pathBounds.len = pathBounds.max - pathBounds.min;\n}\n\nfunction getUnitVector(path, p0, p1) {\n var pt0 = path.getPointAtLength(p0);\n var pt1 = path.getPointAtLength(p1);\n var dx = pt1.x - pt0.x;\n var dy = pt1.y - pt0.y;\n var len = Math.sqrt(dx * dx + dy * dy);\n return [dx / len, dy / len];\n}\n\nfunction normalizeVector(v) {\n var len = Math.sqrt(v[0] * v[0] + v[1] * v[1]);\n return [v[0] / len, v[1] / len];\n}\n\nfunction vectorTan(v0, v1) {\n var cos = Math.abs(v0[0] * v1[0] + v0[1] * v1[1]);\n var sin = Math.sqrt(1 - cos * cos);\n return sin / cos;\n}\n\nfunction makeBackground(plotgroup, clipsegments, xaxis, yaxis, isConstraint, coloring) {\n var seg, xp, yp, i;\n var bggroup = Lib.ensureSingle(plotgroup, 'g', 'contourbg');\n\n var bgfill = bggroup.selectAll('path')\n .data((coloring === 'fill' && !isConstraint) ? [0] : []);\n bgfill.enter().append('path');\n bgfill.exit().remove();\n\n var segs = [];\n for(i = 0; i < clipsegments.length; i++) {\n seg = clipsegments[i];\n xp = map1dArray([], seg.x, xaxis.c2p);\n yp = map1dArray([], seg.y, yaxis.c2p);\n segs.push(makepath(xp, yp, seg.bicubic));\n }\n\n bgfill\n .attr('d', 'M' + segs.join('L') + 'Z')\n .style('stroke', 'none');\n}\n\nfunction makeFills(trace, plotgroup, xa, ya, pathinfo, perimeter, ab2p, carpet, carpetcd, coloring, boundaryPath) {\n var hasFills = coloring === 'fill';\n\n // fills prefixBoundary in pathinfo items\n if(hasFills) {\n closeBoundaries(pathinfo, trace.contours);\n }\n\n var fillgroup = Lib.ensureSingle(plotgroup, 'g', 'contourfill');\n var fillitems = fillgroup.selectAll('path').data(hasFills ? pathinfo : []);\n fillitems.enter().append('path');\n fillitems.exit().remove();\n fillitems.each(function(pi) {\n // join all paths for this level together into a single path\n // first follow clockwise around the perimeter to close any open paths\n // if the whole perimeter is above this level, start with a path\n // enclosing the whole thing. With all that, the parity should mean\n // that we always fill everything above the contour, nothing below\n var fullpath = (pi.prefixBoundary ? boundaryPath : '') +\n joinAllPaths(trace, pi, perimeter, ab2p, carpet, carpetcd, xa, ya);\n\n if(!fullpath) {\n d3.select(this).remove();\n } else {\n d3.select(this)\n .attr('d', fullpath)\n .style('stroke', 'none');\n }\n });\n}\n\nfunction joinAllPaths(trace, pi, perimeter, ab2p, carpet, carpetcd, xa, ya) {\n var i;\n var fullpath = '';\n\n var startsleft = pi.edgepaths.map(function(v, i) { return i; });\n var newloop = true;\n var endpt, newendpt, cnt, nexti, possiblei, addpath;\n\n var atol = Math.abs(perimeter[0][0] - perimeter[2][0]) * 1e-4;\n var btol = Math.abs(perimeter[0][1] - perimeter[2][1]) * 1e-4;\n\n function istop(pt) { return Math.abs(pt[1] - perimeter[0][1]) < btol; }\n function isbottom(pt) { return Math.abs(pt[1] - perimeter[2][1]) < btol; }\n function isleft(pt) { return Math.abs(pt[0] - perimeter[0][0]) < atol; }\n function isright(pt) { return Math.abs(pt[0] - perimeter[2][0]) < atol; }\n\n function pathto(pt0, pt1) {\n var i, j, segments, axis;\n var path = '';\n\n if((istop(pt0) && !isright(pt0)) || (isbottom(pt0) && !isleft(pt0))) {\n axis = carpet.aaxis;\n segments = axisAlignedLine(carpet, carpetcd, [pt0[0], pt1[0]], 0.5 * (pt0[1] + pt1[1]));\n } else {\n axis = carpet.baxis;\n segments = axisAlignedLine(carpet, carpetcd, 0.5 * (pt0[0] + pt1[0]), [pt0[1], pt1[1]]);\n }\n\n for(i = 1; i < segments.length; i++) {\n path += axis.smoothing ? 'C' : 'L';\n for(j = 0; j < segments[i].length; j++) {\n var pt = segments[i][j];\n path += [xa.c2p(pt[0]), ya.c2p(pt[1])] + ' ';\n }\n }\n\n return path;\n }\n\n i = 0;\n endpt = null;\n while(startsleft.length) {\n var startpt = pi.edgepaths[i][0];\n\n if(endpt) {\n fullpath += pathto(endpt, startpt);\n }\n\n addpath = Drawing.smoothopen(pi.edgepaths[i].map(ab2p), pi.smoothing);\n fullpath += newloop ? addpath : addpath.replace(/^M/, 'L');\n startsleft.splice(startsleft.indexOf(i), 1);\n endpt = pi.edgepaths[i][pi.edgepaths[i].length - 1];\n nexti = -1;\n\n // now loop through sides, moving our endpoint until we find a new start\n for(cnt = 0; cnt < 4; cnt++) { // just to prevent infinite loops\n if(!endpt) {\n Lib.log('Missing end?', i, pi);\n break;\n }\n\n if(istop(endpt) && !isright(endpt)) {\n newendpt = perimeter[1]; // left top ---> right top\n } else if(isleft(endpt)) {\n newendpt = perimeter[0]; // left bottom ---> left top\n } else if(isbottom(endpt)) {\n newendpt = perimeter[3]; // right bottom\n } else if(isright(endpt)) {\n newendpt = perimeter[2]; // left bottom\n }\n\n for(possiblei = 0; possiblei < pi.edgepaths.length; possiblei++) {\n var ptNew = pi.edgepaths[possiblei][0];\n // is ptNew on the (horz. or vert.) segment from endpt to newendpt?\n if(Math.abs(endpt[0] - newendpt[0]) < atol) {\n if(Math.abs(endpt[0] - ptNew[0]) < atol &&\n (ptNew[1] - endpt[1]) * (newendpt[1] - ptNew[1]) >= 0) {\n newendpt = ptNew;\n nexti = possiblei;\n }\n } else if(Math.abs(endpt[1] - newendpt[1]) < btol) {\n if(Math.abs(endpt[1] - ptNew[1]) < btol &&\n (ptNew[0] - endpt[0]) * (newendpt[0] - ptNew[0]) >= 0) {\n newendpt = ptNew;\n nexti = possiblei;\n }\n } else {\n Lib.log('endpt to newendpt is not vert. or horz.', endpt, newendpt, ptNew);\n }\n }\n\n if(nexti >= 0) break;\n fullpath += pathto(endpt, newendpt);\n endpt = newendpt;\n }\n\n if(nexti === pi.edgepaths.length) {\n Lib.log('unclosed perimeter path');\n break;\n }\n\n i = nexti;\n\n // if we closed back on a loop we already included,\n // close it and start a new loop\n newloop = (startsleft.indexOf(i) === -1);\n if(newloop) {\n i = startsleft[0];\n fullpath += pathto(endpt, newendpt) + 'Z';\n endpt = null;\n }\n }\n\n // finally add the interior paths\n for(i = 0; i < pi.paths.length; i++) {\n fullpath += Drawing.smoothclosed(pi.paths[i].map(ab2p), pi.smoothing);\n }\n\n return fullpath;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/contourcarpet/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/densitymapbox/attributes.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/densitymapbox/attributes.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar scatterMapboxAttrs = __webpack_require__(/*! ../scattermapbox/attributes */ \"./node_modules/plotly.js/src/traces/scattermapbox/attributes.js\");\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\n/*\n * - https://docs.mapbox.com/help/tutorials/make-a-heatmap-with-mapbox-gl-js/\n * - https://docs.mapbox.com/mapbox-gl-js/example/heatmap-layer/\n * - https://docs.mapbox.com/mapbox-gl-js/style-spec/#layers-heatmap\n * - https://blog.mapbox.com/introducing-heatmaps-in-mapbox-gl-js-71355ada9e6c\n *\n * Gotchas:\n * - https://github.com/mapbox/mapbox-gl-js/issues/6463\n * - https://github.com/mapbox/mapbox-gl-js/issues/6112\n */\n\n/*\n *\n * In mathematical terms, Mapbox GL heatmaps are a bivariate (2D) kernel density\n * estimation with a Gaussian kernel. It means that each data point has an area\n * of “influence” around it (called a kernel) where the numerical value of\n * influence (which we call density) decreases as you go further from the point.\n * If we sum density values of all points in every pixel of the screen, we get a\n * combined density value which we then map to a heatmap color.\n *\n */\n\nmodule.exports = extendFlat({\n lon: scatterMapboxAttrs.lon,\n lat: scatterMapboxAttrs.lat,\n\n z: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n\n radius: {\n valType: 'number',\n \n editType: 'plot',\n arrayOk: true,\n min: 1,\n dflt: 30,\n \n },\n\n below: {\n valType: 'string',\n \n editType: 'plot',\n \n },\n\n text: scatterMapboxAttrs.text,\n hovertext: scatterMapboxAttrs.hovertext,\n\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {\n flags: ['lon', 'lat', 'z', 'text', 'name']\n }),\n hovertemplate: hovertemplateAttrs(),\n showlegend: extendFlat({}, baseAttrs.showlegend, {dflt: false})\n},\n colorScaleAttrs('', {\n cLetter: 'z',\n editTypeOverride: 'calc'\n })\n);\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/densitymapbox/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/densitymapbox/calc.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/densitymapbox/calc.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\nvar isArrayOrTypedArray = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").isArrayOrTypedArray;\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nvar colorscaleCalc = __webpack_require__(/*! ../../components/colorscale/calc */ \"./node_modules/plotly.js/src/components/colorscale/calc.js\");\nvar _ = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\")._;\n\nmodule.exports = function calc(gd, trace) {\n var len = trace._length;\n var calcTrace = new Array(len);\n var z = trace.z;\n var hasZ = isArrayOrTypedArray(z) && z.length;\n\n for(var i = 0; i < len; i++) {\n var cdi = calcTrace[i] = {};\n\n var lon = trace.lon[i];\n var lat = trace.lat[i];\n\n cdi.lonlat = isNumeric(lon) && isNumeric(lat) ?\n [+lon, +lat] :\n [BADNUM, BADNUM];\n\n if(hasZ) {\n var zi = z[i];\n cdi.z = isNumeric(zi) ? zi : BADNUM;\n }\n }\n\n colorscaleCalc(gd, trace, {\n vals: hasZ ? z : [0, 1],\n containerStr: '',\n cLetter: 'z'\n });\n\n if(len) {\n calcTrace[0].t = {\n labels: {\n lat: _(gd, 'lat:') + ' ',\n lon: _(gd, 'lon:') + ' '\n }\n };\n }\n\n return calcTrace;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/densitymapbox/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/densitymapbox/convert.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/densitymapbox/convert.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar Colorscale = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\");\n\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\nvar makeBlank = __webpack_require__(/*! ../../lib/geojson_utils */ \"./node_modules/plotly.js/src/lib/geojson_utils.js\").makeBlank;\n\nmodule.exports = function convert(calcTrace) {\n var trace = calcTrace[0].trace;\n var isVisible = (trace.visible === true && trace._length !== 0);\n\n var heatmap = {\n layout: {visibility: 'none'},\n paint: {}\n };\n\n var opts = trace._opts = {\n heatmap: heatmap,\n geojson: makeBlank()\n };\n\n // early return if not visible or placeholder\n if(!isVisible) return opts;\n\n var features = [];\n var i;\n\n var z = trace.z;\n var radius = trace.radius;\n var hasZ = Lib.isArrayOrTypedArray(z) && z.length;\n var hasArrayRadius = Lib.isArrayOrTypedArray(radius);\n\n for(i = 0; i < calcTrace.length; i++) {\n var cdi = calcTrace[i];\n var lonlat = cdi.lonlat;\n\n if(lonlat[0] !== BADNUM) {\n var props = {};\n\n if(hasZ) {\n var zi = cdi.z;\n props.z = zi !== BADNUM ? zi : 0;\n }\n if(hasArrayRadius) {\n props.r = (isNumeric(radius[i]) && radius[i] > 0) ? +radius[i] : 0;\n }\n\n features.push({\n type: 'Feature',\n geometry: {type: 'Point', coordinates: lonlat},\n properties: props\n });\n }\n }\n\n var cOpts = Colorscale.extractOpts(trace);\n var scl = cOpts.reversescale ?\n Colorscale.flipScale(cOpts.colorscale) :\n cOpts.colorscale;\n\n // Add alpha channel to first colorscale step.\n // If not, we would essentially color the entire map.\n // See https://docs.mapbox.com/mapbox-gl-js/example/heatmap-layer/\n var scl01 = scl[0][1];\n var color0 = Color.opacity(scl01) < 1 ? scl01 : Color.addOpacity(scl01, 0);\n\n var heatmapColor = [\n 'interpolate', ['linear'],\n ['heatmap-density'],\n 0, color0\n ];\n for(i = 1; i < scl.length; i++) {\n heatmapColor.push(scl[i][0], scl[i][1]);\n }\n\n // Those \"weights\" have to be in [0, 1], we can do this either:\n // - as here using a mapbox-gl expression\n // - or, scale the 'z' property in the feature loop\n var zExp = [\n 'interpolate', ['linear'],\n ['get', 'z'],\n cOpts.min, 0,\n cOpts.max, 1\n ];\n\n Lib.extendFlat(opts.heatmap.paint, {\n 'heatmap-weight': hasZ ? zExp : 1 / (cOpts.max - cOpts.min),\n\n 'heatmap-color': heatmapColor,\n\n 'heatmap-radius': hasArrayRadius ?\n {type: 'identity', property: 'r'} :\n trace.radius,\n\n 'heatmap-opacity': trace.opacity\n });\n\n opts.geojson = {type: 'FeatureCollection', features: features};\n opts.heatmap.layout.visibility = 'visible';\n\n return opts;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/densitymapbox/convert.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/densitymapbox/defaults.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/densitymapbox/defaults.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar colorscaleDefaults = __webpack_require__(/*! ../../components/colorscale/defaults */ \"./node_modules/plotly.js/src/components/colorscale/defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/densitymapbox/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var lon = coerce('lon') || [];\n var lat = coerce('lat') || [];\n\n var len = Math.min(lon.length, lat.length);\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n traceOut._length = len;\n\n coerce('z');\n coerce('radius');\n coerce('below');\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'z'});\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/densitymapbox/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/densitymapbox/event_data.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/densitymapbox/event_data.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function eventData(out, pt) {\n out.lon = pt.lon;\n out.lat = pt.lat;\n out.z = pt.z;\n return out;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/densitymapbox/event_data.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/densitymapbox/hover.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/densitymapbox/hover.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar scatterMapboxHoverPoints = __webpack_require__(/*! ../scattermapbox/hover */ \"./node_modules/plotly.js/src/traces/scattermapbox/hover.js\");\n\nmodule.exports = function hoverPoints(pointData, xval, yval) {\n var pts = scatterMapboxHoverPoints(pointData, xval, yval);\n if(!pts) return;\n\n var newPointData = pts[0];\n var cd = newPointData.cd;\n var trace = cd[0].trace;\n var di = cd[newPointData.index];\n\n // let Fx.hover pick the color\n delete newPointData.color;\n\n if('z' in di) {\n var ax = newPointData.subplot.mockAxis;\n newPointData.z = di.z;\n newPointData.zLabel = Axes.tickText(ax, ax.c2l(di.z), 'hover').text;\n }\n\n newPointData.extraText = getExtraText(trace, di, cd[0].t.labels);\n\n return [newPointData];\n};\n\nfunction getExtraText(trace, di, labels) {\n if(trace.hovertemplate) return;\n\n var hoverinfo = di.hi || trace.hoverinfo;\n var parts = hoverinfo.split('+');\n var isAll = parts.indexOf('all') !== -1;\n var hasLon = parts.indexOf('lon') !== -1;\n var hasLat = parts.indexOf('lat') !== -1;\n var lonlat = di.lonlat;\n var text = [];\n\n function format(v) {\n return v + '\\u00B0';\n }\n\n if(isAll || (hasLon && hasLat)) {\n text.push('(' + format(lonlat[0]) + ', ' + format(lonlat[1]) + ')');\n } else if(hasLon) {\n text.push(labels.lon + format(lonlat[0]));\n } else if(hasLat) {\n text.push(labels.lat + format(lonlat[1]));\n }\n\n if(isAll || parts.indexOf('text') !== -1) {\n Lib.fillText(di, trace, text);\n }\n\n return text.join('
');\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/densitymapbox/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/densitymapbox/index.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/densitymapbox/index.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/densitymapbox/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/densitymapbox/defaults.js\"),\n colorbar: __webpack_require__(/*! ../heatmap/colorbar */ \"./node_modules/plotly.js/src/traces/heatmap/colorbar.js\"),\n formatLabels: __webpack_require__(/*! ../scattermapbox/format_labels */ \"./node_modules/plotly.js/src/traces/scattermapbox/format_labels.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/densitymapbox/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/densitymapbox/plot.js\"),\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/densitymapbox/hover.js\"),\n eventData: __webpack_require__(/*! ./event_data */ \"./node_modules/plotly.js/src/traces/densitymapbox/event_data.js\"),\n\n getBelow: function(trace, subplot) {\n var mapLayers = subplot.getMapLayers();\n\n // find first layer with `type: 'symbol'`,\n // that is not a plotly layer\n for(var i = 0; i < mapLayers.length; i++) {\n var layer = mapLayers[i];\n var layerId = layer.id;\n if(layer.type === 'symbol' &&\n typeof layerId === 'string' && layerId.indexOf('plotly-') === -1\n ) {\n return layerId;\n }\n }\n },\n\n moduleType: 'trace',\n name: 'densitymapbox',\n basePlotModule: __webpack_require__(/*! ../../plots/mapbox */ \"./node_modules/plotly.js/src/plots/mapbox/index.js\"),\n categories: ['mapbox', 'gl', 'showLegend'],\n meta: {\n hr_name: 'density_mapbox',\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/densitymapbox/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/densitymapbox/plot.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/densitymapbox/plot.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar convert = __webpack_require__(/*! ./convert */ \"./node_modules/plotly.js/src/traces/densitymapbox/convert.js\");\nvar LAYER_PREFIX = __webpack_require__(/*! ../../plots/mapbox/constants */ \"./node_modules/plotly.js/src/plots/mapbox/constants.js\").traceLayerPrefix;\n\nfunction DensityMapbox(subplot, uid) {\n this.type = 'densitymapbox';\n this.subplot = subplot;\n this.uid = uid;\n\n this.sourceId = 'source-' + uid;\n\n this.layerList = [\n ['heatmap', LAYER_PREFIX + uid + '-heatmap']\n ];\n\n // previous 'below' value,\n // need this to update it properly\n this.below = null;\n}\n\nvar proto = DensityMapbox.prototype;\n\nproto.update = function(calcTrace) {\n var subplot = this.subplot;\n var layerList = this.layerList;\n var optsAll = convert(calcTrace);\n var below = subplot.belowLookup['trace-' + this.uid];\n\n subplot.map\n .getSource(this.sourceId)\n .setData(optsAll.geojson);\n\n if(below !== this.below) {\n this._removeLayers();\n this._addLayers(optsAll, below);\n this.below = below;\n }\n\n for(var i = 0; i < layerList.length; i++) {\n var item = layerList[i];\n var k = item[0];\n var id = item[1];\n var opts = optsAll[k];\n\n subplot.setOptions(id, 'setLayoutProperty', opts.layout);\n\n if(opts.layout.visibility === 'visible') {\n subplot.setOptions(id, 'setPaintProperty', opts.paint);\n }\n }\n};\n\nproto._addLayers = function(optsAll, below) {\n var subplot = this.subplot;\n var layerList = this.layerList;\n var sourceId = this.sourceId;\n\n for(var i = 0; i < layerList.length; i++) {\n var item = layerList[i];\n var k = item[0];\n var opts = optsAll[k];\n\n subplot.addLayer({\n type: k,\n id: item[1],\n source: sourceId,\n layout: opts.layout,\n paint: opts.paint\n }, below);\n }\n};\n\nproto._removeLayers = function() {\n var map = this.subplot.map;\n var layerList = this.layerList;\n\n for(var i = layerList.length - 1; i >= 0; i--) {\n map.removeLayer(layerList[i][1]);\n }\n};\n\nproto.dispose = function() {\n var map = this.subplot.map;\n this._removeLayers();\n map.removeSource(this.sourceId);\n};\n\nmodule.exports = function createDensityMapbox(subplot, calcTrace) {\n var trace = calcTrace[0].trace;\n var densityMapbox = new DensityMapbox(subplot, trace.uid);\n var sourceId = densityMapbox.sourceId;\n var optsAll = convert(calcTrace);\n var below = densityMapbox.below = subplot.belowLookup['trace-' + trace.uid];\n\n subplot.map.addSource(sourceId, {\n type: 'geojson',\n data: optsAll.geojson\n });\n\n densityMapbox._addLayers(optsAll, below);\n\n return densityMapbox;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/densitymapbox/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnel/arrays_to_calcdata.js":
-/*!************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnel/arrays_to_calcdata.js ***!
- \************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\n// arrayOk attributes, merge them into calcdata array\nmodule.exports = function arraysToCalcdata(cd, trace) {\n for(var i = 0; i < cd.length; i++) cd[i].i = i;\n\n Lib.mergeArray(trace.text, cd, 'tx');\n Lib.mergeArray(trace.hovertext, cd, 'htx');\n\n var marker = trace.marker;\n if(marker) {\n Lib.mergeArray(marker.opacity, cd, 'mo');\n Lib.mergeArray(marker.color, cd, 'mc');\n\n var markerLine = marker.line;\n if(markerLine) {\n Lib.mergeArray(markerLine.color, cd, 'mlc');\n Lib.mergeArrayCastPositive(markerLine.width, cd, 'mlw');\n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnel/arrays_to_calcdata.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnel/attributes.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnel/attributes.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar barAttrs = __webpack_require__(/*! ../bar/attributes */ \"./node_modules/plotly.js/src/traces/bar/attributes.js\");\nvar lineAttrs = __webpack_require__(/*! ../scatter/attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\").line;\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar texttemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").texttemplateAttrs;\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/funnel/constants.js\");\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\n\nmodule.exports = {\n x: barAttrs.x,\n x0: barAttrs.x0,\n dx: barAttrs.dx,\n y: barAttrs.y,\n y0: barAttrs.y0,\n dy: barAttrs.dy,\n\n hovertext: barAttrs.hovertext,\n hovertemplate: hovertemplateAttrs({}, {\n keys: constants.eventDataKeys\n }),\n\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {\n flags: ['name', 'x', 'y', 'text', 'percent initial', 'percent previous', 'percent total']\n }),\n\n textinfo: {\n valType: 'flaglist',\n flags: ['label', 'text', 'percent initial', 'percent previous', 'percent total', 'value'],\n extras: ['none'],\n \n editType: 'plot',\n arrayOk: false,\n \n },\n // TODO: incorporate `label` and `value` in the eventData\n texttemplate: texttemplateAttrs({editType: 'plot'}, {\n keys: constants.eventDataKeys.concat(['label', 'value'])\n }),\n\n text: barAttrs.text,\n textposition: extendFlat({}, barAttrs.textposition, {dflt: 'auto'}),\n insidetextanchor: extendFlat({}, barAttrs.insidetextanchor, {dflt: 'middle'}),\n textangle: extendFlat({}, barAttrs.textangle, {dflt: 0}),\n textfont: barAttrs.textfont,\n insidetextfont: barAttrs.insidetextfont,\n outsidetextfont: barAttrs.outsidetextfont,\n constraintext: barAttrs.constraintext,\n cliponaxis: barAttrs.cliponaxis,\n\n orientation: extendFlat({}, barAttrs.orientation, {\n \n }),\n\n offset: extendFlat({}, barAttrs.offset, {arrayOk: false}),\n width: extendFlat({}, barAttrs.width, {arrayOk: false}),\n\n marker: barAttrs.marker,\n\n connector: {\n fillcolor: {\n valType: 'color',\n \n editType: 'style',\n \n },\n line: {\n color: extendFlat({}, lineAttrs.color, {dflt: Color.defaultLine}),\n width: extendFlat({}, lineAttrs.width, {\n dflt: 0,\n editType: 'plot',\n }),\n dash: lineAttrs.dash,\n editType: 'style'\n },\n visible: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'plot',\n \n },\n editType: 'plot'\n },\n\n offsetgroup: barAttrs.offsetgroup,\n alignmentgroup: barAttrs.alignmentgroup\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnel/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnel/calc.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnel/calc.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar arraysToCalcdata = __webpack_require__(/*! ./arrays_to_calcdata */ \"./node_modules/plotly.js/src/traces/funnel/arrays_to_calcdata.js\");\nvar calcSelection = __webpack_require__(/*! ../scatter/calc_selection */ \"./node_modules/plotly.js/src/traces/scatter/calc_selection.js\");\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nmodule.exports = function calc(gd, trace) {\n var xa = Axes.getFromId(gd, trace.xaxis || 'x');\n var ya = Axes.getFromId(gd, trace.yaxis || 'y');\n var size, pos, i, cdi;\n\n if(trace.orientation === 'h') {\n size = xa.makeCalcdata(trace, 'x');\n pos = ya.makeCalcdata(trace, 'y');\n } else {\n size = ya.makeCalcdata(trace, 'y');\n pos = xa.makeCalcdata(trace, 'x');\n }\n\n // create the \"calculated data\" to plot\n var serieslen = Math.min(pos.length, size.length);\n var cd = new Array(serieslen);\n\n // Unlike other bar-like traces funnels do not support base attribute.\n // bases for funnels are computed internally in a way that\n // the mid-point of each bar are located on the axis line.\n trace._base = [];\n\n // set position and size\n for(i = 0; i < serieslen; i++) {\n // treat negative values as bad numbers\n if(size[i] < 0) size[i] = BADNUM;\n\n var connectToNext = false;\n if(size[i] !== BADNUM) {\n if(i + 1 < serieslen && size[i + 1] !== BADNUM) {\n connectToNext = true;\n }\n }\n\n cdi = cd[i] = {\n p: pos[i],\n s: size[i],\n cNext: connectToNext\n };\n\n trace._base[i] = -0.5 * cdi.s;\n\n if(trace.ids) {\n cdi.id = String(trace.ids[i]);\n }\n\n // calculate total values\n if(i === 0) cd[0].vTotal = 0;\n cd[0].vTotal += fixNum(cdi.s);\n\n // ratio from initial value\n cdi.begR = fixNum(cdi.s) / fixNum(cd[0].s);\n }\n\n var prevGoodNum;\n for(i = 0; i < serieslen; i++) {\n cdi = cd[i];\n if(cdi.s === BADNUM) continue;\n\n // ratio of total value\n cdi.sumR = cdi.s / cd[0].vTotal;\n\n // ratio of previous (good) value\n cdi.difR = (prevGoodNum !== undefined) ? cdi.s / prevGoodNum : 1;\n\n prevGoodNum = cdi.s;\n }\n\n arraysToCalcdata(cd, trace);\n calcSelection(cd, trace);\n\n return cd;\n};\n\nfunction fixNum(a) {\n return (a === BADNUM) ? 0 : a;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnel/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnel/constants.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnel/constants.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n eventDataKeys: [\n 'percentInitial',\n 'percentPrevious',\n 'percentTotal'\n ]\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnel/constants.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnel/cross_trace_calc.js":
-/*!**********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnel/cross_trace_calc.js ***!
- \**********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar setGroupPositions = __webpack_require__(/*! ../bar/cross_trace_calc */ \"./node_modules/plotly.js/src/traces/bar/cross_trace_calc.js\").setGroupPositions;\n\nmodule.exports = function crossTraceCalc(gd, plotinfo) {\n var fullLayout = gd._fullLayout;\n var fullData = gd._fullData;\n var calcdata = gd.calcdata;\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n var funnels = [];\n var funnelsVert = [];\n var funnelsHorz = [];\n var cd, i;\n\n for(i = 0; i < fullData.length; i++) {\n var fullTrace = fullData[i];\n var isHorizontal = (fullTrace.orientation === 'h');\n\n if(\n fullTrace.visible === true &&\n fullTrace.xaxis === xa._id &&\n fullTrace.yaxis === ya._id &&\n fullTrace.type === 'funnel'\n ) {\n cd = calcdata[i];\n\n if(isHorizontal) {\n funnelsHorz.push(cd);\n } else {\n funnelsVert.push(cd);\n }\n\n funnels.push(cd);\n }\n }\n\n var opts = {\n mode: fullLayout.funnelmode,\n norm: fullLayout.funnelnorm,\n gap: fullLayout.funnelgap,\n groupgap: fullLayout.funnelgroupgap\n };\n\n setGroupPositions(gd, xa, ya, funnelsVert, opts);\n setGroupPositions(gd, ya, xa, funnelsHorz, opts);\n\n for(i = 0; i < funnels.length; i++) {\n cd = funnels[i];\n\n for(var j = 0; j < cd.length; j++) {\n if(j + 1 < cd.length) {\n cd[j].nextP0 = cd[j + 1].p0;\n cd[j].nextS0 = cd[j + 1].s0;\n\n cd[j].nextP1 = cd[j + 1].p1;\n cd[j].nextS1 = cd[j + 1].s1;\n }\n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnel/cross_trace_calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnel/defaults.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnel/defaults.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar handleGroupingDefaults = __webpack_require__(/*! ../bar/defaults */ \"./node_modules/plotly.js/src/traces/bar/defaults.js\").handleGroupingDefaults;\nvar handleText = __webpack_require__(/*! ../bar/defaults */ \"./node_modules/plotly.js/src/traces/bar/defaults.js\").handleText;\nvar handleXYDefaults = __webpack_require__(/*! ../scatter/xy_defaults */ \"./node_modules/plotly.js/src/traces/scatter/xy_defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/funnel/attributes.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\n\nfunction supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var len = handleXYDefaults(traceIn, traceOut, layout, coerce);\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n coerce('orientation', (traceOut.y && !traceOut.x) ? 'v' : 'h');\n coerce('offset');\n coerce('width');\n\n var text = coerce('text');\n\n coerce('hovertext');\n coerce('hovertemplate');\n\n var textposition = coerce('textposition');\n handleText(traceIn, traceOut, layout, coerce, textposition, {\n moduleHasSelected: false,\n moduleHasUnselected: false,\n moduleHasConstrain: true,\n moduleHasCliponaxis: true,\n moduleHasTextangle: true,\n moduleHasInsideanchor: true\n });\n\n if(traceOut.textposition !== 'none' && !traceOut.texttemplate) {\n coerce('textinfo', Array.isArray(text) ? 'text+value' : 'value');\n }\n\n var markerColor = coerce('marker.color', defaultColor);\n coerce('marker.line.color', Color.defaultLine);\n coerce('marker.line.width');\n\n var connectorVisible = coerce('connector.visible');\n if(connectorVisible) {\n coerce('connector.fillcolor', defaultFillColor(markerColor));\n\n var connectorLineWidth = coerce('connector.line.width');\n if(connectorLineWidth) {\n coerce('connector.line.color');\n coerce('connector.line.dash');\n }\n }\n}\n\nfunction defaultFillColor(markerColor) {\n var cBase = Lib.isArrayOrTypedArray(markerColor) ? '#000' : markerColor;\n\n return Color.addOpacity(cBase, 0.5 * Color.opacity(cBase));\n}\n\nfunction crossTraceDefaults(fullData, fullLayout) {\n var traceIn, traceOut;\n\n function coerce(attr) {\n return Lib.coerce(traceOut._input, traceOut, attributes, attr);\n }\n\n if(fullLayout.funnelmode === 'group') {\n for(var i = 0; i < fullData.length; i++) {\n traceOut = fullData[i];\n traceIn = traceOut._input;\n\n handleGroupingDefaults(traceIn, traceOut, fullLayout, coerce);\n }\n }\n}\n\nmodule.exports = {\n supplyDefaults: supplyDefaults,\n crossTraceDefaults: crossTraceDefaults\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnel/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnel/event_data.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnel/event_data.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function eventData(out, pt /* , trace, cd, pointNumber */) {\n // standard cartesian event data\n out.x = 'xVal' in pt ? pt.xVal : pt.x;\n out.y = 'yVal' in pt ? pt.yVal : pt.y;\n\n // for funnel\n if('percentInitial' in pt) out.percentInitial = pt.percentInitial;\n if('percentPrevious' in pt) out.percentPrevious = pt.percentPrevious;\n if('percentTotal' in pt) out.percentTotal = pt.percentTotal;\n\n if(pt.xa) out.xaxis = pt.xa;\n if(pt.ya) out.yaxis = pt.ya;\n\n return out;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnel/event_data.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnel/hover.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnel/hover.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar opacity = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\").opacity;\nvar hoverOnBars = __webpack_require__(/*! ../bar/hover */ \"./node_modules/plotly.js/src/traces/bar/hover.js\").hoverOnBars;\nvar formatPercent = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").formatPercent;\n\nmodule.exports = function hoverPoints(pointData, xval, yval, hovermode) {\n var point = hoverOnBars(pointData, xval, yval, hovermode);\n if(!point) return;\n\n var cd = point.cd;\n var trace = cd[0].trace;\n var isHorizontal = (trace.orientation === 'h');\n\n // the closest data point\n var index = point.index;\n var di = cd[index];\n\n var sizeLetter = isHorizontal ? 'x' : 'y';\n point[sizeLetter + 'LabelVal'] = di.s;\n\n point.percentInitial = di.begR;\n point.percentInitialLabel = formatPercent(di.begR, 1);\n\n point.percentPrevious = di.difR;\n point.percentPreviousLabel = formatPercent(di.difR, 1);\n\n point.percentTotal = di.sumR;\n point.percentTotalLabel = formatPercent(di.sumR, 1);\n\n var hoverinfo = di.hi || trace.hoverinfo;\n var text = [];\n if(hoverinfo && hoverinfo !== 'none' && hoverinfo !== 'skip') {\n var isAll = (hoverinfo === 'all');\n var parts = hoverinfo.split('+');\n\n var hasFlag = function(flag) { return isAll || parts.indexOf(flag) !== -1; };\n\n if(hasFlag('percent initial')) {\n text.push(point.percentInitialLabel + ' of initial');\n }\n if(hasFlag('percent previous')) {\n text.push(point.percentPreviousLabel + ' of previous');\n }\n if(hasFlag('percent total')) {\n text.push(point.percentTotalLabel + ' of total');\n }\n }\n point.extraText = text.join('
');\n\n point.color = getTraceColor(trace, di);\n\n return [point];\n};\n\nfunction getTraceColor(trace, di) {\n var cont = trace.marker;\n var mc = di.mc || cont.color;\n var mlc = di.mlc || cont.line.color;\n var mlw = di.mlw || cont.line.width;\n if(opacity(mc)) return mc;\n else if(opacity(mlc) && mlw) return mlc;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnel/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnel/index.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnel/index.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/funnel/attributes.js\"),\n layoutAttributes: __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/funnel/layout_attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/funnel/defaults.js\").supplyDefaults,\n crossTraceDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/funnel/defaults.js\").crossTraceDefaults,\n supplyLayoutDefaults: __webpack_require__(/*! ./layout_defaults */ \"./node_modules/plotly.js/src/traces/funnel/layout_defaults.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/funnel/calc.js\"),\n crossTraceCalc: __webpack_require__(/*! ./cross_trace_calc */ \"./node_modules/plotly.js/src/traces/funnel/cross_trace_calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/funnel/plot.js\"),\n style: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/funnel/style.js\").style,\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/funnel/hover.js\"),\n eventData: __webpack_require__(/*! ./event_data */ \"./node_modules/plotly.js/src/traces/funnel/event_data.js\"),\n\n selectPoints: __webpack_require__(/*! ../bar/select */ \"./node_modules/plotly.js/src/traces/bar/select.js\"),\n\n moduleType: 'trace',\n name: 'funnel',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['bar-like', 'cartesian', 'svg', 'oriented', 'showLegend', 'zoomScale'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnel/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnel/layout_attributes.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnel/layout_attributes.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n funnelmode: {\n valType: 'enumerated',\n values: ['stack', 'group', 'overlay'],\n dflt: 'stack',\n \n editType: 'calc',\n \n },\n funnelgap: {\n valType: 'number',\n min: 0,\n max: 1,\n \n editType: 'calc',\n \n },\n funnelgroupgap: {\n valType: 'number',\n min: 0,\n max: 1,\n dflt: 0,\n \n editType: 'calc',\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnel/layout_attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnel/layout_defaults.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnel/layout_defaults.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar layoutAttributes = __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/funnel/layout_attributes.js\");\n\nmodule.exports = function(layoutIn, layoutOut, fullData) {\n var hasTraceType = false;\n\n function coerce(attr, dflt) {\n return Lib.coerce(layoutIn, layoutOut, layoutAttributes, attr, dflt);\n }\n\n for(var i = 0; i < fullData.length; i++) {\n var trace = fullData[i];\n\n if(trace.visible && trace.type === 'funnel') {\n hasTraceType = true;\n break;\n }\n }\n\n if(hasTraceType) {\n coerce('funnelmode');\n coerce('funnelgap', 0.2);\n coerce('funnelgroupgap');\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnel/layout_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnel/plot.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnel/plot.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar barPlot = __webpack_require__(/*! ../bar/plot */ \"./node_modules/plotly.js/src/traces/bar/plot.js\");\nvar clearMinTextSize = __webpack_require__(/*! ../bar/uniform_text */ \"./node_modules/plotly.js/src/traces/bar/uniform_text.js\").clearMinTextSize;\n\nmodule.exports = function plot(gd, plotinfo, cdModule, traceLayer) {\n var fullLayout = gd._fullLayout;\n\n clearMinTextSize('funnel', fullLayout);\n\n plotConnectorRegions(gd, plotinfo, cdModule, traceLayer);\n plotConnectorLines(gd, plotinfo, cdModule, traceLayer);\n\n barPlot.plot(gd, plotinfo, cdModule, traceLayer, {\n mode: fullLayout.funnelmode,\n norm: fullLayout.funnelmode,\n gap: fullLayout.funnelgap,\n groupgap: fullLayout.funnelgroupgap\n });\n};\n\nfunction plotConnectorRegions(gd, plotinfo, cdModule, traceLayer) {\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n\n Lib.makeTraceGroups(traceLayer, cdModule, 'trace bars').each(function(cd) {\n var plotGroup = d3.select(this);\n var trace = cd[0].trace;\n\n var group = Lib.ensureSingle(plotGroup, 'g', 'regions');\n\n if(!trace.connector || !trace.connector.visible) {\n group.remove();\n return;\n }\n\n var isHorizontal = (trace.orientation === 'h');\n\n var connectors = group.selectAll('g.region').data(Lib.identity);\n\n connectors.enter().append('g')\n .classed('region', true);\n\n connectors.exit().remove();\n\n var len = connectors.size();\n\n connectors.each(function(di, i) {\n // don't draw lines between nulls\n if(i !== len - 1 && !di.cNext) return;\n\n var xy = getXY(di, xa, ya, isHorizontal);\n var x = xy[0];\n var y = xy[1];\n\n var shape = '';\n\n if(x[3] !== undefined && y[3] !== undefined) {\n if(isHorizontal) {\n shape += 'M' + x[0] + ',' + y[1] + 'L' + x[2] + ',' + y[2] + 'H' + x[3] + 'L' + x[1] + ',' + y[1] + 'Z';\n } else {\n shape += 'M' + x[1] + ',' + y[1] + 'L' + x[2] + ',' + y[3] + 'V' + y[2] + 'L' + x[1] + ',' + y[0] + 'Z';\n }\n }\n\n Lib.ensureSingle(d3.select(this), 'path')\n .attr('d', shape)\n .call(Drawing.setClipUrl, plotinfo.layerClipId, gd);\n });\n });\n}\n\nfunction plotConnectorLines(gd, plotinfo, cdModule, traceLayer) {\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n\n Lib.makeTraceGroups(traceLayer, cdModule, 'trace bars').each(function(cd) {\n var plotGroup = d3.select(this);\n var trace = cd[0].trace;\n\n var group = Lib.ensureSingle(plotGroup, 'g', 'lines');\n\n if(!trace.connector || !trace.connector.visible || !trace.connector.line.width) {\n group.remove();\n return;\n }\n\n var isHorizontal = (trace.orientation === 'h');\n\n var connectors = group.selectAll('g.line').data(Lib.identity);\n\n connectors.enter().append('g')\n .classed('line', true);\n\n connectors.exit().remove();\n\n var len = connectors.size();\n\n connectors.each(function(di, i) {\n // don't draw lines between nulls\n if(i !== len - 1 && !di.cNext) return;\n\n var xy = getXY(di, xa, ya, isHorizontal);\n var x = xy[0];\n var y = xy[1];\n\n var shape = '';\n\n if(x[3] !== undefined && y[3] !== undefined) {\n if(isHorizontal) {\n shape += 'M' + x[0] + ',' + y[1] + 'L' + x[2] + ',' + y[2];\n shape += 'M' + x[1] + ',' + y[1] + 'L' + x[3] + ',' + y[2];\n } else {\n shape += 'M' + x[1] + ',' + y[1] + 'L' + x[2] + ',' + y[3];\n shape += 'M' + x[1] + ',' + y[0] + 'L' + x[2] + ',' + y[2];\n }\n }\n\n if(shape === '') shape = 'M0,0Z';\n\n Lib.ensureSingle(d3.select(this), 'path')\n .attr('d', shape)\n .call(Drawing.setClipUrl, plotinfo.layerClipId, gd);\n });\n });\n}\n\nfunction getXY(di, xa, ya, isHorizontal) {\n var s = [];\n var p = [];\n\n var sAxis = isHorizontal ? xa : ya;\n var pAxis = isHorizontal ? ya : xa;\n\n s[0] = sAxis.c2p(di.s0, true);\n p[0] = pAxis.c2p(di.p0, true);\n\n s[1] = sAxis.c2p(di.s1, true);\n p[1] = pAxis.c2p(di.p1, true);\n\n s[2] = sAxis.c2p(di.nextS0, true);\n p[2] = pAxis.c2p(di.nextP0, true);\n\n s[3] = sAxis.c2p(di.nextS1, true);\n p[3] = pAxis.c2p(di.nextP1, true);\n\n return isHorizontal ? [s, p] : [p, s];\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnel/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnel/style.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnel/style.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar DESELECTDIM = __webpack_require__(/*! ../../constants/interactions */ \"./node_modules/plotly.js/src/constants/interactions.js\").DESELECTDIM;\nvar barStyle = __webpack_require__(/*! ../bar/style */ \"./node_modules/plotly.js/src/traces/bar/style.js\");\nvar resizeText = __webpack_require__(/*! ../bar/uniform_text */ \"./node_modules/plotly.js/src/traces/bar/uniform_text.js\").resizeText;\nvar styleTextPoints = barStyle.styleTextPoints;\n\nfunction style(gd, cd, sel) {\n var s = sel ? sel : d3.select(gd).selectAll('g.funnellayer').selectAll('g.trace');\n resizeText(gd, s, 'funnel');\n\n s.style('opacity', function(d) { return d[0].trace.opacity; });\n\n s.each(function(d) {\n var gTrace = d3.select(this);\n var trace = d[0].trace;\n\n gTrace.selectAll('.point > path').each(function(di) {\n if(!di.isBlank) {\n var cont = trace.marker;\n\n d3.select(this)\n .call(Color.fill, di.mc || cont.color)\n .call(Color.stroke, di.mlc || cont.line.color)\n .call(Drawing.dashLine, cont.line.dash, di.mlw || cont.line.width)\n .style('opacity', trace.selectedpoints && !di.selected ? DESELECTDIM : 1);\n }\n });\n\n styleTextPoints(gTrace, trace, gd);\n\n gTrace.selectAll('.regions').each(function() {\n d3.select(this).selectAll('path').style('stroke-width', 0).call(Color.fill, trace.connector.fillcolor);\n });\n\n gTrace.selectAll('.lines').each(function() {\n var cont = trace.connector.line;\n\n Drawing.lineGroupStyle(\n d3.select(this).selectAll('path'),\n cont.width,\n cont.color,\n cont.dash\n );\n });\n });\n}\n\nmodule.exports = {\n style: style\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnel/style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnelarea/attributes.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnelarea/attributes.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar pieAttrs = __webpack_require__(/*! ../pie/attributes */ \"./node_modules/plotly.js/src/traces/pie/attributes.js\");\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar domainAttrs = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").attributes;\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar texttemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").texttemplateAttrs;\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nmodule.exports = {\n labels: pieAttrs.labels,\n // equivalent of x0 and dx, if label is missing\n label0: pieAttrs.label0,\n dlabel: pieAttrs.dlabel,\n values: pieAttrs.values,\n\n marker: {\n colors: pieAttrs.marker.colors,\n line: {\n color: extendFlat({}, pieAttrs.marker.line.color, {\n dflt: null,\n \n }),\n width: extendFlat({}, pieAttrs.marker.line.width, {dflt: 1}),\n editType: 'calc'\n },\n editType: 'calc'\n },\n\n text: pieAttrs.text,\n hovertext: pieAttrs.hovertext,\n\n scalegroup: extendFlat({}, pieAttrs.scalegroup, {\n \n }),\n\n textinfo: extendFlat({}, pieAttrs.textinfo, {\n flags: ['label', 'text', 'value', 'percent']\n }),\n\n texttemplate: texttemplateAttrs({editType: 'plot'}, {\n keys: ['label', 'color', 'value', 'text', 'percent']\n }),\n\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {\n flags: ['label', 'text', 'value', 'percent', 'name']\n }),\n\n hovertemplate: hovertemplateAttrs({}, {\n keys: ['label', 'color', 'value', 'text', 'percent']\n }),\n\n textposition: extendFlat({}, pieAttrs.textposition, {\n values: ['inside', 'none'],\n dflt: 'inside'\n }),\n\n textfont: pieAttrs.textfont,\n insidetextfont: pieAttrs.insidetextfont,\n\n title: {\n text: pieAttrs.title.text,\n font: pieAttrs.title.font,\n position: extendFlat({}, pieAttrs.title.position, {\n values: ['top left', 'top center', 'top right'],\n dflt: 'top center'\n }),\n editType: 'plot'\n },\n\n domain: domainAttrs({name: 'funnelarea', trace: true, editType: 'calc'}),\n\n aspectratio: {\n valType: 'number',\n \n min: 0,\n dflt: 1,\n editType: 'plot',\n \n },\n\n baseratio: {\n valType: 'number',\n \n min: 0,\n max: 1,\n dflt: 0.333,\n editType: 'plot',\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnelarea/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnelarea/base_plot.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnelarea/base_plot.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar plots = __webpack_require__(/*! ../../plots/plots */ \"./node_modules/plotly.js/src/plots/plots.js\");\n\nexports.name = 'funnelarea';\n\nexports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) {\n plots.plotBasePlot(exports.name, gd, traces, transitionOpts, makeOnCompleteCallback);\n};\n\nexports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {\n plots.cleanBasePlot(exports.name, newFullData, newFullLayout, oldFullData, oldFullLayout);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnelarea/base_plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnelarea/calc.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnelarea/calc.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar pieCalc = __webpack_require__(/*! ../pie/calc */ \"./node_modules/plotly.js/src/traces/pie/calc.js\");\n\nfunction calc(gd, trace) {\n return pieCalc.calc(gd, trace);\n}\n\nfunction crossTraceCalc(gd) {\n pieCalc.crossTraceCalc(gd, { type: 'funnelarea' });\n}\n\nmodule.exports = {\n calc: calc,\n crossTraceCalc: crossTraceCalc\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnelarea/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnelarea/defaults.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnelarea/defaults.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/funnelarea/attributes.js\");\nvar handleDomainDefaults = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").defaults;\nvar handleText = __webpack_require__(/*! ../bar/defaults */ \"./node_modules/plotly.js/src/traces/bar/defaults.js\").handleText;\nvar handleLabelsAndValues = __webpack_require__(/*! ../pie/defaults */ \"./node_modules/plotly.js/src/traces/pie/defaults.js\").handleLabelsAndValues;\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var labels = coerce('labels');\n var values = coerce('values');\n\n var res = handleLabelsAndValues(labels, values);\n var len = res.len;\n traceOut._hasLabels = res.hasLabels;\n traceOut._hasValues = res.hasValues;\n\n if(!traceOut._hasLabels &&\n traceOut._hasValues\n ) {\n coerce('label0');\n coerce('dlabel');\n }\n\n if(!len) {\n traceOut.visible = false;\n return;\n }\n traceOut._length = len;\n\n var lineWidth = coerce('marker.line.width');\n if(lineWidth) coerce('marker.line.color', layout.paper_bgcolor);\n\n coerce('marker.colors');\n\n coerce('scalegroup');\n\n var textData = coerce('text');\n var textTemplate = coerce('texttemplate');\n var textInfo;\n if(!textTemplate) textInfo = coerce('textinfo', Array.isArray(textData) ? 'text+percent' : 'percent');\n\n coerce('hovertext');\n coerce('hovertemplate');\n\n if(textTemplate || (textInfo && textInfo !== 'none')) {\n var textposition = coerce('textposition');\n handleText(traceIn, traceOut, layout, coerce, textposition, {\n moduleHasSelected: false,\n moduleHasUnselected: false,\n moduleHasConstrain: false,\n moduleHasCliponaxis: false,\n moduleHasTextangle: false,\n moduleHasInsideanchor: false\n });\n }\n\n handleDomainDefaults(traceOut, layout, coerce);\n\n var title = coerce('title.text');\n if(title) {\n coerce('title.position');\n Lib.coerceFont(coerce, 'title.font', layout.font);\n }\n\n coerce('aspectratio');\n coerce('baseratio');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnelarea/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnelarea/index.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnelarea/index.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n moduleType: 'trace',\n name: 'funnelarea',\n basePlotModule: __webpack_require__(/*! ./base_plot */ \"./node_modules/plotly.js/src/traces/funnelarea/base_plot.js\"),\n categories: ['pie-like', 'funnelarea', 'showLegend'],\n\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/funnelarea/attributes.js\"),\n layoutAttributes: __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/funnelarea/layout_attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/funnelarea/defaults.js\"),\n supplyLayoutDefaults: __webpack_require__(/*! ./layout_defaults */ \"./node_modules/plotly.js/src/traces/funnelarea/layout_defaults.js\"),\n\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/funnelarea/calc.js\").calc,\n crossTraceCalc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/funnelarea/calc.js\").crossTraceCalc,\n\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/funnelarea/plot.js\"),\n style: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/funnelarea/style.js\"),\n styleOne: __webpack_require__(/*! ../pie/style_one */ \"./node_modules/plotly.js/src/traces/pie/style_one.js\"),\n\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnelarea/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnelarea/layout_attributes.js":
-/*!***************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnelarea/layout_attributes.js ***!
- \***************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar hiddenlabels = __webpack_require__(/*! ../pie/layout_attributes */ \"./node_modules/plotly.js/src/traces/pie/layout_attributes.js\").hiddenlabels;\n\nmodule.exports = {\n hiddenlabels: hiddenlabels,\n\n funnelareacolorway: {\n valType: 'colorlist',\n \n editType: 'calc',\n \n },\n extendfunnelareacolors: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'calc',\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnelarea/layout_attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnelarea/layout_defaults.js":
-/*!*************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnelarea/layout_defaults.js ***!
- \*************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar layoutAttributes = __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/funnelarea/layout_attributes.js\");\n\nmodule.exports = function supplyLayoutDefaults(layoutIn, layoutOut) {\n function coerce(attr, dflt) {\n return Lib.coerce(layoutIn, layoutOut, layoutAttributes, attr, dflt);\n }\n\n coerce('hiddenlabels');\n coerce('funnelareacolorway', layoutOut.colorway);\n coerce('extendfunnelareacolors');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnelarea/layout_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnelarea/plot.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnelarea/plot.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar svgTextUtils = __webpack_require__(/*! ../../lib/svg_text_utils */ \"./node_modules/plotly.js/src/lib/svg_text_utils.js\");\n\nvar barPlot = __webpack_require__(/*! ../bar/plot */ \"./node_modules/plotly.js/src/traces/bar/plot.js\");\nvar toMoveInsideBar = barPlot.toMoveInsideBar;\nvar uniformText = __webpack_require__(/*! ../bar/uniform_text */ \"./node_modules/plotly.js/src/traces/bar/uniform_text.js\");\nvar recordMinTextSize = uniformText.recordMinTextSize;\nvar clearMinTextSize = uniformText.clearMinTextSize;\nvar pieHelpers = __webpack_require__(/*! ../pie/helpers */ \"./node_modules/plotly.js/src/traces/pie/helpers.js\");\nvar piePlot = __webpack_require__(/*! ../pie/plot */ \"./node_modules/plotly.js/src/traces/pie/plot.js\");\n\nvar attachFxHandlers = piePlot.attachFxHandlers;\nvar determineInsideTextFont = piePlot.determineInsideTextFont;\n\nvar layoutAreas = piePlot.layoutAreas;\nvar prerenderTitles = piePlot.prerenderTitles;\nvar positionTitleOutside = piePlot.positionTitleOutside;\nvar formatSliceLabel = piePlot.formatSliceLabel;\n\nmodule.exports = function plot(gd, cdModule) {\n var fullLayout = gd._fullLayout;\n\n clearMinTextSize('funnelarea', fullLayout);\n\n prerenderTitles(cdModule, gd);\n layoutAreas(cdModule, fullLayout._size);\n\n Lib.makeTraceGroups(fullLayout._funnelarealayer, cdModule, 'trace').each(function(cd) {\n var plotGroup = d3.select(this);\n var cd0 = cd[0];\n var trace = cd0.trace;\n\n setCoords(cd);\n\n plotGroup.each(function() {\n var slices = d3.select(this).selectAll('g.slice').data(cd);\n\n slices.enter().append('g')\n .classed('slice', true);\n slices.exit().remove();\n\n slices.each(function(pt, i) {\n if(pt.hidden) {\n d3.select(this).selectAll('path,g').remove();\n return;\n }\n\n // to have consistent event data compared to other traces\n pt.pointNumber = pt.i;\n pt.curveNumber = trace.index;\n\n var cx = cd0.cx;\n var cy = cd0.cy;\n var sliceTop = d3.select(this);\n var slicePath = sliceTop.selectAll('path.surface').data([pt]);\n\n slicePath.enter().append('path')\n .classed('surface', true)\n .style({'pointer-events': 'all'});\n\n sliceTop.call(attachFxHandlers, gd, cd);\n\n var shape =\n 'M' + (cx + pt.TR[0]) + ',' + (cy + pt.TR[1]) +\n line(pt.TR, pt.BR) +\n line(pt.BR, pt.BL) +\n line(pt.BL, pt.TL) +\n 'Z';\n\n slicePath.attr('d', shape);\n\n // add text\n formatSliceLabel(gd, pt, cd0);\n var textPosition = pieHelpers.castOption(trace.textposition, pt.pts);\n var sliceTextGroup = sliceTop.selectAll('g.slicetext')\n .data(pt.text && (textPosition !== 'none') ? [0] : []);\n\n sliceTextGroup.enter().append('g')\n .classed('slicetext', true);\n sliceTextGroup.exit().remove();\n\n sliceTextGroup.each(function() {\n var sliceText = Lib.ensureSingle(d3.select(this), 'text', '', function(s) {\n // prohibit tex interpretation until we can handle\n // tex and regular text together\n s.attr('data-notex', 1);\n });\n\n var font = Lib.ensureUniformFontSize(gd, determineInsideTextFont(trace, pt, fullLayout.font));\n\n sliceText.text(pt.text)\n .attr({\n 'class': 'slicetext',\n transform: '',\n 'text-anchor': 'middle'\n })\n .call(Drawing.font, font)\n .call(svgTextUtils.convertToTspans, gd);\n\n // position the text relative to the slice\n var textBB = Drawing.bBox(sliceText.node());\n var transform;\n\n var x0, x1;\n var y0 = Math.min(pt.BL[1], pt.BR[1]) + cy;\n var y1 = Math.max(pt.TL[1], pt.TR[1]) + cy;\n\n x0 = Math.max(pt.TL[0], pt.BL[0]) + cx;\n x1 = Math.min(pt.TR[0], pt.BR[0]) + cx;\n\n transform = toMoveInsideBar(x0, x1, y0, y1, textBB, {\n isHorizontal: true,\n constrained: true,\n angle: 0,\n anchor: 'middle'\n });\n\n transform.fontSize = font.size;\n recordMinTextSize(trace.type, transform, fullLayout);\n cd[i].transform = transform;\n\n sliceText.attr('transform', Lib.getTextTransform(transform));\n });\n });\n\n // add the title\n var titleTextGroup = d3.select(this).selectAll('g.titletext')\n .data(trace.title.text ? [0] : []);\n\n titleTextGroup.enter().append('g')\n .classed('titletext', true);\n titleTextGroup.exit().remove();\n\n titleTextGroup.each(function() {\n var titleText = Lib.ensureSingle(d3.select(this), 'text', '', function(s) {\n // prohibit tex interpretation as above\n s.attr('data-notex', 1);\n });\n\n var txt = trace.title.text;\n if(trace._meta) {\n txt = Lib.templateString(txt, trace._meta);\n }\n\n titleText.text(txt)\n .attr({\n 'class': 'titletext',\n transform: '',\n 'text-anchor': 'middle',\n })\n .call(Drawing.font, trace.title.font)\n .call(svgTextUtils.convertToTspans, gd);\n\n var transform = positionTitleOutside(cd0, fullLayout._size);\n\n titleText.attr('transform',\n 'translate(' + transform.x + ',' + transform.y + ')' +\n (transform.scale < 1 ? ('scale(' + transform.scale + ')') : '') +\n 'translate(' + transform.tx + ',' + transform.ty + ')');\n });\n });\n });\n};\n\nfunction line(a, b) {\n var dx = b[0] - a[0];\n var dy = b[1] - a[1];\n\n return 'l' + dx + ',' + dy;\n}\n\nfunction getBetween(a, b) {\n return [\n 0.5 * (a[0] + b[0]),\n 0.5 * (a[1] + b[1])\n ];\n}\n\nfunction setCoords(cd) {\n if(!cd.length) return;\n\n var cd0 = cd[0];\n var trace = cd0.trace;\n\n var aspectratio = trace.aspectratio;\n\n var h = trace.baseratio;\n if(h > 0.999) h = 0.999; // TODO: may handle this case separately\n var h2 = Math.pow(h, 2);\n\n var v1 = cd0.vTotal;\n var v0 = v1 * h2 / (1 - h2);\n\n var totalValues = v1;\n var sumSteps = v0 / v1;\n\n function calcPos() {\n var q = Math.sqrt(sumSteps);\n return {\n x: q,\n y: -q\n };\n }\n\n function getPoint() {\n var pos = calcPos();\n return [pos.x, pos.y];\n }\n\n var p;\n var allPoints = [];\n allPoints.push(getPoint());\n\n var i, cdi;\n for(i = cd.length - 1; i > -1; i--) {\n cdi = cd[i];\n if(cdi.hidden) continue;\n\n var step = cdi.v / totalValues;\n sumSteps += step;\n\n allPoints.push(getPoint());\n }\n\n var minY = Infinity;\n var maxY = -Infinity;\n for(i = 0; i < allPoints.length; i++) {\n p = allPoints[i];\n minY = Math.min(minY, p[1]);\n maxY = Math.max(maxY, p[1]);\n }\n\n // center the shape\n for(i = 0; i < allPoints.length; i++) {\n allPoints[i][1] -= (maxY + minY) / 2;\n }\n\n var lastX = allPoints[allPoints.length - 1][0];\n\n // get pie r\n var r = cd0.r;\n\n var rY = (maxY - minY) / 2;\n var scaleX = r / lastX;\n var scaleY = r / rY * aspectratio;\n\n // set funnelarea r\n cd0.r = scaleY * rY;\n\n // scale the shape\n for(i = 0; i < allPoints.length; i++) {\n allPoints[i][0] *= scaleX;\n allPoints[i][1] *= scaleY;\n }\n\n // record first position\n p = allPoints[0];\n var prevLeft = [-p[0], p[1]];\n var prevRight = [p[0], p[1]];\n\n var n = 0; // note we skip the very first point.\n for(i = cd.length - 1; i > -1; i--) {\n cdi = cd[i];\n if(cdi.hidden) continue;\n\n n += 1;\n var x = allPoints[n][0];\n var y = allPoints[n][1];\n\n cdi.TL = [-x, y];\n cdi.TR = [x, y];\n\n cdi.BL = prevLeft;\n cdi.BR = prevRight;\n\n cdi.pxmid = getBetween(cdi.TR, cdi.BR);\n\n prevLeft = cdi.TL;\n prevRight = cdi.TR;\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnelarea/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/funnelarea/style.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/funnelarea/style.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar styleOne = __webpack_require__(/*! ../pie/style_one */ \"./node_modules/plotly.js/src/traces/pie/style_one.js\");\nvar resizeText = __webpack_require__(/*! ../bar/uniform_text */ \"./node_modules/plotly.js/src/traces/bar/uniform_text.js\").resizeText;\n\nmodule.exports = function style(gd) {\n var s = gd._fullLayout._funnelarealayer.selectAll('.trace');\n resizeText(gd, s, 'funnelarea');\n\n s.each(function(cd) {\n var cd0 = cd[0];\n var trace = cd0.trace;\n var traceSelection = d3.select(this);\n\n traceSelection.style({opacity: trace.opacity});\n\n traceSelection.selectAll('path.surface').each(function(pt) {\n d3.select(this).call(styleOne, pt, trace);\n });\n });\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/funnelarea/style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmap/attributes.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmap/attributes.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar scatterAttrs = __webpack_require__(/*! ../scatter/attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\");\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar FORMAT_LINK = __webpack_require__(/*! ../../constants/docs */ \"./node_modules/plotly.js/src/constants/docs.js\").FORMAT_LINK;\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nmodule.exports = extendFlat({\n z: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n x: extendFlat({}, scatterAttrs.x, {impliedEdits: {xtype: 'array'}}),\n x0: extendFlat({}, scatterAttrs.x0, {impliedEdits: {xtype: 'scaled'}}),\n dx: extendFlat({}, scatterAttrs.dx, {impliedEdits: {xtype: 'scaled'}}),\n y: extendFlat({}, scatterAttrs.y, {impliedEdits: {ytype: 'array'}}),\n y0: extendFlat({}, scatterAttrs.y0, {impliedEdits: {ytype: 'scaled'}}),\n dy: extendFlat({}, scatterAttrs.dy, {impliedEdits: {ytype: 'scaled'}}),\n\n text: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n hovertext: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n transpose: {\n valType: 'boolean',\n dflt: false,\n \n editType: 'calc',\n \n },\n xtype: {\n valType: 'enumerated',\n values: ['array', 'scaled'],\n \n editType: 'calc+clearAxisTypes',\n \n },\n ytype: {\n valType: 'enumerated',\n values: ['array', 'scaled'],\n \n editType: 'calc+clearAxisTypes',\n \n },\n zsmooth: {\n valType: 'enumerated',\n values: ['fast', 'best', false],\n dflt: false,\n \n editType: 'calc',\n \n },\n hoverongaps: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'none',\n \n },\n connectgaps: {\n valType: 'boolean',\n \n editType: 'calc',\n \n },\n xgap: {\n valType: 'number',\n dflt: 0,\n min: 0,\n \n editType: 'plot',\n \n },\n ygap: {\n valType: 'number',\n dflt: 0,\n min: 0,\n \n editType: 'plot',\n \n },\n zhoverformat: {\n valType: 'string',\n dflt: '',\n \n editType: 'none',\n \n },\n hovertemplate: hovertemplateAttrs(),\n showlegend: extendFlat({}, baseAttrs.showlegend, {dflt: false})\n}, {\n transforms: undefined\n},\n colorScaleAttrs('', {cLetter: 'z', autoColorDflt: false})\n);\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmap/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmap/calc.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmap/calc.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\n\nvar histogram2dCalc = __webpack_require__(/*! ../histogram2d/calc */ \"./node_modules/plotly.js/src/traces/histogram2d/calc.js\");\nvar colorscaleCalc = __webpack_require__(/*! ../../components/colorscale/calc */ \"./node_modules/plotly.js/src/components/colorscale/calc.js\");\nvar convertColumnData = __webpack_require__(/*! ./convert_column_xyz */ \"./node_modules/plotly.js/src/traces/heatmap/convert_column_xyz.js\");\nvar clean2dArray = __webpack_require__(/*! ./clean_2d_array */ \"./node_modules/plotly.js/src/traces/heatmap/clean_2d_array.js\");\nvar interp2d = __webpack_require__(/*! ./interp2d */ \"./node_modules/plotly.js/src/traces/heatmap/interp2d.js\");\nvar findEmpties = __webpack_require__(/*! ./find_empties */ \"./node_modules/plotly.js/src/traces/heatmap/find_empties.js\");\nvar makeBoundArray = __webpack_require__(/*! ./make_bound_array */ \"./node_modules/plotly.js/src/traces/heatmap/make_bound_array.js\");\n\nmodule.exports = function calc(gd, trace) {\n // prepare the raw data\n // run makeCalcdata on x and y even for heatmaps, in case of category mappings\n var xa = Axes.getFromId(gd, trace.xaxis || 'x');\n var ya = Axes.getFromId(gd, trace.yaxis || 'y');\n var isContour = Registry.traceIs(trace, 'contour');\n var isHist = Registry.traceIs(trace, 'histogram');\n var isGL2D = Registry.traceIs(trace, 'gl2d');\n var zsmooth = isContour ? 'best' : trace.zsmooth;\n var x;\n var x0;\n var dx;\n var y;\n var y0;\n var dy;\n var z;\n var i;\n var binned;\n\n // cancel minimum tick spacings (only applies to bars and boxes)\n xa._minDtick = 0;\n ya._minDtick = 0;\n\n if(isHist) {\n binned = histogram2dCalc(gd, trace);\n x = binned.x;\n x0 = binned.x0;\n dx = binned.dx;\n y = binned.y;\n y0 = binned.y0;\n dy = binned.dy;\n z = binned.z;\n } else {\n var zIn = trace.z;\n if(Lib.isArray1D(zIn)) {\n convertColumnData(trace, xa, ya, 'x', 'y', ['z']);\n x = trace._x;\n y = trace._y;\n zIn = trace._z;\n } else {\n x = trace._x = trace.x ? xa.makeCalcdata(trace, 'x') : [];\n y = trace._y = trace.y ? ya.makeCalcdata(trace, 'y') : [];\n }\n\n x0 = trace.x0;\n dx = trace.dx;\n y0 = trace.y0;\n dy = trace.dy;\n\n z = clean2dArray(zIn, trace, xa, ya);\n\n if(isContour || trace.connectgaps) {\n trace._emptypoints = findEmpties(z);\n interp2d(z, trace._emptypoints);\n }\n }\n\n function noZsmooth(msg) {\n zsmooth = trace._input.zsmooth = trace.zsmooth = false;\n Lib.warn('cannot use zsmooth: \"fast\": ' + msg);\n }\n\n // check whether we really can smooth (ie all boxes are about the same size)\n if(zsmooth === 'fast') {\n if(xa.type === 'log' || ya.type === 'log') {\n noZsmooth('log axis found');\n } else if(!isHist) {\n if(x.length) {\n var avgdx = (x[x.length - 1] - x[0]) / (x.length - 1);\n var maxErrX = Math.abs(avgdx / 100);\n for(i = 0; i < x.length - 1; i++) {\n if(Math.abs(x[i + 1] - x[i] - avgdx) > maxErrX) {\n noZsmooth('x scale is not linear');\n break;\n }\n }\n }\n if(y.length && zsmooth === 'fast') {\n var avgdy = (y[y.length - 1] - y[0]) / (y.length - 1);\n var maxErrY = Math.abs(avgdy / 100);\n for(i = 0; i < y.length - 1; i++) {\n if(Math.abs(y[i + 1] - y[i] - avgdy) > maxErrY) {\n noZsmooth('y scale is not linear');\n break;\n }\n }\n }\n }\n }\n\n // create arrays of brick boundaries, to be used by autorange and heatmap.plot\n var xlen = Lib.maxRowLength(z);\n var xIn = trace.xtype === 'scaled' ? '' : x;\n var xArray = makeBoundArray(trace, xIn, x0, dx, xlen, xa);\n var yIn = trace.ytype === 'scaled' ? '' : y;\n var yArray = makeBoundArray(trace, yIn, y0, dy, z.length, ya);\n\n // handled in gl2d convert step\n if(!isGL2D) {\n trace._extremes[xa._id] = Axes.findExtremes(xa, xArray);\n trace._extremes[ya._id] = Axes.findExtremes(ya, yArray);\n }\n\n var cd0 = {\n x: xArray,\n y: yArray,\n z: z,\n text: trace._text || trace.text,\n hovertext: trace._hovertext || trace.hovertext\n };\n\n if(xIn && xIn.length === xArray.length - 1) cd0.xCenter = xIn;\n if(yIn && yIn.length === yArray.length - 1) cd0.yCenter = yIn;\n\n if(isHist) {\n cd0.xRanges = binned.xRanges;\n cd0.yRanges = binned.yRanges;\n cd0.pts = binned.pts;\n }\n\n if(!isContour) {\n colorscaleCalc(gd, trace, {vals: z, cLetter: 'z'});\n }\n\n if(isContour && trace.contours && trace.contours.coloring === 'heatmap') {\n var dummyTrace = {\n type: trace.type === 'contour' ? 'heatmap' : 'histogram2d',\n xcalendar: trace.xcalendar,\n ycalendar: trace.ycalendar\n };\n cd0.xfill = makeBoundArray(dummyTrace, xIn, x0, dx, xlen, xa);\n cd0.yfill = makeBoundArray(dummyTrace, yIn, y0, dy, z.length, ya);\n }\n\n return [cd0];\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmap/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmap/clean_2d_array.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmap/clean_2d_array.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nmodule.exports = function clean2dArray(zOld, trace, xa, ya) {\n var rowlen, collen, getCollen, old2new, i, j;\n\n function cleanZvalue(v) {\n if(!isNumeric(v)) return undefined;\n return +v;\n }\n\n if(trace && trace.transpose) {\n rowlen = 0;\n for(i = 0; i < zOld.length; i++) rowlen = Math.max(rowlen, zOld[i].length);\n if(rowlen === 0) return false;\n getCollen = function(zOld) { return zOld.length; };\n old2new = function(zOld, i, j) { return (zOld[j] || [])[i]; };\n } else {\n rowlen = zOld.length;\n getCollen = function(zOld, i) { return zOld[i].length; };\n old2new = function(zOld, i, j) { return (zOld[i] || [])[j]; };\n }\n\n var padOld2new = function(zOld, i, j) {\n if(i === BADNUM || j === BADNUM) return BADNUM;\n return old2new(zOld, i, j);\n };\n\n function axisMapping(ax) {\n if(trace && trace.type !== 'carpet' && trace.type !== 'contourcarpet' &&\n ax && ax.type === 'category' && trace['_' + ax._id.charAt(0)].length) {\n var axLetter = ax._id.charAt(0);\n var axMapping = {};\n var traceCategories = trace['_' + axLetter + 'CategoryMap'] || trace[axLetter];\n for(i = 0; i < traceCategories.length; i++) {\n axMapping[traceCategories[i]] = i;\n }\n return function(i) {\n var ind = axMapping[ax._categories[i]];\n return ind + 1 ? ind : BADNUM;\n };\n } else {\n return Lib.identity;\n }\n }\n\n var xMap = axisMapping(xa);\n var yMap = axisMapping(ya);\n\n if(ya && ya.type === 'category') rowlen = ya._categories.length;\n var zNew = new Array(rowlen);\n\n for(i = 0; i < rowlen; i++) {\n if(xa && xa.type === 'category') {\n collen = xa._categories.length;\n } else {\n collen = getCollen(zOld, i);\n }\n zNew[i] = new Array(collen);\n for(j = 0; j < collen; j++) zNew[i][j] = cleanZvalue(padOld2new(zOld, yMap(i), xMap(j)));\n }\n\n return zNew;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmap/clean_2d_array.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmap/colorbar.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmap/colorbar.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n min: 'zmin',\n max: 'zmax'\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmap/colorbar.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmap/convert_column_xyz.js":
-/*!*************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmap/convert_column_xyz.js ***!
- \*************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nmodule.exports = function convertColumnData(trace, ax1, ax2, var1Name, var2Name, arrayVarNames) {\n var colLen = trace._length;\n var col1 = ax1.makeCalcdata(trace, var1Name);\n var col2 = ax2.makeCalcdata(trace, var2Name);\n var textCol = trace.text;\n var hasColumnText = (textCol !== undefined && Lib.isArray1D(textCol));\n var hoverTextCol = trace.hovertext;\n var hasColumnHoverText = (hoverTextCol !== undefined && Lib.isArray1D(hoverTextCol));\n var i, j;\n\n var col1dv = Lib.distinctVals(col1);\n var col1vals = col1dv.vals;\n var col2dv = Lib.distinctVals(col2);\n var col2vals = col2dv.vals;\n var newArrays = [];\n var text;\n var hovertext;\n\n for(i = 0; i < arrayVarNames.length; i++) {\n newArrays[i] = Lib.init2dArray(col2vals.length, col1vals.length);\n }\n\n if(hasColumnText) {\n text = Lib.init2dArray(col2vals.length, col1vals.length);\n }\n if(hasColumnHoverText) {\n hovertext = Lib.init2dArray(col2vals.length, col1vals.length);\n }\n\n var after2before = Lib.init2dArray(col2vals.length, col1vals.length);\n\n for(i = 0; i < colLen; i++) {\n if(col1[i] !== BADNUM && col2[i] !== BADNUM) {\n var i1 = Lib.findBin(col1[i] + col1dv.minDiff / 2, col1vals);\n var i2 = Lib.findBin(col2[i] + col2dv.minDiff / 2, col2vals);\n\n for(j = 0; j < arrayVarNames.length; j++) {\n var arrayVarName = arrayVarNames[j];\n var arrayVar = trace[arrayVarName];\n var newArray = newArrays[j];\n newArray[i2][i1] = arrayVar[i];\n after2before[i2][i1] = i;\n }\n\n if(hasColumnText) text[i2][i1] = textCol[i];\n if(hasColumnHoverText) hovertext[i2][i1] = hoverTextCol[i];\n }\n }\n\n trace['_' + var1Name] = col1vals;\n trace['_' + var2Name] = col2vals;\n for(j = 0; j < arrayVarNames.length; j++) {\n trace['_' + arrayVarNames[j]] = newArrays[j];\n }\n if(hasColumnText) trace._text = text;\n if(hasColumnHoverText) trace._hovertext = hovertext;\n\n if(ax1 && ax1.type === 'category') {\n trace['_' + var1Name + 'CategoryMap'] = col1vals.map(function(v) { return ax1._categories[v];});\n }\n\n if(ax2 && ax2.type === 'category') {\n trace['_' + var2Name + 'CategoryMap'] = col2vals.map(function(v) { return ax2._categories[v];});\n }\n\n trace._after2before = after2before;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmap/convert_column_xyz.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmap/defaults.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmap/defaults.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar handleXYZDefaults = __webpack_require__(/*! ./xyz_defaults */ \"./node_modules/plotly.js/src/traces/heatmap/xyz_defaults.js\");\nvar handleStyleDefaults = __webpack_require__(/*! ./style_defaults */ \"./node_modules/plotly.js/src/traces/heatmap/style_defaults.js\");\nvar colorscaleDefaults = __webpack_require__(/*! ../../components/colorscale/defaults */ \"./node_modules/plotly.js/src/components/colorscale/defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/heatmap/attributes.js\");\n\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var validData = handleXYZDefaults(traceIn, traceOut, coerce, layout);\n if(!validData) {\n traceOut.visible = false;\n return;\n }\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n\n handleStyleDefaults(traceIn, traceOut, coerce, layout);\n\n coerce('hoverongaps');\n coerce('connectgaps', Lib.isArray1D(traceOut.z) && (traceOut.zsmooth !== false));\n\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'z'});\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmap/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmap/find_empties.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmap/find_empties.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar maxRowLength = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").maxRowLength;\n\n/* Return a list of empty points in 2D array z\n * each empty point z[i][j] gives an array [i, j, neighborCount]\n * neighborCount is the count of 4 nearest neighbors that DO exist\n * this is to give us an order of points to evaluate for interpolation.\n * if no neighbors exist, we iteratively look for neighbors that HAVE\n * neighbors, and add a fractional neighborCount\n */\nmodule.exports = function findEmpties(z) {\n var empties = [];\n var neighborHash = {};\n var noNeighborList = [];\n var nextRow = z[0];\n var row = [];\n var blank = [0, 0, 0];\n var rowLength = maxRowLength(z);\n var prevRow;\n var i;\n var j;\n var thisPt;\n var p;\n var neighborCount;\n var newNeighborHash;\n var foundNewNeighbors;\n\n for(i = 0; i < z.length; i++) {\n prevRow = row;\n row = nextRow;\n nextRow = z[i + 1] || [];\n for(j = 0; j < rowLength; j++) {\n if(row[j] === undefined) {\n neighborCount = (row[j - 1] !== undefined ? 1 : 0) +\n (row[j + 1] !== undefined ? 1 : 0) +\n (prevRow[j] !== undefined ? 1 : 0) +\n (nextRow[j] !== undefined ? 1 : 0);\n\n if(neighborCount) {\n // for this purpose, don't count off-the-edge points\n // as undefined neighbors\n if(i === 0) neighborCount++;\n if(j === 0) neighborCount++;\n if(i === z.length - 1) neighborCount++;\n if(j === row.length - 1) neighborCount++;\n\n // if all neighbors that could exist do, we don't\n // need this for finding farther neighbors\n if(neighborCount < 4) {\n neighborHash[[i, j]] = [i, j, neighborCount];\n }\n\n empties.push([i, j, neighborCount]);\n } else noNeighborList.push([i, j]);\n }\n }\n }\n\n while(noNeighborList.length) {\n newNeighborHash = {};\n foundNewNeighbors = false;\n\n // look for cells that now have neighbors but didn't before\n for(p = noNeighborList.length - 1; p >= 0; p--) {\n thisPt = noNeighborList[p];\n i = thisPt[0];\n j = thisPt[1];\n\n neighborCount = ((neighborHash[[i - 1, j]] || blank)[2] +\n (neighborHash[[i + 1, j]] || blank)[2] +\n (neighborHash[[i, j - 1]] || blank)[2] +\n (neighborHash[[i, j + 1]] || blank)[2]) / 20;\n\n if(neighborCount) {\n newNeighborHash[thisPt] = [i, j, neighborCount];\n noNeighborList.splice(p, 1);\n foundNewNeighbors = true;\n }\n }\n\n if(!foundNewNeighbors) {\n throw 'findEmpties iterated with no new neighbors';\n }\n\n // put these new cells into the main neighbor list\n for(thisPt in newNeighborHash) {\n neighborHash[thisPt] = newNeighborHash[thisPt];\n empties.push(newNeighborHash[thisPt]);\n }\n }\n\n // sort the full list in descending order of neighbor count\n return empties.sort(function(a, b) { return b[2] - a[2]; });\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmap/find_empties.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmap/hover.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmap/hover.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Fx = __webpack_require__(/*! ../../components/fx */ \"./node_modules/plotly.js/src/components/fx/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar extractOpts = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\").extractOpts;\n\nmodule.exports = function hoverPoints(pointData, xval, yval, hovermode, hoverLayer, contour) {\n var cd0 = pointData.cd[0];\n var trace = cd0.trace;\n var xa = pointData.xa;\n var ya = pointData.ya;\n var x = cd0.x;\n var y = cd0.y;\n var z = cd0.z;\n var xc = cd0.xCenter;\n var yc = cd0.yCenter;\n var zmask = cd0.zmask;\n var zhoverformat = trace.zhoverformat;\n var x2 = x;\n var y2 = y;\n\n var xl, yl, nx, ny;\n\n if(pointData.index !== false) {\n try {\n nx = Math.round(pointData.index[1]);\n ny = Math.round(pointData.index[0]);\n } catch(e) {\n Lib.error('Error hovering on heatmap, ' +\n 'pointNumber must be [row,col], found:', pointData.index);\n return;\n }\n if(nx < 0 || nx >= z[0].length || ny < 0 || ny > z.length) {\n return;\n }\n } else if(Fx.inbox(xval - x[0], xval - x[x.length - 1], 0) > 0 ||\n Fx.inbox(yval - y[0], yval - y[y.length - 1], 0) > 0) {\n return;\n } else {\n if(contour) {\n var i2;\n x2 = [2 * x[0] - x[1]];\n\n for(i2 = 1; i2 < x.length; i2++) {\n x2.push((x[i2] + x[i2 - 1]) / 2);\n }\n x2.push([2 * x[x.length - 1] - x[x.length - 2]]);\n\n y2 = [2 * y[0] - y[1]];\n for(i2 = 1; i2 < y.length; i2++) {\n y2.push((y[i2] + y[i2 - 1]) / 2);\n }\n y2.push([2 * y[y.length - 1] - y[y.length - 2]]);\n }\n nx = Math.max(0, Math.min(x2.length - 2, Lib.findBin(xval, x2)));\n ny = Math.max(0, Math.min(y2.length - 2, Lib.findBin(yval, y2)));\n }\n\n var x0 = xa.c2p(x[nx]);\n var x1 = xa.c2p(x[nx + 1]);\n var y0 = ya.c2p(y[ny]);\n var y1 = ya.c2p(y[ny + 1]);\n\n if(contour) {\n x1 = x0;\n xl = x[nx];\n y1 = y0;\n yl = y[ny];\n } else {\n xl = xc ? xc[nx] : ((x[nx] + x[nx + 1]) / 2);\n yl = yc ? yc[ny] : ((y[ny] + y[ny + 1]) / 2);\n\n if(xa && xa.type === 'category') xl = x[nx];\n if(ya && ya.type === 'category') yl = y[ny];\n\n if(trace.zsmooth) {\n x0 = x1 = xa.c2p(xl);\n y0 = y1 = ya.c2p(yl);\n }\n }\n\n var zVal = z[ny][nx];\n if(zmask && !zmask[ny][nx]) zVal = undefined;\n\n if(zVal === undefined && !trace.hoverongaps) return;\n\n var text;\n if(Array.isArray(cd0.hovertext) && Array.isArray(cd0.hovertext[ny])) {\n text = cd0.hovertext[ny][nx];\n } else if(Array.isArray(cd0.text) && Array.isArray(cd0.text[ny])) {\n text = cd0.text[ny][nx];\n }\n\n // dummy axis for formatting the z value\n var cOpts = extractOpts(trace);\n var dummyAx = {\n type: 'linear',\n range: [cOpts.min, cOpts.max],\n hoverformat: zhoverformat,\n _separators: xa._separators,\n _numFormat: xa._numFormat\n };\n var zLabel = Axes.tickText(dummyAx, zVal, 'hover').text;\n\n return [Lib.extendFlat(pointData, {\n index: trace._after2before ? trace._after2before[ny][nx] : [ny, nx],\n // never let a 2D override 1D type as closest point\n distance: pointData.maxHoverDistance,\n spikeDistance: pointData.maxSpikeDistance,\n x0: x0,\n x1: x1,\n y0: y0,\n y1: y1,\n xLabelVal: xl,\n yLabelVal: yl,\n zLabelVal: zVal,\n zLabel: zLabel,\n text: text\n })];\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmap/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmap/index.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmap/index.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/heatmap/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/heatmap/defaults.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/heatmap/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/heatmap/plot.js\"),\n colorbar: __webpack_require__(/*! ./colorbar */ \"./node_modules/plotly.js/src/traces/heatmap/colorbar.js\"),\n style: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/heatmap/style.js\"),\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/heatmap/hover.js\"),\n\n moduleType: 'trace',\n name: 'heatmap',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['cartesian', 'svg', '2dMap', 'showLegend'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmap/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmap/interp2d.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmap/interp2d.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar INTERPTHRESHOLD = 1e-2;\nvar NEIGHBORSHIFTS = [[-1, 0], [1, 0], [0, -1], [0, 1]];\n\nfunction correctionOvershoot(maxFractionalChange) {\n // start with less overshoot, until we know it's converging,\n // then ramp up the overshoot for faster convergence\n return 0.5 - 0.25 * Math.min(1, maxFractionalChange * 0.5);\n}\n\n/*\n * interp2d: Fill in missing data from a 2D array using an iterative\n * poisson equation solver with zero-derivative BC at edges.\n * Amazingly, this just amounts to repeatedly averaging all the existing\n * nearest neighbors, at least if we don't take x/y scaling into account,\n * which is the right approach here where x and y may not even have the\n * same units.\n *\n * @param {array of arrays} z\n * The 2D array to fill in. Will be mutated here. Assumed to already be\n * cleaned, so all entries are numbers except gaps, which are `undefined`.\n * @param {array of arrays} emptyPoints\n * Each entry [i, j, neighborCount] for empty points z[i][j] and the number\n * of neighbors that are *not* missing. Assumed to be sorted from most to\n * least neighbors, as produced by heatmap/find_empties.\n */\nmodule.exports = function interp2d(z, emptyPoints) {\n var maxFractionalChange = 1;\n var i;\n\n // one pass to fill in a starting value for all the empties\n iterateInterp2d(z, emptyPoints);\n\n // we're don't need to iterate lone empties - remove them\n for(i = 0; i < emptyPoints.length; i++) {\n if(emptyPoints[i][2] < 4) break;\n }\n // but don't remove these points from the original array,\n // we'll use them for masking, so make a copy.\n emptyPoints = emptyPoints.slice(i);\n\n for(i = 0; i < 100 && maxFractionalChange > INTERPTHRESHOLD; i++) {\n maxFractionalChange = iterateInterp2d(z, emptyPoints,\n correctionOvershoot(maxFractionalChange));\n }\n if(maxFractionalChange > INTERPTHRESHOLD) {\n Lib.log('interp2d didn\\'t converge quickly', maxFractionalChange);\n }\n\n return z;\n};\n\nfunction iterateInterp2d(z, emptyPoints, overshoot) {\n var maxFractionalChange = 0;\n var thisPt;\n var i;\n var j;\n var p;\n var q;\n var neighborShift;\n var neighborRow;\n var neighborVal;\n var neighborCount;\n var neighborSum;\n var initialVal;\n var minNeighbor;\n var maxNeighbor;\n\n for(p = 0; p < emptyPoints.length; p++) {\n thisPt = emptyPoints[p];\n i = thisPt[0];\n j = thisPt[1];\n initialVal = z[i][j];\n neighborSum = 0;\n neighborCount = 0;\n\n for(q = 0; q < 4; q++) {\n neighborShift = NEIGHBORSHIFTS[q];\n neighborRow = z[i + neighborShift[0]];\n if(!neighborRow) continue;\n neighborVal = neighborRow[j + neighborShift[1]];\n if(neighborVal !== undefined) {\n if(neighborSum === 0) {\n minNeighbor = maxNeighbor = neighborVal;\n } else {\n minNeighbor = Math.min(minNeighbor, neighborVal);\n maxNeighbor = Math.max(maxNeighbor, neighborVal);\n }\n neighborCount++;\n neighborSum += neighborVal;\n }\n }\n\n if(neighborCount === 0) {\n throw 'iterateInterp2d order is wrong: no defined neighbors';\n }\n\n // this is the laplace equation interpolation:\n // each point is just the average of its neighbors\n // note that this ignores differential x/y scaling\n // which I think is the right approach, since we\n // don't know what that scaling means\n z[i][j] = neighborSum / neighborCount;\n\n if(initialVal === undefined) {\n if(neighborCount < 4) maxFractionalChange = 1;\n } else {\n // we can make large empty regions converge faster\n // if we overshoot the change vs the previous value\n z[i][j] = (1 + overshoot) * z[i][j] - overshoot * initialVal;\n\n if(maxNeighbor > minNeighbor) {\n maxFractionalChange = Math.max(maxFractionalChange,\n Math.abs(z[i][j] - initialVal) / (maxNeighbor - minNeighbor));\n }\n }\n }\n\n return maxFractionalChange;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmap/interp2d.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmap/make_bound_array.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmap/make_bound_array.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar isArrayOrTypedArray = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").isArrayOrTypedArray;\n\nmodule.exports = function makeBoundArray(trace, arrayIn, v0In, dvIn, numbricks, ax) {\n var arrayOut = [];\n var isContour = Registry.traceIs(trace, 'contour');\n var isHist = Registry.traceIs(trace, 'histogram');\n var isGL2D = Registry.traceIs(trace, 'gl2d');\n var v0;\n var dv;\n var i;\n\n var isArrayOfTwoItemsOrMore = isArrayOrTypedArray(arrayIn) && arrayIn.length > 1;\n\n if(isArrayOfTwoItemsOrMore && !isHist && (ax.type !== 'category')) {\n var len = arrayIn.length;\n\n // given vals are brick centers\n // hopefully length === numbricks, but use this method even if too few are supplied\n // and extend it linearly based on the last two points\n if(len <= numbricks) {\n // contour plots only want the centers\n if(isContour || isGL2D) arrayOut = arrayIn.slice(0, numbricks);\n else if(numbricks === 1) {\n arrayOut = [arrayIn[0] - 0.5, arrayIn[0] + 0.5];\n } else {\n arrayOut = [1.5 * arrayIn[0] - 0.5 * arrayIn[1]];\n\n for(i = 1; i < len; i++) {\n arrayOut.push((arrayIn[i - 1] + arrayIn[i]) * 0.5);\n }\n\n arrayOut.push(1.5 * arrayIn[len - 1] - 0.5 * arrayIn[len - 2]);\n }\n\n if(len < numbricks) {\n var lastPt = arrayOut[arrayOut.length - 1];\n var delta = lastPt - arrayOut[arrayOut.length - 2];\n\n for(i = len; i < numbricks; i++) {\n lastPt += delta;\n arrayOut.push(lastPt);\n }\n }\n } else {\n // hopefully length === numbricks+1, but do something regardless:\n // given vals are brick boundaries\n return isContour ?\n arrayIn.slice(0, numbricks) : // we must be strict for contours\n arrayIn.slice(0, numbricks + 1);\n }\n } else {\n var calendar = trace[ax._id.charAt(0) + 'calendar'];\n\n if(isHist) {\n v0 = ax.r2c(v0In, 0, calendar);\n } else {\n if(isArrayOrTypedArray(arrayIn) && arrayIn.length === 1) {\n v0 = arrayIn[0];\n } else if(v0In === undefined) {\n v0 = 0;\n } else {\n var fn = ax.type === 'log' ? ax.d2c : ax.r2c;\n v0 = fn(v0In, 0, calendar);\n }\n }\n\n dv = dvIn || 1;\n\n for(i = (isContour || isGL2D) ? 0 : -0.5; i < numbricks; i++) {\n arrayOut.push(v0 + dv * i);\n }\n }\n\n return arrayOut;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmap/make_bound_array.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmap/plot.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmap/plot.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar tinycolor = __webpack_require__(/*! tinycolor2 */ \"./node_modules/tinycolor2/tinycolor.js\");\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar makeColorScaleFuncFromTrace = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\").makeColorScaleFuncFromTrace;\nvar xmlnsNamespaces = __webpack_require__(/*! ../../constants/xmlns_namespaces */ \"./node_modules/plotly.js/src/constants/xmlns_namespaces.js\");\n\nmodule.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n\n Lib.makeTraceGroups(heatmapLayer, cdheatmaps, 'hm').each(function(cd) {\n var plotGroup = d3.select(this);\n var cd0 = cd[0];\n var trace = cd0.trace;\n\n var z = cd0.z;\n var x = cd0.x;\n var y = cd0.y;\n var xc = cd0.xCenter;\n var yc = cd0.yCenter;\n var isContour = Registry.traceIs(trace, 'contour');\n var zsmooth = isContour ? 'best' : trace.zsmooth;\n\n // get z dims\n var m = z.length;\n var n = Lib.maxRowLength(z);\n var xrev = false;\n var yrev = false;\n\n var left, right, temp, top, bottom, i;\n\n // TODO: if there are multiple overlapping categorical heatmaps,\n // or if we allow category sorting, then the categories may not be\n // sequential... may need to reorder and/or expand z\n\n // Get edges of png in pixels (xa.c2p() maps axes coordinates to pixel coordinates)\n // figure out if either axis is reversed (y is usually reversed, in pixel coords)\n // also clip the image to maximum 50% outside the visible plot area\n // bigger image lets you pan more naturally, but slows performance.\n // TODO: use low-resolution images outside the visible plot for panning\n // these while loops find the first and last brick bounds that are defined\n // (in case of log of a negative)\n i = 0;\n while(left === undefined && i < x.length - 1) {\n left = xa.c2p(x[i]);\n i++;\n }\n i = x.length - 1;\n while(right === undefined && i > 0) {\n right = xa.c2p(x[i]);\n i--;\n }\n\n if(right < left) {\n temp = right;\n right = left;\n left = temp;\n xrev = true;\n }\n\n i = 0;\n while(top === undefined && i < y.length - 1) {\n top = ya.c2p(y[i]);\n i++;\n }\n i = y.length - 1;\n while(bottom === undefined && i > 0) {\n bottom = ya.c2p(y[i]);\n i--;\n }\n\n if(bottom < top) {\n temp = top;\n top = bottom;\n bottom = temp;\n yrev = true;\n }\n\n // for contours with heatmap fill, we generate the boundaries based on\n // brick centers but then use the brick edges for drawing the bricks\n if(isContour) {\n xc = x;\n yc = y;\n x = cd0.xfill;\n y = cd0.yfill;\n }\n\n // make an image that goes at most half a screen off either side, to keep\n // time reasonable when you zoom in. if zsmooth is true/fast, don't worry\n // about this, because zooming doesn't increase number of pixels\n // if zsmooth is best, don't include anything off screen because it takes too long\n if(zsmooth !== 'fast') {\n var extra = zsmooth === 'best' ? 0 : 0.5;\n left = Math.max(-extra * xa._length, left);\n right = Math.min((1 + extra) * xa._length, right);\n top = Math.max(-extra * ya._length, top);\n bottom = Math.min((1 + extra) * ya._length, bottom);\n }\n\n var imageWidth = Math.round(right - left);\n var imageHeight = Math.round(bottom - top);\n\n // setup image nodes\n\n // if image is entirely off-screen, don't even draw it\n var isOffScreen = (imageWidth <= 0 || imageHeight <= 0);\n\n if(isOffScreen) {\n var noImage = plotGroup.selectAll('image').data([]);\n noImage.exit().remove();\n return;\n }\n\n // generate image data\n\n var canvasW, canvasH;\n if(zsmooth === 'fast') {\n canvasW = n;\n canvasH = m;\n } else {\n canvasW = imageWidth;\n canvasH = imageHeight;\n }\n\n var canvas = document.createElement('canvas');\n canvas.width = canvasW;\n canvas.height = canvasH;\n var context = canvas.getContext('2d');\n\n var sclFunc = makeColorScaleFuncFromTrace(trace, {noNumericCheck: true, returnArray: true});\n\n // map brick boundaries to image pixels\n var xpx,\n ypx;\n if(zsmooth === 'fast') {\n xpx = xrev ?\n function(index) { return n - 1 - index; } :\n Lib.identity;\n ypx = yrev ?\n function(index) { return m - 1 - index; } :\n Lib.identity;\n } else {\n xpx = function(index) {\n return Lib.constrain(Math.round(xa.c2p(x[index]) - left),\n 0, imageWidth);\n };\n ypx = function(index) {\n return Lib.constrain(Math.round(ya.c2p(y[index]) - top),\n 0, imageHeight);\n };\n }\n\n // build the pixel map brick-by-brick\n // cruise through z-matrix row-by-row\n // build a brick at each z-matrix value\n var yi = ypx(0);\n var yb = [yi, yi];\n var xbi = xrev ? 0 : 1;\n var ybi = yrev ? 0 : 1;\n // for collecting an average luminosity of the heatmap\n var pixcount = 0;\n var rcount = 0;\n var gcount = 0;\n var bcount = 0;\n\n var xb, j, xi, v, row, c;\n\n function setColor(v, pixsize) {\n if(v !== undefined) {\n var c = sclFunc(v);\n c[0] = Math.round(c[0]);\n c[1] = Math.round(c[1]);\n c[2] = Math.round(c[2]);\n\n pixcount += pixsize;\n rcount += c[0] * pixsize;\n gcount += c[1] * pixsize;\n bcount += c[2] * pixsize;\n return c;\n }\n return [0, 0, 0, 0];\n }\n\n function interpColor(r0, r1, xinterp, yinterp) {\n var z00 = r0[xinterp.bin0];\n if(z00 === undefined) return setColor(undefined, 1);\n\n var z01 = r0[xinterp.bin1];\n var z10 = r1[xinterp.bin0];\n var z11 = r1[xinterp.bin1];\n var dx = (z01 - z00) || 0;\n var dy = (z10 - z00) || 0;\n var dxy;\n\n // the bilinear interpolation term needs different calculations\n // for all the different permutations of missing data\n // among the neighbors of the main point, to ensure\n // continuity across brick boundaries.\n if(z01 === undefined) {\n if(z11 === undefined) dxy = 0;\n else if(z10 === undefined) dxy = 2 * (z11 - z00);\n else dxy = (2 * z11 - z10 - z00) * 2 / 3;\n } else if(z11 === undefined) {\n if(z10 === undefined) dxy = 0;\n else dxy = (2 * z00 - z01 - z10) * 2 / 3;\n } else if(z10 === undefined) dxy = (2 * z11 - z01 - z00) * 2 / 3;\n else dxy = (z11 + z00 - z01 - z10);\n\n return setColor(z00 + xinterp.frac * dx + yinterp.frac * (dy + xinterp.frac * dxy));\n }\n\n if(zsmooth) { // best or fast, works fastest with imageData\n var pxIndex = 0;\n var pixels;\n\n try {\n pixels = new Uint8Array(imageWidth * imageHeight * 4);\n } catch(e) {\n pixels = new Array(imageWidth * imageHeight * 4);\n }\n\n if(zsmooth === 'best') {\n var xForPx = xc || x;\n var yForPx = yc || y;\n var xPixArray = new Array(xForPx.length);\n var yPixArray = new Array(yForPx.length);\n var xinterpArray = new Array(imageWidth);\n var findInterpX = xc ? findInterpFromCenters : findInterp;\n var findInterpY = yc ? findInterpFromCenters : findInterp;\n var yinterp, r0, r1;\n\n // first make arrays of x and y pixel locations of brick boundaries\n for(i = 0; i < xForPx.length; i++) xPixArray[i] = Math.round(xa.c2p(xForPx[i]) - left);\n for(i = 0; i < yForPx.length; i++) yPixArray[i] = Math.round(ya.c2p(yForPx[i]) - top);\n\n // then make arrays of interpolations\n // (bin0=closest, bin1=next, frac=fractional dist.)\n for(i = 0; i < imageWidth; i++) xinterpArray[i] = findInterpX(i, xPixArray);\n\n // now do the interpolations and fill the png\n for(j = 0; j < imageHeight; j++) {\n yinterp = findInterpY(j, yPixArray);\n r0 = z[yinterp.bin0];\n r1 = z[yinterp.bin1];\n for(i = 0; i < imageWidth; i++, pxIndex += 4) {\n c = interpColor(r0, r1, xinterpArray[i], yinterp);\n putColor(pixels, pxIndex, c);\n }\n }\n } else { // zsmooth = fast\n for(j = 0; j < m; j++) {\n row = z[j];\n yb = ypx(j);\n for(i = 0; i < imageWidth; i++) {\n c = setColor(row[i], 1);\n pxIndex = (yb * imageWidth + xpx(i)) * 4;\n putColor(pixels, pxIndex, c);\n }\n }\n }\n\n var imageData = context.createImageData(imageWidth, imageHeight);\n try {\n imageData.data.set(pixels);\n } catch(e) {\n var pxArray = imageData.data;\n var dlen = pxArray.length;\n for(j = 0; j < dlen; j ++) {\n pxArray[j] = pixels[j];\n }\n }\n\n context.putImageData(imageData, 0, 0);\n } else { // zsmooth = false -> filling potentially large bricks works fastest with fillRect\n // gaps do not need to be exact integers, but if they *are* we will get\n // cleaner edges by rounding at least one edge\n var xGap = trace.xgap;\n var yGap = trace.ygap;\n var xGapLeft = Math.floor(xGap / 2);\n var yGapTop = Math.floor(yGap / 2);\n\n for(j = 0; j < m; j++) {\n row = z[j];\n yb.reverse();\n yb[ybi] = ypx(j + 1);\n if(yb[0] === yb[1] || yb[0] === undefined || yb[1] === undefined) {\n continue;\n }\n xi = xpx(0);\n xb = [xi, xi];\n for(i = 0; i < n; i++) {\n // build one color brick!\n xb.reverse();\n xb[xbi] = xpx(i + 1);\n if(xb[0] === xb[1] || xb[0] === undefined || xb[1] === undefined) {\n continue;\n }\n v = row[i];\n c = setColor(v, (xb[1] - xb[0]) * (yb[1] - yb[0]));\n context.fillStyle = 'rgba(' + c.join(',') + ')';\n\n context.fillRect(xb[0] + xGapLeft, yb[0] + yGapTop,\n xb[1] - xb[0] - xGap, yb[1] - yb[0] - yGap);\n }\n }\n }\n\n rcount = Math.round(rcount / pixcount);\n gcount = Math.round(gcount / pixcount);\n bcount = Math.round(bcount / pixcount);\n var avgColor = tinycolor('rgb(' + rcount + ',' + gcount + ',' + bcount + ')');\n\n gd._hmpixcount = (gd._hmpixcount||0) + pixcount;\n gd._hmlumcount = (gd._hmlumcount||0) + pixcount * avgColor.getLuminance();\n\n var image3 = plotGroup.selectAll('image')\n .data(cd);\n\n image3.enter().append('svg:image').attr({\n xmlns: xmlnsNamespaces.svg,\n preserveAspectRatio: 'none'\n });\n\n image3.attr({\n height: imageHeight,\n width: imageWidth,\n x: left,\n y: top,\n 'xlink:href': canvas.toDataURL('image/png')\n });\n });\n};\n\n// get interpolated bin value. Returns {bin0:closest bin, frac:fractional dist to next, bin1:next bin}\nfunction findInterp(pixel, pixArray) {\n var maxBin = pixArray.length - 2;\n var bin = Lib.constrain(Lib.findBin(pixel, pixArray), 0, maxBin);\n var pix0 = pixArray[bin];\n var pix1 = pixArray[bin + 1];\n var interp = Lib.constrain(bin + (pixel - pix0) / (pix1 - pix0) - 0.5, 0, maxBin);\n var bin0 = Math.round(interp);\n var frac = Math.abs(interp - bin0);\n\n if(!interp || interp === maxBin || !frac) {\n return {\n bin0: bin0,\n bin1: bin0,\n frac: 0\n };\n }\n return {\n bin0: bin0,\n frac: frac,\n bin1: Math.round(bin0 + frac / (interp - bin0))\n };\n}\n\nfunction findInterpFromCenters(pixel, centerPixArray) {\n var maxBin = centerPixArray.length - 1;\n var bin = Lib.constrain(Lib.findBin(pixel, centerPixArray), 0, maxBin);\n var pix0 = centerPixArray[bin];\n var pix1 = centerPixArray[bin + 1];\n var frac = ((pixel - pix0) / (pix1 - pix0)) || 0;\n if(frac <= 0) {\n return {\n bin0: bin,\n bin1: bin,\n frac: 0\n };\n }\n if(frac < 0.5) {\n return {\n bin0: bin,\n bin1: bin + 1,\n frac: frac\n };\n }\n return {\n bin0: bin + 1,\n bin1: bin,\n frac: 1 - frac\n };\n}\n\nfunction putColor(pixels, pxIndex, c) {\n pixels[pxIndex] = c[0];\n pixels[pxIndex + 1] = c[1];\n pixels[pxIndex + 2] = c[2];\n pixels[pxIndex + 3] = Math.round(c[3] * 255);\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmap/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmap/style.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmap/style.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nmodule.exports = function style(gd) {\n d3.select(gd).selectAll('.hm image')\n .style('opacity', function(d) {\n return d.trace.opacity;\n });\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmap/style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmap/style_defaults.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmap/style_defaults.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nmodule.exports = function handleStyleDefaults(traceIn, traceOut, coerce) {\n var zsmooth = coerce('zsmooth');\n if(zsmooth === false) {\n // ensure that xgap and ygap are coerced only when zsmooth allows them to have an effect.\n coerce('xgap');\n coerce('ygap');\n }\n\n coerce('zhoverformat');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmap/style_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmap/xyz_defaults.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmap/xyz_defaults.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\n\nmodule.exports = function handleXYZDefaults(traceIn, traceOut, coerce, layout, xName, yName) {\n var z = coerce('z');\n xName = xName || 'x';\n yName = yName || 'y';\n var x, y;\n\n if(z === undefined || !z.length) return 0;\n\n if(Lib.isArray1D(traceIn.z)) {\n x = coerce(xName);\n y = coerce(yName);\n\n var xlen = Lib.minRowLength(x);\n var ylen = Lib.minRowLength(y);\n\n // column z must be accompanied by xName and yName arrays\n if(xlen === 0 || ylen === 0) return 0;\n\n traceOut._length = Math.min(xlen, ylen, z.length);\n } else {\n x = coordDefaults(xName, coerce);\n y = coordDefaults(yName, coerce);\n\n // TODO put z validation elsewhere\n if(!isValidZ(z)) return 0;\n\n coerce('transpose');\n\n traceOut._length = null;\n }\n\n var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleTraceDefaults');\n handleCalendarDefaults(traceIn, traceOut, [xName, yName], layout);\n\n return true;\n};\n\nfunction coordDefaults(coordStr, coerce) {\n var coord = coerce(coordStr);\n var coordType = coord ? coerce(coordStr + 'type', 'array') : 'scaled';\n\n if(coordType === 'scaled') {\n coerce(coordStr + '0');\n coerce('d' + coordStr);\n }\n\n return coord;\n}\n\nfunction isValidZ(z) {\n var allRowsAreArrays = true;\n var oneRowIsFilled = false;\n var hasOneNumber = false;\n var zi;\n\n /*\n * Without this step:\n *\n * hasOneNumber = false breaks contour but not heatmap\n * allRowsAreArrays = false breaks contour but not heatmap\n * oneRowIsFilled = false breaks both\n */\n\n for(var i = 0; i < z.length; i++) {\n zi = z[i];\n if(!Lib.isArrayOrTypedArray(zi)) {\n allRowsAreArrays = false;\n break;\n }\n if(zi.length > 0) oneRowIsFilled = true;\n for(var j = 0; j < zi.length; j++) {\n if(isNumeric(zi[j])) {\n hasOneNumber = true;\n break;\n }\n }\n }\n\n return (allRowsAreArrays && oneRowIsFilled && hasOneNumber);\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmap/xyz_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmapgl/attributes.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmapgl/attributes.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar heatmapAttrs = __webpack_require__(/*! ../heatmap/attributes */ \"./node_modules/plotly.js/src/traces/heatmap/attributes.js\");\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar overrideAll = __webpack_require__(/*! ../../plot_api/edit_types */ \"./node_modules/plotly.js/src/plot_api/edit_types.js\").overrideAll;\n\nvar commonList = [\n 'z',\n 'x', 'x0', 'dx',\n 'y', 'y0', 'dy',\n 'text', 'transpose',\n 'xtype', 'ytype'\n];\n\nvar attrs = {};\n\nfor(var i = 0; i < commonList.length; i++) {\n var k = commonList[i];\n attrs[k] = heatmapAttrs[k];\n}\n\nextendFlat(\n attrs,\n colorScaleAttrs('', {cLetter: 'z', autoColorDflt: false})\n);\n\nmodule.exports = overrideAll(attrs, 'calc', 'nested');\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmapgl/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmapgl/convert.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmapgl/convert.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar createHeatmap2D = __webpack_require__(/*! gl-heatmap2d */ \"./node_modules/gl-heatmap2d/heatmap.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar str2RGBArray = __webpack_require__(/*! ../../lib/str2rgbarray */ \"./node_modules/plotly.js/src/lib/str2rgbarray.js\");\n\n\nfunction Heatmap(scene, uid) {\n this.scene = scene;\n this.uid = uid;\n this.type = 'heatmapgl';\n\n this.name = '';\n this.hoverinfo = 'all';\n\n this.xData = [];\n this.yData = [];\n this.zData = [];\n this.textLabels = [];\n\n this.idToIndex = [];\n this.bounds = [0, 0, 0, 0];\n\n this.options = {\n z: [],\n x: [],\n y: [],\n shape: [0, 0],\n colorLevels: [0],\n colorValues: [0, 0, 0, 1]\n };\n\n this.heatmap = createHeatmap2D(scene.glplot, this.options);\n this.heatmap._trace = this;\n}\n\nvar proto = Heatmap.prototype;\n\nproto.handlePick = function(pickResult) {\n var options = this.options;\n var shape = options.shape;\n var index = pickResult.pointId;\n var xIndex = index % shape[0];\n var yIndex = Math.floor(index / shape[0]);\n var zIndex = index;\n\n return {\n trace: this,\n dataCoord: pickResult.dataCoord,\n traceCoord: [\n options.x[xIndex],\n options.y[yIndex],\n options.z[zIndex]\n ],\n textLabel: this.textLabels[index],\n name: this.name,\n pointIndex: [yIndex, xIndex],\n hoverinfo: this.hoverinfo\n };\n};\n\nproto.update = function(fullTrace, calcTrace) {\n var calcPt = calcTrace[0];\n\n this.index = fullTrace.index;\n this.name = fullTrace.name;\n this.hoverinfo = fullTrace.hoverinfo;\n\n // convert z from 2D -> 1D\n var z = calcPt.z;\n this.options.z = [].concat.apply([], z);\n\n var rowLen = z[0].length;\n var colLen = z.length;\n this.options.shape = [rowLen, colLen];\n\n this.options.x = calcPt.x;\n this.options.y = calcPt.y;\n\n var colorOptions = convertColorscale(fullTrace);\n this.options.colorLevels = colorOptions.colorLevels;\n this.options.colorValues = colorOptions.colorValues;\n\n // convert text from 2D -> 1D\n this.textLabels = [].concat.apply([], fullTrace.text);\n\n this.heatmap.update(this.options);\n\n var xa = this.scene.xaxis;\n var ya = this.scene.yaxis;\n fullTrace._extremes[xa._id] = Axes.findExtremes(xa, calcPt.x);\n fullTrace._extremes[ya._id] = Axes.findExtremes(ya, calcPt.y);\n};\n\nproto.dispose = function() {\n this.heatmap.dispose();\n};\n\nfunction convertColorscale(fullTrace) {\n var scl = fullTrace.colorscale;\n var zmin = fullTrace.zmin;\n var zmax = fullTrace.zmax;\n\n var N = scl.length;\n var domain = new Array(N);\n var range = new Array(4 * N);\n\n for(var i = 0; i < N; i++) {\n var si = scl[i];\n var color = str2RGBArray(si[1]);\n\n domain[i] = zmin + si[0] * (zmax - zmin);\n\n for(var j = 0; j < 4; j++) {\n range[(4 * i) + j] = color[j];\n }\n }\n\n return {\n colorLevels: domain,\n colorValues: range\n };\n}\n\nfunction createHeatmap(scene, fullTrace, calcTrace) {\n var plot = new Heatmap(scene, fullTrace.uid);\n plot.update(fullTrace, calcTrace);\n return plot;\n}\n\nmodule.exports = createHeatmap;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmapgl/convert.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/heatmapgl/index.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/heatmapgl/index.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/heatmapgl/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ../heatmap/defaults */ \"./node_modules/plotly.js/src/traces/heatmap/defaults.js\"),\n colorbar: __webpack_require__(/*! ../heatmap/colorbar */ \"./node_modules/plotly.js/src/traces/heatmap/colorbar.js\"),\n\n calc: __webpack_require__(/*! ../heatmap/calc */ \"./node_modules/plotly.js/src/traces/heatmap/calc.js\"),\n plot: __webpack_require__(/*! ./convert */ \"./node_modules/plotly.js/src/traces/heatmapgl/convert.js\"),\n\n moduleType: 'trace',\n name: 'heatmapgl',\n basePlotModule: __webpack_require__(/*! ../../plots/gl2d */ \"./node_modules/plotly.js/src/plots/gl2d/index.js\"),\n categories: ['gl', 'gl2d', '2dMap'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/heatmapgl/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram/attributes.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram/attributes.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar barAttrs = __webpack_require__(/*! ../bar/attributes */ \"./node_modules/plotly.js/src/traces/bar/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar makeBinAttrs = __webpack_require__(/*! ./bin_attributes */ \"./node_modules/plotly.js/src/traces/histogram/bin_attributes.js\");\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/histogram/constants.js\");\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nmodule.exports = {\n x: {\n valType: 'data_array',\n editType: 'calc+clearAxisTypes',\n \n },\n y: {\n valType: 'data_array',\n editType: 'calc+clearAxisTypes',\n \n },\n\n text: extendFlat({}, barAttrs.text, {\n \n }),\n hovertext: extendFlat({}, barAttrs.hovertext, {\n \n }),\n orientation: barAttrs.orientation,\n\n histfunc: {\n valType: 'enumerated',\n values: ['count', 'sum', 'avg', 'min', 'max'],\n \n dflt: 'count',\n editType: 'calc',\n \n },\n histnorm: {\n valType: 'enumerated',\n values: ['', 'percent', 'probability', 'density', 'probability density'],\n dflt: '',\n \n editType: 'calc',\n \n },\n\n cumulative: {\n enabled: {\n valType: 'boolean',\n dflt: false,\n \n editType: 'calc',\n \n },\n\n direction: {\n valType: 'enumerated',\n values: ['increasing', 'decreasing'],\n dflt: 'increasing',\n \n editType: 'calc',\n \n },\n\n currentbin: {\n valType: 'enumerated',\n values: ['include', 'exclude', 'half'],\n dflt: 'include',\n \n editType: 'calc',\n \n },\n editType: 'calc'\n },\n nbinsx: {\n valType: 'integer',\n min: 0,\n dflt: 0,\n \n editType: 'calc',\n \n },\n xbins: makeBinAttrs('x', true),\n\n nbinsy: {\n valType: 'integer',\n min: 0,\n dflt: 0,\n \n editType: 'calc',\n \n },\n ybins: makeBinAttrs('y', true),\n autobinx: {\n valType: 'boolean',\n dflt: null,\n \n editType: 'calc',\n \n },\n autobiny: {\n valType: 'boolean',\n dflt: null,\n \n editType: 'calc',\n \n },\n\n bingroup: {\n valType: 'string',\n \n dflt: '',\n editType: 'calc',\n \n },\n\n hovertemplate: hovertemplateAttrs({}, {\n keys: constants.eventDataKeys\n }),\n\n marker: barAttrs.marker,\n\n offsetgroup: barAttrs.offsetgroup,\n alignmentgroup: barAttrs.alignmentgroup,\n\n selected: barAttrs.selected,\n unselected: barAttrs.unselected,\n\n _deprecated: {\n bardir: barAttrs._deprecated.bardir\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram/average.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram/average.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\n\nmodule.exports = function doAvg(size, counts) {\n var nMax = size.length;\n var total = 0;\n for(var i = 0; i < nMax; i++) {\n if(counts[i]) {\n size[i] /= counts[i];\n total += size[i];\n } else size[i] = null;\n }\n return total;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram/average.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram/bin_attributes.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram/bin_attributes.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function makeBinAttrs(axLetter, match) {\n return {\n start: {\n valType: 'any', // for date axes\n \n editType: 'calc',\n \n },\n end: {\n valType: 'any', // for date axes\n \n editType: 'calc',\n \n },\n size: {\n valType: 'any', // for date axes\n \n editType: 'calc',\n \n },\n editType: 'calc'\n };\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram/bin_attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram/bin_functions.js":
-/*!**********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram/bin_functions.js ***!
- \**********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\n\nmodule.exports = {\n count: function(n, i, size) {\n size[n]++;\n return 1;\n },\n\n sum: function(n, i, size, counterData) {\n var v = counterData[i];\n if(isNumeric(v)) {\n v = Number(v);\n size[n] += v;\n return v;\n }\n return 0;\n },\n\n avg: function(n, i, size, counterData, counts) {\n var v = counterData[i];\n if(isNumeric(v)) {\n v = Number(v);\n size[n] += v;\n counts[n]++;\n }\n return 0;\n },\n\n min: function(n, i, size, counterData) {\n var v = counterData[i];\n if(isNumeric(v)) {\n v = Number(v);\n if(!isNumeric(size[n])) {\n size[n] = v;\n return v;\n } else if(size[n] > v) {\n var delta = v - size[n];\n size[n] = v;\n return delta;\n }\n }\n return 0;\n },\n\n max: function(n, i, size, counterData) {\n var v = counterData[i];\n if(isNumeric(v)) {\n v = Number(v);\n if(!isNumeric(size[n])) {\n size[n] = v;\n return v;\n } else if(size[n] < v) {\n var delta = v - size[n];\n size[n] = v;\n return delta;\n }\n }\n return 0;\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram/bin_functions.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram/bin_label_vals.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram/bin_label_vals.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar numConstants = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\");\nvar oneYear = numConstants.ONEAVGYEAR;\nvar oneMonth = numConstants.ONEAVGMONTH;\nvar oneDay = numConstants.ONEDAY;\nvar oneHour = numConstants.ONEHOUR;\nvar oneMin = numConstants.ONEMIN;\nvar oneSec = numConstants.ONESEC;\nvar tickIncrement = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\").tickIncrement;\n\n\n/*\n * make a function that will find rounded bin edges\n * @param {number} leftGap: how far from the left edge of any bin is the closest data value?\n * @param {number} rightGap: how far from the right edge of any bin is the closest data value?\n * @param {Array[number]} binEdges: the actual edge values used in binning\n * @param {object} pa: the position axis\n * @param {string} calendar: the data calendar\n *\n * @return {function(v, isRightEdge)}:\n * find the start (isRightEdge is falsy) or end (truthy) label value for a bin edge `v`\n */\nmodule.exports = function getBinSpanLabelRound(leftGap, rightGap, binEdges, pa, calendar) {\n // the rounding digit is the largest digit that changes in *all* of 4 regions:\n // - inside the rightGap before binEdges[0] (shifted 10% to the left)\n // - inside the leftGap after binEdges[0] (expanded by 10% of rightGap on each end)\n // - same for binEdges[1]\n var dv0 = -1.1 * rightGap;\n var dv1 = -0.1 * rightGap;\n var dv2 = leftGap - dv1;\n var edge0 = binEdges[0];\n var edge1 = binEdges[1];\n var leftDigit = Math.min(\n biggestDigitChanged(edge0 + dv1, edge0 + dv2, pa, calendar),\n biggestDigitChanged(edge1 + dv1, edge1 + dv2, pa, calendar)\n );\n var rightDigit = Math.min(\n biggestDigitChanged(edge0 + dv0, edge0 + dv1, pa, calendar),\n biggestDigitChanged(edge1 + dv0, edge1 + dv1, pa, calendar)\n );\n\n // normally we try to make the label for the right edge different from\n // the left edge label, so it's unambiguous which bin gets data on the edge.\n // but if this results in more than 3 extra digits (or for dates, more than\n // 2 fields ie hr&min or min&sec, which is 3600x), it'll be more clutter than\n // useful so keep the label cleaner instead\n var digit, disambiguateEdges;\n if(leftDigit > rightDigit && rightDigit < Math.abs(edge1 - edge0) / 4000) {\n digit = leftDigit;\n disambiguateEdges = false;\n } else {\n digit = Math.min(leftDigit, rightDigit);\n disambiguateEdges = true;\n }\n\n if(pa.type === 'date' && digit > oneDay) {\n var dashExclude = (digit === oneYear) ? 1 : 6;\n var increment = (digit === oneYear) ? 'M12' : 'M1';\n\n return function(v, isRightEdge) {\n var dateStr = pa.c2d(v, oneYear, calendar);\n var dashPos = dateStr.indexOf('-', dashExclude);\n if(dashPos > 0) dateStr = dateStr.substr(0, dashPos);\n var roundedV = pa.d2c(dateStr, 0, calendar);\n\n if(roundedV < v) {\n var nextV = tickIncrement(roundedV, increment, false, calendar);\n if((roundedV + nextV) / 2 < v + leftGap) roundedV = nextV;\n }\n\n if(isRightEdge && disambiguateEdges) {\n return tickIncrement(roundedV, increment, true, calendar);\n }\n\n return roundedV;\n };\n }\n\n return function(v, isRightEdge) {\n var roundedV = digit * Math.round(v / digit);\n // if we rounded down and we could round up and still be < leftGap\n // (or what leftGap values round to), do that\n if(roundedV + (digit / 10) < v && roundedV + (digit * 0.9) < v + leftGap) {\n roundedV += digit;\n }\n // finally for the right edge back off one digit - but only if we can do that\n // and not clip off any data that's potentially in the bin\n if(isRightEdge && disambiguateEdges) {\n roundedV -= digit;\n }\n return roundedV;\n };\n};\n\n/*\n * Find the largest digit that changes within a (calcdata) region [v1, v2]\n * if dates, \"digit\" means date/time part when it's bigger than a second\n * returns the unit value to round to this digit, eg 0.01 to round to hundredths, or\n * 100 to round to hundreds. returns oneMonth or oneYear for month or year rounding,\n * so that Math.min will work, rather than 'M1' and 'M12'\n */\nfunction biggestDigitChanged(v1, v2, pa, calendar) {\n // are we crossing zero? can't say anything.\n // in principle this doesn't apply to dates but turns out this doesn't matter.\n if(v1 * v2 <= 0) return Infinity;\n\n var dv = Math.abs(v2 - v1);\n var isDate = pa.type === 'date';\n var digit = biggestGuaranteedDigitChanged(dv, isDate);\n // see if a larger digit also changed\n for(var i = 0; i < 10; i++) {\n // numbers: next digit needs to be >10x but <100x then gets rounded down.\n // dates: next digit can be as much as 60x (then rounded down)\n var nextDigit = biggestGuaranteedDigitChanged(digit * 80, isDate);\n // if we get to years, the chain stops\n if(digit === nextDigit) break;\n if(didDigitChange(nextDigit, v1, v2, isDate, pa, calendar)) digit = nextDigit;\n else break;\n }\n return digit;\n}\n\n/*\n * Find the largest digit that *definitely* changes in a region [v, v + dv] for any v\n * for nonuniform date regions (months/years) pick the largest\n */\nfunction biggestGuaranteedDigitChanged(dv, isDate) {\n if(isDate && dv > oneSec) {\n // this is supposed to be the biggest *guaranteed* change\n // so compare to the longest month and year across any calendar,\n // and we'll iterate back up later\n // note: does not support rounding larger than one year. We could add\n // that if anyone wants it, but seems unusual and not strictly necessary.\n if(dv > oneDay) {\n if(dv > oneYear * 1.1) return oneYear;\n if(dv > oneMonth * 1.1) return oneMonth;\n return oneDay;\n }\n\n if(dv > oneHour) return oneHour;\n if(dv > oneMin) return oneMin;\n return oneSec;\n }\n return Math.pow(10, Math.floor(Math.log(dv) / Math.LN10));\n}\n\nfunction didDigitChange(digit, v1, v2, isDate, pa, calendar) {\n if(isDate && digit > oneDay) {\n var dateParts1 = dateParts(v1, pa, calendar);\n var dateParts2 = dateParts(v2, pa, calendar);\n var parti = (digit === oneYear) ? 0 : 1;\n return dateParts1[parti] !== dateParts2[parti];\n }\n return Math.floor(v2 / digit) - Math.floor(v1 / digit) > 0.1;\n}\n\nfunction dateParts(v, pa, calendar) {\n var parts = pa.c2d(v, oneYear, calendar).split('-');\n if(parts[0] === '') {\n parts.unshift();\n parts[0] = '-' + parts[0];\n }\n return parts;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram/bin_label_vals.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram/calc.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram/calc.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\n\nvar arraysToCalcdata = __webpack_require__(/*! ../bar/arrays_to_calcdata */ \"./node_modules/plotly.js/src/traces/bar/arrays_to_calcdata.js\");\nvar binFunctions = __webpack_require__(/*! ./bin_functions */ \"./node_modules/plotly.js/src/traces/histogram/bin_functions.js\");\nvar normFunctions = __webpack_require__(/*! ./norm_functions */ \"./node_modules/plotly.js/src/traces/histogram/norm_functions.js\");\nvar doAvg = __webpack_require__(/*! ./average */ \"./node_modules/plotly.js/src/traces/histogram/average.js\");\nvar getBinSpanLabelRound = __webpack_require__(/*! ./bin_label_vals */ \"./node_modules/plotly.js/src/traces/histogram/bin_label_vals.js\");\n\nfunction calc(gd, trace) {\n var pos = [];\n var size = [];\n var pa = Axes.getFromId(gd, trace.orientation === 'h' ? trace.yaxis : trace.xaxis);\n var mainData = trace.orientation === 'h' ? 'y' : 'x';\n var counterData = {x: 'y', y: 'x'}[mainData];\n var calendar = trace[mainData + 'calendar'];\n var cumulativeSpec = trace.cumulative;\n var i;\n\n var binsAndPos = calcAllAutoBins(gd, trace, pa, mainData);\n var binSpec = binsAndPos[0];\n var pos0 = binsAndPos[1];\n\n var nonuniformBins = typeof binSpec.size === 'string';\n var binEdges = [];\n var bins = nonuniformBins ? binEdges : binSpec;\n // make the empty bin array\n var inc = [];\n var counts = [];\n var inputPoints = [];\n var total = 0;\n var norm = trace.histnorm;\n var func = trace.histfunc;\n var densityNorm = norm.indexOf('density') !== -1;\n var i2, binEnd, n;\n\n if(cumulativeSpec.enabled && densityNorm) {\n // we treat \"cumulative\" like it means \"integral\" if you use a density norm,\n // which in the end means it's the same as without \"density\"\n norm = norm.replace(/ ?density$/, '');\n densityNorm = false;\n }\n\n var extremeFunc = func === 'max' || func === 'min';\n var sizeInit = extremeFunc ? null : 0;\n var binFunc = binFunctions.count;\n var normFunc = normFunctions[norm];\n var isAvg = false;\n var pr2c = function(v) { return pa.r2c(v, 0, calendar); };\n var rawCounterData;\n\n if(Lib.isArrayOrTypedArray(trace[counterData]) && func !== 'count') {\n rawCounterData = trace[counterData];\n isAvg = func === 'avg';\n binFunc = binFunctions[func];\n }\n\n // create the bins (and any extra arrays needed)\n // assume more than 1e6 bins is an error, so we don't crash the browser\n i = pr2c(binSpec.start);\n\n // decrease end a little in case of rounding errors\n binEnd = pr2c(binSpec.end) + (i - Axes.tickIncrement(i, binSpec.size, false, calendar)) / 1e6;\n\n while(i < binEnd && pos.length < 1e6) {\n i2 = Axes.tickIncrement(i, binSpec.size, false, calendar);\n pos.push((i + i2) / 2);\n size.push(sizeInit);\n inputPoints.push([]);\n // nonuniform bins (like months) we need to search,\n // rather than straight calculate the bin we're in\n binEdges.push(i);\n // nonuniform bins also need nonuniform normalization factors\n if(densityNorm) inc.push(1 / (i2 - i));\n if(isAvg) counts.push(0);\n // break to avoid infinite loops\n if(i2 <= i) break;\n i = i2;\n }\n binEdges.push(i);\n\n // for date axes we need bin bounds to be calcdata. For nonuniform bins\n // we already have this, but uniform with start/end/size they're still strings.\n if(!nonuniformBins && pa.type === 'date') {\n bins = {\n start: pr2c(bins.start),\n end: pr2c(bins.end),\n size: bins.size\n };\n }\n\n // bin the data\n // and make histogram-specific pt-number-to-cd-index map object\n var nMax = size.length;\n var uniqueValsPerBin = true;\n var leftGap = Infinity;\n var rightGap = Infinity;\n var ptNumber2cdIndex = {};\n for(i = 0; i < pos0.length; i++) {\n var posi = pos0[i];\n n = Lib.findBin(posi, bins);\n if(n >= 0 && n < nMax) {\n total += binFunc(n, i, size, rawCounterData, counts);\n if(uniqueValsPerBin && inputPoints[n].length && posi !== pos0[inputPoints[n][0]]) {\n uniqueValsPerBin = false;\n }\n inputPoints[n].push(i);\n ptNumber2cdIndex[i] = n;\n\n leftGap = Math.min(leftGap, posi - binEdges[n]);\n rightGap = Math.min(rightGap, binEdges[n + 1] - posi);\n }\n }\n\n var roundFn;\n if(!uniqueValsPerBin) {\n roundFn = getBinSpanLabelRound(leftGap, rightGap, binEdges, pa, calendar);\n }\n\n // average and/or normalize the data, if needed\n if(isAvg) total = doAvg(size, counts);\n if(normFunc) normFunc(size, total, inc);\n\n // after all normalization etc, now we can accumulate if desired\n if(cumulativeSpec.enabled) cdf(size, cumulativeSpec.direction, cumulativeSpec.currentbin);\n\n var seriesLen = Math.min(pos.length, size.length);\n var cd = [];\n var firstNonzero = 0;\n var lastNonzero = seriesLen - 1;\n\n // look for empty bins at the ends to remove, so autoscale omits them\n for(i = 0; i < seriesLen; i++) {\n if(size[i]) {\n firstNonzero = i;\n break;\n }\n }\n for(i = seriesLen - 1; i >= firstNonzero; i--) {\n if(size[i]) {\n lastNonzero = i;\n break;\n }\n }\n\n // create the \"calculated data\" to plot\n for(i = firstNonzero; i <= lastNonzero; i++) {\n if((isNumeric(pos[i]) && isNumeric(size[i]))) {\n var cdi = {\n p: pos[i],\n s: size[i],\n b: 0\n };\n\n // setup hover and event data fields,\n // N.B. pts and \"hover\" positions ph0/ph1 don't seem to make much sense\n // for cumulative distributions\n if(!cumulativeSpec.enabled) {\n cdi.pts = inputPoints[i];\n if(uniqueValsPerBin) {\n cdi.ph0 = cdi.ph1 = (inputPoints[i].length) ? pos0[inputPoints[i][0]] : pos[i];\n } else {\n cdi.ph0 = roundFn(binEdges[i]);\n cdi.ph1 = roundFn(binEdges[i + 1], true);\n }\n }\n cd.push(cdi);\n }\n }\n\n if(cd.length === 1) {\n // when we collapse to a single bin, calcdata no longer describes bin size\n // so we need to explicitly specify it\n cd[0].width1 = Axes.tickIncrement(cd[0].p, binSpec.size, false, calendar) - cd[0].p;\n }\n\n arraysToCalcdata(cd, trace);\n\n if(Lib.isArrayOrTypedArray(trace.selectedpoints)) {\n Lib.tagSelected(cd, trace, ptNumber2cdIndex);\n }\n\n return cd;\n}\n\n/*\n * calcAllAutoBins: we want all histograms inside the same bingroup\n * (see logic in Histogram.crossTraceDefaults) to share bin specs\n *\n * If the user has explicitly specified differing\n * bin specs, there's nothing we can do, but if possible we will try to use the\n * smallest bins of any of the auto values for all histograms inside the same\n * bingroup.\n */\nfunction calcAllAutoBins(gd, trace, pa, mainData, _overlayEdgeCase) {\n var binAttr = mainData + 'bins';\n var fullLayout = gd._fullLayout;\n var groupName = trace['_' + mainData + 'bingroup'];\n var binOpts = fullLayout._histogramBinOpts[groupName];\n var isOverlay = fullLayout.barmode === 'overlay';\n var i, traces, tracei, calendar, pos0, autoVals, cumulativeSpec;\n\n var r2c = function(v) { return pa.r2c(v, 0, calendar); };\n var c2r = function(v) { return pa.c2r(v, 0, calendar); };\n\n var cleanBound = pa.type === 'date' ?\n function(v) { return (v || v === 0) ? Lib.cleanDate(v, null, calendar) : null; } :\n function(v) { return isNumeric(v) ? Number(v) : null; };\n\n function setBound(attr, bins, newBins) {\n if(bins[attr + 'Found']) {\n bins[attr] = cleanBound(bins[attr]);\n if(bins[attr] === null) bins[attr] = newBins[attr];\n } else {\n autoVals[attr] = bins[attr] = newBins[attr];\n Lib.nestedProperty(traces[0], binAttr + '.' + attr).set(newBins[attr]);\n }\n }\n\n // all but the first trace in this group has already been marked finished\n // clear this flag, so next time we run calc we will run autobin again\n if(trace['_' + mainData + 'autoBinFinished']) {\n delete trace['_' + mainData + 'autoBinFinished'];\n } else {\n traces = binOpts.traces;\n var allPos = [];\n\n // Note: we're including `legendonly` traces here for autobin purposes,\n // so that showing & hiding from the legend won't affect bins.\n // But this complicates things a bit since those traces don't `calc`,\n // hence `isFirstVisible`.\n var isFirstVisible = true;\n var has2dMap = false;\n var hasHist2dContour = false;\n for(i = 0; i < traces.length; i++) {\n tracei = traces[i];\n\n if(tracei.visible) {\n var mainDatai = binOpts.dirs[i];\n pos0 = tracei['_' + mainDatai + 'pos0'] = pa.makeCalcdata(tracei, mainDatai);\n\n allPos = Lib.concat(allPos, pos0);\n delete tracei['_' + mainData + 'autoBinFinished'];\n\n if(trace.visible === true) {\n if(isFirstVisible) {\n isFirstVisible = false;\n } else {\n delete tracei._autoBin;\n tracei['_' + mainData + 'autoBinFinished'] = 1;\n }\n if(Registry.traceIs(tracei, '2dMap')) {\n has2dMap = true;\n }\n if(tracei.type === 'histogram2dcontour') {\n hasHist2dContour = true;\n }\n }\n }\n }\n\n calendar = traces[0][mainData + 'calendar'];\n var newBinSpec = Axes.autoBin(allPos, pa, binOpts.nbins, has2dMap, calendar, binOpts.sizeFound && binOpts.size);\n\n var autoBin = traces[0]._autoBin = {};\n autoVals = autoBin[binOpts.dirs[0]] = {};\n\n if(hasHist2dContour) {\n // the \"true\" 2nd argument reverses the tick direction (which we can't\n // just do with a minus sign because of month bins)\n if(!binOpts.size) {\n newBinSpec.start = c2r(Axes.tickIncrement(\n r2c(newBinSpec.start), newBinSpec.size, true, calendar));\n }\n if(binOpts.end === undefined) {\n newBinSpec.end = c2r(Axes.tickIncrement(\n r2c(newBinSpec.end), newBinSpec.size, false, calendar));\n }\n }\n\n // Edge case: single-valued histogram overlaying others\n // Use them all together to calculate the bin size for the single-valued one\n if(isOverlay && !Registry.traceIs(trace, '2dMap') && newBinSpec._dataSpan === 0 &&\n pa.type !== 'category' && pa.type !== 'multicategory') {\n // Several single-valued histograms! Stop infinite recursion,\n // just return an extra flag that tells handleSingleValueOverlays\n // to sort out this trace too\n if(_overlayEdgeCase) return [newBinSpec, pos0, true];\n\n newBinSpec = handleSingleValueOverlays(gd, trace, pa, mainData, binAttr);\n }\n\n // adjust for CDF edge cases\n cumulativeSpec = tracei.cumulative || {};\n if(cumulativeSpec.enabled && (cumulativeSpec.currentbin !== 'include')) {\n if(cumulativeSpec.direction === 'decreasing') {\n newBinSpec.start = c2r(Axes.tickIncrement(\n r2c(newBinSpec.start), newBinSpec.size, true, calendar));\n } else {\n newBinSpec.end = c2r(Axes.tickIncrement(\n r2c(newBinSpec.end), newBinSpec.size, false, calendar));\n }\n }\n\n binOpts.size = newBinSpec.size;\n if(!binOpts.sizeFound) {\n autoVals.size = newBinSpec.size;\n Lib.nestedProperty(traces[0], binAttr + '.size').set(newBinSpec.size);\n }\n\n setBound('start', binOpts, newBinSpec);\n setBound('end', binOpts, newBinSpec);\n }\n\n pos0 = trace['_' + mainData + 'pos0'];\n delete trace['_' + mainData + 'pos0'];\n\n // Each trace can specify its own start/end, or if omitted\n // we ensure they're beyond the bounds of this trace's data,\n // and we need to make sure start is aligned with the main start\n var traceInputBins = trace._input[binAttr] || {};\n var traceBinOptsCalc = Lib.extendFlat({}, binOpts);\n var mainStart = binOpts.start;\n var startIn = pa.r2l(traceInputBins.start);\n var hasStart = startIn !== undefined;\n if((binOpts.startFound || hasStart) && startIn !== pa.r2l(mainStart)) {\n // We have an explicit start to reconcile across traces\n // if this trace has an explicit start, shift it down to a bin edge\n // if another trace had an explicit start, shift it down to a\n // bin edge past our data\n var traceStart = hasStart ?\n startIn :\n Lib.aggNums(Math.min, null, pos0);\n\n var dummyAx = {\n type: (pa.type === 'category' || pa.type === 'multicategory') ? 'linear' : pa.type,\n r2l: pa.r2l,\n dtick: binOpts.size,\n tick0: mainStart,\n calendar: calendar,\n range: ([traceStart, Axes.tickIncrement(traceStart, binOpts.size, false, calendar)]).map(pa.l2r)\n };\n var newStart = Axes.tickFirst(dummyAx);\n if(newStart > pa.r2l(traceStart)) {\n newStart = Axes.tickIncrement(newStart, binOpts.size, true, calendar);\n }\n traceBinOptsCalc.start = pa.l2r(newStart);\n if(!hasStart) Lib.nestedProperty(trace, binAttr + '.start').set(traceBinOptsCalc.start);\n }\n\n var mainEnd = binOpts.end;\n var endIn = pa.r2l(traceInputBins.end);\n var hasEnd = endIn !== undefined;\n if((binOpts.endFound || hasEnd) && endIn !== pa.r2l(mainEnd)) {\n // Reconciling an explicit end is easier, as it doesn't need to\n // match bin edges\n var traceEnd = hasEnd ?\n endIn :\n Lib.aggNums(Math.max, null, pos0);\n\n traceBinOptsCalc.end = pa.l2r(traceEnd);\n if(!hasEnd) Lib.nestedProperty(trace, binAttr + '.start').set(traceBinOptsCalc.end);\n }\n\n // Backward compatibility for one-time autobinning.\n // autobin: true is handled in cleanData, but autobin: false\n // needs to be here where we have determined the values.\n var autoBinAttr = 'autobin' + mainData;\n if(trace._input[autoBinAttr] === false) {\n trace._input[binAttr] = Lib.extendFlat({}, trace[binAttr] || {});\n delete trace._input[autoBinAttr];\n delete trace[autoBinAttr];\n }\n\n return [traceBinOptsCalc, pos0];\n}\n\n/*\n * Adjust single-value histograms in overlay mode to make as good a\n * guess as we can at autobin values the user would like.\n *\n * Returns the binSpec for the trace that sparked all this\n */\nfunction handleSingleValueOverlays(gd, trace, pa, mainData, binAttr) {\n var fullLayout = gd._fullLayout;\n var overlaidTraceGroup = getConnectedHistograms(gd, trace);\n var pastThisTrace = false;\n var minSize = Infinity;\n var singleValuedTraces = [trace];\n var i, tracei, binOpts;\n\n // first collect all the:\n // - min bin size from all multi-valued traces\n // - single-valued traces\n for(i = 0; i < overlaidTraceGroup.length; i++) {\n tracei = overlaidTraceGroup[i];\n\n if(tracei === trace) {\n pastThisTrace = true;\n } else if(!pastThisTrace) {\n // This trace has already had its autobins calculated, so either:\n // - it is part of a bingroup\n // - it is NOT a single-valued trace\n binOpts = fullLayout._histogramBinOpts[tracei['_' + mainData + 'bingroup']];\n minSize = Math.min(minSize, binOpts.size || tracei[binAttr].size);\n } else {\n var resulti = calcAllAutoBins(gd, tracei, pa, mainData, true);\n var binSpeci = resulti[0];\n var isSingleValued = resulti[2];\n\n // so we can use this result when we get to tracei in the normal\n // course of events, mark it as done and put _pos0 back\n tracei['_' + mainData + 'autoBinFinished'] = 1;\n tracei['_' + mainData + 'pos0'] = resulti[1];\n\n if(isSingleValued) {\n singleValuedTraces.push(tracei);\n } else {\n minSize = Math.min(minSize, binSpeci.size);\n }\n }\n }\n\n // find the real data values for each single-valued trace\n // hunt through pos0 for the first valid value\n var dataVals = new Array(singleValuedTraces.length);\n for(i = 0; i < singleValuedTraces.length; i++) {\n var pos0 = singleValuedTraces[i]['_' + mainData + 'pos0'];\n for(var j = 0; j < pos0.length; j++) {\n if(pos0[j] !== undefined) {\n dataVals[i] = pos0[j];\n break;\n }\n }\n }\n\n // are ALL traces are single-valued? use the min difference between\n // all of their values (which defaults to 1 if there's still only one)\n if(!isFinite(minSize)) {\n minSize = Lib.distinctVals(dataVals).minDiff;\n }\n\n // now apply the min size we found to all single-valued traces\n for(i = 0; i < singleValuedTraces.length; i++) {\n tracei = singleValuedTraces[i];\n var calendar = tracei[mainData + 'calendar'];\n\n var newBins = {\n start: pa.c2r(dataVals[i] - minSize / 2, 0, calendar),\n end: pa.c2r(dataVals[i] + minSize / 2, 0, calendar),\n size: minSize\n };\n\n tracei._input[binAttr] = tracei[binAttr] = newBins;\n\n binOpts = fullLayout._histogramBinOpts[tracei['_' + mainData + 'bingroup']];\n if(binOpts) Lib.extendFlat(binOpts, newBins);\n }\n\n return trace[binAttr];\n}\n\n/*\n * Return an array of histograms that share axes and orientation.\n *\n * Only considers histograms. In principle we could include bars in a\n * similar way to how we do manually binned histograms, though this\n * would have tons of edge cases and value judgments to make.\n */\nfunction getConnectedHistograms(gd, trace) {\n var xid = trace.xaxis;\n var yid = trace.yaxis;\n var orientation = trace.orientation;\n\n var out = [];\n var fullData = gd._fullData;\n for(var i = 0; i < fullData.length; i++) {\n var tracei = fullData[i];\n if(tracei.type === 'histogram' &&\n tracei.visible === true &&\n tracei.orientation === orientation &&\n tracei.xaxis === xid && tracei.yaxis === yid\n ) {\n out.push(tracei);\n }\n }\n\n return out;\n}\n\nfunction cdf(size, direction, currentBin) {\n var i, vi, prevSum;\n\n function firstHalfPoint(i) {\n prevSum = size[i];\n size[i] /= 2;\n }\n\n function nextHalfPoint(i) {\n vi = size[i];\n size[i] = prevSum + vi / 2;\n prevSum += vi;\n }\n\n if(currentBin === 'half') {\n if(direction === 'increasing') {\n firstHalfPoint(0);\n for(i = 1; i < size.length; i++) {\n nextHalfPoint(i);\n }\n } else {\n firstHalfPoint(size.length - 1);\n for(i = size.length - 2; i >= 0; i--) {\n nextHalfPoint(i);\n }\n }\n } else if(direction === 'increasing') {\n for(i = 1; i < size.length; i++) {\n size[i] += size[i - 1];\n }\n\n // 'exclude' is identical to 'include' just shifted one bin over\n if(currentBin === 'exclude') {\n size.unshift(0);\n size.pop();\n }\n } else {\n for(i = size.length - 2; i >= 0; i--) {\n size[i] += size[i + 1];\n }\n\n if(currentBin === 'exclude') {\n size.push(0);\n size.shift();\n }\n }\n}\n\nmodule.exports = {\n calc: calc,\n calcAllAutoBins: calcAllAutoBins\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram/constants.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram/constants.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nmodule.exports = {\n eventDataKeys: ['binNumber']\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram/constants.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram/cross_trace_defaults.js":
-/*!*****************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram/cross_trace_defaults.js ***!
- \*****************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar axisIds = __webpack_require__(/*! ../../plots/cartesian/axis_ids */ \"./node_modules/plotly.js/src/plots/cartesian/axis_ids.js\");\n\nvar traceIs = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\").traceIs;\nvar handleGroupingDefaults = __webpack_require__(/*! ../bar/defaults */ \"./node_modules/plotly.js/src/traces/bar/defaults.js\").handleGroupingDefaults;\n\nvar nestedProperty = Lib.nestedProperty;\nvar getAxisGroup = axisIds.getAxisGroup;\n\nvar BINATTRS = [\n {aStr: {x: 'xbins.start', y: 'ybins.start'}, name: 'start'},\n {aStr: {x: 'xbins.end', y: 'ybins.end'}, name: 'end'},\n {aStr: {x: 'xbins.size', y: 'ybins.size'}, name: 'size'},\n {aStr: {x: 'nbinsx', y: 'nbinsy'}, name: 'nbins'}\n];\n\nvar BINDIRECTIONS = ['x', 'y'];\n\n// handle bin attrs and relink auto-determined values so fullData is complete\nmodule.exports = function crossTraceDefaults(fullData, fullLayout) {\n var allBinOpts = fullLayout._histogramBinOpts = {};\n var histTraces = [];\n var mustMatchTracesLookup = {};\n var otherTracesList = [];\n\n var traceOut, traces, groupName, binDir;\n var i, j, k;\n\n function coerce(attr, dflt) {\n return Lib.coerce(traceOut._input, traceOut, traceOut._module.attributes, attr, dflt);\n }\n\n function orientation2binDir(traceOut) {\n return traceOut.orientation === 'v' ? 'x' : 'y';\n }\n\n function getAxisType(traceOut, binDir) {\n var ax = axisIds.getFromTrace({_fullLayout: fullLayout}, traceOut, binDir);\n return ax.type;\n }\n\n function fillBinOpts(traceOut, groupName, binDir) {\n // N.B. group traces that don't have a bingroup with themselves\n var fallbackGroupName = traceOut.uid + '__' + binDir;\n if(!groupName) groupName = fallbackGroupName;\n\n var axType = getAxisType(traceOut, binDir);\n var calendar = traceOut[binDir + 'calendar'] || '';\n var binOpts = allBinOpts[groupName];\n var needsNewItem = true;\n\n if(binOpts) {\n if(axType === binOpts.axType && calendar === binOpts.calendar) {\n needsNewItem = false;\n binOpts.traces.push(traceOut);\n binOpts.dirs.push(binDir);\n } else {\n groupName = fallbackGroupName;\n\n if(axType !== binOpts.axType) {\n Lib.warn([\n 'Attempted to group the bins of trace', traceOut.index,\n 'set on a', 'type:' + axType, 'axis',\n 'with bins on', 'type:' + binOpts.axType, 'axis.'\n ].join(' '));\n }\n if(calendar !== binOpts.calendar) {\n // prohibit bingroup for traces using different calendar,\n // there's probably a way to make this work, but skip for now\n Lib.warn([\n 'Attempted to group the bins of trace', traceOut.index,\n 'set with a', calendar, 'calendar',\n 'with bins',\n (binOpts.calendar ? 'on a ' + binOpts.calendar + ' calendar' : 'w/o a set calendar')\n ].join(' '));\n }\n }\n }\n\n if(needsNewItem) {\n allBinOpts[groupName] = {\n traces: [traceOut],\n dirs: [binDir],\n axType: axType,\n calendar: traceOut[binDir + 'calendar'] || ''\n };\n }\n traceOut['_' + binDir + 'bingroup'] = groupName;\n }\n\n for(i = 0; i < fullData.length; i++) {\n traceOut = fullData[i];\n\n if(traceIs(traceOut, 'histogram')) {\n histTraces.push(traceOut);\n\n // TODO: this shouldn't be relinked as it's only used within calc\n // https://github.com/plotly/plotly.js/issues/749\n delete traceOut._xautoBinFinished;\n delete traceOut._yautoBinFinished;\n\n // N.B. need to coerce *alignmentgroup* before *bingroup*, as traces\n // in same alignmentgroup \"have to match\"\n if(!traceIs(traceOut, '2dMap')) {\n handleGroupingDefaults(traceOut._input, traceOut, fullLayout, coerce);\n }\n }\n }\n\n var alignmentOpts = fullLayout._alignmentOpts || {};\n\n // Look for traces that \"have to match\", that is:\n // - 1d histogram traces on the same subplot with same orientation under barmode:stack,\n // - 1d histogram traces on the same subplot with same orientation under barmode:group\n // - 1d histogram traces on the same position axis with the same orientation\n // and the same *alignmentgroup* (coerced under barmode:group)\n // - Once `stackgroup` gets implemented (see https://github.com/plotly/plotly.js/issues/3614),\n // traces within the same stackgroup will also \"have to match\"\n for(i = 0; i < histTraces.length; i++) {\n traceOut = histTraces[i];\n groupName = '';\n\n if(!traceIs(traceOut, '2dMap')) {\n binDir = orientation2binDir(traceOut);\n\n if(fullLayout.barmode === 'group' && traceOut.alignmentgroup) {\n var pa = traceOut[binDir + 'axis'];\n var aGroupId = getAxisGroup(fullLayout, pa) + traceOut.orientation;\n if((alignmentOpts[aGroupId] || {})[traceOut.alignmentgroup]) {\n groupName = aGroupId;\n }\n }\n\n if(!groupName && fullLayout.barmode !== 'overlay') {\n groupName = (\n getAxisGroup(fullLayout, traceOut.xaxis) +\n getAxisGroup(fullLayout, traceOut.yaxis) +\n orientation2binDir(traceOut)\n );\n }\n }\n\n if(groupName) {\n if(!mustMatchTracesLookup[groupName]) {\n mustMatchTracesLookup[groupName] = [];\n }\n mustMatchTracesLookup[groupName].push(traceOut);\n } else {\n otherTracesList.push(traceOut);\n }\n }\n\n // Setup binOpts for traces that have to match,\n // if the traces have a valid bingroup, use that\n // if not use axis+binDir groupName\n for(groupName in mustMatchTracesLookup) {\n traces = mustMatchTracesLookup[groupName];\n\n // no need to 'force' anything when a single\n // trace is detected as \"must match\"\n if(traces.length === 1) {\n otherTracesList.push(traces[0]);\n continue;\n }\n\n var binGroupFound = false;\n for(i = 0; i < traces.length; i++) {\n traceOut = traces[i];\n binGroupFound = coerce('bingroup');\n break;\n }\n\n groupName = binGroupFound || groupName;\n\n for(i = 0; i < traces.length; i++) {\n traceOut = traces[i];\n var bingroupIn = traceOut._input.bingroup;\n if(bingroupIn && bingroupIn !== groupName) {\n Lib.warn([\n 'Trace', traceOut.index, 'must match',\n 'within bingroup', groupName + '.',\n 'Ignoring its bingroup:', bingroupIn, 'setting.'\n ].join(' '));\n }\n traceOut.bingroup = groupName;\n\n // N.B. no need to worry about 2dMap case\n // (where both bin direction are set in each trace)\n // as 2dMap trace never \"have to match\"\n fillBinOpts(traceOut, groupName, orientation2binDir(traceOut));\n }\n }\n\n // setup binOpts for traces that can but don't have to match,\n // notice that these traces can be matched with traces that have to match\n for(i = 0; i < otherTracesList.length; i++) {\n traceOut = otherTracesList[i];\n\n var binGroup = coerce('bingroup');\n\n if(traceIs(traceOut, '2dMap')) {\n for(k = 0; k < 2; k++) {\n binDir = BINDIRECTIONS[k];\n var binGroupInDir = coerce(binDir + 'bingroup',\n binGroup ? binGroup + '__' + binDir : null\n );\n fillBinOpts(traceOut, binGroupInDir, binDir);\n }\n } else {\n fillBinOpts(traceOut, binGroup, orientation2binDir(traceOut));\n }\n }\n\n // coerce bin attrs!\n for(groupName in allBinOpts) {\n var binOpts = allBinOpts[groupName];\n traces = binOpts.traces;\n\n for(j = 0; j < BINATTRS.length; j++) {\n var attrSpec = BINATTRS[j];\n var attr = attrSpec.name;\n var aStr;\n var autoVals;\n\n // nbins(x|y) is moot if we have a size. This depends on\n // nbins coming after size in binAttrs.\n if(attr === 'nbins' && binOpts.sizeFound) continue;\n\n for(i = 0; i < traces.length; i++) {\n traceOut = traces[i];\n binDir = binOpts.dirs[i];\n aStr = attrSpec.aStr[binDir];\n\n if(nestedProperty(traceOut._input, aStr).get() !== undefined) {\n binOpts[attr] = coerce(aStr);\n binOpts[attr + 'Found'] = true;\n break;\n }\n\n autoVals = (traceOut._autoBin || {})[binDir] || {};\n if(autoVals[attr]) {\n // if this is the *first* autoval\n nestedProperty(traceOut, aStr).set(autoVals[attr]);\n }\n }\n\n // start and end we need to coerce anyway, after having collected the\n // first of each into binOpts, in case a trace wants to restrict its\n // data to a certain range\n if(attr === 'start' || attr === 'end') {\n for(; i < traces.length; i++) {\n traceOut = traces[i];\n if(traceOut['_' + binDir + 'bingroup']) {\n autoVals = (traceOut._autoBin || {})[binDir] || {};\n coerce(aStr, autoVals[attr]);\n }\n }\n }\n\n if(attr === 'nbins' && !binOpts.sizeFound && !binOpts.nbinsFound) {\n traceOut = traces[0];\n binOpts[attr] = coerce(aStr);\n }\n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram/cross_trace_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram/defaults.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram/defaults.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\n\nvar handleStyleDefaults = __webpack_require__(/*! ../bar/style_defaults */ \"./node_modules/plotly.js/src/traces/bar/style_defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/histogram/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var x = coerce('x');\n var y = coerce('y');\n\n var cumulative = coerce('cumulative.enabled');\n if(cumulative) {\n coerce('cumulative.direction');\n coerce('cumulative.currentbin');\n }\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n\n var orientation = coerce('orientation', (y && !x) ? 'h' : 'v');\n var sampleLetter = orientation === 'v' ? 'x' : 'y';\n var aggLetter = orientation === 'v' ? 'y' : 'x';\n\n var len = (x && y) ?\n Math.min(Lib.minRowLength(x) && Lib.minRowLength(y)) :\n Lib.minRowLength(traceOut[sampleLetter] || []);\n\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n traceOut._length = len;\n\n var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleTraceDefaults');\n handleCalendarDefaults(traceIn, traceOut, ['x', 'y'], layout);\n\n var hasAggregationData = traceOut[aggLetter];\n if(hasAggregationData) coerce('histfunc');\n coerce('histnorm');\n\n // Note: bin defaults are now handled in Histogram.crossTraceDefaults\n // autobin(x|y) are only included here to appease Plotly.validate\n coerce('autobin' + sampleLetter);\n\n handleStyleDefaults(traceIn, traceOut, coerce, defaultColor, layout);\n\n Lib.coerceSelectionMarkerOpacity(traceOut, coerce);\n\n var lineColor = (traceOut.marker.line || {}).color;\n\n // override defaultColor for error bars with defaultLine\n var errorBarsSupplyDefaults = Registry.getComponentMethod('errorbars', 'supplyDefaults');\n errorBarsSupplyDefaults(traceIn, traceOut, lineColor || Color.defaultLine, {axis: 'y'});\n errorBarsSupplyDefaults(traceIn, traceOut, lineColor || Color.defaultLine, {axis: 'x', inherit: 'y'});\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram/event_data.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram/event_data.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function eventData(out, pt, trace, cd, pointNumber) {\n // standard cartesian event data\n out.x = 'xVal' in pt ? pt.xVal : pt.x;\n out.y = 'yVal' in pt ? pt.yVal : pt.y;\n\n // for 2d histograms\n if('zLabelVal' in pt) out.z = pt.zLabelVal;\n\n if(pt.xa) out.xaxis = pt.xa;\n if(pt.ya) out.yaxis = pt.ya;\n\n // specific to histogram - CDFs do not have pts (yet?)\n if(!(trace.cumulative || {}).enabled) {\n var pts = Array.isArray(pointNumber) ?\n cd[0].pts[pointNumber[0]][pointNumber[1]] :\n cd[pointNumber].pts;\n\n out.pointNumbers = pts;\n out.binNumber = out.pointNumber;\n delete out.pointNumber;\n delete out.pointIndex;\n\n var pointIndices;\n if(trace._indexToPoints) {\n pointIndices = [];\n for(var i = 0; i < pts.length; i++) {\n pointIndices = pointIndices.concat(trace._indexToPoints[pts[i]]);\n }\n } else {\n pointIndices = pts;\n }\n\n out.pointIndices = pointIndices;\n }\n\n return out;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram/event_data.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram/hover.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram/hover.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar barHover = __webpack_require__(/*! ../bar/hover */ \"./node_modules/plotly.js/src/traces/bar/hover.js\").hoverPoints;\nvar hoverLabelText = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\").hoverLabelText;\n\nmodule.exports = function hoverPoints(pointData, xval, yval, hovermode) {\n var pts = barHover(pointData, xval, yval, hovermode);\n\n if(!pts) return;\n\n pointData = pts[0];\n var di = pointData.cd[pointData.index];\n var trace = pointData.cd[0].trace;\n\n if(!trace.cumulative.enabled) {\n var posLetter = trace.orientation === 'h' ? 'y' : 'x';\n\n pointData[posLetter + 'Label'] = hoverLabelText(pointData[posLetter + 'a'], di.ph0, di.ph1);\n }\n\n if(trace.hovermplate) pointData.hovertemplate = trace.hovertemplate;\n\n return pts;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram/index.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram/index.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n/**\n * Histogram has its own attribute, defaults and calc steps,\n * but uses bar's plot to display\n * and bar's crossTraceCalc (formerly known as setPositions) for stacking and grouping\n */\n\n/**\n * histogram errorBarsOK is debatable, but it's put in for backward compat.\n * there are use cases for it - sqrt for a simple histogram works right now,\n * constant and % work but they're not so meaningful. I guess it could be cool\n * to allow quadrature combination of errors in summed histograms...\n */\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/histogram/attributes.js\"),\n layoutAttributes: __webpack_require__(/*! ../bar/layout_attributes */ \"./node_modules/plotly.js/src/traces/bar/layout_attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/histogram/defaults.js\"),\n crossTraceDefaults: __webpack_require__(/*! ./cross_trace_defaults */ \"./node_modules/plotly.js/src/traces/histogram/cross_trace_defaults.js\"),\n supplyLayoutDefaults: __webpack_require__(/*! ../bar/layout_defaults */ \"./node_modules/plotly.js/src/traces/bar/layout_defaults.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/histogram/calc.js\").calc,\n crossTraceCalc: __webpack_require__(/*! ../bar/cross_trace_calc */ \"./node_modules/plotly.js/src/traces/bar/cross_trace_calc.js\").crossTraceCalc,\n plot: __webpack_require__(/*! ../bar/plot */ \"./node_modules/plotly.js/src/traces/bar/plot.js\").plot,\n layerName: 'barlayer',\n style: __webpack_require__(/*! ../bar/style */ \"./node_modules/plotly.js/src/traces/bar/style.js\").style,\n styleOnSelect: __webpack_require__(/*! ../bar/style */ \"./node_modules/plotly.js/src/traces/bar/style.js\").styleOnSelect,\n colorbar: __webpack_require__(/*! ../scatter/marker_colorbar */ \"./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js\"),\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/histogram/hover.js\"),\n selectPoints: __webpack_require__(/*! ../bar/select */ \"./node_modules/plotly.js/src/traces/bar/select.js\"),\n eventData: __webpack_require__(/*! ./event_data */ \"./node_modules/plotly.js/src/traces/histogram/event_data.js\"),\n\n moduleType: 'trace',\n name: 'histogram',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['bar-like', 'cartesian', 'svg', 'bar', 'histogram', 'oriented', 'errorBarsOK', 'showLegend'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram/norm_functions.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram/norm_functions.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\n\nmodule.exports = {\n percent: function(size, total) {\n var nMax = size.length;\n var norm = 100 / total;\n for(var n = 0; n < nMax; n++) size[n] *= norm;\n },\n probability: function(size, total) {\n var nMax = size.length;\n for(var n = 0; n < nMax; n++) size[n] /= total;\n },\n density: function(size, total, inc, yinc) {\n var nMax = size.length;\n yinc = yinc || 1;\n for(var n = 0; n < nMax; n++) size[n] *= inc[n] * yinc;\n },\n 'probability density': function(size, total, inc, yinc) {\n var nMax = size.length;\n if(yinc) total /= yinc;\n for(var n = 0; n < nMax; n++) size[n] *= inc[n] / total;\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram/norm_functions.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram2d/attributes.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram2d/attributes.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar histogramAttrs = __webpack_require__(/*! ../histogram/attributes */ \"./node_modules/plotly.js/src/traces/histogram/attributes.js\");\nvar makeBinAttrs = __webpack_require__(/*! ../histogram/bin_attributes */ \"./node_modules/plotly.js/src/traces/histogram/bin_attributes.js\");\nvar heatmapAttrs = __webpack_require__(/*! ../heatmap/attributes */ \"./node_modules/plotly.js/src/traces/heatmap/attributes.js\");\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nmodule.exports = extendFlat(\n {\n x: histogramAttrs.x,\n y: histogramAttrs.y,\n\n z: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n marker: {\n color: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n editType: 'calc'\n },\n\n histnorm: histogramAttrs.histnorm,\n histfunc: histogramAttrs.histfunc,\n nbinsx: histogramAttrs.nbinsx,\n xbins: makeBinAttrs('x'),\n nbinsy: histogramAttrs.nbinsy,\n ybins: makeBinAttrs('y'),\n autobinx: histogramAttrs.autobinx,\n autobiny: histogramAttrs.autobiny,\n\n bingroup: extendFlat({}, histogramAttrs.bingroup, {\n \n }),\n xbingroup: extendFlat({}, histogramAttrs.bingroup, {\n \n }),\n ybingroup: extendFlat({}, histogramAttrs.bingroup, {\n \n }),\n\n xgap: heatmapAttrs.xgap,\n ygap: heatmapAttrs.ygap,\n zsmooth: heatmapAttrs.zsmooth,\n zhoverformat: heatmapAttrs.zhoverformat,\n hovertemplate: hovertemplateAttrs({}, {keys: 'z'}),\n showlegend: extendFlat({}, baseAttrs.showlegend, {dflt: false})\n },\n colorScaleAttrs('', {cLetter: 'z', autoColorDflt: false})\n);\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram2d/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram2d/calc.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram2d/calc.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\n\nvar binFunctions = __webpack_require__(/*! ../histogram/bin_functions */ \"./node_modules/plotly.js/src/traces/histogram/bin_functions.js\");\nvar normFunctions = __webpack_require__(/*! ../histogram/norm_functions */ \"./node_modules/plotly.js/src/traces/histogram/norm_functions.js\");\nvar doAvg = __webpack_require__(/*! ../histogram/average */ \"./node_modules/plotly.js/src/traces/histogram/average.js\");\nvar getBinSpanLabelRound = __webpack_require__(/*! ../histogram/bin_label_vals */ \"./node_modules/plotly.js/src/traces/histogram/bin_label_vals.js\");\nvar calcAllAutoBins = __webpack_require__(/*! ../histogram/calc */ \"./node_modules/plotly.js/src/traces/histogram/calc.js\").calcAllAutoBins;\n\nmodule.exports = function calc(gd, trace) {\n var xa = Axes.getFromId(gd, trace.xaxis);\n var ya = Axes.getFromId(gd, trace.yaxis);\n\n var xcalendar = trace.xcalendar;\n var ycalendar = trace.ycalendar;\n var xr2c = function(v) { return xa.r2c(v, 0, xcalendar); };\n var yr2c = function(v) { return ya.r2c(v, 0, ycalendar); };\n var xc2r = function(v) { return xa.c2r(v, 0, xcalendar); };\n var yc2r = function(v) { return ya.c2r(v, 0, ycalendar); };\n\n var i, j, n, m;\n\n // calculate the bins\n var xBinsAndPos = calcAllAutoBins(gd, trace, xa, 'x');\n var xBinSpec = xBinsAndPos[0];\n var xPos0 = xBinsAndPos[1];\n var yBinsAndPos = calcAllAutoBins(gd, trace, ya, 'y');\n var yBinSpec = yBinsAndPos[0];\n var yPos0 = yBinsAndPos[1];\n\n var serieslen = trace._length;\n if(xPos0.length > serieslen) xPos0.splice(serieslen, xPos0.length - serieslen);\n if(yPos0.length > serieslen) yPos0.splice(serieslen, yPos0.length - serieslen);\n\n // make the empty bin array & scale the map\n var z = [];\n var onecol = [];\n var zerocol = [];\n var nonuniformBinsX = typeof xBinSpec.size === 'string';\n var nonuniformBinsY = typeof yBinSpec.size === 'string';\n var xEdges = [];\n var yEdges = [];\n var xbins = nonuniformBinsX ? xEdges : xBinSpec;\n var ybins = nonuniformBinsY ? yEdges : yBinSpec;\n var total = 0;\n var counts = [];\n var inputPoints = [];\n var norm = trace.histnorm;\n var func = trace.histfunc;\n var densitynorm = norm.indexOf('density') !== -1;\n var extremefunc = func === 'max' || func === 'min';\n var sizeinit = extremefunc ? null : 0;\n var binfunc = binFunctions.count;\n var normfunc = normFunctions[norm];\n var doavg = false;\n var xinc = [];\n var yinc = [];\n\n // set a binning function other than count?\n // for binning functions: check first for 'z',\n // then 'mc' in case we had a colored scatter plot\n // and want to transfer these colors to the 2D histo\n // TODO: axe this, make it the responsibility of the app changing type? or an impliedEdit?\n var rawCounterData = ('z' in trace) ?\n trace.z :\n (('marker' in trace && Array.isArray(trace.marker.color)) ?\n trace.marker.color : '');\n if(rawCounterData && func !== 'count') {\n doavg = func === 'avg';\n binfunc = binFunctions[func];\n }\n\n // decrease end a little in case of rounding errors\n var xBinSize = xBinSpec.size;\n var xBinStart = xr2c(xBinSpec.start);\n var xBinEnd = xr2c(xBinSpec.end) +\n (xBinStart - Axes.tickIncrement(xBinStart, xBinSize, false, xcalendar)) / 1e6;\n\n for(i = xBinStart; i < xBinEnd; i = Axes.tickIncrement(i, xBinSize, false, xcalendar)) {\n onecol.push(sizeinit);\n xEdges.push(i);\n if(doavg) zerocol.push(0);\n }\n xEdges.push(i);\n\n var nx = onecol.length;\n var dx = (i - xBinStart) / nx;\n var x0 = xc2r(xBinStart + dx / 2);\n\n var yBinSize = yBinSpec.size;\n var yBinStart = yr2c(yBinSpec.start);\n var yBinEnd = yr2c(yBinSpec.end) +\n (yBinStart - Axes.tickIncrement(yBinStart, yBinSize, false, ycalendar)) / 1e6;\n\n for(i = yBinStart; i < yBinEnd; i = Axes.tickIncrement(i, yBinSize, false, ycalendar)) {\n z.push(onecol.slice());\n yEdges.push(i);\n var ipCol = new Array(nx);\n for(j = 0; j < nx; j++) ipCol[j] = [];\n inputPoints.push(ipCol);\n if(doavg) counts.push(zerocol.slice());\n }\n yEdges.push(i);\n\n var ny = z.length;\n var dy = (i - yBinStart) / ny;\n var y0 = yc2r(yBinStart + dy / 2);\n\n if(densitynorm) {\n xinc = makeIncrements(onecol.length, xbins, dx, nonuniformBinsX);\n yinc = makeIncrements(z.length, ybins, dy, nonuniformBinsY);\n }\n\n // for date axes we need bin bounds to be calcdata. For nonuniform bins\n // we already have this, but uniform with start/end/size they're still strings.\n if(!nonuniformBinsX && xa.type === 'date') xbins = binsToCalc(xr2c, xbins);\n if(!nonuniformBinsY && ya.type === 'date') ybins = binsToCalc(yr2c, ybins);\n\n // put data into bins\n var uniqueValsPerX = true;\n var uniqueValsPerY = true;\n var xVals = new Array(nx);\n var yVals = new Array(ny);\n var xGapLow = Infinity;\n var xGapHigh = Infinity;\n var yGapLow = Infinity;\n var yGapHigh = Infinity;\n for(i = 0; i < serieslen; i++) {\n var xi = xPos0[i];\n var yi = yPos0[i];\n n = Lib.findBin(xi, xbins);\n m = Lib.findBin(yi, ybins);\n if(n >= 0 && n < nx && m >= 0 && m < ny) {\n total += binfunc(n, i, z[m], rawCounterData, counts[m]);\n inputPoints[m][n].push(i);\n\n if(uniqueValsPerX) {\n if(xVals[n] === undefined) xVals[n] = xi;\n else if(xVals[n] !== xi) uniqueValsPerX = false;\n }\n if(uniqueValsPerY) {\n if(yVals[m] === undefined) yVals[m] = yi;\n else if(yVals[m] !== yi) uniqueValsPerY = false;\n }\n\n xGapLow = Math.min(xGapLow, xi - xEdges[n]);\n xGapHigh = Math.min(xGapHigh, xEdges[n + 1] - xi);\n yGapLow = Math.min(yGapLow, yi - yEdges[m]);\n yGapHigh = Math.min(yGapHigh, yEdges[m + 1] - yi);\n }\n }\n // normalize, if needed\n if(doavg) {\n for(m = 0; m < ny; m++) total += doAvg(z[m], counts[m]);\n }\n if(normfunc) {\n for(m = 0; m < ny; m++) normfunc(z[m], total, xinc, yinc[m]);\n }\n\n return {\n x: xPos0,\n xRanges: getRanges(xEdges, uniqueValsPerX && xVals, xGapLow, xGapHigh, xa, xcalendar),\n x0: x0,\n dx: dx,\n y: yPos0,\n yRanges: getRanges(yEdges, uniqueValsPerY && yVals, yGapLow, yGapHigh, ya, ycalendar),\n y0: y0,\n dy: dy,\n z: z,\n pts: inputPoints\n };\n};\n\nfunction makeIncrements(len, bins, dv, nonuniform) {\n var out = new Array(len);\n var i;\n if(nonuniform) {\n for(i = 0; i < len; i++) out[i] = 1 / (bins[i + 1] - bins[i]);\n } else {\n var inc = 1 / dv;\n for(i = 0; i < len; i++) out[i] = inc;\n }\n return out;\n}\n\nfunction binsToCalc(r2c, bins) {\n return {\n start: r2c(bins.start),\n end: r2c(bins.end),\n size: bins.size\n };\n}\n\nfunction getRanges(edges, uniqueVals, gapLow, gapHigh, ax, calendar) {\n var i;\n var len = edges.length - 1;\n var out = new Array(len);\n var roundFn = getBinSpanLabelRound(gapLow, gapHigh, edges, ax, calendar);\n\n for(i = 0; i < len; i++) {\n var v = (uniqueVals || [])[i];\n out[i] = v === undefined ?\n [roundFn(edges[i]), roundFn(edges[i + 1], true)] :\n [v, v];\n }\n return out;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram2d/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram2d/defaults.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram2d/defaults.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar handleSampleDefaults = __webpack_require__(/*! ./sample_defaults */ \"./node_modules/plotly.js/src/traces/histogram2d/sample_defaults.js\");\nvar handleStyleDefaults = __webpack_require__(/*! ../heatmap/style_defaults */ \"./node_modules/plotly.js/src/traces/heatmap/style_defaults.js\");\nvar colorscaleDefaults = __webpack_require__(/*! ../../components/colorscale/defaults */ \"./node_modules/plotly.js/src/components/colorscale/defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/histogram2d/attributes.js\");\n\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n handleSampleDefaults(traceIn, traceOut, coerce, layout);\n if(traceOut.visible === false) return;\n\n handleStyleDefaults(traceIn, traceOut, coerce, layout);\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'z'});\n coerce('hovertemplate');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram2d/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram2d/hover.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram2d/hover.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar heatmapHover = __webpack_require__(/*! ../heatmap/hover */ \"./node_modules/plotly.js/src/traces/heatmap/hover.js\");\nvar hoverLabelText = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\").hoverLabelText;\n\nmodule.exports = function hoverPoints(pointData, xval, yval, hovermode, hoverLayer, contour) {\n var pts = heatmapHover(pointData, xval, yval, hovermode, hoverLayer, contour);\n\n if(!pts) return;\n\n pointData = pts[0];\n var indices = pointData.index;\n var ny = indices[0];\n var nx = indices[1];\n var cd0 = pointData.cd[0];\n var xRange = cd0.xRanges[nx];\n var yRange = cd0.yRanges[ny];\n\n pointData.xLabel = hoverLabelText(pointData.xa, xRange[0], xRange[1]);\n pointData.yLabel = hoverLabelText(pointData.ya, yRange[0], yRange[1]);\n\n return pts;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram2d/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram2d/index.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram2d/index.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/histogram2d/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/histogram2d/defaults.js\"),\n crossTraceDefaults: __webpack_require__(/*! ../histogram/cross_trace_defaults */ \"./node_modules/plotly.js/src/traces/histogram/cross_trace_defaults.js\"),\n calc: __webpack_require__(/*! ../heatmap/calc */ \"./node_modules/plotly.js/src/traces/heatmap/calc.js\"),\n plot: __webpack_require__(/*! ../heatmap/plot */ \"./node_modules/plotly.js/src/traces/heatmap/plot.js\"),\n layerName: 'heatmaplayer',\n colorbar: __webpack_require__(/*! ../heatmap/colorbar */ \"./node_modules/plotly.js/src/traces/heatmap/colorbar.js\"),\n style: __webpack_require__(/*! ../heatmap/style */ \"./node_modules/plotly.js/src/traces/heatmap/style.js\"),\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/histogram2d/hover.js\"),\n eventData: __webpack_require__(/*! ../histogram/event_data */ \"./node_modules/plotly.js/src/traces/histogram/event_data.js\"),\n\n moduleType: 'trace',\n name: 'histogram2d',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['cartesian', 'svg', '2dMap', 'histogram', 'showLegend'],\n meta: {\n \n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram2d/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram2d/sample_defaults.js":
-/*!**************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram2d/sample_defaults.js ***!
- \**************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nmodule.exports = function handleSampleDefaults(traceIn, traceOut, coerce, layout) {\n var x = coerce('x');\n var y = coerce('y');\n var xlen = Lib.minRowLength(x);\n var ylen = Lib.minRowLength(y);\n\n // we could try to accept x0 and dx, etc...\n // but that's a pretty weird use case.\n // for now require both x and y explicitly specified.\n if(!xlen || !ylen) {\n traceOut.visible = false;\n return;\n }\n\n traceOut._length = Math.min(xlen, ylen);\n\n var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleTraceDefaults');\n handleCalendarDefaults(traceIn, traceOut, ['x', 'y'], layout);\n\n // if marker.color is an array, we can use it in aggregation instead of z\n var hasAggregationData = coerce('z') || coerce('marker.color');\n\n if(hasAggregationData) coerce('histfunc');\n coerce('histnorm');\n\n // Note: bin defaults are now handled in Histogram2D.crossTraceDefaults\n // autobin(x|y) are only included here to appease Plotly.validate\n coerce('autobinx');\n coerce('autobiny');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram2d/sample_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram2dcontour/attributes.js":
-/*!****************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram2dcontour/attributes.js ***!
- \****************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar histogram2dAttrs = __webpack_require__(/*! ../histogram2d/attributes */ \"./node_modules/plotly.js/src/traces/histogram2d/attributes.js\");\nvar contourAttrs = __webpack_require__(/*! ../contour/attributes */ \"./node_modules/plotly.js/src/traces/contour/attributes.js\");\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nmodule.exports = extendFlat({\n x: histogram2dAttrs.x,\n y: histogram2dAttrs.y,\n z: histogram2dAttrs.z,\n marker: histogram2dAttrs.marker,\n\n histnorm: histogram2dAttrs.histnorm,\n histfunc: histogram2dAttrs.histfunc,\n nbinsx: histogram2dAttrs.nbinsx,\n xbins: histogram2dAttrs.xbins,\n nbinsy: histogram2dAttrs.nbinsy,\n ybins: histogram2dAttrs.ybins,\n autobinx: histogram2dAttrs.autobinx,\n autobiny: histogram2dAttrs.autobiny,\n\n bingroup: histogram2dAttrs.bingroup,\n xbingroup: histogram2dAttrs.xbingroup,\n ybingroup: histogram2dAttrs.ybingroup,\n\n autocontour: contourAttrs.autocontour,\n ncontours: contourAttrs.ncontours,\n contours: contourAttrs.contours,\n line: {\n color: contourAttrs.line.color,\n width: extendFlat({}, contourAttrs.line.width, {\n dflt: 0.5,\n \n }),\n dash: contourAttrs.line.dash,\n smoothing: contourAttrs.line.smoothing,\n editType: 'plot'\n },\n zhoverformat: histogram2dAttrs.zhoverformat,\n hovertemplate: histogram2dAttrs.hovertemplate\n},\n colorScaleAttrs('', {\n cLetter: 'z',\n editTypeOverride: 'calc'\n })\n);\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram2dcontour/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram2dcontour/defaults.js":
-/*!**************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram2dcontour/defaults.js ***!
- \**************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar handleSampleDefaults = __webpack_require__(/*! ../histogram2d/sample_defaults */ \"./node_modules/plotly.js/src/traces/histogram2d/sample_defaults.js\");\nvar handleContoursDefaults = __webpack_require__(/*! ../contour/contours_defaults */ \"./node_modules/plotly.js/src/traces/contour/contours_defaults.js\");\nvar handleStyleDefaults = __webpack_require__(/*! ../contour/style_defaults */ \"./node_modules/plotly.js/src/traces/contour/style_defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/histogram2dcontour/attributes.js\");\n\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n function coerce2(attr) {\n return Lib.coerce2(traceIn, traceOut, attributes, attr);\n }\n\n handleSampleDefaults(traceIn, traceOut, coerce, layout);\n if(traceOut.visible === false) return;\n\n handleContoursDefaults(traceIn, traceOut, coerce, coerce2);\n handleStyleDefaults(traceIn, traceOut, coerce, layout);\n coerce('hovertemplate');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram2dcontour/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/histogram2dcontour/index.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/histogram2dcontour/index.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/histogram2dcontour/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/histogram2dcontour/defaults.js\"),\n crossTraceDefaults: __webpack_require__(/*! ../histogram/cross_trace_defaults */ \"./node_modules/plotly.js/src/traces/histogram/cross_trace_defaults.js\"),\n calc: __webpack_require__(/*! ../contour/calc */ \"./node_modules/plotly.js/src/traces/contour/calc.js\"),\n plot: __webpack_require__(/*! ../contour/plot */ \"./node_modules/plotly.js/src/traces/contour/plot.js\").plot,\n layerName: 'contourlayer',\n style: __webpack_require__(/*! ../contour/style */ \"./node_modules/plotly.js/src/traces/contour/style.js\"),\n colorbar: __webpack_require__(/*! ../contour/colorbar */ \"./node_modules/plotly.js/src/traces/contour/colorbar.js\"),\n hoverPoints: __webpack_require__(/*! ../contour/hover */ \"./node_modules/plotly.js/src/traces/contour/hover.js\"),\n\n moduleType: 'trace',\n name: 'histogram2dcontour',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['cartesian', 'svg', '2dMap', 'contour', 'histogram', 'showLegend'],\n meta: {\n \n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/histogram2dcontour/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/image/attributes.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/image/attributes.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar colormodel = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/image/constants.js\").colormodel;\n\nvar cm = ['rgb', 'rgba', 'hsl', 'hsla'];\nvar zminDesc = [];\nvar zmaxDesc = [];\nfor(var i = 0; i < cm.length; i++) {\n zminDesc.push('For the `' + cm[i] + '` colormodel, it is [' + colormodel[cm[i]].min.join(', ') + '].');\n zmaxDesc.push('For the `' + cm[i] + '` colormodel, it is [' + colormodel[cm[i]].max.join(', ') + '].');\n}\n\nmodule.exports = extendFlat({\n z: {\n valType: 'data_array',\n \n editType: 'calc',\n \n },\n colormodel: {\n valType: 'enumerated',\n values: cm,\n dflt: 'rgb',\n \n editType: 'calc',\n \n },\n zmin: {\n valType: 'info_array',\n items: [\n {valType: 'number', editType: 'calc'},\n {valType: 'number', editType: 'calc'},\n {valType: 'number', editType: 'calc'},\n {valType: 'number', editType: 'calc'}\n ],\n \n editType: 'calc',\n \n },\n zmax: {\n valType: 'info_array',\n items: [\n {valType: 'number', editType: 'calc'},\n {valType: 'number', editType: 'calc'},\n {valType: 'number', editType: 'calc'},\n {valType: 'number', editType: 'calc'}\n ],\n \n editType: 'calc',\n \n },\n x0: {\n valType: 'any',\n dflt: 0,\n \n editType: 'calc+clearAxisTypes',\n \n },\n y0: {\n valType: 'any',\n dflt: 0,\n \n editType: 'calc+clearAxisTypes',\n \n },\n dx: {\n valType: 'number',\n dflt: 1,\n \n editType: 'calc',\n \n },\n dy: {\n valType: 'number',\n dflt: 1,\n \n editType: 'calc',\n \n },\n text: {\n valType: 'data_array',\n editType: 'plot',\n \n },\n hovertext: {\n valType: 'data_array',\n editType: 'plot',\n \n },\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {\n flags: ['x', 'y', 'z', 'color', 'name', 'text'],\n dflt: 'x+y+z+text+name'\n }),\n hovertemplate: hovertemplateAttrs({}, {\n keys: ['z', 'color', 'colormodel']\n }),\n\n transforms: undefined\n});\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/image/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/image/calc.js":
-/*!*********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/image/calc.js ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/image/constants.js\");\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar maxRowLength = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").maxRowLength;\n\nmodule.exports = function calc(gd, trace) {\n var xa = Axes.getFromId(gd, trace.xaxis || 'x');\n var ya = Axes.getFromId(gd, trace.yaxis || 'y');\n\n var x0 = xa.d2c(trace.x0) - trace.dx / 2;\n var y0 = ya.d2c(trace.y0) - trace.dy / 2;\n var h = trace.z.length;\n var w = maxRowLength(trace.z);\n\n // Set axis range\n var i;\n var xrange = [x0, x0 + w * trace.dx];\n var yrange = [y0, y0 + h * trace.dy];\n if(xa && xa.type === 'log') for(i = 0; i < w; i++) xrange.push(x0 + i * trace.dx);\n if(ya && ya.type === 'log') for(i = 0; i < h; i++) yrange.push(y0 + i * trace.dy);\n trace._extremes[xa._id] = Axes.findExtremes(xa, xrange);\n trace._extremes[ya._id] = Axes.findExtremes(ya, yrange);\n trace._scaler = makeScaler(trace);\n\n var cd0 = {\n x0: x0,\n y0: y0,\n z: trace.z,\n w: w,\n h: h\n };\n return [cd0];\n};\n\nfunction scale(zero, ratio, min, max) {\n return function(c) {\n return Lib.constrain((c - zero) * ratio, min, max);\n };\n}\n\nfunction constrain(min, max) {\n return function(c) { return Lib.constrain(c, min, max);};\n}\n\n// Generate a function to scale color components according to zmin/zmax and the colormodel\nfunction makeScaler(trace) {\n var colormodel = trace.colormodel;\n var n = colormodel.length;\n var cr = constants.colormodel[colormodel];\n\n trace._sArray = [];\n // Loop over all color components\n for(var k = 0; k < n; k++) {\n if(cr.min[k] !== trace.zmin[k] || cr.max[k] !== trace.zmax[k]) {\n trace._sArray.push(scale(\n trace.zmin[k],\n (cr.max[k] - cr.min[k]) / (trace.zmax[k] - trace.zmin[k]),\n cr.min[k],\n cr.max[k]\n ));\n } else {\n trace._sArray.push(constrain(cr.min[k], cr.max[k]));\n }\n }\n\n return function(pixel) {\n var c = pixel.slice(0, n);\n for(var k = 0; k < n; k++) {\n var ck = c[k];\n if(!isNumeric(ck)) return false;\n c[k] = trace._sArray[k](ck);\n }\n return c;\n };\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/image/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/image/constants.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/image/constants.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n colormodel: {\n rgb: {\n min: [0, 0, 0],\n max: [255, 255, 255],\n fmt: function(c) {return c.slice(0, 3);},\n suffix: ['', '', '']\n },\n rgba: {\n min: [0, 0, 0, 0],\n max: [255, 255, 255, 1],\n fmt: function(c) {return c.slice(0, 4);},\n suffix: ['', '', '', '']\n },\n hsl: {\n min: [0, 0, 0],\n max: [360, 100, 100],\n fmt: function(c) {\n var p = c.slice(0, 3);\n p[1] = p[1] + '%';\n p[2] = p[2] + '%';\n return p;\n },\n suffix: ['°', '%', '%']\n },\n hsla: {\n min: [0, 0, 0, 0],\n max: [360, 100, 100, 1],\n fmt: function(c) {\n var p = c.slice(0, 4);\n p[1] = p[1] + '%';\n p[2] = p[2] + '%';\n return p;\n },\n suffix: ['°', '%', '%', '']\n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/image/constants.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/image/defaults.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/image/defaults.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/image/attributes.js\");\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/image/constants.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n var z = coerce('z');\n if(z === undefined || !z.length || !z[0] || !z[0].length) {\n traceOut.visible = false;\n return;\n }\n\n coerce('x0');\n coerce('y0');\n coerce('dx');\n coerce('dy');\n var colormodel = coerce('colormodel');\n\n coerce('zmin', constants.colormodel[colormodel].min);\n coerce('zmax', constants.colormodel[colormodel].max);\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n\n traceOut._length = null;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/image/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/image/event_data.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/image/event_data.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function eventData(out, pt) {\n if('xVal' in pt) out.x = pt.xVal;\n if('yVal' in pt) out.y = pt.yVal;\n if(pt.xa) out.xaxis = pt.xa;\n if(pt.ya) out.yaxis = pt.ya;\n out.color = pt.color;\n out.colormodel = pt.trace.colormodel;\n return out;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/image/event_data.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/image/hover.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/image/hover.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Fx = __webpack_require__(/*! ../../components/fx */ \"./node_modules/plotly.js/src/components/fx/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/image/constants.js\");\n\nmodule.exports = function hoverPoints(pointData, xval, yval) {\n var cd0 = pointData.cd[0];\n var trace = cd0.trace;\n var xa = pointData.xa;\n var ya = pointData.ya;\n\n // Return early if not on image\n if(Fx.inbox(xval - cd0.x0, xval - (cd0.x0 + cd0.w * trace.dx), 0) > 0 ||\n Fx.inbox(yval - cd0.y0, yval - (cd0.y0 + cd0.h * trace.dy), 0) > 0) {\n return;\n }\n\n // Find nearest pixel's index\n var nx = Math.floor((xval - cd0.x0) / trace.dx);\n var ny = Math.floor(Math.abs(yval - cd0.y0) / trace.dy);\n\n // return early if pixel is undefined\n if(!cd0.z[ny][nx]) return;\n\n var hoverinfo = cd0.hi || trace.hoverinfo;\n var fmtColor;\n if(hoverinfo) {\n var parts = hoverinfo.split('+');\n if(parts.indexOf('all') !== -1) parts = ['color'];\n if(parts.indexOf('color') !== -1) fmtColor = true;\n }\n\n var colormodel = trace.colormodel;\n var dims = colormodel.length;\n var c = trace._scaler(cd0.z[ny][nx]);\n var s = constants.colormodel[colormodel].suffix;\n\n var colorstring = [];\n if(trace.hovertemplate || fmtColor) {\n colorstring.push('[' + [c[0] + s[0], c[1] + s[1], c[2] + s[2]].join(', '));\n if(dims === 4) colorstring.push(', ' + c[3] + s[3]);\n colorstring.push(']');\n colorstring = colorstring.join('');\n pointData.extraText = colormodel.toUpperCase() + ': ' + colorstring;\n }\n\n var text;\n if(Array.isArray(trace.hovertext) && Array.isArray(trace.hovertext[ny])) {\n text = trace.hovertext[ny][nx];\n } else if(Array.isArray(trace.text) && Array.isArray(trace.text[ny])) {\n text = trace.text[ny][nx];\n }\n\n // TODO: for color model with 3 dims, display something useful for hovertemplate `%{color[3]}`\n var py = ya.c2p(cd0.y0 + (ny + 0.5) * trace.dy);\n var xVal = cd0.x0 + (nx + 0.5) * trace.dx;\n var yVal = cd0.y0 + (ny + 0.5) * trace.dy;\n var zLabel = '[' + cd0.z[ny][nx].slice(0, trace.colormodel.length).join(', ') + ']';\n return [Lib.extendFlat(pointData, {\n index: [ny, nx],\n x0: xa.c2p(cd0.x0 + nx * trace.dx),\n x1: xa.c2p(cd0.x0 + (nx + 1) * trace.dx),\n y0: py,\n y1: py,\n color: c,\n xVal: xVal,\n xLabelVal: xVal,\n yVal: yVal,\n yLabelVal: yVal,\n zLabelVal: zLabel,\n text: text,\n hovertemplateLabels: {\n 'zLabel': zLabel,\n 'colorLabel': colorstring,\n 'color[0]Label': c[0] + s[0],\n 'color[1]Label': c[1] + s[1],\n 'color[2]Label': c[2] + s[2],\n 'color[3]Label': c[3] + s[3]\n }\n })];\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/image/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/image/index.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/image/index.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/image/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/image/defaults.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/image/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/image/plot.js\"),\n style: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/image/style.js\"),\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/image/hover.js\"),\n eventData: __webpack_require__(/*! ./event_data */ \"./node_modules/plotly.js/src/traces/image/event_data.js\"),\n\n moduleType: 'trace',\n name: 'image',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['cartesian', 'svg', '2dMap', 'noSortingByValue'],\n animatable: false,\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/image/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/image/plot.js":
-/*!*********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/image/plot.js ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar xmlnsNamespaces = __webpack_require__(/*! ../../constants/xmlns_namespaces */ \"./node_modules/plotly.js/src/constants/xmlns_namespaces.js\");\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/image/constants.js\");\n\nmodule.exports = function plot(gd, plotinfo, cdimage, imageLayer) {\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n\n Lib.makeTraceGroups(imageLayer, cdimage, 'im').each(function(cd) {\n var plotGroup = d3.select(this);\n var cd0 = cd[0];\n var trace = cd0.trace;\n\n var z = cd0.z;\n var x0 = cd0.x0;\n var y0 = cd0.y0;\n var w = cd0.w;\n var h = cd0.h;\n var dx = trace.dx;\n var dy = trace.dy;\n\n var left, right, temp, top, bottom, i;\n // in case of log of a negative\n i = 0;\n while(left === undefined && i < w) {\n left = xa.c2p(x0 + i * dx);\n i++;\n }\n i = w;\n while(right === undefined && i > 0) {\n right = xa.c2p(x0 + i * dx);\n i--;\n }\n i = 0;\n while(top === undefined && i < h) {\n top = ya.c2p(y0 + i * dy);\n i++;\n }\n i = h;\n while(bottom === undefined && i > 0) {\n bottom = ya.c2p(y0 + i * dy);\n i--;\n }\n\n if(right < left) {\n temp = right;\n right = left;\n left = temp;\n }\n\n if(bottom < top) {\n temp = top;\n top = bottom;\n bottom = temp;\n }\n\n // Reduce image size when zoomed in to save memory\n var extra = 0.5; // half the axis size\n left = Math.max(-extra * xa._length, left);\n right = Math.min((1 + extra) * xa._length, right);\n top = Math.max(-extra * ya._length, top);\n bottom = Math.min((1 + extra) * ya._length, bottom);\n var imageWidth = Math.round(right - left);\n var imageHeight = Math.round(bottom - top);\n\n // if image is entirely off-screen, don't even draw it\n var isOffScreen = (imageWidth <= 0 || imageHeight <= 0);\n if(isOffScreen) {\n var noImage = plotGroup.selectAll('image').data([]);\n noImage.exit().remove();\n return;\n }\n\n // Draw each pixel\n var canvas = document.createElement('canvas');\n canvas.width = imageWidth;\n canvas.height = imageHeight;\n var context = canvas.getContext('2d');\n\n var ipx = function(i) {return Lib.constrain(Math.round(xa.c2p(x0 + i * dx) - left), 0, imageWidth);};\n var jpx = function(j) {return Lib.constrain(Math.round(ya.c2p(y0 + j * dy) - top), 0, imageHeight);};\n\n var fmt = constants.colormodel[trace.colormodel].fmt;\n var c;\n for(i = 0; i < cd0.w; i++) {\n var ipx0 = ipx(i); var ipx1 = ipx(i + 1);\n if(ipx1 === ipx0 || isNaN(ipx1) || isNaN(ipx0)) continue;\n for(var j = 0; j < cd0.h; j++) {\n var jpx0 = jpx(j); var jpx1 = jpx(j + 1);\n if(jpx1 === jpx0 || isNaN(jpx1) || isNaN(jpx0) || !z[j][i]) continue;\n c = trace._scaler(z[j][i]);\n if(c) {\n context.fillStyle = trace.colormodel + '(' + fmt(c).join(',') + ')';\n } else {\n // Return a transparent pixel\n context.fillStyle = 'rgba(0,0,0,0)';\n }\n context.fillRect(ipx0, jpx0, ipx1 - ipx0, jpx1 - jpx0);\n }\n }\n\n var image3 = plotGroup.selectAll('image')\n .data(cd);\n\n image3.enter().append('svg:image').attr({\n xmlns: xmlnsNamespaces.svg,\n preserveAspectRatio: 'none'\n });\n\n image3.attr({\n height: imageHeight,\n width: imageWidth,\n x: left,\n y: top,\n 'xlink:href': canvas.toDataURL('image/png')\n });\n });\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/image/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/image/style.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/image/style.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nmodule.exports = function style(gd) {\n d3.select(gd).selectAll('.im image')\n .style('opacity', function(d) {\n return d.trace.opacity;\n });\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/image/style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/indicator/attributes.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/indicator/attributes.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar extendDeep = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendDeep;\nvar overrideAll = __webpack_require__(/*! ../../plot_api/edit_types */ \"./node_modules/plotly.js/src/plot_api/edit_types.js\").overrideAll;\nvar fontAttrs = __webpack_require__(/*! ../../plots/font_attributes */ \"./node_modules/plotly.js/src/plots/font_attributes.js\");\nvar colorAttrs = __webpack_require__(/*! ../../components/color/attributes */ \"./node_modules/plotly.js/src/components/color/attributes.js\");\nvar domainAttrs = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").attributes;\nvar axesAttrs = __webpack_require__(/*! ../../plots/cartesian/layout_attributes */ \"./node_modules/plotly.js/src/plots/cartesian/layout_attributes.js\");\nvar templatedArray = __webpack_require__(/*! ../../plot_api/plot_template */ \"./node_modules/plotly.js/src/plot_api/plot_template.js\").templatedArray;\nvar delta = __webpack_require__(/*! ../../constants/delta.js */ \"./node_modules/plotly.js/src/constants/delta.js\");\nvar FORMAT_LINK = __webpack_require__(/*! ../../constants/docs */ \"./node_modules/plotly.js/src/constants/docs.js\").FORMAT_LINK;\n\nvar textFontAttrs = fontAttrs({\n editType: 'plot',\n colorEditType: 'plot'\n});\n\nvar gaugeBarAttrs = {\n color: {\n valType: 'color',\n editType: 'plot',\n \n \n },\n line: {\n color: {\n valType: 'color',\n \n dflt: colorAttrs.defaultLine,\n editType: 'plot',\n \n },\n width: {\n valType: 'number',\n \n min: 0,\n dflt: 0,\n editType: 'plot',\n \n },\n editType: 'calc'\n },\n thickness: {\n valType: 'number',\n \n min: 0,\n max: 1,\n dflt: 1,\n editType: 'plot',\n \n },\n editType: 'calc'\n};\n\nvar rangeAttr = {\n valType: 'info_array',\n \n items: [\n {valType: 'number', editType: 'plot'},\n {valType: 'number', editType: 'plot'}\n ],\n editType: 'plot',\n \n};\n\nvar stepsAttrs = templatedArray('step', extendDeep({}, gaugeBarAttrs, {\n range: rangeAttr\n}));\n\nmodule.exports = {\n mode: {\n valType: 'flaglist',\n editType: 'calc',\n \n flags: ['number', 'delta', 'gauge'],\n dflt: 'number',\n \n },\n value: {\n valType: 'number',\n editType: 'calc',\n \n anim: true,\n \n },\n align: {\n valType: 'enumerated',\n values: ['left', 'center', 'right'],\n \n editType: 'plot',\n \n },\n // position\n domain: domainAttrs({name: 'indicator', trace: true, editType: 'calc'}),\n\n title: {\n text: {\n valType: 'string',\n \n editType: 'plot',\n \n },\n align: {\n valType: 'enumerated',\n values: ['left', 'center', 'right'],\n \n editType: 'plot',\n \n },\n font: extendFlat({}, textFontAttrs, {\n \n }),\n editType: 'plot'\n },\n number: {\n valueformat: {\n valType: 'string',\n dflt: '',\n \n editType: 'plot',\n \n },\n font: extendFlat({}, textFontAttrs, {\n \n }),\n prefix: {\n valType: 'string',\n dflt: '',\n \n editType: 'plot',\n \n },\n suffix: {\n valType: 'string',\n dflt: '',\n \n editType: 'plot',\n \n },\n editType: 'plot'\n },\n delta: {\n reference: {\n valType: 'number',\n \n editType: 'calc',\n \n },\n position: {\n valType: 'enumerated',\n values: ['top', 'bottom', 'left', 'right'],\n \n dflt: 'bottom',\n editType: 'plot',\n \n },\n relative: {\n valType: 'boolean',\n editType: 'plot',\n \n dflt: false,\n \n },\n valueformat: {\n valType: 'string',\n \n editType: 'plot',\n \n },\n increasing: {\n symbol: {\n valType: 'string',\n \n dflt: delta.INCREASING.SYMBOL,\n editType: 'plot',\n \n },\n color: {\n valType: 'color',\n \n dflt: delta.INCREASING.COLOR,\n editType: 'plot',\n \n },\n // TODO: add attribute to show sign\n editType: 'plot'\n },\n decreasing: {\n symbol: {\n valType: 'string',\n \n dflt: delta.DECREASING.SYMBOL,\n editType: 'plot',\n \n },\n color: {\n valType: 'color',\n \n dflt: delta.DECREASING.COLOR,\n editType: 'plot',\n \n },\n // TODO: add attribute to hide sign\n editType: 'plot'\n },\n font: extendFlat({}, textFontAttrs, {\n \n }),\n editType: 'calc'\n },\n gauge: {\n shape: {\n valType: 'enumerated',\n editType: 'plot',\n \n dflt: 'angular',\n values: ['angular', 'bullet'],\n \n },\n bar: extendDeep({}, gaugeBarAttrs, {\n color: {dflt: 'green'},\n \n }),\n // Background of the gauge\n bgcolor: {\n valType: 'color',\n \n editType: 'plot',\n \n },\n bordercolor: {\n valType: 'color',\n dflt: colorAttrs.defaultLine,\n \n editType: 'plot',\n \n },\n borderwidth: {\n valType: 'number',\n min: 0,\n dflt: 1,\n \n editType: 'plot',\n \n },\n axis: overrideAll({\n range: rangeAttr,\n visible: extendFlat({}, axesAttrs.visible, {\n dflt: true\n }),\n // tick and title properties named and function exactly as in axes\n tickmode: axesAttrs.tickmode,\n nticks: axesAttrs.nticks,\n tick0: axesAttrs.tick0,\n dtick: axesAttrs.dtick,\n tickvals: axesAttrs.tickvals,\n ticktext: axesAttrs.ticktext,\n ticks: extendFlat({}, axesAttrs.ticks, {dflt: 'outside'}),\n ticklen: axesAttrs.ticklen,\n tickwidth: axesAttrs.tickwidth,\n tickcolor: axesAttrs.tickcolor,\n showticklabels: axesAttrs.showticklabels,\n tickfont: fontAttrs({\n \n }),\n tickangle: axesAttrs.tickangle,\n tickformat: axesAttrs.tickformat,\n tickformatstops: axesAttrs.tickformatstops,\n tickprefix: axesAttrs.tickprefix,\n showtickprefix: axesAttrs.showtickprefix,\n ticksuffix: axesAttrs.ticksuffix,\n showticksuffix: axesAttrs.showticksuffix,\n separatethousands: axesAttrs.separatethousands,\n exponentformat: axesAttrs.exponentformat,\n showexponent: axesAttrs.showexponent,\n editType: 'plot'\n }, 'plot'),\n // Steps (or ranges) and thresholds\n steps: stepsAttrs,\n threshold: {\n line: {\n color: extendFlat({}, gaugeBarAttrs.line.color, {\n \n }),\n width: extendFlat({}, gaugeBarAttrs.line.width, {\n dflt: 1,\n \n }),\n editType: 'plot'\n },\n thickness: extendFlat({}, gaugeBarAttrs.thickness, {\n dflt: 0.85,\n \n }),\n value: {\n valType: 'number',\n editType: 'calc',\n dflt: false,\n \n \n },\n editType: 'plot'\n },\n \n editType: 'plot'\n // TODO: in future version, add marker: (bar|needle)\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/indicator/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/indicator/base_plot.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/indicator/base_plot.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar plots = __webpack_require__(/*! ../../plots/plots */ \"./node_modules/plotly.js/src/plots/plots.js\");\n\nexports.name = 'indicator';\n\nexports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) {\n plots.plotBasePlot(exports.name, gd, traces, transitionOpts, makeOnCompleteCallback);\n};\n\nexports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {\n plots.cleanBasePlot(exports.name, newFullData, newFullLayout, oldFullData, oldFullLayout);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/indicator/base_plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/indicator/calc.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/indicator/calc.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n// var Lib = require('../../lib');\n\nfunction calc(gd, trace) {\n var cd = [];\n\n var lastReading = trace.value;\n if(!(typeof trace._lastValue === 'number')) trace._lastValue = trace.value;\n var secondLastReading = trace._lastValue;\n var deltaRef = secondLastReading;\n if(trace._hasDelta && typeof trace.delta.reference === 'number') {\n deltaRef = trace.delta.reference;\n }\n cd[0] = {\n y: lastReading,\n lastY: secondLastReading,\n\n delta: lastReading - deltaRef,\n relativeDelta: (lastReading - deltaRef) / deltaRef,\n };\n return cd;\n}\n\nmodule.exports = {\n calc: calc\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/indicator/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/indicator/constants.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/indicator/constants.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n // Defaults for delta\n defaultNumberFontSize: 80,\n bulletNumberDomainSize: 0.25,\n bulletPadding: 0.025,\n innerRadius: 0.75,\n valueThickness: 0.5, // thickness of value bars relative to full thickness,\n titlePadding: 5,\n horizontalPadding: 10\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/indicator/constants.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/indicator/defaults.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/indicator/defaults.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/indicator/attributes.js\");\nvar handleDomainDefaults = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").defaults;\nvar Template = __webpack_require__(/*! ../../plot_api/plot_template */ \"./node_modules/plotly.js/src/plot_api/plot_template.js\");\nvar handleArrayContainerDefaults = __webpack_require__(/*! ../../plots/array_container_defaults */ \"./node_modules/plotly.js/src/plots/array_container_defaults.js\");\nvar cn = __webpack_require__(/*! ./constants.js */ \"./node_modules/plotly.js/src/traces/indicator/constants.js\");\n\nvar handleTickValueDefaults = __webpack_require__(/*! ../../plots/cartesian/tick_value_defaults */ \"./node_modules/plotly.js/src/plots/cartesian/tick_value_defaults.js\");\nvar handleTickMarkDefaults = __webpack_require__(/*! ../../plots/cartesian/tick_mark_defaults */ \"./node_modules/plotly.js/src/plots/cartesian/tick_mark_defaults.js\");\nvar handleTickLabelDefaults = __webpack_require__(/*! ../../plots/cartesian/tick_label_defaults */ \"./node_modules/plotly.js/src/plots/cartesian/tick_label_defaults.js\");\n\nfunction supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n handleDomainDefaults(traceOut, layout, coerce);\n\n // Mode\n coerce('mode');\n traceOut._hasNumber = traceOut.mode.indexOf('number') !== -1;\n traceOut._hasDelta = traceOut.mode.indexOf('delta') !== -1;\n traceOut._hasGauge = traceOut.mode.indexOf('gauge') !== -1;\n\n var value = coerce('value');\n traceOut._range = [0, (typeof value === 'number' ? 1.5 * value : 1)];\n\n // Number attributes\n var auto = new Array(2);\n var bignumberFontSize;\n if(traceOut._hasNumber) {\n coerce('number.valueformat');\n coerce('number.font.color', layout.font.color);\n coerce('number.font.family', layout.font.family);\n coerce('number.font.size');\n if(traceOut.number.font.size === undefined) {\n traceOut.number.font.size = cn.defaultNumberFontSize;\n auto[0] = true;\n }\n coerce('number.prefix');\n coerce('number.suffix');\n bignumberFontSize = traceOut.number.font.size;\n }\n\n // delta attributes\n var deltaFontSize;\n if(traceOut._hasDelta) {\n coerce('delta.font.color', layout.font.color);\n coerce('delta.font.family', layout.font.family);\n coerce('delta.font.size');\n if(traceOut.delta.font.size === undefined) {\n traceOut.delta.font.size = (traceOut._hasNumber ? 0.5 : 1) * (bignumberFontSize || cn.defaultNumberFontSize);\n auto[1] = true;\n }\n coerce('delta.reference', traceOut.value);\n coerce('delta.relative');\n coerce('delta.valueformat', traceOut.delta.relative ? '2%' : '');\n coerce('delta.increasing.symbol');\n coerce('delta.increasing.color');\n coerce('delta.decreasing.symbol');\n coerce('delta.decreasing.color');\n coerce('delta.position');\n deltaFontSize = traceOut.delta.font.size;\n }\n traceOut._scaleNumbers = (!traceOut._hasNumber || auto[0]) && (!traceOut._hasDelta || auto[1]) || false;\n\n // Title attributes\n coerce('title.font.color', layout.font.color);\n coerce('title.font.family', layout.font.family);\n coerce('title.font.size', 0.25 * (bignumberFontSize || deltaFontSize || cn.defaultNumberFontSize));\n coerce('title.text');\n\n // Gauge attributes\n var gaugeIn, gaugeOut, axisIn, axisOut;\n function coerceGauge(attr, dflt) {\n return Lib.coerce(gaugeIn, gaugeOut, attributes.gauge, attr, dflt);\n }\n function coerceGaugeAxis(attr, dflt) {\n return Lib.coerce(axisIn, axisOut, attributes.gauge.axis, attr, dflt);\n }\n\n if(traceOut._hasGauge) {\n gaugeIn = traceIn.gauge;\n if(!gaugeIn) gaugeIn = {};\n gaugeOut = Template.newContainer(traceOut, 'gauge');\n coerceGauge('shape');\n var isBullet = traceOut._isBullet = traceOut.gauge.shape === 'bullet';\n if(!isBullet) {\n coerce('title.align', 'center');\n }\n var isAngular = traceOut._isAngular = traceOut.gauge.shape === 'angular';\n if(!isAngular) {\n coerce('align', 'center');\n }\n\n // gauge background\n coerceGauge('bgcolor', layout.paper_bgcolor);\n coerceGauge('borderwidth');\n coerceGauge('bordercolor');\n\n // gauge bar indicator\n coerceGauge('bar.color');\n coerceGauge('bar.line.color');\n coerceGauge('bar.line.width');\n var defaultBarThickness = cn.valueThickness * (traceOut.gauge.shape === 'bullet' ? 0.5 : 1);\n coerceGauge('bar.thickness', defaultBarThickness);\n\n // Gauge steps\n handleArrayContainerDefaults(gaugeIn, gaugeOut, {\n name: 'steps',\n handleItemDefaults: stepDefaults\n });\n\n // Gauge threshold\n coerceGauge('threshold.value');\n coerceGauge('threshold.thickness');\n coerceGauge('threshold.line.width');\n coerceGauge('threshold.line.color');\n\n // Gauge axis\n axisIn = {};\n if(gaugeIn) axisIn = gaugeIn.axis || {};\n axisOut = Template.newContainer(gaugeOut, 'axis');\n coerceGaugeAxis('visible');\n traceOut._range = coerceGaugeAxis('range', traceOut._range);\n\n var opts = {outerTicks: true};\n handleTickValueDefaults(axisIn, axisOut, coerceGaugeAxis, 'linear');\n handleTickLabelDefaults(axisIn, axisOut, coerceGaugeAxis, 'linear', opts);\n handleTickMarkDefaults(axisIn, axisOut, coerceGaugeAxis, opts);\n } else {\n coerce('title.align', 'center');\n coerce('align', 'center');\n traceOut._isAngular = traceOut._isBullet = false;\n }\n\n // disable 1D transforms\n traceOut._length = null;\n}\n\nfunction stepDefaults(stepIn, stepOut) {\n function coerce(attr, dflt) {\n return Lib.coerce(stepIn, stepOut, attributes.gauge.steps, attr, dflt);\n }\n\n coerce('color');\n coerce('line.color');\n coerce('line.width');\n coerce('range');\n coerce('thickness');\n}\n\nmodule.exports = {\n supplyDefaults: supplyDefaults\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/indicator/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/indicator/index.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/indicator/index.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n moduleType: 'trace',\n name: 'indicator',\n basePlotModule: __webpack_require__(/*! ./base_plot */ \"./node_modules/plotly.js/src/traces/indicator/base_plot.js\"),\n categories: ['svg', 'noOpacity', 'noHover'],\n animatable: true,\n\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/indicator/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/indicator/defaults.js\").supplyDefaults,\n\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/indicator/calc.js\").calc,\n\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/indicator/plot.js\"),\n\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/indicator/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/indicator/plot.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/indicator/plot.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar rad2deg = Lib.rad2deg;\nvar MID_SHIFT = __webpack_require__(/*! ../../constants/alignment */ \"./node_modules/plotly.js/src/constants/alignment.js\").MID_SHIFT;\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar cn = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/indicator/constants.js\");\nvar svgTextUtils = __webpack_require__(/*! ../../lib/svg_text_utils */ \"./node_modules/plotly.js/src/lib/svg_text_utils.js\");\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar handleAxisDefaults = __webpack_require__(/*! ../../plots/cartesian/axis_defaults */ \"./node_modules/plotly.js/src/plots/cartesian/axis_defaults.js\");\nvar handleAxisPositionDefaults = __webpack_require__(/*! ../../plots/cartesian/position_defaults */ \"./node_modules/plotly.js/src/plots/cartesian/position_defaults.js\");\nvar axisLayoutAttrs = __webpack_require__(/*! ../../plots/cartesian/layout_attributes */ \"./node_modules/plotly.js/src/plots/cartesian/layout_attributes.js\");\n\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar anchor = {\n 'left': 'start',\n 'center': 'middle',\n 'right': 'end'\n};\nvar position = {\n 'left': 0,\n 'center': 0.5,\n 'right': 1\n};\n\nvar SI_PREFIX = /[yzafpnµmkMGTPEZY]/;\n\nfunction hasTransition(transitionOpts) {\n // If transition config is provided, then it is only a partial replot and traces not\n // updated are removed.\n return transitionOpts && transitionOpts.duration > 0;\n}\n\nmodule.exports = function plot(gd, cdModule, transitionOpts, makeOnCompleteCallback) {\n var fullLayout = gd._fullLayout;\n var onComplete;\n\n if(hasTransition(transitionOpts)) {\n if(makeOnCompleteCallback) {\n // If it was passed a callback to register completion, make a callback. If\n // this is created, then it must be executed on completion, otherwise the\n // pos-transition redraw will not execute:\n onComplete = makeOnCompleteCallback();\n }\n }\n\n Lib.makeTraceGroups(fullLayout._indicatorlayer, cdModule, 'trace').each(function(cd) {\n var cd0 = cd[0];\n var trace = cd0.trace;\n\n var plotGroup = d3.select(this);\n\n // Elements in trace\n var hasGauge = trace._hasGauge;\n var isAngular = trace._isAngular;\n var isBullet = trace._isBullet;\n\n // Domain size\n var domain = trace.domain;\n var size = {\n w: fullLayout._size.w * (domain.x[1] - domain.x[0]),\n h: fullLayout._size.h * (domain.y[1] - domain.y[0]),\n l: fullLayout._size.l + fullLayout._size.w * domain.x[0],\n r: fullLayout._size.r + fullLayout._size.w * (1 - domain.x[1]),\n t: fullLayout._size.t + fullLayout._size.h * (1 - domain.y[1]),\n b: fullLayout._size.b + fullLayout._size.h * (domain.y[0])\n };\n var centerX = size.l + size.w / 2;\n var centerY = size.t + size.h / 2;\n\n // Angular gauge size\n var radius = Math.min(size.w / 2, size.h); // fill domain\n var innerRadius = cn.innerRadius * radius;\n\n // Position numbers based on mode and set the scaling logic\n var numbersX, numbersY, numbersScaler;\n var numbersAlign = trace.align || 'center';\n\n numbersY = centerY;\n if(!hasGauge) {\n numbersX = size.l + position[numbersAlign] * size.w;\n numbersScaler = function(el) {\n return fitTextInsideBox(el, size.w, size.h);\n };\n } else {\n if(isAngular) {\n numbersX = centerX;\n numbersY = centerY + radius / 2;\n numbersScaler = function(el) {\n return fitTextInsideCircle(el, 0.9 * innerRadius);\n };\n }\n if(isBullet) {\n var padding = cn.bulletPadding;\n var p = (1 - cn.bulletNumberDomainSize) + padding;\n numbersX = size.l + (p + (1 - p) * position[numbersAlign]) * size.w;\n numbersScaler = function(el) {\n return fitTextInsideBox(el, (cn.bulletNumberDomainSize - padding) * size.w, size.h);\n };\n }\n }\n\n // Draw numbers\n drawNumbers(gd, plotGroup, cd, {\n numbersX: numbersX,\n numbersY: numbersY,\n numbersScaler: numbersScaler,\n transitionOpts: transitionOpts,\n onComplete: onComplete\n });\n\n // Reexpress our gauge background attributes for drawing\n var gaugeBg, gaugeOutline;\n if(hasGauge) {\n gaugeBg = {\n range: trace.gauge.axis.range,\n color: trace.gauge.bgcolor,\n line: {\n color: trace.gauge.bordercolor,\n width: 0\n },\n thickness: 1\n };\n\n gaugeOutline = {\n range: trace.gauge.axis.range,\n color: 'rgba(0, 0, 0, 0)',\n line: {\n color: trace.gauge.bordercolor,\n width: trace.gauge.borderwidth\n },\n thickness: 1\n };\n }\n\n // Prepare angular gauge layers\n var angularGauge = plotGroup.selectAll('g.angular').data(isAngular ? cd : []);\n angularGauge.exit().remove();\n var angularaxisLayer = plotGroup.selectAll('g.angularaxis').data(isAngular ? cd : []);\n angularaxisLayer.exit().remove();\n\n if(isAngular) {\n drawAngularGauge(gd, plotGroup, cd, {\n radius: radius,\n innerRadius: innerRadius,\n\n gauge: angularGauge,\n layer: angularaxisLayer,\n size: size,\n gaugeBg: gaugeBg,\n gaugeOutline: gaugeOutline,\n transitionOpts: transitionOpts,\n onComplete: onComplete\n });\n }\n\n // Prepare bullet layers\n var bulletGauge = plotGroup.selectAll('g.bullet').data(isBullet ? cd : []);\n bulletGauge.exit().remove();\n var bulletaxisLayer = plotGroup.selectAll('g.bulletaxis').data(isBullet ? cd : []);\n bulletaxisLayer.exit().remove();\n\n if(isBullet) {\n drawBulletGauge(gd, plotGroup, cd, {\n gauge: bulletGauge,\n layer: bulletaxisLayer,\n size: size,\n gaugeBg: gaugeBg,\n gaugeOutline: gaugeOutline,\n transitionOpts: transitionOpts,\n onComplete: onComplete\n });\n }\n\n // title\n var title = plotGroup.selectAll('text.title').data(cd);\n title.exit().remove();\n title.enter().append('text').classed('title', true);\n title\n .attr('text-anchor', function() {\n return isBullet ? anchor.right : anchor[trace.title.align];\n })\n .text(trace.title.text)\n .call(Drawing.font, trace.title.font)\n .call(svgTextUtils.convertToTspans, gd);\n\n // Position title\n title.attr('transform', function() {\n var titleX = size.l + size.w * position[trace.title.align];\n var titleY;\n var titlePadding = cn.titlePadding;\n var titlebBox = Drawing.bBox(title.node());\n if(hasGauge) {\n if(isAngular) {\n // position above axis ticks/labels\n if(trace.gauge.axis.visible) {\n var bBox = Drawing.bBox(angularaxisLayer.node());\n titleY = (bBox.top - titlePadding) - titlebBox.bottom;\n } else {\n titleY = size.t + size.h / 2 - radius / 2 - titlebBox.bottom - titlePadding;\n }\n }\n if(isBullet) {\n // position outside domain\n titleY = numbersY - (titlebBox.top + titlebBox.bottom) / 2;\n titleX = size.l - cn.bulletPadding * size.w; // Outside domain, on the left\n }\n } else {\n // position above numbers\n titleY = (trace._numbersTop - titlePadding) - titlebBox.bottom;\n }\n return strTranslate(titleX, titleY);\n });\n });\n};\n\nfunction drawBulletGauge(gd, plotGroup, cd, opts) {\n var trace = cd[0].trace;\n\n var bullet = opts.gauge;\n var axisLayer = opts.layer;\n var gaugeBg = opts.gaugeBg;\n var gaugeOutline = opts.gaugeOutline;\n var size = opts.size;\n var domain = trace.domain;\n\n var transitionOpts = opts.transitionOpts;\n var onComplete = opts.onComplete;\n\n // preparing axis\n var ax, vals, transFn, tickSign, shift;\n\n // Enter bullet, axis\n bullet.enter().append('g').classed('bullet', true);\n bullet.attr('transform', 'translate(' + size.l + ', ' + size.t + ')');\n\n axisLayer.enter().append('g')\n .classed('bulletaxis', true)\n .classed('crisp', true);\n axisLayer.selectAll('g.' + 'xbulletaxis' + 'tick,path,text').remove();\n\n // Draw bullet\n var bulletHeight = size.h; // use all vertical domain\n var innerBulletHeight = trace.gauge.bar.thickness * bulletHeight;\n var bulletLeft = domain.x[0];\n var bulletRight = domain.x[0] + (domain.x[1] - domain.x[0]) * ((trace._hasNumber || trace._hasDelta) ? (1 - cn.bulletNumberDomainSize) : 1);\n\n ax = mockAxis(gd, trace.gauge.axis);\n ax._id = 'xbulletaxis';\n ax.domain = [bulletLeft, bulletRight];\n ax.setScale();\n\n vals = Axes.calcTicks(ax);\n transFn = Axes.makeTransFn(ax);\n tickSign = Axes.getTickSigns(ax)[2];\n\n shift = size.t + size.h;\n if(ax.visible) {\n Axes.drawTicks(gd, ax, {\n vals: ax.ticks === 'inside' ? Axes.clipEnds(ax, vals) : vals,\n layer: axisLayer,\n path: Axes.makeTickPath(ax, shift, tickSign),\n transFn: transFn\n });\n\n Axes.drawLabels(gd, ax, {\n vals: vals,\n layer: axisLayer,\n transFn: transFn,\n labelFns: Axes.makeLabelFns(ax, shift)\n });\n }\n\n function drawRect(s) {\n s\n .attr('width', function(d) { return Math.max(0, ax.c2p(d.range[1]) - ax.c2p(d.range[0]));})\n .attr('x', function(d) { return ax.c2p(d.range[0]);})\n .attr('y', function(d) { return 0.5 * (1 - d.thickness) * bulletHeight;})\n .attr('height', function(d) { return d.thickness * bulletHeight; });\n }\n\n // Draw bullet background, steps\n var boxes = [gaugeBg].concat(trace.gauge.steps);\n var bgBullet = bullet.selectAll('g.bg-bullet').data(boxes);\n bgBullet.enter().append('g').classed('bg-bullet', true).append('rect');\n bgBullet.select('rect')\n .call(drawRect)\n .call(styleShape);\n bgBullet.exit().remove();\n\n // Draw value bar with transitions\n var fgBullet = bullet.selectAll('g.value-bullet').data([trace.gauge.bar]);\n fgBullet.enter().append('g').classed('value-bullet', true).append('rect');\n fgBullet.select('rect')\n .attr('height', innerBulletHeight)\n .attr('y', (bulletHeight - innerBulletHeight) / 2)\n .call(styleShape);\n if(hasTransition(transitionOpts)) {\n fgBullet.select('rect')\n .transition()\n .duration(transitionOpts.duration)\n .ease(transitionOpts.easing)\n .each('end', function() { onComplete && onComplete(); })\n .each('interrupt', function() { onComplete && onComplete(); })\n .attr('width', Math.max(0, ax.c2p(Math.min(trace.gauge.axis.range[1], cd[0].y))));\n } else {\n fgBullet.select('rect')\n .attr('width', typeof cd[0].y === 'number' ?\n Math.max(0, ax.c2p(Math.min(trace.gauge.axis.range[1], cd[0].y))) :\n 0);\n }\n fgBullet.exit().remove();\n\n var data = cd.filter(function() {return trace.gauge.threshold.value;});\n var threshold = bullet.selectAll('g.threshold-bullet').data(data);\n threshold.enter().append('g').classed('threshold-bullet', true).append('line');\n threshold.select('line')\n .attr('x1', ax.c2p(trace.gauge.threshold.value))\n .attr('x2', ax.c2p(trace.gauge.threshold.value))\n .attr('y1', (1 - trace.gauge.threshold.thickness) / 2 * bulletHeight)\n .attr('y2', (1 - (1 - trace.gauge.threshold.thickness) / 2) * bulletHeight)\n .call(Color.stroke, trace.gauge.threshold.line.color)\n .style('stroke-width', trace.gauge.threshold.line.width);\n threshold.exit().remove();\n\n var bulletOutline = bullet.selectAll('g.gauge-outline').data([gaugeOutline]);\n bulletOutline.enter().append('g').classed('gauge-outline', true).append('rect');\n bulletOutline.select('rect')\n .call(drawRect)\n .call(styleShape);\n bulletOutline.exit().remove();\n}\n\nfunction drawAngularGauge(gd, plotGroup, cd, opts) {\n var trace = cd[0].trace;\n\n var size = opts.size;\n var radius = opts.radius;\n var innerRadius = opts.innerRadius;\n var gaugeBg = opts.gaugeBg;\n var gaugeOutline = opts.gaugeOutline;\n var gaugePosition = [size.l + size.w / 2, size.t + size.h / 2 + radius / 2];\n var gauge = opts.gauge;\n var axisLayer = opts.layer;\n\n var transitionOpts = opts.transitionOpts;\n var onComplete = opts.onComplete;\n\n // circular gauge\n var theta = Math.PI / 2;\n function valueToAngle(v) {\n var min = trace.gauge.axis.range[0];\n var max = trace.gauge.axis.range[1];\n var angle = (v - min) / (max - min) * Math.PI - theta;\n if(angle < -theta) return -theta;\n if(angle > theta) return theta;\n return angle;\n }\n\n function arcPathGenerator(size) {\n return d3.svg.arc()\n .innerRadius((innerRadius + radius) / 2 - size / 2 * (radius - innerRadius))\n .outerRadius((innerRadius + radius) / 2 + size / 2 * (radius - innerRadius))\n .startAngle(-theta);\n }\n\n function drawArc(p) {\n p\n .attr('d', function(d) {\n return arcPathGenerator(d.thickness)\n .startAngle(valueToAngle(d.range[0]))\n .endAngle(valueToAngle(d.range[1]))();\n });\n }\n\n // preparing axis\n var ax, vals, transFn, tickSign;\n\n // Enter gauge and axis\n gauge.enter().append('g').classed('angular', true);\n gauge.attr('transform', strTranslate(gaugePosition[0], gaugePosition[1]));\n\n axisLayer.enter().append('g')\n .classed('angularaxis', true)\n .classed('crisp', true);\n axisLayer.selectAll('g.' + 'xangularaxis' + 'tick,path,text').remove();\n\n ax = mockAxis(gd, trace.gauge.axis);\n ax.type = 'linear';\n ax.range = trace.gauge.axis.range;\n ax._id = 'xangularaxis'; // or 'y', but I don't think this makes a difference here\n ax.setScale();\n\n // 't'ick to 'g'eometric radians is used all over the place here\n var t2g = function(d) {\n return (ax.range[0] - d.x) / (ax.range[1] - ax.range[0]) * Math.PI + Math.PI;\n };\n\n var labelFns = {};\n var out = Axes.makeLabelFns(ax, 0);\n var labelStandoff = out.labelStandoff;\n labelFns.xFn = function(d) {\n var rad = t2g(d);\n return Math.cos(rad) * labelStandoff;\n };\n labelFns.yFn = function(d) {\n var rad = t2g(d);\n var ff = Math.sin(rad) > 0 ? 0.2 : 1;\n return -Math.sin(rad) * (labelStandoff + d.fontSize * ff) +\n Math.abs(Math.cos(rad)) * (d.fontSize * MID_SHIFT);\n };\n labelFns.anchorFn = function(d) {\n var rad = t2g(d);\n var cos = Math.cos(rad);\n return Math.abs(cos) < 0.1 ?\n 'middle' :\n (cos > 0 ? 'start' : 'end');\n };\n labelFns.heightFn = function(d, a, h) {\n var rad = t2g(d);\n return -0.5 * (1 + Math.sin(rad)) * h;\n };\n var _transFn = function(rad) {\n return strTranslate(\n gaugePosition[0] + radius * Math.cos(rad),\n gaugePosition[1] - radius * Math.sin(rad)\n );\n };\n transFn = function(d) {\n return _transFn(t2g(d));\n };\n var transFn2 = function(d) {\n var rad = t2g(d);\n return _transFn(rad) + 'rotate(' + -rad2deg(rad) + ')';\n };\n vals = Axes.calcTicks(ax);\n tickSign = Axes.getTickSigns(ax)[2];\n if(ax.visible) {\n tickSign = ax.ticks === 'inside' ? -1 : 1;\n var pad = (ax.linewidth || 1) / 2;\n Axes.drawTicks(gd, ax, {\n vals: vals,\n layer: axisLayer,\n path: 'M' + (tickSign * pad) + ',0h' + (tickSign * ax.ticklen),\n transFn: transFn2\n });\n Axes.drawLabels(gd, ax, {\n vals: vals,\n layer: axisLayer,\n transFn: transFn,\n labelFns: labelFns\n });\n }\n\n // Draw background + steps\n var arcs = [gaugeBg].concat(trace.gauge.steps);\n var bgArc = gauge.selectAll('g.bg-arc').data(arcs);\n bgArc.enter().append('g').classed('bg-arc', true).append('path');\n bgArc.select('path').call(drawArc).call(styleShape);\n bgArc.exit().remove();\n\n // Draw foreground with transition\n var valueArcPathGenerator = arcPathGenerator(trace.gauge.bar.thickness);\n var valueArc = gauge.selectAll('g.value-arc').data([trace.gauge.bar]);\n valueArc.enter().append('g').classed('value-arc', true).append('path');\n var valueArcPath = valueArc.select('path');\n if(hasTransition(transitionOpts)) {\n valueArcPath\n .transition()\n .duration(transitionOpts.duration)\n .ease(transitionOpts.easing)\n .each('end', function() { onComplete && onComplete(); })\n .each('interrupt', function() { onComplete && onComplete(); })\n .attrTween('d', arcTween(valueArcPathGenerator, valueToAngle(cd[0].lastY), valueToAngle(cd[0].y)));\n trace._lastValue = cd[0].y;\n } else {\n valueArcPath.attr('d', typeof cd[0].y === 'number' ?\n valueArcPathGenerator.endAngle(valueToAngle(cd[0].y)) :\n 'M0,0Z');\n }\n valueArcPath.call(styleShape);\n valueArc.exit().remove();\n\n // Draw threshold\n arcs = [];\n var v = trace.gauge.threshold.value;\n if(v) {\n arcs.push({\n range: [v, v],\n color: trace.gauge.threshold.color,\n line: {\n color: trace.gauge.threshold.line.color,\n width: trace.gauge.threshold.line.width\n },\n thickness: trace.gauge.threshold.thickness\n });\n }\n var thresholdArc = gauge.selectAll('g.threshold-arc').data(arcs);\n thresholdArc.enter().append('g').classed('threshold-arc', true).append('path');\n thresholdArc.select('path').call(drawArc).call(styleShape);\n thresholdArc.exit().remove();\n\n // Draw border last\n var gaugeBorder = gauge.selectAll('g.gauge-outline').data([gaugeOutline]);\n gaugeBorder.enter().append('g').classed('gauge-outline', true).append('path');\n gaugeBorder.select('path').call(drawArc).call(styleShape);\n gaugeBorder.exit().remove();\n}\n\nfunction drawNumbers(gd, plotGroup, cd, opts) {\n var trace = cd[0].trace;\n\n var numbersX = opts.numbersX;\n var numbersY = opts.numbersY;\n var numbersAlign = trace.align || 'center';\n var numbersAnchor = anchor[numbersAlign];\n\n var transitionOpts = opts.transitionOpts;\n var onComplete = opts.onComplete;\n\n var numbers = Lib.ensureSingle(plotGroup, 'g', 'numbers');\n var bignumberbBox, deltabBox;\n var numbersbBox;\n\n var data = [];\n if(trace._hasNumber) data.push('number');\n if(trace._hasDelta) {\n data.push('delta');\n if(trace.delta.position === 'left') data.reverse();\n }\n var sel = numbers.selectAll('text').data(data);\n sel.enter().append('text');\n sel\n .attr('text-anchor', function() {return numbersAnchor;})\n .attr('class', function(d) { return d;})\n .attr('x', null)\n .attr('y', null)\n .attr('dx', null)\n .attr('dy', null);\n sel.exit().remove();\n\n // Function to override the number formatting used during transitions\n function transitionFormat(valueformat, fmt, from, to) {\n // For now, do not display SI prefix if start and end value do not have any\n if(valueformat.match('s') && // If using SI prefix\n (from >= 0 !== to >= 0) && // If sign change\n (!fmt(from).slice(-1).match(SI_PREFIX) && !fmt(to).slice(-1).match(SI_PREFIX)) // Has no SI prefix\n ) {\n var transitionValueFormat = valueformat.slice().replace('s', 'f').replace(/\\d+/, function(m) { return parseInt(m) - 1;});\n var transitionAx = mockAxis(gd, {tickformat: transitionValueFormat});\n return function(v) {\n // Switch to fixed precision if number is smaller than one\n if(Math.abs(v) < 1) return Axes.tickText(transitionAx, v).text;\n return fmt(v);\n };\n } else {\n return fmt;\n }\n }\n\n function drawBignumber() {\n var bignumberAx = mockAxis(gd, {tickformat: trace.number.valueformat}, trace._range);\n bignumberAx.setScale();\n Axes.prepTicks(bignumberAx);\n\n var fmt = function(v) { return Axes.tickText(bignumberAx, v).text;};\n var bignumberSuffix = trace.number.suffix;\n var bignumberPrefix = trace.number.prefix;\n\n var number = numbers.select('text.number');\n\n function writeNumber() {\n var txt = typeof cd[0].y === 'number' ?\n bignumberPrefix + fmt(cd[0].y) + bignumberSuffix :\n '-';\n number.text(txt)\n .call(Drawing.font, trace.number.font)\n .call(svgTextUtils.convertToTspans, gd);\n }\n\n if(hasTransition(transitionOpts)) {\n number\n .transition()\n .duration(transitionOpts.duration)\n .ease(transitionOpts.easing)\n .each('end', function() { writeNumber(); onComplete && onComplete(); })\n .each('interrupt', function() { writeNumber(); onComplete && onComplete(); })\n .attrTween('text', function() {\n var that = d3.select(this);\n var interpolator = d3.interpolateNumber(cd[0].lastY, cd[0].y);\n trace._lastValue = cd[0].y;\n\n var transitionFmt = transitionFormat(trace.number.valueformat, fmt, cd[0].lastY, cd[0].y);\n return function(t) {\n that.text(bignumberPrefix + transitionFmt(interpolator(t)) + bignumberSuffix);\n };\n });\n } else {\n writeNumber();\n }\n\n bignumberbBox = measureText(bignumberPrefix + fmt(cd[0].y) + bignumberSuffix, trace.number.font, numbersAnchor, gd);\n return number;\n }\n\n function drawDelta() {\n var deltaAx = mockAxis(gd, {tickformat: trace.delta.valueformat}, trace._range);\n deltaAx.setScale();\n Axes.prepTicks(deltaAx);\n\n var deltaFmt = function(v) { return Axes.tickText(deltaAx, v).text;};\n var deltaValue = function(d) {\n var value = trace.delta.relative ? d.relativeDelta : d.delta;\n return value;\n };\n var deltaFormatText = function(value, numberFmt) {\n if(value === 0 || typeof value !== 'number' || isNaN(value)) return '-';\n return (value > 0 ? trace.delta.increasing.symbol : trace.delta.decreasing.symbol) + numberFmt(value);\n };\n var deltaFill = function(d) {\n return d.delta >= 0 ? trace.delta.increasing.color : trace.delta.decreasing.color;\n };\n if(trace._deltaLastValue === undefined) {\n trace._deltaLastValue = deltaValue(cd[0]);\n }\n var delta = numbers.select('text.delta');\n delta\n .call(Drawing.font, trace.delta.font)\n .call(Color.fill, deltaFill({delta: trace._deltaLastValue}));\n\n function writeDelta() {\n delta.text(deltaFormatText(deltaValue(cd[0]), deltaFmt))\n .call(Color.fill, deltaFill(cd[0]))\n .call(svgTextUtils.convertToTspans, gd);\n }\n\n if(hasTransition(transitionOpts)) {\n delta\n .transition()\n .duration(transitionOpts.duration)\n .ease(transitionOpts.easing)\n .tween('text', function() {\n var that = d3.select(this);\n var to = deltaValue(cd[0]);\n var from = trace._deltaLastValue;\n var transitionFmt = transitionFormat(trace.delta.valueformat, deltaFmt, from, to);\n var interpolator = d3.interpolateNumber(from, to);\n trace._deltaLastValue = to;\n return function(t) {\n that.text(deltaFormatText(interpolator(t), transitionFmt));\n that.call(Color.fill, deltaFill({delta: interpolator(t)}));\n };\n })\n .each('end', function() { writeDelta(); onComplete && onComplete(); })\n .each('interrupt', function() { writeDelta(); onComplete && onComplete(); });\n } else {\n writeDelta();\n }\n\n deltabBox = measureText(deltaFormatText(deltaValue(cd[0]), deltaFmt), trace.delta.font, numbersAnchor, gd);\n return delta;\n }\n\n var key = trace.mode + trace.align;\n var delta;\n if(trace._hasDelta) {\n delta = drawDelta();\n key += trace.delta.position + trace.delta.font.size + trace.delta.font.family + trace.delta.valueformat;\n key += trace.delta.increasing.symbol + trace.delta.decreasing.symbol;\n numbersbBox = deltabBox;\n }\n if(trace._hasNumber) {\n drawBignumber();\n key += trace.number.font.size + trace.number.font.family + trace.number.valueformat + trace.number.suffix + trace.number.prefix;\n numbersbBox = bignumberbBox;\n }\n\n // Position delta relative to bignumber\n if(trace._hasDelta && trace._hasNumber) {\n var bignumberCenter = [\n (bignumberbBox.left + bignumberbBox.right) / 2,\n (bignumberbBox.top + bignumberbBox.bottom) / 2\n ];\n var deltaCenter = [\n (deltabBox.left + deltabBox.right) / 2,\n (deltabBox.top + deltabBox.bottom) / 2\n ];\n\n var dx, dy;\n var padding = 0.75 * trace.delta.font.size;\n if(trace.delta.position === 'left') {\n dx = cache(trace, 'deltaPos', 0, -1 * (bignumberbBox.width * (position[trace.align]) + deltabBox.width * (1 - position[trace.align]) + padding), key, Math.min);\n dy = bignumberCenter[1] - deltaCenter[1];\n\n numbersbBox = {\n width: bignumberbBox.width + deltabBox.width + padding,\n height: Math.max(bignumberbBox.height, deltabBox.height),\n left: deltabBox.left + dx,\n right: bignumberbBox.right,\n top: Math.min(bignumberbBox.top, deltabBox.top + dy),\n bottom: Math.max(bignumberbBox.bottom, deltabBox.bottom + dy)\n };\n }\n if(trace.delta.position === 'right') {\n dx = cache(trace, 'deltaPos', 0, bignumberbBox.width * (1 - position[trace.align]) + deltabBox.width * position[trace.align] + padding, key, Math.max);\n dy = bignumberCenter[1] - deltaCenter[1];\n\n numbersbBox = {\n width: bignumberbBox.width + deltabBox.width + padding,\n height: Math.max(bignumberbBox.height, deltabBox.height),\n left: bignumberbBox.left,\n right: deltabBox.right + dx,\n top: Math.min(bignumberbBox.top, deltabBox.top + dy),\n bottom: Math.max(bignumberbBox.bottom, deltabBox.bottom + dy)\n };\n }\n if(trace.delta.position === 'bottom') {\n dx = null;\n dy = deltabBox.height;\n\n numbersbBox = {\n width: Math.max(bignumberbBox.width, deltabBox.width),\n height: bignumberbBox.height + deltabBox.height,\n left: Math.min(bignumberbBox.left, deltabBox.left),\n right: Math.max(bignumberbBox.right, deltabBox.right),\n top: bignumberbBox.bottom - bignumberbBox.height,\n bottom: bignumberbBox.bottom + deltabBox.height\n };\n }\n if(trace.delta.position === 'top') {\n dx = null;\n dy = bignumberbBox.top;\n\n numbersbBox = {\n width: Math.max(bignumberbBox.width, deltabBox.width),\n height: bignumberbBox.height + deltabBox.height,\n left: Math.min(bignumberbBox.left, deltabBox.left),\n right: Math.max(bignumberbBox.right, deltabBox.right),\n top: bignumberbBox.bottom - bignumberbBox.height - deltabBox.height,\n bottom: bignumberbBox.bottom\n };\n }\n\n delta.attr({dx: dx, dy: dy});\n }\n\n // Resize numbers to fit within space and position\n if(trace._hasNumber || trace._hasDelta) {\n numbers.attr('transform', function() {\n var m = opts.numbersScaler(numbersbBox);\n key += m[2];\n var scaleRatio = cache(trace, 'numbersScale', 1, m[0], key, Math.min);\n var translateY;\n if(!trace._scaleNumbers) scaleRatio = 1;\n if(trace._isAngular) {\n // align vertically to bottom\n translateY = numbersY - scaleRatio * numbersbBox.bottom;\n } else {\n // align vertically to center\n translateY = numbersY - scaleRatio * (numbersbBox.top + numbersbBox.bottom) / 2;\n }\n\n // Stash the top position of numbersbBox for title positioning\n trace._numbersTop = scaleRatio * (numbersbBox.top) + translateY;\n\n var ref = numbersbBox[numbersAlign];\n if(numbersAlign === 'center') ref = (numbersbBox.left + numbersbBox.right) / 2;\n var translateX = numbersX - scaleRatio * ref;\n\n // Stash translateX\n translateX = cache(trace, 'numbersTranslate', 0, translateX, key, Math.max);\n return strTranslate(translateX, translateY) + ' scale(' + scaleRatio + ')';\n });\n }\n}\n\n// Apply fill, stroke, stroke-width to SVG shape\nfunction styleShape(p) {\n p\n .each(function(d) { Color.stroke(d3.select(this), d.line.color);})\n .each(function(d) { Color.fill(d3.select(this), d.color);})\n .style('stroke-width', function(d) { return d.line.width;});\n}\n\n// Returns a tween for a transition’s \"d\" attribute, transitioning any selected\n// arcs from their current angle to the specified new angle.\nfunction arcTween(arc, endAngle, newAngle) {\n return function() {\n var interpolate = d3.interpolate(endAngle, newAngle);\n return function(t) {\n return arc.endAngle(interpolate(t))();\n };\n };\n}\n\n// mocks our axis\nfunction mockAxis(gd, opts, zrange) {\n var fullLayout = gd._fullLayout;\n\n var axisIn = Lib.extendFlat({\n type: 'linear',\n ticks: 'outside',\n range: zrange,\n showline: true\n }, opts);\n\n var axisOut = {\n type: 'linear',\n _id: 'x' + opts._id\n };\n\n var axisOptions = {\n letter: 'x',\n font: fullLayout.font,\n noHover: true,\n noTickson: true\n };\n\n function coerce(attr, dflt) {\n return Lib.coerce(axisIn, axisOut, axisLayoutAttrs, attr, dflt);\n }\n\n handleAxisDefaults(axisIn, axisOut, coerce, axisOptions, fullLayout);\n handleAxisPositionDefaults(axisIn, axisOut, coerce, axisOptions);\n\n return axisOut;\n}\n\nfunction strTranslate(x, y) {\n return 'translate(' + x + ',' + y + ')';\n}\n\nfunction fitTextInsideBox(textBB, width, height) {\n // compute scaling ratio to have text fit within specified width and height\n var ratio = Math.min(width / textBB.width, height / textBB.height);\n return [ratio, textBB, width + 'x' + height];\n}\n\nfunction fitTextInsideCircle(textBB, radius) {\n // compute scaling ratio to have text fit within specified radius\n var elRadius = Math.sqrt((textBB.width / 2) * (textBB.width / 2) + textBB.height * textBB.height);\n var ratio = radius / elRadius;\n return [ratio, textBB, radius];\n}\n\nfunction measureText(txt, font, textAnchor, gd) {\n var element = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n var sel = d3.select(element);\n sel.text(txt)\n .attr('x', 0)\n .attr('y', 0)\n .attr('text-anchor', textAnchor)\n .attr('data-unformatted', txt)\n .call(svgTextUtils.convertToTspans, gd)\n .call(Drawing.font, font);\n return Drawing.bBox(sel.node());\n}\n\nfunction cache(trace, name, initialValue, value, key, fn) {\n var objName = '_cache' + name;\n if(!(trace[objName] && trace[objName].key === key)) {\n trace[objName] = {key: key, value: initialValue};\n }\n var v = Lib.aggNums(fn, null, [trace[objName].value, value], 2);\n trace[objName].value = v;\n\n return v;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/indicator/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/isosurface/attributes.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/isosurface/attributes.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar meshAttrs = __webpack_require__(/*! ../mesh3d/attributes */ \"./node_modules/plotly.js/src/traces/mesh3d/attributes.js\");\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar overrideAll = __webpack_require__(/*! ../../plot_api/edit_types */ \"./node_modules/plotly.js/src/plot_api/edit_types.js\").overrideAll;\n\nfunction makeSliceAttr(axLetter) {\n return {\n show: {\n valType: 'boolean',\n \n dflt: false,\n \n },\n locations: {\n valType: 'data_array',\n dflt: [],\n \n \n },\n fill: {\n valType: 'number',\n \n min: 0,\n max: 1,\n dflt: 1,\n \n }\n };\n}\n\nfunction makeCapAttr(axLetter) {\n return {\n show: {\n valType: 'boolean',\n \n dflt: true,\n \n },\n fill: {\n valType: 'number',\n \n min: 0,\n max: 1,\n dflt: 1,\n \n }\n };\n}\n\nvar attrs = module.exports = overrideAll(extendFlat({\n x: {\n valType: 'data_array',\n \n \n },\n y: {\n valType: 'data_array',\n \n \n },\n z: {\n valType: 'data_array',\n \n \n },\n value: {\n valType: 'data_array',\n \n \n },\n isomin: {\n valType: 'number',\n \n \n },\n isomax: {\n valType: 'number',\n \n \n },\n\n surface: {\n show: {\n valType: 'boolean',\n \n dflt: true,\n \n },\n count: {\n valType: 'integer',\n \n dflt: 2,\n min: 1,\n \n },\n fill: {\n valType: 'number',\n \n min: 0,\n max: 1,\n dflt: 1,\n \n },\n pattern: {\n valType: 'flaglist',\n flags: ['A', 'B', 'C', 'D', 'E'],\n extras: ['all', 'odd', 'even'],\n dflt: 'all',\n \n \n }\n },\n\n spaceframe: {\n show: {\n valType: 'boolean',\n \n dflt: false,\n \n },\n fill: {\n valType: 'number',\n \n min: 0,\n max: 1,\n dflt: 0.15,\n \n }\n },\n\n slices: {\n x: makeSliceAttr('x'),\n y: makeSliceAttr('y'),\n z: makeSliceAttr('z')\n },\n\n caps: {\n x: makeCapAttr('x'),\n y: makeCapAttr('y'),\n z: makeCapAttr('z')\n },\n\n text: {\n valType: 'string',\n \n dflt: '',\n arrayOk: true,\n \n },\n hovertext: {\n valType: 'string',\n \n dflt: '',\n arrayOk: true,\n \n },\n hovertemplate: hovertemplateAttrs(),\n showlegend: extendFlat({}, baseAttrs.showlegend, {dflt: false})\n},\n\ncolorScaleAttrs('', {\n colorAttr: '`value`',\n showScaleDflt: true,\n editTypeOverride: 'calc'\n}), {\n opacity: meshAttrs.opacity,\n lightposition: meshAttrs.lightposition,\n lighting: meshAttrs.lighting,\n flatshading: meshAttrs.flatshading,\n contour: meshAttrs.contour,\n\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo)\n}), 'calc', 'nested');\n\n// required defaults to speed up surface normal calculations\nattrs.flatshading.dflt = true; attrs.lighting.facenormalsepsilon.dflt = 0;\n\nattrs.x.editType = attrs.y.editType = attrs.z.editType = attrs.value.editType = 'calc+clearAxisTypes';\nattrs.transforms = undefined;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/isosurface/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/isosurface/calc.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/isosurface/calc.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar colorscaleCalc = __webpack_require__(/*! ../../components/colorscale/calc */ \"./node_modules/plotly.js/src/components/colorscale/calc.js\");\nvar processGrid = __webpack_require__(/*! ../streamtube/calc */ \"./node_modules/plotly.js/src/traces/streamtube/calc.js\").processGrid;\nvar filter = __webpack_require__(/*! ../streamtube/calc */ \"./node_modules/plotly.js/src/traces/streamtube/calc.js\").filter;\n\nmodule.exports = function calc(gd, trace) {\n trace._len = Math.min(\n trace.x.length,\n trace.y.length,\n trace.z.length,\n trace.value.length\n );\n\n trace._x = filter(trace.x, trace._len);\n trace._y = filter(trace.y, trace._len);\n trace._z = filter(trace.z, trace._len);\n trace._value = filter(trace.value, trace._len);\n\n var grid = processGrid(trace);\n trace._gridFill = grid.fill;\n trace._Xs = grid.Xs;\n trace._Ys = grid.Ys;\n trace._Zs = grid.Zs;\n trace._len = grid.len;\n\n var min = Infinity;\n var max = -Infinity;\n for(var i = 0; i < trace._len; i++) {\n var v = trace._value[i];\n min = Math.min(min, v);\n max = Math.max(max, v);\n }\n\n trace._minValues = min;\n trace._maxValues = max;\n trace._vMin = (trace.isomin === undefined || trace.isomin === null) ? min : trace.isomin;\n trace._vMax = (trace.isomax === undefined || trace.isomin === null) ? max : trace.isomax;\n\n colorscaleCalc(gd, trace, {\n vals: [trace._vMin, trace._vMax],\n containerStr: '',\n cLetter: 'c'\n });\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/isosurface/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/isosurface/convert.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/isosurface/convert.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar createMesh = __webpack_require__(/*! gl-mesh3d */ \"./node_modules/gl-mesh3d/mesh.js\");\nvar parseColorScale = __webpack_require__(/*! ../../lib/gl_format_color */ \"./node_modules/plotly.js/src/lib/gl_format_color.js\").parseColorScale;\nvar str2RgbaArray = __webpack_require__(/*! ../../lib/str2rgbarray */ \"./node_modules/plotly.js/src/lib/str2rgbarray.js\");\nvar extractOpts = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\").extractOpts;\nvar zip3 = __webpack_require__(/*! ../../plots/gl3d/zip3 */ \"./node_modules/plotly.js/src/plots/gl3d/zip3.js\");\n\nvar findNearestOnAxis = function(w, arr) {\n for(var q = arr.length - 1; q > 0; q--) {\n var min = Math.min(arr[q], arr[q - 1]);\n var max = Math.max(arr[q], arr[q - 1]);\n if(max > min && min < w && w <= max) {\n return {\n id: q,\n distRatio: (max - w) / (max - min)\n };\n }\n }\n return {\n id: 0,\n distRatio: 0\n };\n};\n\nfunction IsosurfaceTrace(scene, mesh, uid) {\n this.scene = scene;\n this.uid = uid;\n this.mesh = mesh;\n this.name = '';\n this.data = null;\n this.showContour = false;\n}\n\nvar proto = IsosurfaceTrace.prototype;\n\nproto.handlePick = function(selection) {\n if(selection.object === this.mesh) {\n var rawId = selection.data.index;\n\n var x = this.data._meshX[rawId];\n var y = this.data._meshY[rawId];\n var z = this.data._meshZ[rawId];\n\n var height = this.data._Ys.length;\n var depth = this.data._Zs.length;\n\n var i = findNearestOnAxis(x, this.data._Xs).id;\n var j = findNearestOnAxis(y, this.data._Ys).id;\n var k = findNearestOnAxis(z, this.data._Zs).id;\n\n var selectIndex = selection.index = k + depth * j + depth * height * i;\n\n selection.traceCoordinate = [\n this.data._meshX[selectIndex],\n this.data._meshY[selectIndex],\n this.data._meshZ[selectIndex],\n this.data._value[selectIndex]\n ];\n\n var text = this.data.hovertext || this.data.text;\n if(Array.isArray(text) && text[selectIndex] !== undefined) {\n selection.textLabel = text[selectIndex];\n } else if(text) {\n selection.textLabel = text;\n }\n\n return true;\n }\n};\n\nproto.update = function(data) {\n var scene = this.scene;\n var layout = scene.fullSceneLayout;\n\n this.data = generateIsoMeshes(data);\n\n // Unpack position data\n function toDataCoords(axis, coord, scale, calendar) {\n return coord.map(function(x) {\n return axis.d2l(x, 0, calendar) * scale;\n });\n }\n\n var positions = zip3(\n toDataCoords(layout.xaxis, data._meshX, scene.dataScale[0], data.xcalendar),\n toDataCoords(layout.yaxis, data._meshY, scene.dataScale[1], data.ycalendar),\n toDataCoords(layout.zaxis, data._meshZ, scene.dataScale[2], data.zcalendar));\n\n var cells = zip3(data._meshI, data._meshJ, data._meshK);\n\n var config = {\n positions: positions,\n cells: cells,\n lightPosition: [data.lightposition.x, data.lightposition.y, data.lightposition.z],\n ambient: data.lighting.ambient,\n diffuse: data.lighting.diffuse,\n specular: data.lighting.specular,\n roughness: data.lighting.roughness,\n fresnel: data.lighting.fresnel,\n vertexNormalsEpsilon: data.lighting.vertexnormalsepsilon,\n faceNormalsEpsilon: data.lighting.facenormalsepsilon,\n opacity: data.opacity,\n contourEnable: data.contour.show,\n contourColor: str2RgbaArray(data.contour.color).slice(0, 3),\n contourWidth: data.contour.width,\n useFacetNormals: data.flatshading\n };\n\n var cOpts = extractOpts(data);\n config.vertexIntensity = data._meshIntensity;\n config.vertexIntensityBounds = [cOpts.min, cOpts.max];\n config.colormap = parseColorScale(data);\n\n // Update mesh\n this.mesh.update(config);\n};\n\nproto.dispose = function() {\n this.scene.glplot.remove(this.mesh);\n this.mesh.dispose();\n};\n\nvar GRID_TYPES = ['xyz', 'xzy', 'yxz', 'yzx', 'zxy', 'zyx'];\n\nfunction generateIsoMeshes(data) {\n data._meshI = [];\n data._meshJ = [];\n data._meshK = [];\n\n var showSurface = data.surface.show;\n var showSpaceframe = data.spaceframe.show;\n\n var surfaceFill = data.surface.fill;\n var spaceframeFill = data.spaceframe.fill;\n\n var drawingSurface = false;\n var drawingSpaceframe = false;\n\n var numFaces = 0;\n var numVertices;\n var beginVertextLength;\n\n var Xs = data._Xs;\n var Ys = data._Ys;\n var Zs = data._Zs;\n\n var width = Xs.length;\n var height = Ys.length;\n var depth = Zs.length;\n\n var filled = GRID_TYPES.indexOf(data._gridFill.replace(/-/g, '').replace(/\\+/g, ''));\n\n var getIndex = function(i, j, k) {\n switch(filled) {\n case 5: // 'zyx'\n return k + depth * j + depth * height * i;\n case 4: // 'zxy'\n return k + depth * i + depth * width * j;\n case 3: // 'yzx'\n return j + height * k + height * depth * i;\n case 2: // 'yxz'\n return j + height * i + height * width * k;\n case 1: // 'xzy'\n return i + width * k + width * depth * j;\n default: // case 0: // 'xyz'\n return i + width * j + width * height * k;\n }\n };\n\n var minValues = data._minValues;\n var maxValues = data._maxValues;\n\n var vMin = data._vMin;\n var vMax = data._vMax;\n\n var allXs;\n var allYs;\n var allZs;\n var allVs;\n\n function findVertexId(x, y, z) {\n // could be used to find the vertex id of previously generated vertex within the group\n\n var len = allVs.length;\n for(var f = beginVertextLength; f < len; f++) {\n if(\n x === allXs[f] &&\n y === allYs[f] &&\n z === allZs[f]\n ) {\n return f;\n }\n }\n return -1;\n }\n\n function beginGroup() {\n beginVertextLength = numVertices;\n }\n\n function emptyVertices() {\n allXs = [];\n allYs = [];\n allZs = [];\n allVs = [];\n numVertices = 0;\n\n beginGroup();\n }\n\n function addVertex(x, y, z, v) {\n allXs.push(x);\n allYs.push(y);\n allZs.push(z);\n allVs.push(v);\n numVertices++;\n\n return numVertices - 1;\n }\n\n function addFace(a, b, c) {\n data._meshI.push(a);\n data._meshJ.push(b);\n data._meshK.push(c);\n numFaces++;\n\n return numFaces - 1;\n }\n\n function getCenter(A, B, C) {\n var M = [];\n for(var i = 0; i < A.length; i++) {\n M[i] = (A[i] + B[i] + C[i]) / 3.0;\n }\n return M;\n }\n\n function getBetween(A, B, r) {\n var M = [];\n for(var i = 0; i < A.length; i++) {\n M[i] = A[i] * (1 - r) + r * B[i];\n }\n return M;\n }\n\n var activeFill;\n function setFill(fill) {\n activeFill = fill;\n }\n\n function createOpenTri(xyzv, abc) {\n var A = xyzv[0];\n var B = xyzv[1];\n var C = xyzv[2];\n var G = getCenter(A, B, C);\n\n var r = Math.sqrt(1 - activeFill);\n var p1 = getBetween(G, A, r);\n var p2 = getBetween(G, B, r);\n var p3 = getBetween(G, C, r);\n\n var a = abc[0];\n var b = abc[1];\n var c = abc[2];\n\n return {\n xyzv: [\n [A, B, p2], [p2, p1, A],\n [B, C, p3], [p3, p2, B],\n [C, A, p1], [p1, p3, C]\n ],\n abc: [\n [a, b, -1], [-1, -1, a],\n [b, c, -1], [-1, -1, b],\n [c, a, -1], [-1, -1, c]\n ]\n };\n }\n\n function styleIncludes(style, char) {\n if(style === 'all' || style === null) return true;\n return (style.indexOf(char) > -1);\n }\n\n function mapValue(style, value) {\n if(style === null) return value;\n return style;\n }\n\n function drawTri(style, xyzv, abc) {\n beginGroup();\n\n var allXYZVs = [xyzv];\n var allABCs = [abc];\n if(activeFill >= 1) {\n allXYZVs = [xyzv];\n allABCs = [abc];\n } else if(activeFill > 0) {\n var openTri = createOpenTri(xyzv, abc);\n allXYZVs = openTri.xyzv;\n allABCs = openTri.abc;\n }\n\n for(var f = 0; f < allXYZVs.length; f++) {\n xyzv = allXYZVs[f];\n abc = allABCs[f];\n\n var pnts = [];\n for(var i = 0; i < 3; i++) {\n var x = xyzv[i][0];\n var y = xyzv[i][1];\n var z = xyzv[i][2];\n var v = xyzv[i][3];\n\n var id = (abc[i] > -1) ? abc[i] : findVertexId(x, y, z);\n if(id > -1) {\n pnts[i] = id;\n } else {\n pnts[i] = addVertex(x, y, z, mapValue(style, v));\n }\n }\n\n addFace(pnts[0], pnts[1], pnts[2]);\n }\n }\n\n function drawQuad(style, xyzv, abcd) {\n var makeTri = function(i, j, k) {\n drawTri(style, [xyzv[i], xyzv[j], xyzv[k]], [abcd[i], abcd[j], abcd[k]]);\n };\n\n makeTri(0, 1, 2);\n makeTri(2, 3, 0);\n }\n\n function drawTetra(style, xyzv, abcd) {\n var makeTri = function(i, j, k) {\n drawTri(style, [xyzv[i], xyzv[j], xyzv[k]], [abcd[i], abcd[j], abcd[k]]);\n };\n\n makeTri(0, 1, 2);\n makeTri(3, 0, 1);\n makeTri(2, 3, 0);\n makeTri(1, 2, 3);\n }\n\n function calcIntersection(pointOut, pointIn, min, max) {\n var value = pointOut[3];\n\n if(value < min) value = min;\n if(value > max) value = max;\n\n var ratio = (pointOut[3] - value) / (pointOut[3] - pointIn[3] + 0.000000001); // we had to add this error to force solve the tiny caps\n\n var result = [];\n for(var s = 0; s < 4; s++) {\n result[s] = (1 - ratio) * pointOut[s] + ratio * pointIn[s];\n }\n return result;\n }\n\n function inRange(value, min, max) {\n return (\n value >= min &&\n value <= max\n );\n }\n\n function almostInFinalRange(value) {\n var vErr = 0.001 * (vMax - vMin);\n return (\n value >= vMin - vErr &&\n value <= vMax + vErr\n );\n }\n\n function getXYZV(indecies) {\n var xyzv = [];\n for(var q = 0; q < 4; q++) {\n var index = indecies[q];\n xyzv.push(\n [\n data._x[index],\n data._y[index],\n data._z[index],\n data._value[index]\n ]\n );\n }\n\n return xyzv;\n }\n\n var MAX_PASS = 3;\n\n function tryCreateTri(style, xyzv, abc, min, max, nPass) {\n if(!nPass) nPass = 1;\n\n abc = [-1, -1, -1]; // Note: for the moment we override indices\n // to run faster! But it is possible to comment this line\n // to reduce the number of vertices.\n\n var result = false;\n\n var ok = [\n inRange(xyzv[0][3], min, max),\n inRange(xyzv[1][3], min, max),\n inRange(xyzv[2][3], min, max)\n ];\n\n if(!ok[0] && !ok[1] && !ok[2]) {\n return false;\n }\n\n var tryDrawTri = function(style, xyzv, abc) {\n if( // we check here if the points are in `real` iso-min/max range\n almostInFinalRange(xyzv[0][3]) &&\n almostInFinalRange(xyzv[1][3]) &&\n almostInFinalRange(xyzv[2][3])\n ) {\n drawTri(style, xyzv, abc);\n return true;\n } else if(nPass < MAX_PASS) {\n return tryCreateTri(style, xyzv, abc, vMin, vMax, ++nPass); // i.e. second pass using actual vMin vMax bounds\n }\n return false;\n };\n\n if(ok[0] && ok[1] && ok[2]) {\n return tryDrawTri(style, xyzv, abc) || result;\n }\n\n var interpolated = false;\n\n [\n [0, 1, 2],\n [2, 0, 1],\n [1, 2, 0]\n ].forEach(function(e) {\n if(ok[e[0]] && ok[e[1]] && !ok[e[2]]) {\n var A = xyzv[e[0]];\n var B = xyzv[e[1]];\n var C = xyzv[e[2]];\n\n var p1 = calcIntersection(C, A, min, max);\n var p2 = calcIntersection(C, B, min, max);\n\n result = tryDrawTri(style, [p2, p1, A], [-1, -1, abc[e[0]]]) || result;\n result = tryDrawTri(style, [A, B, p2], [abc[e[0]], abc[e[1]], -1]) || result;\n\n interpolated = true;\n }\n });\n if(interpolated) return result;\n\n [\n [0, 1, 2],\n [1, 2, 0],\n [2, 0, 1]\n ].forEach(function(e) {\n if(ok[e[0]] && !ok[e[1]] && !ok[e[2]]) {\n var A = xyzv[e[0]];\n var B = xyzv[e[1]];\n var C = xyzv[e[2]];\n\n var p1 = calcIntersection(B, A, min, max);\n var p2 = calcIntersection(C, A, min, max);\n\n result = tryDrawTri(style, [p2, p1, A], [-1, -1, abc[e[0]]]) || result;\n\n interpolated = true;\n }\n });\n return result;\n }\n\n function tryCreateTetra(style, abcd, min, max) {\n var result = false;\n\n var xyzv = getXYZV(abcd);\n\n var ok = [\n inRange(xyzv[0][3], min, max),\n inRange(xyzv[1][3], min, max),\n inRange(xyzv[2][3], min, max),\n inRange(xyzv[3][3], min, max)\n ];\n\n if(!ok[0] && !ok[1] && !ok[2] && !ok[3]) {\n return result;\n }\n\n if(ok[0] && ok[1] && ok[2] && ok[3]) {\n if(drawingSpaceframe) {\n result = drawTetra(style, xyzv, abcd) || result;\n }\n return result;\n }\n\n var interpolated = false;\n\n [\n [0, 1, 2, 3],\n [3, 0, 1, 2],\n [2, 3, 0, 1],\n [1, 2, 3, 0]\n ].forEach(function(e) {\n if(ok[e[0]] && ok[e[1]] && ok[e[2]] && !ok[e[3]]) {\n var A = xyzv[e[0]];\n var B = xyzv[e[1]];\n var C = xyzv[e[2]];\n var D = xyzv[e[3]];\n\n if(drawingSpaceframe) {\n result = drawTri(style, [A, B, C], [abcd[e[0]], abcd[e[1]], abcd[e[2]]]) || result;\n } else {\n var p1 = calcIntersection(D, A, min, max);\n var p2 = calcIntersection(D, B, min, max);\n var p3 = calcIntersection(D, C, min, max);\n\n result = drawTri(null, [p1, p2, p3], [-1, -1, -1]) || result;\n }\n\n interpolated = true;\n }\n });\n if(interpolated) return result;\n\n [\n [0, 1, 2, 3],\n [1, 2, 3, 0],\n [2, 3, 0, 1],\n [3, 0, 1, 2],\n [0, 2, 3, 1],\n [1, 3, 2, 0]\n ].forEach(function(e) {\n if(ok[e[0]] && ok[e[1]] && !ok[e[2]] && !ok[e[3]]) {\n var A = xyzv[e[0]];\n var B = xyzv[e[1]];\n var C = xyzv[e[2]];\n var D = xyzv[e[3]];\n\n var p1 = calcIntersection(C, A, min, max);\n var p2 = calcIntersection(C, B, min, max);\n var p3 = calcIntersection(D, B, min, max);\n var p4 = calcIntersection(D, A, min, max);\n\n if(drawingSpaceframe) {\n result = drawTri(style, [A, p4, p1], [abcd[e[0]], -1, -1]) || result;\n result = drawTri(style, [B, p2, p3], [abcd[e[1]], -1, -1]) || result;\n } else {\n result = drawQuad(null, [p1, p2, p3, p4], [-1, -1, -1, -1]) || result;\n }\n\n interpolated = true;\n }\n });\n if(interpolated) return result;\n\n [\n [0, 1, 2, 3],\n [1, 2, 3, 0],\n [2, 3, 0, 1],\n [3, 0, 1, 2]\n ].forEach(function(e) {\n if(ok[e[0]] && !ok[e[1]] && !ok[e[2]] && !ok[e[3]]) {\n var A = xyzv[e[0]];\n var B = xyzv[e[1]];\n var C = xyzv[e[2]];\n var D = xyzv[e[3]];\n\n var p1 = calcIntersection(B, A, min, max);\n var p2 = calcIntersection(C, A, min, max);\n var p3 = calcIntersection(D, A, min, max);\n\n if(drawingSpaceframe) {\n result = drawTri(style, [A, p1, p2], [abcd[e[0]], -1, -1]) || result;\n result = drawTri(style, [A, p2, p3], [abcd[e[0]], -1, -1]) || result;\n result = drawTri(style, [A, p3, p1], [abcd[e[0]], -1, -1]) || result;\n } else {\n result = drawTri(null, [p1, p2, p3], [-1, -1, -1]) || result;\n }\n\n interpolated = true;\n }\n });\n return result;\n }\n\n function addCube(style, p000, p001, p010, p011, p100, p101, p110, p111, min, max) {\n var result = false;\n\n if(drawingSurface) {\n if(styleIncludes(style, 'A')) {\n result = tryCreateTetra(null, [p000, p001, p010, p100], min, max) || result;\n }\n if(styleIncludes(style, 'B')) {\n result = tryCreateTetra(null, [p001, p010, p011, p111], min, max) || result;\n }\n if(styleIncludes(style, 'C')) {\n result = tryCreateTetra(null, [p001, p100, p101, p111], min, max) || result;\n }\n if(styleIncludes(style, 'D')) {\n result = tryCreateTetra(null, [p010, p100, p110, p111], min, max) || result;\n }\n if(styleIncludes(style, 'E')) {\n result = tryCreateTetra(null, [p001, p010, p100, p111], min, max) || result;\n }\n }\n\n if(drawingSpaceframe) {\n result = tryCreateTetra(style, [p001, p010, p100, p111], min, max) || result;\n }\n\n return result;\n }\n\n function addRect(style, a, b, c, d, min, max, previousResult) {\n return [\n (previousResult[0] === true) ? true :\n tryCreateTri(style, getXYZV([a, b, c]), [a, b, c], min, max),\n (previousResult[1] === true) ? true :\n tryCreateTri(style, getXYZV([c, d, a]), [c, d, a], min, max)\n ];\n }\n\n function begin2dCell(style, p00, p01, p10, p11, min, max, isEven, previousResult) {\n // used to create caps and/or slices on exact axis points\n if(isEven) {\n return addRect(style, p00, p01, p11, p10, min, max, previousResult);\n } else {\n return addRect(style, p01, p11, p10, p00, min, max, previousResult);\n }\n }\n\n function beginSection(style, i, j, k, min, max, distRatios) {\n // used to create slices between axis points\n\n var result = false;\n var A, B, C, D;\n\n var makeSection = function() {\n result = tryCreateTri(style, [A, B, C], [-1, -1, -1], min, max) || result;\n result = tryCreateTri(style, [C, D, A], [-1, -1, -1], min, max) || result;\n };\n\n var rX = distRatios[0];\n var rY = distRatios[1];\n var rZ = distRatios[2];\n\n if(rX) {\n A = getBetween(getXYZV([getIndex(i, j - 0, k - 0)])[0], getXYZV([getIndex(i - 1, j - 0, k - 0)])[0], rX);\n B = getBetween(getXYZV([getIndex(i, j - 0, k - 1)])[0], getXYZV([getIndex(i - 1, j - 0, k - 1)])[0], rX);\n C = getBetween(getXYZV([getIndex(i, j - 1, k - 1)])[0], getXYZV([getIndex(i - 1, j - 1, k - 1)])[0], rX);\n D = getBetween(getXYZV([getIndex(i, j - 1, k - 0)])[0], getXYZV([getIndex(i - 1, j - 1, k - 0)])[0], rX);\n makeSection();\n }\n\n if(rY) {\n A = getBetween(getXYZV([getIndex(i - 0, j, k - 0)])[0], getXYZV([getIndex(i - 0, j - 1, k - 0)])[0], rY);\n B = getBetween(getXYZV([getIndex(i - 0, j, k - 1)])[0], getXYZV([getIndex(i - 0, j - 1, k - 1)])[0], rY);\n C = getBetween(getXYZV([getIndex(i - 1, j, k - 1)])[0], getXYZV([getIndex(i - 1, j - 1, k - 1)])[0], rY);\n D = getBetween(getXYZV([getIndex(i - 1, j, k - 0)])[0], getXYZV([getIndex(i - 1, j - 1, k - 0)])[0], rY);\n makeSection();\n }\n\n if(rZ) {\n A = getBetween(getXYZV([getIndex(i - 0, j - 0, k)])[0], getXYZV([getIndex(i - 0, j - 0, k - 1)])[0], rZ);\n B = getBetween(getXYZV([getIndex(i - 0, j - 1, k)])[0], getXYZV([getIndex(i - 0, j - 1, k - 1)])[0], rZ);\n C = getBetween(getXYZV([getIndex(i - 1, j - 1, k)])[0], getXYZV([getIndex(i - 1, j - 1, k - 1)])[0], rZ);\n D = getBetween(getXYZV([getIndex(i - 1, j - 0, k)])[0], getXYZV([getIndex(i - 1, j - 0, k - 1)])[0], rZ);\n makeSection();\n }\n\n return result;\n }\n\n function begin3dCell(style, p000, p001, p010, p011, p100, p101, p110, p111, min, max, isEven) {\n // used to create spaceframe and/or iso-surfaces\n\n var cellStyle = style;\n if(isEven) {\n if(drawingSurface && style === 'even') cellStyle = null;\n return addCube(cellStyle, p000, p001, p010, p011, p100, p101, p110, p111, min, max);\n } else {\n if(drawingSurface && style === 'odd') cellStyle = null;\n return addCube(cellStyle, p111, p110, p101, p100, p011, p010, p001, p000, min, max);\n }\n }\n\n function draw2dX(style, items, min, max, previousResult) {\n var result = [];\n var n = 0;\n for(var q = 0; q < items.length; q++) {\n var i = items[q];\n for(var k = 1; k < depth; k++) {\n for(var j = 1; j < height; j++) {\n result.push(\n begin2dCell(style,\n getIndex(i, j - 1, k - 1),\n getIndex(i, j - 1, k),\n getIndex(i, j, k - 1),\n getIndex(i, j, k),\n min,\n max,\n (i + j + k) % 2,\n (previousResult && previousResult[n]) ? previousResult[n] : []\n )\n );\n n++;\n }\n }\n }\n return result;\n }\n\n function draw2dY(style, items, min, max, previousResult) {\n var result = [];\n var n = 0;\n for(var q = 0; q < items.length; q++) {\n var j = items[q];\n for(var i = 1; i < width; i++) {\n for(var k = 1; k < depth; k++) {\n result.push(\n begin2dCell(style,\n getIndex(i - 1, j, k - 1),\n getIndex(i, j, k - 1),\n getIndex(i - 1, j, k),\n getIndex(i, j, k),\n min,\n max,\n (i + j + k) % 2,\n (previousResult && previousResult[n]) ? previousResult[n] : []\n )\n );\n n++;\n }\n }\n }\n return result;\n }\n\n function draw2dZ(style, items, min, max, previousResult) {\n var result = [];\n var n = 0;\n for(var q = 0; q < items.length; q++) {\n var k = items[q];\n for(var j = 1; j < height; j++) {\n for(var i = 1; i < width; i++) {\n result.push(\n begin2dCell(style,\n getIndex(i - 1, j - 1, k),\n getIndex(i - 1, j, k),\n getIndex(i, j - 1, k),\n getIndex(i, j, k),\n min,\n max,\n (i + j + k) % 2,\n (previousResult && previousResult[n]) ? previousResult[n] : []\n )\n );\n n++;\n }\n }\n }\n return result;\n }\n\n function draw3d(style, min, max) {\n for(var k = 1; k < depth; k++) {\n for(var j = 1; j < height; j++) {\n for(var i = 1; i < width; i++) {\n begin3dCell(style,\n getIndex(i - 1, j - 1, k - 1),\n getIndex(i - 1, j - 1, k),\n getIndex(i - 1, j, k - 1),\n getIndex(i - 1, j, k),\n getIndex(i, j - 1, k - 1),\n getIndex(i, j - 1, k),\n getIndex(i, j, k - 1),\n getIndex(i, j, k),\n min,\n max,\n (i + j + k) % 2\n );\n }\n }\n }\n }\n\n function drawSpaceframe(style, min, max) {\n drawingSpaceframe = true;\n draw3d(style, min, max);\n drawingSpaceframe = false;\n }\n\n function drawSurface(style, min, max) {\n drawingSurface = true;\n draw3d(style, min, max);\n drawingSurface = false;\n }\n\n function drawSectionX(style, items, min, max, distRatios, previousResult) {\n var result = [];\n var n = 0;\n for(var q = 0; q < items.length; q++) {\n var i = items[q];\n for(var k = 1; k < depth; k++) {\n for(var j = 1; j < height; j++) {\n result.push(\n beginSection(style, i, j, k, min, max, distRatios[q],\n (previousResult && previousResult[n]) ? previousResult[n] : []\n )\n );\n n++;\n }\n }\n }\n return result;\n }\n\n function drawSectionY(style, items, min, max, distRatios, previousResult) {\n var result = [];\n var n = 0;\n for(var q = 0; q < items.length; q++) {\n var j = items[q];\n for(var i = 1; i < width; i++) {\n for(var k = 1; k < depth; k++) {\n result.push(\n beginSection(style, i, j, k, min, max, distRatios[q],\n (previousResult && previousResult[n]) ? previousResult[n] : []\n )\n );\n n++;\n }\n }\n }\n return result;\n }\n\n function drawSectionZ(style, items, min, max, distRatios, previousResult) {\n var result = [];\n var n = 0;\n for(var q = 0; q < items.length; q++) {\n var k = items[q];\n for(var j = 1; j < height; j++) {\n for(var i = 1; i < width; i++) {\n result.push(\n beginSection(style, i, j, k, min, max, distRatios[q],\n (previousResult && previousResult[n]) ? previousResult[n] : []\n )\n );\n n++;\n }\n }\n }\n return result;\n }\n\n function createRange(a, b) {\n var range = [];\n for(var q = a; q < b; q++) {\n range.push(q);\n }\n return range;\n }\n\n function insertGridPoints() {\n for(var i = 0; i < width; i++) {\n for(var j = 0; j < height; j++) {\n for(var k = 0; k < depth; k++) {\n var index = getIndex(i, j, k);\n addVertex(\n data._x[index],\n data._y[index],\n data._z[index],\n data._value[index]\n );\n }\n }\n }\n }\n\n function drawAll() {\n emptyVertices();\n\n // insert grid points\n insertGridPoints();\n\n var activeStyle = null;\n\n // draw spaceframes\n if(showSpaceframe && spaceframeFill) {\n setFill(spaceframeFill);\n\n drawSpaceframe(activeStyle, vMin, vMax);\n }\n\n // draw iso-surfaces\n if(showSurface && surfaceFill) {\n setFill(surfaceFill);\n\n var surfacePattern = data.surface.pattern;\n var surfaceCount = data.surface.count;\n for(var q = 0; q < surfaceCount; q++) {\n var ratio = (surfaceCount === 1) ? 0.5 : q / (surfaceCount - 1);\n var level = (1 - ratio) * vMin + ratio * vMax;\n\n var d1 = Math.abs(level - minValues);\n var d2 = Math.abs(level - maxValues);\n var ranges = (d1 > d2) ?\n [minValues, level] :\n [level, maxValues];\n\n drawSurface(surfacePattern, ranges[0], ranges[1]);\n }\n }\n\n var setupMinMax = [\n [ Math.min(vMin, maxValues), Math.max(vMin, maxValues) ],\n [ Math.min(minValues, vMax), Math.max(minValues, vMax) ]\n ];\n\n ['x', 'y', 'z'].forEach(function(e) {\n var preRes = [];\n for(var s = 0; s < setupMinMax.length; s++) {\n var count = 0;\n\n var activeMin = setupMinMax[s][0];\n var activeMax = setupMinMax[s][1];\n\n // draw slices\n var slice = data.slices[e];\n if(slice.show && slice.fill) {\n setFill(slice.fill);\n\n var exactIndices = [];\n var ceilIndices = [];\n var distRatios = [];\n if(slice.locations.length) {\n for(var q = 0; q < slice.locations.length; q++) {\n var near = findNearestOnAxis(\n slice.locations[q],\n (e === 'x') ? Xs :\n (e === 'y') ? Ys : Zs\n );\n\n if(near.distRatio === 0) {\n exactIndices.push(near.id);\n } else if(near.id > 0) {\n ceilIndices.push(near.id);\n if(e === 'x') {\n distRatios.push([near.distRatio, 0, 0]);\n } else if(e === 'y') {\n distRatios.push([0, near.distRatio, 0]);\n } else {\n distRatios.push([0, 0, near.distRatio]);\n }\n }\n }\n } else {\n if(e === 'x') {\n exactIndices = createRange(1, width - 1);\n } else if(e === 'y') {\n exactIndices = createRange(1, height - 1);\n } else {\n exactIndices = createRange(1, depth - 1);\n }\n }\n\n if(ceilIndices.length > 0) {\n if(e === 'x') {\n preRes[count] = drawSectionX(activeStyle, ceilIndices, activeMin, activeMax, distRatios, preRes[count]);\n } else if(e === 'y') {\n preRes[count] = drawSectionY(activeStyle, ceilIndices, activeMin, activeMax, distRatios, preRes[count]);\n } else {\n preRes[count] = drawSectionZ(activeStyle, ceilIndices, activeMin, activeMax, distRatios, preRes[count]);\n }\n count++;\n }\n\n if(exactIndices.length > 0) {\n if(e === 'x') {\n preRes[count] = draw2dX(activeStyle, exactIndices, activeMin, activeMax, preRes[count]);\n } else if(e === 'y') {\n preRes[count] = draw2dY(activeStyle, exactIndices, activeMin, activeMax, preRes[count]);\n } else {\n preRes[count] = draw2dZ(activeStyle, exactIndices, activeMin, activeMax, preRes[count]);\n }\n count++;\n }\n }\n\n // draw caps\n var cap = data.caps[e];\n if(cap.show && cap.fill) {\n setFill(cap.fill);\n if(e === 'x') {\n preRes[count] = draw2dX(activeStyle, [0, width - 1], activeMin, activeMax, preRes[count]);\n } else if(e === 'y') {\n preRes[count] = draw2dY(activeStyle, [0, height - 1], activeMin, activeMax, preRes[count]);\n } else {\n preRes[count] = draw2dZ(activeStyle, [0, depth - 1], activeMin, activeMax, preRes[count]);\n }\n count++;\n }\n }\n });\n\n // remove vertices arrays (i.e. grid points) in case no face was created.\n if(numFaces === 0) {\n emptyVertices();\n }\n\n data._meshX = allXs;\n data._meshY = allYs;\n data._meshZ = allZs;\n data._meshIntensity = allVs;\n\n data._Xs = Xs;\n data._Ys = Ys;\n data._Zs = Zs;\n }\n\n drawAll();\n\n return data;\n}\n\nfunction createIsosurfaceTrace(scene, data) {\n var gl = scene.glplot.gl;\n var mesh = createMesh({gl: gl});\n var result = new IsosurfaceTrace(scene, mesh, data.uid);\n\n mesh._trace = result;\n result.update(data);\n scene.glplot.add(mesh);\n return result;\n}\n\nmodule.exports = {\n findNearestOnAxis: findNearestOnAxis,\n generateIsoMeshes: generateIsoMeshes,\n createIsosurfaceTrace: createIsosurfaceTrace,\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/isosurface/convert.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/isosurface/defaults.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/isosurface/defaults.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/isosurface/attributes.js\");\nvar colorscaleDefaults = __webpack_require__(/*! ../../components/colorscale/defaults */ \"./node_modules/plotly.js/src/components/colorscale/defaults.js\");\n\nfunction supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n supplyIsoDefaults(traceIn, traceOut, defaultColor, layout, coerce);\n}\n\nfunction supplyIsoDefaults(traceIn, traceOut, defaultColor, layout, coerce) {\n var isomin = coerce('isomin');\n var isomax = coerce('isomax');\n\n if(isomax !== undefined && isomax !== null &&\n isomin !== undefined && isomin !== null &&\n isomin > isomax) {\n // applying default values in this case:\n traceOut.isomin = null;\n traceOut.isomax = null;\n }\n\n var x = coerce('x');\n var y = coerce('y');\n var z = coerce('z');\n var value = coerce('value');\n\n if(\n !x || !x.length ||\n !y || !y.length ||\n !z || !z.length ||\n !value || !value.length\n ) {\n traceOut.visible = false;\n return;\n }\n\n var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleTraceDefaults');\n handleCalendarDefaults(traceIn, traceOut, ['x', 'y', 'z'], layout);\n\n ['x', 'y', 'z'].forEach(function(dim) {\n var capDim = 'caps.' + dim;\n var showCap = coerce(capDim + '.show');\n if(showCap) {\n coerce(capDim + '.fill');\n }\n\n var sliceDim = 'slices.' + dim;\n var showSlice = coerce(sliceDim + '.show');\n if(showSlice) {\n coerce(sliceDim + '.fill');\n coerce(sliceDim + '.locations');\n }\n });\n\n var showSpaceframe = coerce('spaceframe.show');\n if(showSpaceframe) {\n coerce('spaceframe.fill');\n }\n\n var showSurface = coerce('surface.show');\n if(showSurface) {\n coerce('surface.count');\n coerce('surface.fill');\n coerce('surface.pattern');\n }\n\n var showContour = coerce('contour.show');\n if(showContour) {\n coerce('contour.color');\n coerce('contour.width');\n }\n\n // Coerce remaining properties\n [\n 'text',\n 'hovertext',\n 'hovertemplate',\n 'lighting.ambient',\n 'lighting.diffuse',\n 'lighting.specular',\n 'lighting.roughness',\n 'lighting.fresnel',\n 'lighting.vertexnormalsepsilon',\n 'lighting.facenormalsepsilon',\n 'lightposition.x',\n 'lightposition.y',\n 'lightposition.z',\n 'flatshading',\n 'opacity'\n ].forEach(function(x) { coerce(x); });\n\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'c'});\n\n // disable 1D transforms (for now)\n traceOut._length = null;\n}\n\nmodule.exports = {\n supplyDefaults: supplyDefaults,\n supplyIsoDefaults: supplyIsoDefaults\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/isosurface/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/isosurface/index.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/isosurface/index.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/isosurface/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/isosurface/defaults.js\").supplyDefaults,\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/isosurface/calc.js\"),\n colorbar: {\n min: 'cmin',\n max: 'cmax'\n },\n plot: __webpack_require__(/*! ./convert */ \"./node_modules/plotly.js/src/traces/isosurface/convert.js\").createIsosurfaceTrace,\n\n moduleType: 'trace',\n name: 'isosurface',\n basePlotModule: __webpack_require__(/*! ../../plots/gl3d */ \"./node_modules/plotly.js/src/plots/gl3d/index.js\"),\n categories: ['gl3d', 'showLegend'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/isosurface/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/mesh3d/attributes.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/mesh3d/attributes.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar surfaceAttrs = __webpack_require__(/*! ../surface/attributes */ \"./node_modules/plotly.js/src/traces/surface/attributes.js\");\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nmodule.exports = extendFlat({\n x: {\n valType: 'data_array',\n editType: 'calc+clearAxisTypes',\n \n },\n y: {\n valType: 'data_array',\n editType: 'calc+clearAxisTypes',\n \n },\n z: {\n valType: 'data_array',\n editType: 'calc+clearAxisTypes',\n \n },\n\n i: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n j: {\n valType: 'data_array',\n editType: 'calc',\n \n\n },\n k: {\n valType: 'data_array',\n editType: 'calc',\n \n\n },\n\n text: {\n valType: 'string',\n \n dflt: '',\n arrayOk: true,\n editType: 'calc',\n \n },\n hovertext: {\n valType: 'string',\n \n dflt: '',\n arrayOk: true,\n editType: 'calc',\n \n },\n hovertemplate: hovertemplateAttrs({editType: 'calc'}),\n\n delaunayaxis: {\n valType: 'enumerated',\n \n values: [ 'x', 'y', 'z' ],\n dflt: 'z',\n editType: 'calc',\n \n },\n\n alphahull: {\n valType: 'number',\n \n dflt: -1,\n editType: 'calc',\n \n },\n\n intensity: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n intensitymode: {\n valType: 'enumerated',\n values: ['vertex', 'cell'],\n dflt: 'vertex',\n editType: 'calc',\n \n \n },\n\n // Color field\n color: {\n valType: 'color',\n \n editType: 'calc',\n \n },\n vertexcolor: {\n valType: 'data_array',\n \n editType: 'calc',\n \n },\n facecolor: {\n valType: 'data_array',\n \n editType: 'calc',\n \n },\n transforms: undefined\n},\n\ncolorScaleAttrs('', {\n colorAttr: '`intensity`',\n showScaleDflt: true,\n editTypeOverride: 'calc'\n}), {\n opacity: surfaceAttrs.opacity,\n\n // Flat shaded mode\n flatshading: {\n valType: 'boolean',\n \n dflt: false,\n editType: 'calc',\n \n },\n\n contour: {\n show: extendFlat({}, surfaceAttrs.contours.x.show, {\n \n }),\n color: surfaceAttrs.contours.x.color,\n width: surfaceAttrs.contours.x.width,\n editType: 'calc'\n },\n\n lightposition: {\n x: extendFlat({}, surfaceAttrs.lightposition.x, {dflt: 1e5}),\n y: extendFlat({}, surfaceAttrs.lightposition.y, {dflt: 1e5}),\n z: extendFlat({}, surfaceAttrs.lightposition.z, {dflt: 0}),\n editType: 'calc'\n },\n lighting: extendFlat({\n vertexnormalsepsilon: {\n valType: 'number',\n \n min: 0.00,\n max: 1,\n dflt: 1e-12, // otherwise finely tessellated things eg. the brain will have no specular light reflection\n editType: 'calc',\n \n },\n facenormalsepsilon: {\n valType: 'number',\n \n min: 0.00,\n max: 1,\n dflt: 1e-6, // even the brain model doesn't appear to need finer than this\n editType: 'calc',\n \n },\n editType: 'calc'\n }, surfaceAttrs.lighting),\n\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {editType: 'calc'}),\n showlegend: extendFlat({}, baseAttrs.showlegend, {dflt: false})\n});\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/mesh3d/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/mesh3d/calc.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/mesh3d/calc.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar colorscaleCalc = __webpack_require__(/*! ../../components/colorscale/calc */ \"./node_modules/plotly.js/src/components/colorscale/calc.js\");\n\nmodule.exports = function calc(gd, trace) {\n if(trace.intensity) {\n colorscaleCalc(gd, trace, {\n vals: trace.intensity,\n containerStr: '',\n cLetter: 'c'\n });\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/mesh3d/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/mesh3d/convert.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/mesh3d/convert.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar createMesh = __webpack_require__(/*! gl-mesh3d */ \"./node_modules/gl-mesh3d/mesh.js\");\nvar triangulate = __webpack_require__(/*! delaunay-triangulate */ \"./node_modules/delaunay-triangulate/triangulate.js\");\nvar alphaShape = __webpack_require__(/*! alpha-shape */ \"./node_modules/alpha-shape/alpha.js\");\nvar convexHull = __webpack_require__(/*! convex-hull */ \"./node_modules/convex-hull/ch.js\");\n\nvar parseColorScale = __webpack_require__(/*! ../../lib/gl_format_color */ \"./node_modules/plotly.js/src/lib/gl_format_color.js\").parseColorScale;\nvar str2RgbaArray = __webpack_require__(/*! ../../lib/str2rgbarray */ \"./node_modules/plotly.js/src/lib/str2rgbarray.js\");\nvar extractOpts = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\").extractOpts;\nvar zip3 = __webpack_require__(/*! ../../plots/gl3d/zip3 */ \"./node_modules/plotly.js/src/plots/gl3d/zip3.js\");\n\nfunction Mesh3DTrace(scene, mesh, uid) {\n this.scene = scene;\n this.uid = uid;\n this.mesh = mesh;\n this.name = '';\n this.color = '#fff';\n this.data = null;\n this.showContour = false;\n}\n\nvar proto = Mesh3DTrace.prototype;\n\nproto.handlePick = function(selection) {\n if(selection.object === this.mesh) {\n var selectIndex = selection.index = selection.data.index;\n\n selection.traceCoordinate = [\n this.data.x[selectIndex],\n this.data.y[selectIndex],\n this.data.z[selectIndex]\n ];\n\n var text = this.data.hovertext || this.data.text;\n if(Array.isArray(text) && text[selectIndex] !== undefined) {\n selection.textLabel = text[selectIndex];\n } else if(text) {\n selection.textLabel = text;\n }\n\n return true;\n }\n};\n\nfunction parseColorArray(colors) {\n var b = [];\n var len = colors.length;\n for(var i = 0; i < len; i++) {\n b[i] = str2RgbaArray(colors[i]);\n }\n return b;\n}\n\n// Unpack position data\nfunction toDataCoords(axis, coord, scale, calendar) {\n var b = [];\n var len = coord.length;\n for(var i = 0; i < len; i++) {\n b[i] = axis.d2l(coord[i], 0, calendar) * scale;\n }\n return b;\n}\n\n// Round indices if passed as floats\nfunction toRoundIndex(a) {\n var b = [];\n var len = a.length;\n for(var i = 0; i < len; i++) {\n b[i] = Math.round(a[i]);\n }\n return b;\n}\n\nfunction delaunayCells(delaunayaxis, positions) {\n var d = ['x', 'y', 'z'].indexOf(delaunayaxis);\n var b = [];\n var len = positions.length;\n for(var i = 0; i < len; i++) {\n b[i] = [positions[i][(d + 1) % 3], positions[i][(d + 2) % 3]];\n }\n return triangulate(b);\n}\n\n// Validate indices\nfunction hasValidIndices(list, numVertices) {\n var len = list.length;\n for(var i = 0; i < len; i++) {\n if(list[i] <= -0.5 || list[i] >= numVertices - 0.5) { // Note: the indices would be rounded -0.49 is valid.\n return false;\n }\n }\n return true;\n}\n\nproto.update = function(data) {\n var scene = this.scene;\n var layout = scene.fullSceneLayout;\n\n this.data = data;\n\n var numVertices = data.x.length;\n\n var positions = zip3(\n toDataCoords(layout.xaxis, data.x, scene.dataScale[0], data.xcalendar),\n toDataCoords(layout.yaxis, data.y, scene.dataScale[1], data.ycalendar),\n toDataCoords(layout.zaxis, data.z, scene.dataScale[2], data.zcalendar)\n );\n\n var cells;\n if(data.i && data.j && data.k) {\n if(\n data.i.length !== data.j.length ||\n data.j.length !== data.k.length ||\n !hasValidIndices(data.i, numVertices) ||\n !hasValidIndices(data.j, numVertices) ||\n !hasValidIndices(data.k, numVertices)\n ) {\n return;\n }\n cells = zip3(\n toRoundIndex(data.i),\n toRoundIndex(data.j),\n toRoundIndex(data.k)\n );\n } else if(data.alphahull === 0) {\n cells = convexHull(positions);\n } else if(data.alphahull > 0) {\n cells = alphaShape(data.alphahull, positions);\n } else {\n cells = delaunayCells(data.delaunayaxis, positions);\n }\n\n var config = {\n positions: positions,\n cells: cells,\n lightPosition: [data.lightposition.x, data.lightposition.y, data.lightposition.z],\n ambient: data.lighting.ambient,\n diffuse: data.lighting.diffuse,\n specular: data.lighting.specular,\n roughness: data.lighting.roughness,\n fresnel: data.lighting.fresnel,\n vertexNormalsEpsilon: data.lighting.vertexnormalsepsilon,\n faceNormalsEpsilon: data.lighting.facenormalsepsilon,\n opacity: data.opacity,\n contourEnable: data.contour.show,\n contourColor: str2RgbaArray(data.contour.color).slice(0, 3),\n contourWidth: data.contour.width,\n useFacetNormals: data.flatshading\n };\n\n if(data.intensity) {\n var cOpts = extractOpts(data);\n this.color = '#fff';\n var mode = data.intensitymode;\n config[mode + 'Intensity'] = data.intensity;\n config[mode + 'IntensityBounds'] = [cOpts.min, cOpts.max];\n config.colormap = parseColorScale(data);\n } else if(data.vertexcolor) {\n this.color = data.vertexcolor[0];\n config.vertexColors = parseColorArray(data.vertexcolor);\n } else if(data.facecolor) {\n this.color = data.facecolor[0];\n config.cellColors = parseColorArray(data.facecolor);\n } else {\n this.color = data.color;\n config.meshColor = str2RgbaArray(data.color);\n }\n\n // Update mesh\n this.mesh.update(config);\n};\n\nproto.dispose = function() {\n this.scene.glplot.remove(this.mesh);\n this.mesh.dispose();\n};\n\nfunction createMesh3DTrace(scene, data) {\n var gl = scene.glplot.gl;\n var mesh = createMesh({gl: gl});\n var result = new Mesh3DTrace(scene, mesh, data.uid);\n mesh._trace = result;\n result.update(data);\n scene.glplot.add(mesh);\n return result;\n}\n\nmodule.exports = createMesh3DTrace;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/mesh3d/convert.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/mesh3d/defaults.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/mesh3d/defaults.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar colorscaleDefaults = __webpack_require__(/*! ../../components/colorscale/defaults */ \"./node_modules/plotly.js/src/components/colorscale/defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/mesh3d/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n // read in face/vertex properties\n function readComponents(array) {\n var ret = array.map(function(attr) {\n var result = coerce(attr);\n\n if(result && Lib.isArrayOrTypedArray(result)) return result;\n return null;\n });\n\n return ret.every(function(x) {\n return x && x.length === ret[0].length;\n }) && ret;\n }\n\n var coords = readComponents(['x', 'y', 'z']);\n if(!coords) {\n traceOut.visible = false;\n return;\n }\n\n readComponents(['i', 'j', 'k']);\n // three indices should be all provided or not\n if(\n (traceOut.i && (!traceOut.j || !traceOut.k)) ||\n (traceOut.j && (!traceOut.k || !traceOut.i)) ||\n (traceOut.k && (!traceOut.i || !traceOut.j))\n ) {\n traceOut.visible = false;\n return;\n }\n\n var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleTraceDefaults');\n handleCalendarDefaults(traceIn, traceOut, ['x', 'y', 'z'], layout);\n\n // Coerce remaining properties\n [\n 'lighting.ambient',\n 'lighting.diffuse',\n 'lighting.specular',\n 'lighting.roughness',\n 'lighting.fresnel',\n 'lighting.vertexnormalsepsilon',\n 'lighting.facenormalsepsilon',\n 'lightposition.x',\n 'lightposition.y',\n 'lightposition.z',\n 'flatshading',\n 'alphahull',\n 'delaunayaxis',\n 'opacity'\n ].forEach(function(x) { coerce(x); });\n\n var showContour = coerce('contour.show');\n if(showContour) {\n coerce('contour.color');\n coerce('contour.width');\n }\n\n if('intensity' in traceIn) {\n coerce('intensity');\n coerce('intensitymode');\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'c'});\n } else {\n traceOut.showscale = false;\n\n if('facecolor' in traceIn) coerce('facecolor');\n else if('vertexcolor' in traceIn) coerce('vertexcolor');\n else coerce('color', defaultColor);\n }\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n\n // disable 1D transforms\n // x/y/z should match lengths, and i/j/k should match as well, but\n // the two sets have different lengths so transforms wouldn't work.\n traceOut._length = null;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/mesh3d/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/mesh3d/index.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/mesh3d/index.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/mesh3d/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/mesh3d/defaults.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/mesh3d/calc.js\"),\n colorbar: {\n min: 'cmin',\n max: 'cmax'\n },\n plot: __webpack_require__(/*! ./convert */ \"./node_modules/plotly.js/src/traces/mesh3d/convert.js\"),\n\n moduleType: 'trace',\n name: 'mesh3d',\n basePlotModule: __webpack_require__(/*! ../../plots/gl3d */ \"./node_modules/plotly.js/src/plots/gl3d/index.js\"),\n categories: ['gl3d', 'showLegend'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/mesh3d/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/ohlc/attributes.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/ohlc/attributes.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar extendFlat = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").extendFlat;\nvar scatterAttrs = __webpack_require__(/*! ../scatter/attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\");\nvar dash = __webpack_require__(/*! ../../components/drawing/attributes */ \"./node_modules/plotly.js/src/components/drawing/attributes.js\").dash;\nvar fxAttrs = __webpack_require__(/*! ../../components/fx/attributes */ \"./node_modules/plotly.js/src/components/fx/attributes.js\");\nvar delta = __webpack_require__(/*! ../../constants/delta.js */ \"./node_modules/plotly.js/src/constants/delta.js\");\n\nvar INCREASING_COLOR = delta.INCREASING.COLOR;\nvar DECREASING_COLOR = delta.DECREASING.COLOR;\n\nvar lineAttrs = scatterAttrs.line;\n\nfunction directionAttrs(lineColorDefault) {\n return {\n line: {\n color: extendFlat({}, lineAttrs.color, {dflt: lineColorDefault}),\n width: lineAttrs.width,\n dash: dash,\n editType: 'style'\n },\n editType: 'style'\n };\n}\n\nmodule.exports = {\n\n x: {\n valType: 'data_array',\n editType: 'calc+clearAxisTypes',\n \n },\n\n open: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n\n high: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n\n low: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n\n close: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n\n line: {\n width: extendFlat({}, lineAttrs.width, {\n \n }),\n dash: extendFlat({}, dash, {\n \n }),\n editType: 'style'\n },\n\n increasing: directionAttrs(INCREASING_COLOR),\n\n decreasing: directionAttrs(DECREASING_COLOR),\n\n text: {\n valType: 'string',\n \n dflt: '',\n arrayOk: true,\n editType: 'calc',\n \n },\n hovertext: {\n valType: 'string',\n \n dflt: '',\n arrayOk: true,\n editType: 'calc',\n \n },\n\n tickwidth: {\n valType: 'number',\n min: 0,\n max: 0.5,\n dflt: 0.3,\n \n editType: 'calc',\n \n },\n\n hoverlabel: extendFlat({}, fxAttrs.hoverlabel, {\n split: {\n valType: 'boolean',\n \n dflt: false,\n editType: 'style',\n \n }\n }),\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/ohlc/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/ohlc/calc.js":
-/*!********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/ohlc/calc.js ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar _ = Lib._;\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nfunction calc(gd, trace) {\n var xa = Axes.getFromId(gd, trace.xaxis);\n var ya = Axes.getFromId(gd, trace.yaxis);\n\n var tickLen = convertTickWidth(gd, xa, trace);\n var minDiff = trace._minDiff;\n trace._minDiff = null;\n var x = trace._xcalc;\n trace._xcalc = null;\n\n var cd = calcCommon(gd, trace, x, ya, ptFunc);\n\n trace._extremes[xa._id] = Axes.findExtremes(xa, x, {vpad: minDiff / 2});\n if(cd.length) {\n Lib.extendFlat(cd[0].t, {\n wHover: minDiff / 2,\n tickLen: tickLen\n });\n return cd;\n } else {\n return [{t: {empty: true}}];\n }\n}\n\nfunction ptFunc(o, h, l, c) {\n return {\n o: o,\n h: h,\n l: l,\n c: c\n };\n}\n\n\n// shared between OHLC and candlestick\n// ptFunc makes a calcdata point specific to each trace type, from oi, hi, li, ci\nfunction calcCommon(gd, trace, x, ya, ptFunc) {\n var o = ya.makeCalcdata(trace, 'open');\n var h = ya.makeCalcdata(trace, 'high');\n var l = ya.makeCalcdata(trace, 'low');\n var c = ya.makeCalcdata(trace, 'close');\n\n var hasTextArray = Array.isArray(trace.text);\n var hasHovertextArray = Array.isArray(trace.hovertext);\n\n // we're optimists - before we have any changing data, assume increasing\n var increasing = true;\n var cPrev = null;\n\n var cd = [];\n for(var i = 0; i < x.length; i++) {\n var xi = x[i];\n var oi = o[i];\n var hi = h[i];\n var li = l[i];\n var ci = c[i];\n\n if(xi !== BADNUM && oi !== BADNUM && hi !== BADNUM && li !== BADNUM && ci !== BADNUM) {\n if(ci === oi) {\n // if open == close, look for a change from the previous close\n if(cPrev !== null && ci !== cPrev) increasing = ci > cPrev;\n // else (c === cPrev or cPrev is null) no change\n } else increasing = ci > oi;\n\n cPrev = ci;\n\n var pt = ptFunc(oi, hi, li, ci);\n\n pt.pos = xi;\n pt.yc = (oi + ci) / 2;\n pt.i = i;\n pt.dir = increasing ? 'increasing' : 'decreasing';\n\n // For categoryorder, store low and high\n pt.x = pt.pos;\n pt.y = [li, hi];\n\n if(hasTextArray) pt.tx = trace.text[i];\n if(hasHovertextArray) pt.htx = trace.hovertext[i];\n\n cd.push(pt);\n } else {\n cd.push({pos: xi, empty: true});\n }\n }\n\n trace._extremes[ya._id] = Axes.findExtremes(ya, Lib.concat(l, h), {padded: true});\n\n if(cd.length) {\n cd[0].t = {\n labels: {\n open: _(gd, 'open:') + ' ',\n high: _(gd, 'high:') + ' ',\n low: _(gd, 'low:') + ' ',\n close: _(gd, 'close:') + ' '\n }\n };\n }\n\n return cd;\n}\n\n/*\n * find min x-coordinates difference of all traces\n * attached to this x-axis and stash the result in _minDiff\n * in all traces; when a trace uses this in its\n * calc step it deletes _minDiff, so that next calc this is\n * done again in case the data changed.\n * also since we need it here, stash _xcalc on the trace\n */\nfunction convertTickWidth(gd, xa, trace) {\n var minDiff = trace._minDiff;\n\n if(!minDiff) {\n var fullData = gd._fullData;\n var ohlcTracesOnThisXaxis = [];\n\n minDiff = Infinity;\n\n var i;\n\n for(i = 0; i < fullData.length; i++) {\n var tracei = fullData[i];\n\n if(tracei.type === 'ohlc' &&\n tracei.visible === true &&\n tracei.xaxis === xa._id\n ) {\n ohlcTracesOnThisXaxis.push(tracei);\n\n var xcalc = xa.makeCalcdata(tracei, 'x');\n tracei._xcalc = xcalc;\n\n var _minDiff = Lib.distinctVals(xcalc).minDiff;\n if(_minDiff && isFinite(_minDiff)) {\n minDiff = Math.min(minDiff, _minDiff);\n }\n }\n }\n\n // if minDiff is still Infinity here, set it to 1\n if(minDiff === Infinity) minDiff = 1;\n\n for(i = 0; i < ohlcTracesOnThisXaxis.length; i++) {\n ohlcTracesOnThisXaxis[i]._minDiff = minDiff;\n }\n }\n\n return minDiff * trace.tickwidth;\n}\n\nmodule.exports = {\n calc: calc,\n calcCommon: calcCommon\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/ohlc/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/ohlc/defaults.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/ohlc/defaults.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar handleOHLC = __webpack_require__(/*! ./ohlc_defaults */ \"./node_modules/plotly.js/src/traces/ohlc/ohlc_defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/ohlc/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var len = handleOHLC(traceIn, traceOut, coerce, layout);\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n coerce('line.width');\n coerce('line.dash');\n\n handleDirection(traceIn, traceOut, coerce, 'increasing');\n handleDirection(traceIn, traceOut, coerce, 'decreasing');\n\n coerce('text');\n coerce('hovertext');\n coerce('tickwidth');\n\n layout._requestRangeslider[traceOut.xaxis] = true;\n};\n\nfunction handleDirection(traceIn, traceOut, coerce, direction) {\n coerce(direction + '.line.color');\n coerce(direction + '.line.width', traceOut.line.width);\n coerce(direction + '.line.dash', traceOut.line.dash);\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/ohlc/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/ohlc/hover.js":
-/*!*********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/ohlc/hover.js ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Fx = __webpack_require__(/*! ../../components/fx */ \"./node_modules/plotly.js/src/components/fx/index.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar fillText = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").fillText;\nvar delta = __webpack_require__(/*! ../../constants/delta.js */ \"./node_modules/plotly.js/src/constants/delta.js\");\n\nvar DIRSYMBOL = {\n increasing: delta.INCREASING.SYMBOL,\n decreasing: delta.DECREASING.SYMBOL\n};\n\nfunction hoverPoints(pointData, xval, yval, hovermode) {\n var cd = pointData.cd;\n var trace = cd[0].trace;\n\n if(trace.hoverlabel.split) {\n return hoverSplit(pointData, xval, yval, hovermode);\n }\n\n return hoverOnPoints(pointData, xval, yval, hovermode);\n}\n\nfunction getClosestPoint(pointData, xval, yval, hovermode) {\n var cd = pointData.cd;\n var xa = pointData.xa;\n var trace = cd[0].trace;\n var t = cd[0].t;\n\n var type = trace.type;\n var minAttr = type === 'ohlc' ? 'l' : 'min';\n var maxAttr = type === 'ohlc' ? 'h' : 'max';\n\n var hoverPseudoDistance, spikePseudoDistance;\n\n // potentially shift xval for grouped candlesticks\n var centerShift = t.bPos || 0;\n var shiftPos = function(di) { return di.pos + centerShift - xval; };\n\n // ohlc and candlestick call displayHalfWidth different things...\n var displayHalfWidth = t.bdPos || t.tickLen;\n var hoverHalfWidth = t.wHover;\n\n // if two figures are overlaying, let the narrowest one win\n var pseudoDistance = Math.min(1, displayHalfWidth / Math.abs(xa.r2c(xa.range[1]) - xa.r2c(xa.range[0])));\n hoverPseudoDistance = pointData.maxHoverDistance - pseudoDistance;\n spikePseudoDistance = pointData.maxSpikeDistance - pseudoDistance;\n\n function dx(di) {\n var pos = shiftPos(di);\n return Fx.inbox(pos - hoverHalfWidth, pos + hoverHalfWidth, hoverPseudoDistance);\n }\n\n function dy(di) {\n var min = di[minAttr];\n var max = di[maxAttr];\n return min === max || Fx.inbox(min - yval, max - yval, hoverPseudoDistance);\n }\n\n function dxy(di) { return (dx(di) + dy(di)) / 2; }\n\n var distfn = Fx.getDistanceFunction(hovermode, dx, dy, dxy);\n Fx.getClosest(cd, distfn, pointData);\n\n if(pointData.index === false) return null;\n\n var di = cd[pointData.index];\n\n if(di.empty) return null;\n\n var dir = di.dir;\n var container = trace[dir];\n var lc = container.line.color;\n\n if(Color.opacity(lc) && container.line.width) pointData.color = lc;\n else pointData.color = container.fillcolor;\n\n pointData.x0 = xa.c2p(di.pos + centerShift - displayHalfWidth, true);\n pointData.x1 = xa.c2p(di.pos + centerShift + displayHalfWidth, true);\n\n pointData.xLabelVal = di.pos;\n\n pointData.spikeDistance = dxy(di) * spikePseudoDistance / hoverPseudoDistance;\n pointData.xSpike = xa.c2p(di.pos, true);\n\n return pointData;\n}\n\nfunction hoverSplit(pointData, xval, yval, hovermode) {\n var cd = pointData.cd;\n var ya = pointData.ya;\n var trace = cd[0].trace;\n var t = cd[0].t;\n var closeBoxData = [];\n\n var closestPoint = getClosestPoint(pointData, xval, yval, hovermode);\n // skip the rest (for this trace) if we didn't find a close point\n if(!closestPoint) return [];\n\n var cdIndex = closestPoint.index;\n var di = cd[cdIndex];\n var hoverinfo = di.hi || trace.hoverinfo;\n var hoverParts = hoverinfo.split('+');\n var isAll = hoverinfo === 'all';\n var hasY = isAll || hoverParts.indexOf('y') !== -1;\n\n // similar to hoverOnPoints, we return nothing\n // if all or y is not present.\n if(!hasY) return [];\n\n var attrs = ['high', 'open', 'close', 'low'];\n\n // several attributes can have the same y-coordinate. We will\n // bunch them together in a single text block. For this, we keep\n // a dictionary mapping y-coord -> point data.\n var usedVals = {};\n\n for(var i = 0; i < attrs.length; i++) {\n var attr = attrs[i];\n\n var val = trace[attr][closestPoint.index];\n var valPx = ya.c2p(val, true);\n var pointData2;\n if(val in usedVals) {\n pointData2 = usedVals[val];\n pointData2.yLabel += '
' + t.labels[attr] + Axes.hoverLabelText(ya, val);\n } else {\n // copy out to a new object for each new y-value to label\n pointData2 = Lib.extendFlat({}, closestPoint);\n\n pointData2.y0 = pointData2.y1 = valPx;\n pointData2.yLabelVal = val;\n pointData2.yLabel = t.labels[attr] + Axes.hoverLabelText(ya, val);\n\n pointData2.name = '';\n\n closeBoxData.push(pointData2);\n usedVals[val] = pointData2;\n }\n }\n\n return closeBoxData;\n}\n\nfunction hoverOnPoints(pointData, xval, yval, hovermode) {\n var cd = pointData.cd;\n var ya = pointData.ya;\n var trace = cd[0].trace;\n var t = cd[0].t;\n\n var closestPoint = getClosestPoint(pointData, xval, yval, hovermode);\n // skip the rest (for this trace) if we didn't find a close point\n if(!closestPoint) return [];\n\n // we don't make a calcdata point if we're missing any piece (x/o/h/l/c)\n // so we need to fix the index here to point to the data arrays\n var cdIndex = closestPoint.index;\n var di = cd[cdIndex];\n var i = closestPoint.index = di.i;\n var dir = di.dir;\n\n function getLabelLine(attr) {\n return t.labels[attr] + Axes.hoverLabelText(ya, trace[attr][i]);\n }\n\n var hoverinfo = di.hi || trace.hoverinfo;\n var hoverParts = hoverinfo.split('+');\n var isAll = hoverinfo === 'all';\n var hasY = isAll || hoverParts.indexOf('y') !== -1;\n var hasText = isAll || hoverParts.indexOf('text') !== -1;\n\n var textParts = hasY ? [\n getLabelLine('open'),\n getLabelLine('high'),\n getLabelLine('low'),\n getLabelLine('close') + ' ' + DIRSYMBOL[dir]\n ] : [];\n if(hasText) fillText(di, trace, textParts);\n\n // don't make .yLabelVal or .text, since we're managing hoverinfo\n // put it all in .extraText\n closestPoint.extraText = textParts.join('
');\n\n // this puts the label *and the spike* at the midpoint of the box, ie\n // halfway between open and close, not between high and low.\n closestPoint.y0 = closestPoint.y1 = ya.c2p(di.yc, true);\n\n return [closestPoint];\n}\n\nmodule.exports = {\n hoverPoints: hoverPoints,\n hoverSplit: hoverSplit,\n hoverOnPoints: hoverOnPoints\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/ohlc/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/ohlc/index.js":
-/*!*********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/ohlc/index.js ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n moduleType: 'trace',\n name: 'ohlc',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['cartesian', 'svg', 'showLegend'],\n meta: {\n \n },\n\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/ohlc/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/ohlc/defaults.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/ohlc/calc.js\").calc,\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/ohlc/plot.js\"),\n style: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/ohlc/style.js\"),\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/ohlc/hover.js\").hoverPoints,\n selectPoints: __webpack_require__(/*! ./select */ \"./node_modules/plotly.js/src/traces/ohlc/select.js\")\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/ohlc/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/ohlc/ohlc_defaults.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/ohlc/ohlc_defaults.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nmodule.exports = function handleOHLC(traceIn, traceOut, coerce, layout) {\n var x = coerce('x');\n var open = coerce('open');\n var high = coerce('high');\n var low = coerce('low');\n var close = coerce('close');\n\n coerce('hoverlabel.split');\n\n var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleTraceDefaults');\n handleCalendarDefaults(traceIn, traceOut, ['x'], layout);\n\n if(!(open && high && low && close)) return;\n\n var len = Math.min(open.length, high.length, low.length, close.length);\n if(x) len = Math.min(len, Lib.minRowLength(x));\n traceOut._length = len;\n\n return len;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/ohlc/ohlc_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/ohlc/plot.js":
-/*!********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/ohlc/plot.js ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nmodule.exports = function plot(gd, plotinfo, cdOHLC, ohlcLayer) {\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n\n Lib.makeTraceGroups(ohlcLayer, cdOHLC, 'trace ohlc').each(function(cd) {\n var plotGroup = d3.select(this);\n var cd0 = cd[0];\n var t = cd0.t;\n var trace = cd0.trace;\n\n if(trace.visible !== true || t.empty) {\n plotGroup.remove();\n return;\n }\n\n var tickLen = t.tickLen;\n\n var paths = plotGroup.selectAll('path').data(Lib.identity);\n\n paths.enter().append('path');\n\n paths.exit().remove();\n\n paths.attr('d', function(d) {\n if(d.empty) return 'M0,0Z';\n\n var x = xa.c2p(d.pos, true);\n var xo = xa.c2p(d.pos - tickLen, true);\n var xc = xa.c2p(d.pos + tickLen, true);\n\n var yo = ya.c2p(d.o, true);\n var yh = ya.c2p(d.h, true);\n var yl = ya.c2p(d.l, true);\n var yc = ya.c2p(d.c, true);\n\n return 'M' + xo + ',' + yo + 'H' + x +\n 'M' + x + ',' + yh + 'V' + yl +\n 'M' + xc + ',' + yc + 'H' + x;\n });\n });\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/ohlc/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/ohlc/select.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/ohlc/select.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function selectPoints(searchInfo, selectionTester) {\n var cd = searchInfo.cd;\n var xa = searchInfo.xaxis;\n var ya = searchInfo.yaxis;\n var selection = [];\n var i;\n // for (potentially grouped) candlesticks\n var posOffset = cd[0].t.bPos || 0;\n\n if(selectionTester === false) {\n // clear selection\n for(i = 0; i < cd.length; i++) {\n cd[i].selected = 0;\n }\n } else {\n for(i = 0; i < cd.length; i++) {\n var di = cd[i];\n\n if(selectionTester.contains([xa.c2p(di.pos + posOffset), ya.c2p(di.yc)], null, di.i, searchInfo)) {\n selection.push({\n pointNumber: di.i,\n x: xa.c2d(di.pos),\n y: ya.c2d(di.yc)\n });\n di.selected = 1;\n } else {\n di.selected = 0;\n }\n }\n }\n\n return selection;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/ohlc/select.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/ohlc/style.js":
-/*!*********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/ohlc/style.js ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\n\nmodule.exports = function style(gd, cd, sel) {\n var s = sel ? sel : d3.select(gd).selectAll('g.ohlclayer').selectAll('g.trace');\n\n s.style('opacity', function(d) {\n return d[0].trace.opacity;\n });\n\n s.each(function(d) {\n var trace = d[0].trace;\n\n d3.select(this).selectAll('path').each(function(di) {\n if(di.empty) return;\n\n var dirLine = trace[di.dir].line;\n d3.select(this)\n .style('fill', 'none')\n .call(Color.stroke, dirLine.color)\n .call(Drawing.dashLine, dirLine.dash, dirLine.width)\n // TODO: custom selection style for OHLC\n .style('opacity', trace.selectedpoints && !di.selected ? 0.3 : 1);\n });\n });\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/ohlc/style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcats/attributes.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcats/attributes.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar fontAttrs = __webpack_require__(/*! ../../plots/font_attributes */ \"./node_modules/plotly.js/src/plots/font_attributes.js\");\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar domainAttrs = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").attributes;\n\nvar line = extendFlat(\n {editType: 'calc'},\n colorScaleAttrs('line', {editTypeOverride: 'calc'}),\n {\n shape: {\n valType: 'enumerated',\n values: ['linear', 'hspline'],\n dflt: 'linear',\n \n editType: 'plot',\n \n },\n\n hovertemplate: hovertemplateAttrs({\n editType: 'plot',\n arrayOk: false\n }, {\n keys: ['count', 'probability'],\n \n })\n }\n);\n\nmodule.exports = {\n domain: domainAttrs({name: 'parcats', trace: true, editType: 'calc'}),\n\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {\n flags: ['count', 'probability'],\n editType: 'plot',\n arrayOk: false\n }),\n hoveron: {\n valType: 'enumerated',\n values: ['category', 'color', 'dimension'],\n dflt: 'category',\n \n editType: 'plot',\n \n },\n hovertemplate: hovertemplateAttrs({\n editType: 'plot',\n arrayOk: false\n }, {\n keys: [\n 'count', 'probability', 'category',\n 'categorycount', 'colorcount', 'bandcolorcount'\n ],\n \n }),\n\n arrangement: {\n valType: 'enumerated',\n values: ['perpendicular', 'freeform', 'fixed'],\n dflt: 'perpendicular',\n \n editType: 'plot',\n \n },\n bundlecolors: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'plot',\n \n },\n sortpaths: {\n valType: 'enumerated',\n values: ['forward', 'backward'],\n dflt: 'forward',\n \n editType: 'plot',\n \n },\n labelfont: fontAttrs({\n editType: 'calc',\n \n }),\n\n tickfont: fontAttrs({\n editType: 'calc',\n \n }),\n\n dimensions: {\n _isLinkedToArray: 'dimension',\n label: {\n valType: 'string',\n \n editType: 'calc',\n \n },\n categoryorder: {\n valType: 'enumerated',\n values: [\n 'trace', 'category ascending', 'category descending', 'array'\n ],\n dflt: 'trace',\n \n editType: 'calc',\n \n },\n categoryarray: {\n valType: 'data_array',\n \n editType: 'calc',\n \n },\n ticktext: {\n valType: 'data_array',\n \n editType: 'calc',\n \n },\n values: {\n valType: 'data_array',\n \n dflt: [],\n editType: 'calc',\n \n },\n displayindex: {\n valType: 'integer',\n \n editType: 'calc',\n \n },\n editType: 'calc',\n \n visible: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'calc',\n \n }\n },\n\n line: line,\n counts: {\n valType: 'number',\n min: 0,\n dflt: 1,\n arrayOk: true,\n \n editType: 'calc',\n \n },\n\n // Hide unsupported top-level properties from plot-schema\n customdata: undefined,\n hoverlabel: undefined,\n ids: undefined,\n legendgroup: undefined,\n opacity: undefined,\n selectedpoints: undefined,\n showlegend: undefined\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcats/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcats/base_plot.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcats/base_plot.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar getModuleCalcData = __webpack_require__(/*! ../../plots/get_data */ \"./node_modules/plotly.js/src/plots/get_data.js\").getModuleCalcData;\nvar parcatsPlot = __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/parcats/plot.js\");\n\nvar PARCATS = 'parcats';\nexports.name = PARCATS;\n\nexports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) {\n var cdModuleAndOthers = getModuleCalcData(gd.calcdata, PARCATS);\n\n if(cdModuleAndOthers.length) {\n var calcData = cdModuleAndOthers[0];\n parcatsPlot(gd, calcData, transitionOpts, makeOnCompleteCallback);\n }\n};\n\nexports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {\n var hadTable = (oldFullLayout._has && oldFullLayout._has('parcats'));\n var hasTable = (newFullLayout._has && newFullLayout._has('parcats'));\n\n if(hadTable && !hasTable) {\n oldFullLayout._paperdiv.selectAll('.parcats').remove();\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcats/base_plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcats/calc.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcats/calc.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n// Requirements\n// ============\nvar wrap = __webpack_require__(/*! ../../lib/gup */ \"./node_modules/plotly.js/src/lib/gup.js\").wrap;\nvar hasColorscale = __webpack_require__(/*! ../../components/colorscale/helpers */ \"./node_modules/plotly.js/src/components/colorscale/helpers.js\").hasColorscale;\nvar colorscaleCalc = __webpack_require__(/*! ../../components/colorscale/calc */ \"./node_modules/plotly.js/src/components/colorscale/calc.js\");\nvar filterUnique = __webpack_require__(/*! ../../lib/filter_unique.js */ \"./node_modules/plotly.js/src/lib/filter_unique.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\n/**\n * Create a wrapped ParcatsModel object from trace\n *\n * Note: trace defaults have already been applied\n * @param {Object} gd\n * @param {Object} trace\n * @return {Array.
}\n */\nmodule.exports = function calc(gd, trace) {\n var visibleDims = Lib.filterVisible(trace.dimensions);\n\n if(visibleDims.length === 0) return [];\n\n var uniqueInfoDims = visibleDims.map(function(dim) {\n var categoryValues;\n if(dim.categoryorder === 'trace') {\n // Use order of first occurrence in trace\n categoryValues = null;\n } else if(dim.categoryorder === 'array') {\n // Use categories specified in `categoryarray` first,\n // then add extra to the end in trace order\n categoryValues = dim.categoryarray;\n } else {\n // Get all categories up front so we can order them\n // Should we check for numbers as sort numerically?\n categoryValues = filterUnique(dim.values).sort();\n if(dim.categoryorder === 'category descending') {\n categoryValues = categoryValues.reverse();\n }\n }\n return getUniqueInfo(dim.values, categoryValues);\n });\n\n var counts,\n count,\n totalCount;\n if(Lib.isArrayOrTypedArray(trace.counts)) {\n counts = trace.counts;\n } else {\n counts = [trace.counts];\n }\n\n validateDimensionDisplayInds(visibleDims);\n\n visibleDims.forEach(function(dim, dimInd) {\n validateCategoryProperties(dim, uniqueInfoDims[dimInd]);\n });\n\n // Handle path colors\n // ------------------\n var line = trace.line;\n var markerColorscale;\n\n // Process colorscale\n if(line) {\n if(hasColorscale(trace, 'line')) {\n colorscaleCalc(gd, trace, {\n vals: trace.line.color,\n containerStr: 'line',\n cLetter: 'c'\n });\n }\n markerColorscale = Drawing.tryColorscale(line);\n } else {\n markerColorscale = Lib.identity;\n }\n\n // Build color generation function\n function getMarkerColorInfo(index) {\n var value, rawColor;\n if(Lib.isArrayOrTypedArray(line.color)) {\n value = line.color[index % line.color.length];\n rawColor = value;\n } else {\n value = line.color;\n }\n\n return {color: markerColorscale(value), rawColor: rawColor};\n }\n\n // Number of values and counts\n // ---------------------------\n var numValues = visibleDims[0].values.length;\n\n // Build path info\n // ---------------\n // Mapping from category inds to PathModel objects\n var pathModels = {};\n\n // Category inds array for each dimension\n var categoryIndsDims = uniqueInfoDims.map(function(di) {return di.inds;});\n\n // Initialize total count\n totalCount = 0;\n var valueInd;\n var d;\n\n for(valueInd = 0; valueInd < numValues; valueInd++) {\n // Category inds for this input value across dimensions\n var categoryIndsPath = [];\n for(d = 0; d < categoryIndsDims.length; d++) {\n categoryIndsPath.push(categoryIndsDims[d][valueInd]);\n }\n\n // Count\n count = counts[valueInd % counts.length];\n\n // Update total count\n totalCount += count;\n\n // Path color\n var pathColorInfo = getMarkerColorInfo(valueInd);\n\n // path key\n var pathKey = categoryIndsPath + '-' + pathColorInfo.rawColor;\n\n // Create / Update PathModel\n if(pathModels[pathKey] === undefined) {\n pathModels[pathKey] = createPathModel(categoryIndsPath,\n pathColorInfo.color,\n pathColorInfo.rawColor);\n }\n updatePathModel(pathModels[pathKey], valueInd, count);\n }\n\n var dimensionModels = visibleDims.map(function(di, i) {\n return createDimensionModel(i, di._index, di._displayindex, di.label, totalCount);\n });\n\n\n for(valueInd = 0; valueInd < numValues; valueInd++) {\n count = counts[valueInd % counts.length];\n\n for(d = 0; d < dimensionModels.length; d++) {\n var containerInd = dimensionModels[d].containerInd;\n var catInd = uniqueInfoDims[d].inds[valueInd];\n var cats = dimensionModels[d].categories;\n\n if(cats[catInd] === undefined) {\n var catValue = trace.dimensions[containerInd]._categoryarray[catInd];\n var catLabel = trace.dimensions[containerInd]._ticktext[catInd];\n cats[catInd] = createCategoryModel(d, catInd, catValue, catLabel);\n }\n\n updateCategoryModel(cats[catInd], valueInd, count);\n }\n }\n\n // Compute unique\n return wrap(createParcatsModel(dimensionModels, pathModels, totalCount));\n};\n\n// Models\n// ======\n\n// Parcats Model\n// -------------\n/**\n * @typedef {Object} ParcatsModel\n * Object containing calculated information about a parcats trace\n *\n * @property {Array.} dimensions\n * Array of dimension models\n * @property {Object.} paths\n * Dictionary from category inds string (e.g. \"1,2,1,1\") to path model\n * @property {Number} maxCats\n * The maximum number of categories of any dimension in the diagram\n * @property {Number} count\n * Total number of input values\n * @property {Object} trace\n */\n\n/**\n * Create and new ParcatsModel object\n * @param {Array.} dimensions\n * @param {Object.} paths\n * @param {Number} count\n * @return {ParcatsModel}\n */\nfunction createParcatsModel(dimensions, paths, count) {\n var maxCats = dimensions\n .map(function(d) {return d.categories.length;})\n .reduce(function(v1, v2) {return Math.max(v1, v2);});\n return {dimensions: dimensions, paths: paths, trace: undefined, maxCats: maxCats, count: count};\n}\n\n// Dimension Model\n// ---------------\n/**\n * @typedef {Object} DimensionModel\n * Object containing calculated information about a single dimension\n *\n * @property {Number} dimensionInd\n * The index of this dimension among the *visible* dimensions\n * @property {Number} containerInd\n * The index of this dimension in the original dimensions container,\n * irrespective of dimension visibility\n * @property {Number} displayInd\n * The display index of this dimension (where 0 is the left most dimension)\n * @property {String} dimensionLabel\n * The label of this dimension\n * @property {Number} count\n * Total number of input values\n * @property {Array.} categories\n * @property {Number|null} dragX\n * The x position of dimension that is currently being dragged. null if not being dragged\n */\n\n/**\n * Create and new DimensionModel object with an empty categories array\n * @param {Number} dimensionInd\n * @param {Number} containerInd\n * @param {Number} displayInd\n * @param {String} dimensionLabel\n * @param {Number} count\n * Total number of input values\n * @return {DimensionModel}\n */\nfunction createDimensionModel(dimensionInd, containerInd, displayInd, dimensionLabel, count) {\n return {\n dimensionInd: dimensionInd,\n containerInd: containerInd,\n displayInd: displayInd,\n dimensionLabel: dimensionLabel,\n count: count,\n categories: [],\n dragX: null\n };\n}\n\n// Category Model\n// --------------\n/**\n * @typedef {Object} CategoryModel\n * Object containing calculated information about a single category.\n *\n * @property {Number} dimensionInd\n * The index of this categories dimension\n * @property {Number} categoryInd\n * The index of this category\n * @property {Number} displayInd\n * The display index of this category (where 0 is the topmost category)\n * @property {String} categoryLabel\n * The name of this category\n * @property categoryValue: Raw value of the category\n * @property {Array} valueInds\n * Array of indices (into the original value array) of all samples in this category\n * @property {Number} count\n * The number of elements from the original array in this path\n * @property {Number|null} dragY\n * The y position of category that is currently being dragged. null if not being dragged\n */\n\n/**\n * Create and return a new CategoryModel object\n * @param {Number} dimensionInd\n * @param {Number} categoryInd\n * The display index of this category (where 0 is the topmost category)\n * @param {String} categoryValue\n * @param {String} categoryLabel\n * @return {CategoryModel}\n */\nfunction createCategoryModel(dimensionInd, categoryInd, categoryValue, categoryLabel) {\n return {\n dimensionInd: dimensionInd,\n categoryInd: categoryInd,\n categoryValue: categoryValue,\n displayInd: categoryInd,\n categoryLabel: categoryLabel,\n valueInds: [],\n count: 0,\n dragY: null\n };\n}\n\n/**\n * Update a CategoryModel object with a new value index\n * Note: The calling parameter is modified in place.\n *\n * @param {CategoryModel} categoryModel\n * @param {Number} valueInd\n * @param {Number} count\n */\nfunction updateCategoryModel(categoryModel, valueInd, count) {\n categoryModel.valueInds.push(valueInd);\n categoryModel.count += count;\n}\n\n\n// Path Model\n// ----------\n/**\n * @typedef {Object} PathModel\n * Object containing calculated information about the samples in a path.\n *\n * @property {Array} categoryInds\n * Array of category indices for each dimension (length `numDimensions`)\n * @param {String} pathColor\n * Color of this path. (Note: Any colorscaling has already taken place)\n * @property {Array} valueInds\n * Array of indices (into the original value array) of all samples in this path\n * @property {Number} count\n * The number of elements from the original array in this path\n * @property {String} color\n * The path's color (ass CSS color string)\n * @property rawColor\n * The raw color value specified by the user. May be a CSS color string or a Number\n */\n\n/**\n * Create and return a new PathModel object\n * @param {Array} categoryInds\n * @param color\n * @param rawColor\n * @return {PathModel}\n */\nfunction createPathModel(categoryInds, color, rawColor) {\n return {\n categoryInds: categoryInds,\n color: color,\n rawColor: rawColor,\n valueInds: [],\n count: 0\n };\n}\n\n/**\n * Update a PathModel object with a new value index\n * Note: The calling parameter is modified in place.\n *\n * @param {PathModel} pathModel\n * @param {Number} valueInd\n * @param {Number} count\n */\nfunction updatePathModel(pathModel, valueInd, count) {\n pathModel.valueInds.push(valueInd);\n pathModel.count += count;\n}\n\n// Unique calculations\n// ===================\n/**\n * @typedef {Object} UniqueInfo\n * Object containing information about the unique values of an input array\n *\n * @property {Array} uniqueValues\n * The unique values in the input array\n * @property {Array} uniqueCounts\n * The number of times each entry in uniqueValues occurs in input array.\n * This has the same length as `uniqueValues`\n * @property {Array} inds\n * Indices into uniqueValues that would reproduce original input array\n */\n\n/**\n * Compute unique value information for an array\n *\n * IMPORTANT: Note that values are considered unique\n * if their string representations are unique.\n *\n * @param {Array} values\n * @param {Array|undefined} uniqueValues\n * Array of expected unique values. The uniqueValues property of the resulting UniqueInfo object will begin with\n * these entries. Entries are included even if there are zero occurrences in the values array. Entries found in\n * the values array that are not present in uniqueValues will be included at the end of the array in the\n * UniqueInfo object.\n * @return {UniqueInfo}\n */\nfunction getUniqueInfo(values, uniqueValues) {\n // Initialize uniqueValues if not specified\n if(uniqueValues === undefined || uniqueValues === null) {\n uniqueValues = [];\n } else {\n // Shallow copy so append below doesn't alter input array\n uniqueValues = uniqueValues.map(function(e) {return e;});\n }\n\n // Initialize Variables\n var uniqueValueCounts = {};\n var uniqueValueInds = {};\n var inds = [];\n\n // Initialize uniqueValueCounts and\n uniqueValues.forEach(function(uniqueVal, valInd) {\n uniqueValueCounts[uniqueVal] = 0;\n uniqueValueInds[uniqueVal] = valInd;\n });\n\n // Compute the necessary unique info in a single pass\n for(var i = 0; i < values.length; i++) {\n var item = values[i];\n var itemInd;\n\n if(uniqueValueCounts[item] === undefined) {\n // This item has a previously unseen value\n uniqueValueCounts[item] = 1;\n itemInd = uniqueValues.push(item) - 1;\n uniqueValueInds[item] = itemInd;\n } else {\n // Increment count for this item\n uniqueValueCounts[item]++;\n itemInd = uniqueValueInds[item];\n }\n inds.push(itemInd);\n }\n\n // Build UniqueInfo\n var uniqueCounts = uniqueValues.map(function(v) { return uniqueValueCounts[v]; });\n\n return {\n uniqueValues: uniqueValues,\n uniqueCounts: uniqueCounts,\n inds: inds\n };\n}\n\n\n/**\n * Validate the requested display order for the dimensions.\n * If the display order is a permutation of 0 through dimensions.length - 1, link to _displayindex\n * Otherwise, replace the display order with the dimension order\n * @param {Object} trace\n */\nfunction validateDimensionDisplayInds(visibleDims) {\n var displayInds = visibleDims.map(function(d) { return d.displayindex; });\n var i;\n\n if(isRangePermutation(displayInds)) {\n for(i = 0; i < visibleDims.length; i++) {\n visibleDims[i]._displayindex = visibleDims[i].displayindex;\n }\n } else {\n for(i = 0; i < visibleDims.length; i++) {\n visibleDims[i]._displayindex = i;\n }\n }\n}\n\n\n/**\n * Update category properties based on the unique values found for this dimension\n * @param {Object} dim\n * @param {UniqueInfo} uniqueInfoDim\n */\nfunction validateCategoryProperties(dim, uniqueInfoDim) {\n // Update categoryarray\n dim._categoryarray = uniqueInfoDim.uniqueValues;\n\n // Handle ticktext\n if(dim.ticktext === null || dim.ticktext === undefined) {\n dim._ticktext = [];\n } else {\n // Shallow copy to avoid modifying input array\n dim._ticktext = dim.ticktext.slice();\n }\n\n // Extend ticktext with elements from uniqueInfoDim.uniqueValues\n for(var i = dim._ticktext.length; i < uniqueInfoDim.uniqueValues.length; i++) {\n dim._ticktext.push(uniqueInfoDim.uniqueValues[i]);\n }\n}\n\n/**\n * Determine whether an array contains a permutation of the integers from 0 to the array's length - 1\n * @param {Array} inds\n * @return {boolean}\n */\nfunction isRangePermutation(inds) {\n var indsSpecified = new Array(inds.length);\n\n for(var i = 0; i < inds.length; i++) {\n // Check for out of bounds\n if(inds[i] < 0 || inds[i] >= inds.length) {\n return false;\n }\n\n // Check for collisions with already specified index\n if(indsSpecified[inds[i]] !== undefined) {\n return false;\n }\n\n indsSpecified[inds[i]] = true;\n }\n\n // Nothing out of bounds and no collisions. We have a permutation\n return true;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcats/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcats/defaults.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcats/defaults.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar hasColorscale = __webpack_require__(/*! ../../components/colorscale/helpers */ \"./node_modules/plotly.js/src/components/colorscale/helpers.js\").hasColorscale;\nvar colorscaleDefaults = __webpack_require__(/*! ../../components/colorscale/defaults */ \"./node_modules/plotly.js/src/components/colorscale/defaults.js\");\nvar handleDomainDefaults = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").defaults;\nvar handleArrayContainerDefaults = __webpack_require__(/*! ../../plots/array_container_defaults */ \"./node_modules/plotly.js/src/plots/array_container_defaults.js\");\n\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/parcats/attributes.js\");\nvar mergeLength = __webpack_require__(/*! ../parcoords/merge_length */ \"./node_modules/plotly.js/src/traces/parcoords/merge_length.js\");\n\nfunction handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce) {\n coerce('line.shape');\n coerce('line.hovertemplate');\n\n var lineColor = coerce('line.color', layout.colorway[0]);\n if(hasColorscale(traceIn, 'line') && Lib.isArrayOrTypedArray(lineColor)) {\n if(lineColor.length) {\n coerce('line.colorscale');\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: 'line.', cLetter: 'c'});\n return lineColor.length;\n } else {\n traceOut.line.color = defaultColor;\n }\n }\n return Infinity;\n}\n\nfunction dimensionDefaults(dimensionIn, dimensionOut) {\n function coerce(attr, dflt) {\n return Lib.coerce(dimensionIn, dimensionOut, attributes.dimensions, attr, dflt);\n }\n\n var values = coerce('values');\n var visible = coerce('visible');\n if(!(values && values.length)) {\n visible = dimensionOut.visible = false;\n }\n\n if(visible) {\n // Dimension level\n coerce('label');\n coerce('displayindex', dimensionOut._index);\n\n // Category level\n var arrayIn = dimensionIn.categoryarray;\n var isValidArray = (Array.isArray(arrayIn) && arrayIn.length > 0);\n\n var orderDefault;\n if(isValidArray) orderDefault = 'array';\n var order = coerce('categoryorder', orderDefault);\n\n // coerce 'categoryarray' only in array order case\n if(order === 'array') {\n coerce('categoryarray');\n coerce('ticktext');\n } else {\n delete dimensionIn.categoryarray;\n delete dimensionIn.ticktext;\n }\n\n // cannot set 'categoryorder' to 'array' with an invalid 'categoryarray'\n if(!isValidArray && order === 'array') {\n dimensionOut.categoryorder = 'trace';\n }\n }\n}\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var dimensions = handleArrayContainerDefaults(traceIn, traceOut, {\n name: 'dimensions',\n handleItemDefaults: dimensionDefaults\n });\n\n var len = handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);\n\n handleDomainDefaults(traceOut, layout, coerce);\n\n if(!Array.isArray(dimensions) || !dimensions.length) {\n traceOut.visible = false;\n }\n\n mergeLength(traceOut, dimensions, 'values', len);\n\n coerce('hoveron');\n coerce('hovertemplate');\n coerce('arrangement');\n coerce('bundlecolors');\n coerce('sortpaths');\n coerce('counts');\n\n var labelfontDflt = {\n family: layout.font.family,\n size: Math.round(layout.font.size),\n color: layout.font.color\n };\n\n Lib.coerceFont(coerce, 'labelfont', labelfontDflt);\n\n var categoryfontDefault = {\n family: layout.font.family,\n size: Math.round(layout.font.size / 1.2),\n color: layout.font.color\n };\n\n Lib.coerceFont(coerce, 'tickfont', categoryfontDefault);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcats/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcats/index.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcats/index.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/parcats/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/parcats/defaults.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/parcats/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/parcats/plot.js\"),\n colorbar: {\n container: 'line',\n min: 'cmin',\n max: 'cmax'\n },\n\n moduleType: 'trace',\n name: 'parcats',\n basePlotModule: __webpack_require__(/*! ./base_plot */ \"./node_modules/plotly.js/src/traces/parcats/base_plot.js\"),\n categories: ['noOpacity'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcats/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcats/parcats.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcats/parcats.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Plotly = __webpack_require__(/*! ../../plot_api/plot_api */ \"./node_modules/plotly.js/src/plot_api/plot_api.js\");\nvar Fx = __webpack_require__(/*! ../../components/fx */ \"./node_modules/plotly.js/src/components/fx/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar tinycolor = __webpack_require__(/*! tinycolor2 */ \"./node_modules/tinycolor2/tinycolor.js\");\nvar svgTextUtils = __webpack_require__(/*! ../../lib/svg_text_utils */ \"./node_modules/plotly.js/src/lib/svg_text_utils.js\");\n\nfunction performPlot(parcatsModels, graphDiv, layout, svg) {\n var viewModels = parcatsModels.map(createParcatsViewModel.bind(0, graphDiv, layout));\n\n // Get (potentially empty) parcatslayer selection with bound data to single element array\n var layerSelection = svg.selectAll('g.parcatslayer').data([null]);\n\n // Initialize single parcatslayer group if it doesn't exist\n layerSelection.enter()\n .append('g')\n .attr('class', 'parcatslayer')\n .style('pointer-events', 'all');\n\n // Bind data to children of layerSelection and get reference to traceSelection\n var traceSelection = layerSelection\n .selectAll('g.trace.parcats')\n .data(viewModels, key);\n\n // Initialize group for each trace/dimensions\n var traceEnter = traceSelection.enter()\n .append('g')\n .attr('class', 'trace parcats');\n\n // Update properties for each trace\n traceSelection\n .attr('transform', function(d) {\n return 'translate(' + d.x + ', ' + d.y + ')';\n });\n\n // Initialize paths group\n traceEnter\n .append('g')\n .attr('class', 'paths');\n\n // Update paths transform\n var pathsSelection = traceSelection\n .select('g.paths');\n\n // Get paths selection\n var pathSelection = pathsSelection\n .selectAll('path.path')\n .data(function(d) {\n return d.paths;\n }, key);\n\n // Update existing path colors\n pathSelection\n .attr('fill', function(d) {\n return d.model.color;\n });\n\n // Create paths\n var pathSelectionEnter = pathSelection\n .enter()\n .append('path')\n .attr('class', 'path')\n .attr('stroke-opacity', 0)\n .attr('fill', function(d) {\n return d.model.color;\n })\n .attr('fill-opacity', 0);\n\n stylePathsNoHover(pathSelectionEnter);\n\n // Set path geometry\n pathSelection\n .attr('d', function(d) {\n return d.svgD;\n });\n\n // sort paths\n if(!pathSelectionEnter.empty()) {\n // Only sort paths if there has been a change.\n // Otherwise paths are already sorted or a hover operation may be in progress\n pathSelection.sort(compareRawColor);\n }\n\n // Remove any old paths\n pathSelection.exit().remove();\n\n // Path hover\n pathSelection\n .on('mouseover', mouseoverPath)\n .on('mouseout', mouseoutPath)\n .on('click', clickPath);\n\n // Initialize dimensions group\n traceEnter.append('g').attr('class', 'dimensions');\n\n // Update dimensions transform\n var dimensionsSelection = traceSelection\n .select('g.dimensions');\n\n // Get dimension selection\n var dimensionSelection = dimensionsSelection\n .selectAll('g.dimension')\n .data(function(d) {\n return d.dimensions;\n }, key);\n\n // Create dimension groups\n dimensionSelection.enter()\n .append('g')\n .attr('class', 'dimension');\n\n // Update dimension group transforms\n dimensionSelection.attr('transform', function(d) {\n return 'translate(' + d.x + ', 0)';\n });\n\n // Remove any old dimensions\n dimensionSelection.exit().remove();\n\n // Get category selection\n var categorySelection = dimensionSelection\n .selectAll('g.category')\n .data(function(d) {\n return d.categories;\n }, key);\n\n // Initialize category groups\n var categoryGroupEnterSelection = categorySelection\n .enter()\n .append('g')\n .attr('class', 'category');\n\n // Update category transforms\n categorySelection\n .attr('transform', function(d) {\n return 'translate(0, ' + d.y + ')';\n });\n\n\n // Initialize rectangle\n categoryGroupEnterSelection\n .append('rect')\n .attr('class', 'catrect')\n .attr('pointer-events', 'none');\n\n\n // Update rectangle\n categorySelection.select('rect.catrect')\n .attr('fill', 'none')\n .attr('width', function(d) {\n return d.width;\n })\n .attr('height', function(d) {\n return d.height;\n });\n\n styleCategoriesNoHover(categoryGroupEnterSelection);\n\n // Initialize color band rects\n var bandSelection = categorySelection\n .selectAll('rect.bandrect')\n .data(\n /** @param {CategoryViewModel} catViewModel*/\n function(catViewModel) {\n return catViewModel.bands;\n }, key);\n\n // Raise all update bands to the top so that fading enter/exit bands will be behind\n bandSelection.each(function() {Lib.raiseToTop(this);});\n\n // Update band color\n bandSelection\n .attr('fill', function(d) {\n return d.color;\n });\n\n var bandsSelectionEnter = bandSelection.enter()\n .append('rect')\n .attr('class', 'bandrect')\n .attr('stroke-opacity', 0)\n .attr('fill', function(d) {\n return d.color;\n })\n .attr('fill-opacity', 0);\n\n bandSelection\n .attr('fill', function(d) {\n return d.color;\n })\n .attr('width', function(d) {\n return d.width;\n })\n .attr('height', function(d) {\n return d.height;\n })\n .attr('y', function(d) {\n return d.y;\n })\n .attr('cursor',\n /** @param {CategoryBandViewModel} bandModel*/\n function(bandModel) {\n if(bandModel.parcatsViewModel.arrangement === 'fixed') {\n return 'default';\n } else if(bandModel.parcatsViewModel.arrangement === 'perpendicular') {\n return 'ns-resize';\n } else {\n return 'move';\n }\n });\n\n styleBandsNoHover(bandsSelectionEnter);\n\n bandSelection.exit().remove();\n\n // Initialize category label\n categoryGroupEnterSelection\n .append('text')\n .attr('class', 'catlabel')\n .attr('pointer-events', 'none');\n\n var paperColor = graphDiv._fullLayout.paper_bgcolor;\n\n // Update category label\n categorySelection.select('text.catlabel')\n .attr('text-anchor',\n function(d) {\n if(catInRightDim(d)) {\n // Place label to the right of category\n return 'start';\n } else {\n // Place label to the left of category\n return 'end';\n }\n })\n .attr('alignment-baseline', 'middle')\n\n .style('text-shadow',\n paperColor + ' -1px 1px 2px, ' +\n paperColor + ' 1px 1px 2px, ' +\n paperColor + ' 1px -1px 2px, ' +\n paperColor + ' -1px -1px 2px')\n .style('fill', 'rgb(0, 0, 0)')\n .attr('x',\n function(d) {\n if(catInRightDim(d)) {\n // Place label to the right of category\n return d.width + 5;\n } else {\n // Place label to the left of category\n return -5;\n }\n })\n .attr('y', function(d) {\n return d.height / 2;\n })\n .text(function(d) {\n return d.model.categoryLabel;\n })\n .each(\n /** @param {CategoryViewModel} catModel*/\n function(catModel) {\n Drawing.font(d3.select(this), catModel.parcatsViewModel.categorylabelfont);\n svgTextUtils.convertToTspans(d3.select(this), graphDiv);\n });\n\n // Initialize dimension label\n categoryGroupEnterSelection\n .append('text')\n .attr('class', 'dimlabel');\n\n // Update dimension label\n categorySelection.select('text.dimlabel')\n .attr('text-anchor', 'middle')\n .attr('alignment-baseline', 'baseline')\n .attr('cursor',\n /** @param {CategoryViewModel} catModel*/\n function(catModel) {\n if(catModel.parcatsViewModel.arrangement === 'fixed') {\n return 'default';\n } else {\n return 'ew-resize';\n }\n })\n .attr('x', function(d) {\n return d.width / 2;\n })\n .attr('y', -5)\n .text(function(d, i) {\n if(i === 0) {\n // Add dimension label above topmost category\n return d.parcatsViewModel.model.dimensions[d.model.dimensionInd].dimensionLabel;\n } else {\n return null;\n }\n })\n .each(\n /** @param {CategoryViewModel} catModel*/\n function(catModel) {\n Drawing.font(d3.select(this), catModel.parcatsViewModel.labelfont);\n });\n\n // Category hover\n // categorySelection.select('rect.catrect')\n categorySelection.selectAll('rect.bandrect')\n .on('mouseover', mouseoverCategoryBand)\n .on('mouseout', mouseoutCategory);\n\n // Remove unused categories\n categorySelection.exit().remove();\n\n // Setup drag\n dimensionSelection.call(d3.behavior.drag()\n .origin(function(d) {\n return {x: d.x, y: 0};\n })\n .on('dragstart', dragDimensionStart)\n .on('drag', dragDimension)\n .on('dragend', dragDimensionEnd));\n\n\n // Save off selections to view models\n traceSelection.each(function(d) {\n d.traceSelection = d3.select(this);\n d.pathSelection = d3.select(this).selectAll('g.paths').selectAll('path.path');\n d.dimensionSelection = d3.select(this).selectAll('g.dimensions').selectAll('g.dimension');\n });\n\n // Remove any orphan traces\n traceSelection.exit().remove();\n}\n\n/**\n * Create / update parcat traces\n *\n * @param {Object} graphDiv\n * @param {Object} svg\n * @param {Array.} parcatsModels\n * @param {Layout} layout\n */\nmodule.exports = function(graphDiv, svg, parcatsModels, layout) {\n performPlot(parcatsModels, graphDiv, layout, svg);\n};\n\n/**\n * Function the returns the key property of an object for use with as D3 join function\n * @param d\n */\nfunction key(d) {\n return d.key;\n}\n\n /** True if a category view model is in the right-most display dimension\n * @param {CategoryViewModel} d */\nfunction catInRightDim(d) {\n var numDims = d.parcatsViewModel.dimensions.length;\n var leftDimInd = d.parcatsViewModel.dimensions[numDims - 1].model.dimensionInd;\n return d.model.dimensionInd === leftDimInd;\n}\n\n/**\n * @param {PathViewModel} a\n * @param {PathViewModel} b\n */\nfunction compareRawColor(a, b) {\n if(a.model.rawColor > b.model.rawColor) {\n return 1;\n } else if(a.model.rawColor < b.model.rawColor) {\n return -1;\n } else {\n return 0;\n }\n}\n\n/**\n * Handle path mouseover\n * @param {PathViewModel} d\n */\nfunction mouseoverPath(d) {\n if(!d.parcatsViewModel.dragDimension) {\n // We're not currently dragging\n\n if(d.parcatsViewModel.hoverinfoItems.indexOf('skip') === -1) {\n // hoverinfo is not skip, so we at least style the paths and emit interaction events\n\n // Raise path to top\n Lib.raiseToTop(this);\n\n stylePathsHover(d3.select(this));\n\n // Emit hover event\n var points = buildPointsArrayForPath(d);\n var constraints = buildConstraintsForPath(d);\n d.parcatsViewModel.graphDiv.emit('plotly_hover', {\n points: points, event: d3.event, constraints: constraints\n });\n\n // Handle hover label\n if(d.parcatsViewModel.hoverinfoItems.indexOf('none') === -1) {\n // hoverinfo is a combination of 'count' and 'probability'\n\n // Mouse\n var hoverX = d3.mouse(this)[0];\n\n // Label\n var gd = d.parcatsViewModel.graphDiv;\n var trace = d.parcatsViewModel.trace;\n var fullLayout = gd._fullLayout;\n var rootBBox = fullLayout._paperdiv.node().getBoundingClientRect();\n var graphDivBBox = d.parcatsViewModel.graphDiv.getBoundingClientRect();\n\n // Find path center in path coordinates\n var pathCenterX,\n pathCenterY,\n dimInd;\n\n for(dimInd = 0; dimInd < (d.leftXs.length - 1); dimInd++) {\n if(d.leftXs[dimInd] + d.dimWidths[dimInd] - 2 <= hoverX && hoverX <= d.leftXs[dimInd + 1] + 2) {\n var leftDim = d.parcatsViewModel.dimensions[dimInd];\n var rightDim = d.parcatsViewModel.dimensions[dimInd + 1];\n pathCenterX = (leftDim.x + leftDim.width + rightDim.x) / 2;\n pathCenterY = (d.topYs[dimInd] + d.topYs[dimInd + 1] + d.height) / 2;\n break;\n }\n }\n\n // Find path center in root coordinates\n var hoverCenterX = d.parcatsViewModel.x + pathCenterX;\n var hoverCenterY = d.parcatsViewModel.y + pathCenterY;\n\n var textColor = tinycolor.mostReadable(d.model.color, ['black', 'white']);\n\n var count = d.model.count;\n var prob = count / d.parcatsViewModel.model.count;\n var labels = {\n countLabel: count,\n probabilityLabel: prob.toFixed(3)\n };\n\n // Build hover text\n var hovertextParts = [];\n if(d.parcatsViewModel.hoverinfoItems.indexOf('count') !== -1) {\n hovertextParts.push(['Count:', labels.countLabel].join(' '));\n }\n if(d.parcatsViewModel.hoverinfoItems.indexOf('probability') !== -1) {\n hovertextParts.push(['P:', labels.probabilityLabel].join(' '));\n }\n\n var hovertext = hovertextParts.join('
');\n var mouseX = d3.mouse(gd)[0];\n\n Fx.loneHover({\n trace: trace,\n x: hoverCenterX - rootBBox.left + graphDivBBox.left,\n y: hoverCenterY - rootBBox.top + graphDivBBox.top,\n text: hovertext,\n color: d.model.color,\n borderColor: 'black',\n fontFamily: 'Monaco, \"Courier New\", monospace',\n fontSize: 10,\n fontColor: textColor,\n idealAlign: mouseX < hoverCenterX ? 'right' : 'left',\n hovertemplate: (trace.line || {}).hovertemplate,\n hovertemplateLabels: labels,\n eventData: [{\n data: trace._input,\n fullData: trace,\n count: count,\n probability: prob\n }]\n }, {\n container: fullLayout._hoverlayer.node(),\n outerContainer: fullLayout._paper.node(),\n gd: gd\n });\n }\n }\n }\n}\n\n/**\n * Handle path mouseout\n * @param {PathViewModel} d\n */\nfunction mouseoutPath(d) {\n if(!d.parcatsViewModel.dragDimension) {\n // We're not currently dragging\n stylePathsNoHover(d3.select(this));\n\n // Remove and hover label\n Fx.loneUnhover(d.parcatsViewModel.graphDiv._fullLayout._hoverlayer.node());\n\n // Restore path order\n d.parcatsViewModel.pathSelection.sort(compareRawColor);\n\n // Emit unhover event\n if(d.parcatsViewModel.hoverinfoItems.indexOf('skip') === -1) {\n var points = buildPointsArrayForPath(d);\n var constraints = buildConstraintsForPath(d);\n d.parcatsViewModel.graphDiv.emit('plotly_unhover', {\n points: points, event: d3.event, constraints: constraints\n });\n }\n }\n}\n\n/**\n * Build array of point objects for a path\n *\n * For use in click/hover events\n * @param {PathViewModel} d\n */\nfunction buildPointsArrayForPath(d) {\n var points = [];\n var curveNumber = getTraceIndex(d.parcatsViewModel);\n\n for(var i = 0; i < d.model.valueInds.length; i++) {\n var pointNumber = d.model.valueInds[i];\n points.push({\n curveNumber: curveNumber,\n pointNumber: pointNumber\n });\n }\n return points;\n}\n\n/**\n * Build constraints object for a path\n *\n * For use in click/hover events\n * @param {PathViewModel} d\n */\nfunction buildConstraintsForPath(d) {\n var constraints = {};\n var dimensions = d.parcatsViewModel.model.dimensions;\n\n // dimensions\n for(var i = 0; i < dimensions.length; i++) {\n var dimension = dimensions[i];\n var category = dimension.categories[d.model.categoryInds[i]];\n constraints[dimension.containerInd] = category.categoryValue;\n }\n\n // color\n if(d.model.rawColor !== undefined) {\n constraints.color = d.model.rawColor;\n }\n return constraints;\n}\n\n/**\n * Handle path click\n * @param {PathViewModel} d\n */\nfunction clickPath(d) {\n if(d.parcatsViewModel.hoverinfoItems.indexOf('skip') === -1) {\n // hoverinfo it's skip, so interaction events aren't disabled\n var points = buildPointsArrayForPath(d);\n var constraints = buildConstraintsForPath(d);\n d.parcatsViewModel.graphDiv.emit('plotly_click', {\n points: points, event: d3.event, constraints: constraints\n });\n }\n}\n\nfunction stylePathsNoHover(pathSelection) {\n pathSelection\n .attr('fill', function(d) {\n return d.model.color;\n })\n .attr('fill-opacity', 0.6)\n .attr('stroke', 'lightgray')\n .attr('stroke-width', 0.2)\n .attr('stroke-opacity', 1.0);\n}\n\nfunction stylePathsHover(pathSelection) {\n pathSelection\n .attr('fill-opacity', 0.8)\n .attr('stroke', function(d) {\n return tinycolor.mostReadable(d.model.color, ['black', 'white']);\n })\n .attr('stroke-width', 0.3);\n}\n\nfunction styleCategoryHover(categorySelection) {\n categorySelection\n .select('rect.catrect')\n .attr('stroke', 'black')\n .attr('stroke-width', 2.5);\n}\n\nfunction styleCategoriesNoHover(categorySelection) {\n categorySelection\n .select('rect.catrect')\n .attr('stroke', 'black')\n .attr('stroke-width', 1)\n .attr('stroke-opacity', 1);\n}\n\nfunction styleBandsHover(bandsSelection) {\n bandsSelection\n .attr('stroke', 'black')\n .attr('stroke-width', 1.5);\n}\n\nfunction styleBandsNoHover(bandsSelection) {\n bandsSelection\n .attr('stroke', 'black')\n .attr('stroke-width', 0.2)\n .attr('stroke-opacity', 1.0)\n .attr('fill-opacity', 1.0);\n}\n\n/**\n * Return selection of all paths that pass through the specified category\n * @param {CategoryBandViewModel} catBandViewModel\n */\nfunction selectPathsThroughCategoryBandColor(catBandViewModel) {\n var allPaths = catBandViewModel.parcatsViewModel.pathSelection;\n var dimInd = catBandViewModel.categoryViewModel.model.dimensionInd;\n var catInd = catBandViewModel.categoryViewModel.model.categoryInd;\n\n return allPaths\n .filter(\n /** @param {PathViewModel} pathViewModel */\n function(pathViewModel) {\n return pathViewModel.model.categoryInds[dimInd] === catInd &&\n pathViewModel.model.color === catBandViewModel.color;\n });\n}\n\n\n/**\n * Perform hover styling for all paths that pass though the specified band element's category\n *\n * @param {HTMLElement} bandElement\n * HTML element for band\n *\n */\nfunction styleForCategoryHovermode(bandElement) {\n // Get all bands in the current category\n var bandSel = d3.select(bandElement.parentNode).selectAll('rect.bandrect');\n\n // Raise and style paths\n bandSel.each(function(bvm) {\n var paths = selectPathsThroughCategoryBandColor(bvm);\n stylePathsHover(paths);\n paths.each(function() {\n // Raise path to top\n Lib.raiseToTop(this);\n });\n });\n\n // Style category\n styleCategoryHover(d3.select(bandElement.parentNode));\n}\n\n/**\n * Perform hover styling for all paths that pass though the category of the specified band element and share the\n * same color\n *\n * @param {HTMLElement} bandElement\n * HTML element for band\n *\n */\nfunction styleForColorHovermode(bandElement) {\n var bandViewModel = d3.select(bandElement).datum();\n var catPaths = selectPathsThroughCategoryBandColor(bandViewModel);\n stylePathsHover(catPaths);\n catPaths.each(function() {\n // Raise path to top\n Lib.raiseToTop(this);\n });\n\n // Style category for drag\n d3.select(bandElement.parentNode)\n .selectAll('rect.bandrect')\n .filter(function(b) {return b.color === bandViewModel.color;})\n .each(function() {\n Lib.raiseToTop(this);\n styleBandsHover(d3.select(this));\n });\n}\n\n\n/**\n * @param {HTMLElement} bandElement\n * HTML element for band\n * @param eventName\n * Event name (plotly_hover or plotly_click)\n * @param event\n * Mouse Event\n */\nfunction emitPointsEventCategoryHovermode(bandElement, eventName, event) {\n // Get all bands in the current category\n var bandViewModel = d3.select(bandElement).datum();\n var categoryModel = bandViewModel.categoryViewModel.model;\n var gd = bandViewModel.parcatsViewModel.graphDiv;\n var bandSel = d3.select(bandElement.parentNode).selectAll('rect.bandrect');\n\n var points = [];\n bandSel.each(function(bvm) {\n var paths = selectPathsThroughCategoryBandColor(bvm);\n paths.each(function(pathViewModel) {\n // Extend points array\n Array.prototype.push.apply(points, buildPointsArrayForPath(pathViewModel));\n });\n });\n\n var constraints = {};\n constraints[categoryModel.dimensionInd] = categoryModel.categoryValue;\n gd.emit(eventName, {\n points: points, event: event, constraints: constraints\n });\n}\n\n/**\n * @param {HTMLElement} bandElement\n * HTML element for band\n * @param eventName\n * Event name (plotly_hover or plotly_click)\n * @param event\n * Mouse Event\n */\nfunction emitPointsEventColorHovermode(bandElement, eventName, event) {\n var bandViewModel = d3.select(bandElement).datum();\n var categoryModel = bandViewModel.categoryViewModel.model;\n var gd = bandViewModel.parcatsViewModel.graphDiv;\n var paths = selectPathsThroughCategoryBandColor(bandViewModel);\n\n var points = [];\n paths.each(function(pathViewModel) {\n // Extend points array\n Array.prototype.push.apply(points, buildPointsArrayForPath(pathViewModel));\n });\n\n var constraints = {};\n constraints[categoryModel.dimensionInd] = categoryModel.categoryValue;\n // color\n if(bandViewModel.rawColor !== undefined) {\n constraints.color = bandViewModel.rawColor;\n }\n gd.emit(eventName, {\n points: points, event: event, constraints: constraints\n });\n}\n\n/**\n * Create hover label for a band element's category (for use when hoveron === 'category')\n *\n * @param {ClientRect} rootBBox\n * Client bounding box for root of figure\n * @param {HTMLElement} bandElement\n * HTML element for band\n *\n */\nfunction createHoverLabelForCategoryHovermode(rootBBox, bandElement) {\n // Selections\n var rectSelection = d3.select(bandElement.parentNode).select('rect.catrect');\n var rectBoundingBox = rectSelection.node().getBoundingClientRect();\n\n // Models\n /** @type {CategoryViewModel} */\n var catViewModel = rectSelection.datum();\n var parcatsViewModel = catViewModel.parcatsViewModel;\n var dimensionModel = parcatsViewModel.model.dimensions[catViewModel.model.dimensionInd];\n var trace = parcatsViewModel.trace;\n\n // Positions\n var hoverCenterY = rectBoundingBox.top + rectBoundingBox.height / 2;\n var hoverCenterX,\n hoverLabelIdealAlign;\n\n if(parcatsViewModel.dimensions.length > 1 &&\n dimensionModel.displayInd === parcatsViewModel.dimensions.length - 1) {\n // right most dimension\n hoverCenterX = rectBoundingBox.left;\n hoverLabelIdealAlign = 'left';\n } else {\n hoverCenterX = rectBoundingBox.left + rectBoundingBox.width;\n hoverLabelIdealAlign = 'right';\n }\n\n var count = catViewModel.model.count;\n var catLabel = catViewModel.model.categoryLabel;\n var prob = count / catViewModel.parcatsViewModel.model.count;\n var labels = {\n countLabel: count,\n categoryLabel: catLabel,\n probabilityLabel: prob.toFixed(3)\n };\n\n // Hover label text\n var hoverinfoParts = [];\n if(catViewModel.parcatsViewModel.hoverinfoItems.indexOf('count') !== -1) {\n hoverinfoParts.push(['Count:', labels.countLabel].join(' '));\n }\n if(catViewModel.parcatsViewModel.hoverinfoItems.indexOf('probability') !== -1) {\n hoverinfoParts.push(['P(' + labels.categoryLabel + '):', labels.probabilityLabel].join(' '));\n }\n\n var hovertext = hoverinfoParts.join('
');\n return {\n trace: trace,\n x: hoverCenterX - rootBBox.left,\n y: hoverCenterY - rootBBox.top,\n text: hovertext,\n color: 'lightgray',\n borderColor: 'black',\n fontFamily: 'Monaco, \"Courier New\", monospace',\n fontSize: 12,\n fontColor: 'black',\n idealAlign: hoverLabelIdealAlign,\n hovertemplate: trace.hovertemplate,\n hovertemplateLabels: labels,\n eventData: [{\n data: trace._input,\n fullData: trace,\n count: count,\n category: catLabel,\n probability: prob\n }]\n };\n}\n\n/**\n * Create hover label for a band element's category (for use when hoveron === 'category')\n *\n * @param {ClientRect} rootBBox\n * Client bounding box for root of figure\n * @param {HTMLElement} bandElement\n * HTML element for band\n *\n */\nfunction createHoverLabelForDimensionHovermode(rootBBox, bandElement) {\n var allHoverlabels = [];\n\n d3.select(bandElement.parentNode.parentNode)\n .selectAll('g.category')\n .select('rect.catrect')\n .each(function() {\n var bandNode = this;\n allHoverlabels.push(createHoverLabelForCategoryHovermode(rootBBox, bandNode));\n });\n\n return allHoverlabels;\n}\n\n/**\n * Create hover labels for a band element's category (for use when hoveron === 'dimension')\n *\n * @param {ClientRect} rootBBox\n * Client bounding box for root of figure\n * @param {HTMLElement} bandElement\n * HTML element for band\n *\n */\nfunction createHoverLabelForColorHovermode(rootBBox, bandElement) {\n var bandBoundingBox = bandElement.getBoundingClientRect();\n\n // Models\n /** @type {CategoryBandViewModel} */\n var bandViewModel = d3.select(bandElement).datum();\n var catViewModel = bandViewModel.categoryViewModel;\n var parcatsViewModel = catViewModel.parcatsViewModel;\n var dimensionModel = parcatsViewModel.model.dimensions[catViewModel.model.dimensionInd];\n var trace = parcatsViewModel.trace;\n\n // positions\n var hoverCenterY = bandBoundingBox.y + bandBoundingBox.height / 2;\n\n var hoverCenterX,\n hoverLabelIdealAlign;\n if(parcatsViewModel.dimensions.length > 1 &&\n dimensionModel.displayInd === parcatsViewModel.dimensions.length - 1) {\n // right most dimension\n hoverCenterX = bandBoundingBox.left;\n hoverLabelIdealAlign = 'left';\n } else {\n hoverCenterX = bandBoundingBox.left + bandBoundingBox.width;\n hoverLabelIdealAlign = 'right';\n }\n\n // Labels\n var catLabel = catViewModel.model.categoryLabel;\n\n // Counts\n var totalCount = bandViewModel.parcatsViewModel.model.count;\n\n var bandColorCount = 0;\n bandViewModel.categoryViewModel.bands.forEach(function(b) {\n if(b.color === bandViewModel.color) {\n bandColorCount += b.count;\n }\n });\n\n var catCount = catViewModel.model.count;\n\n var colorCount = 0;\n parcatsViewModel.pathSelection.each(\n /** @param {PathViewModel} pathViewModel */\n function(pathViewModel) {\n if(pathViewModel.model.color === bandViewModel.color) {\n colorCount += pathViewModel.model.count;\n }\n });\n\n var pColorAndCat = bandColorCount / totalCount;\n var pCatGivenColor = bandColorCount / colorCount;\n var pColorGivenCat = bandColorCount / catCount;\n\n var labels = {\n countLabel: totalCount,\n categoryLabel: catLabel,\n probabilityLabel: pColorAndCat.toFixed(3)\n };\n\n // Hover label text\n var hoverinfoParts = [];\n if(catViewModel.parcatsViewModel.hoverinfoItems.indexOf('count') !== -1) {\n hoverinfoParts.push(['Count:', labels.countLabel].join(' '));\n }\n if(catViewModel.parcatsViewModel.hoverinfoItems.indexOf('probability') !== -1) {\n hoverinfoParts.push('P(color ∩ ' + catLabel + '): ' + labels.probabilityLabel);\n hoverinfoParts.push('P(' + catLabel + ' | color): ' + pCatGivenColor.toFixed(3));\n hoverinfoParts.push('P(color | ' + catLabel + '): ' + pColorGivenCat.toFixed(3));\n }\n\n var hovertext = hoverinfoParts.join('
');\n\n // Compute text color\n var textColor = tinycolor.mostReadable(bandViewModel.color, ['black', 'white']);\n\n return {\n trace: trace,\n x: hoverCenterX - rootBBox.left,\n y: hoverCenterY - rootBBox.top,\n // name: 'NAME',\n text: hovertext,\n color: bandViewModel.color,\n borderColor: 'black',\n fontFamily: 'Monaco, \"Courier New\", monospace',\n fontColor: textColor,\n fontSize: 10,\n idealAlign: hoverLabelIdealAlign,\n hovertemplate: trace.hovertemplate,\n hovertemplateLabels: labels,\n eventData: [{\n data: trace._input,\n fullData: trace,\n category: catLabel,\n count: totalCount,\n probability: pColorAndCat,\n categorycount: catCount,\n colorcount: colorCount,\n bandcolorcount: bandColorCount\n }]\n };\n}\n\n/**\n * Handle dimension mouseover\n * @param {CategoryBandViewModel} bandViewModel\n */\nfunction mouseoverCategoryBand(bandViewModel) {\n if(!bandViewModel.parcatsViewModel.dragDimension) {\n // We're not currently dragging\n\n if(bandViewModel.parcatsViewModel.hoverinfoItems.indexOf('skip') === -1) {\n // hoverinfo is not skip, so we at least style the bands and emit interaction events\n\n // Mouse\n var mouseY = d3.mouse(this)[1];\n if(mouseY < -1) {\n // Hover is above above the category rectangle (probably the dimension title text)\n return;\n }\n\n var gd = bandViewModel.parcatsViewModel.graphDiv;\n var fullLayout = gd._fullLayout;\n var rootBBox = fullLayout._paperdiv.node().getBoundingClientRect();\n var hoveron = bandViewModel.parcatsViewModel.hoveron;\n\n /** @type {HTMLElement} */\n var bandElement = this;\n\n // Handle style and events\n if(hoveron === 'color') {\n styleForColorHovermode(bandElement);\n emitPointsEventColorHovermode(bandElement, 'plotly_hover', d3.event);\n } else {\n styleForCategoryHovermode(bandElement);\n emitPointsEventCategoryHovermode(bandElement, 'plotly_hover', d3.event);\n }\n\n // Handle hover label\n if(bandViewModel.parcatsViewModel.hoverinfoItems.indexOf('none') === -1) {\n var hoverItems;\n if(hoveron === 'category') {\n hoverItems = createHoverLabelForCategoryHovermode(rootBBox, bandElement);\n } else if(hoveron === 'color') {\n hoverItems = createHoverLabelForColorHovermode(rootBBox, bandElement);\n } else if(hoveron === 'dimension') {\n hoverItems = createHoverLabelForDimensionHovermode(rootBBox, bandElement);\n }\n\n if(hoverItems) {\n Fx.loneHover(hoverItems, {\n container: fullLayout._hoverlayer.node(),\n outerContainer: fullLayout._paper.node(),\n gd: gd\n });\n }\n }\n }\n }\n}\n\n\n/**\n * Handle dimension mouseover\n * @param {CategoryBandViewModel} bandViewModel\n */\nfunction mouseoutCategory(bandViewModel) {\n var parcatsViewModel = bandViewModel.parcatsViewModel;\n\n if(!parcatsViewModel.dragDimension) {\n // We're not dragging anything\n\n // Reset unhovered styles\n stylePathsNoHover(parcatsViewModel.pathSelection);\n styleCategoriesNoHover(parcatsViewModel.dimensionSelection.selectAll('g.category'));\n styleBandsNoHover(parcatsViewModel.dimensionSelection.selectAll('g.category').selectAll('rect.bandrect'));\n\n // Remove hover label\n Fx.loneUnhover(parcatsViewModel.graphDiv._fullLayout._hoverlayer.node());\n\n // Restore path order\n parcatsViewModel.pathSelection.sort(compareRawColor);\n\n // Emit unhover event\n if(parcatsViewModel.hoverinfoItems.indexOf('skip') === -1) {\n var hoveron = bandViewModel.parcatsViewModel.hoveron;\n var bandElement = this;\n\n // Handle style and events\n if(hoveron === 'color') {\n emitPointsEventColorHovermode(bandElement, 'plotly_unhover', d3.event);\n } else {\n emitPointsEventCategoryHovermode(bandElement, 'plotly_unhover', d3.event);\n }\n }\n }\n}\n\n\n/**\n * Handle dimension drag start\n * @param {DimensionViewModel} d\n */\nfunction dragDimensionStart(d) {\n // Check if dragging is supported\n if(d.parcatsViewModel.arrangement === 'fixed') {\n return;\n }\n\n // Save off initial drag indexes for dimension\n d.dragDimensionDisplayInd = d.model.displayInd;\n d.initialDragDimensionDisplayInds = d.parcatsViewModel.model.dimensions.map(function(d) {return d.displayInd;});\n d.dragHasMoved = false;\n\n // Check for category hit\n d.dragCategoryDisplayInd = null;\n d3.select(this)\n .selectAll('g.category')\n .select('rect.catrect')\n .each(\n /** @param {CategoryViewModel} catViewModel */\n function(catViewModel) {\n var catMouseX = d3.mouse(this)[0];\n var catMouseY = d3.mouse(this)[1];\n\n\n if(-2 <= catMouseX && catMouseX <= catViewModel.width + 2 &&\n -2 <= catMouseY && catMouseY <= catViewModel.height + 2) {\n // Save off initial drag indexes for categories\n d.dragCategoryDisplayInd = catViewModel.model.displayInd;\n d.initialDragCategoryDisplayInds = d.model.categories.map(function(c) {\n return c.displayInd;\n });\n\n // Initialize categories dragY to be the current y position\n catViewModel.model.dragY = catViewModel.y;\n\n // Raise category\n Lib.raiseToTop(this.parentNode);\n\n // Get band element\n d3.select(this.parentNode)\n .selectAll('rect.bandrect')\n /** @param {CategoryBandViewModel} bandViewModel */\n .each(function(bandViewModel) {\n if(bandViewModel.y < catMouseY && catMouseY <= bandViewModel.y + bandViewModel.height) {\n d.potentialClickBand = this;\n }\n });\n }\n });\n\n // Update toplevel drag dimension\n d.parcatsViewModel.dragDimension = d;\n\n // Remove hover label if any\n Fx.loneUnhover(d.parcatsViewModel.graphDiv._fullLayout._hoverlayer.node());\n}\n\n/**\n * Handle dimension drag\n * @param {DimensionViewModel} d\n */\nfunction dragDimension(d) {\n // Check if dragging is supported\n if(d.parcatsViewModel.arrangement === 'fixed') {\n return;\n }\n\n d.dragHasMoved = true;\n\n if(d.dragDimensionDisplayInd === null) {\n return;\n }\n\n var dragDimInd = d.dragDimensionDisplayInd;\n var prevDimInd = dragDimInd - 1;\n var nextDimInd = dragDimInd + 1;\n\n var dragDimension = d.parcatsViewModel\n .dimensions[dragDimInd];\n\n // Update category\n if(d.dragCategoryDisplayInd !== null) {\n var dragCategory = dragDimension.categories[d.dragCategoryDisplayInd];\n\n // Update dragY by dy\n dragCategory.model.dragY += d3.event.dy;\n var categoryY = dragCategory.model.dragY;\n\n // Check for category drag swaps\n var catDisplayInd = dragCategory.model.displayInd;\n var dimCategoryViews = dragDimension.categories;\n\n var catAbove = dimCategoryViews[catDisplayInd - 1];\n var catBelow = dimCategoryViews[catDisplayInd + 1];\n\n // Check for overlap above\n if(catAbove !== undefined) {\n if(categoryY < (catAbove.y + catAbove.height / 2.0)) {\n // Swap display inds\n dragCategory.model.displayInd = catAbove.model.displayInd;\n catAbove.model.displayInd = catDisplayInd;\n }\n }\n\n if(catBelow !== undefined) {\n if((categoryY + dragCategory.height) > (catBelow.y + catBelow.height / 2.0)) {\n // Swap display inds\n dragCategory.model.displayInd = catBelow.model.displayInd;\n catBelow.model.displayInd = catDisplayInd;\n }\n }\n\n // Update category drag display index\n d.dragCategoryDisplayInd = dragCategory.model.displayInd;\n }\n\n // Update dimension position\n if(d.dragCategoryDisplayInd === null || d.parcatsViewModel.arrangement === 'freeform') {\n dragDimension.model.dragX = d3.event.x;\n\n // Check for dimension swaps\n var prevDimension = d.parcatsViewModel.dimensions[prevDimInd];\n var nextDimension = d.parcatsViewModel.dimensions[nextDimInd];\n\n if(prevDimension !== undefined) {\n if(dragDimension.model.dragX < (prevDimension.x + prevDimension.width)) {\n // Swap display inds\n dragDimension.model.displayInd = prevDimension.model.displayInd;\n prevDimension.model.displayInd = dragDimInd;\n }\n }\n\n if(nextDimension !== undefined) {\n if((dragDimension.model.dragX + dragDimension.width) > nextDimension.x) {\n // Swap display inds\n dragDimension.model.displayInd = nextDimension.model.displayInd;\n nextDimension.model.displayInd = d.dragDimensionDisplayInd;\n }\n }\n\n // Update drag display index\n d.dragDimensionDisplayInd = dragDimension.model.displayInd;\n }\n\n // Update view models\n updateDimensionViewModels(d.parcatsViewModel);\n updatePathViewModels(d.parcatsViewModel);\n\n // Update svg geometry\n updateSvgCategories(d.parcatsViewModel);\n updateSvgPaths(d.parcatsViewModel);\n}\n\n\n/**\n * Handle dimension drag end\n * @param {DimensionViewModel} d\n */\nfunction dragDimensionEnd(d) {\n // Check if dragging is supported\n if(d.parcatsViewModel.arrangement === 'fixed') {\n return;\n }\n\n if(d.dragDimensionDisplayInd === null) {\n return;\n }\n\n d3.select(this).selectAll('text').attr('font-weight', 'normal');\n\n // Compute restyle command\n // -----------------------\n var restyleData = {};\n var traceInd = getTraceIndex(d.parcatsViewModel);\n\n // ### Handle dimension reordering ###\n var finalDragDimensionDisplayInds = d.parcatsViewModel.model.dimensions.map(function(d) {return d.displayInd;});\n var anyDimsReordered = d.initialDragDimensionDisplayInds.some(function(initDimDisplay, dimInd) {\n return initDimDisplay !== finalDragDimensionDisplayInds[dimInd];\n });\n\n if(anyDimsReordered) {\n finalDragDimensionDisplayInds.forEach(function(finalDimDisplay, dimInd) {\n var containerInd = d.parcatsViewModel.model.dimensions[dimInd].containerInd;\n restyleData['dimensions[' + containerInd + '].displayindex'] = finalDimDisplay;\n });\n }\n\n // ### Handle category reordering ###\n var anyCatsReordered = false;\n if(d.dragCategoryDisplayInd !== null) {\n var finalDragCategoryDisplayInds = d.model.categories.map(function(c) {\n return c.displayInd;\n });\n\n anyCatsReordered = d.initialDragCategoryDisplayInds.some(function(initCatDisplay, catInd) {\n return initCatDisplay !== finalDragCategoryDisplayInds[catInd];\n });\n\n if(anyCatsReordered) {\n // Sort a shallow copy of the category models by display index\n var sortedCategoryModels = d.model.categories.slice().sort(\n function(a, b) { return a.displayInd - b.displayInd; });\n\n // Get new categoryarray and ticktext values\n var newCategoryArray = sortedCategoryModels.map(function(v) { return v.categoryValue; });\n var newCategoryLabels = sortedCategoryModels.map(function(v) { return v.categoryLabel; });\n\n restyleData['dimensions[' + d.model.containerInd + '].categoryarray'] = [newCategoryArray];\n restyleData['dimensions[' + d.model.containerInd + '].ticktext'] = [newCategoryLabels];\n restyleData['dimensions[' + d.model.containerInd + '].categoryorder'] = 'array';\n }\n }\n\n // Handle potential click event\n // ----------------------------\n if(d.parcatsViewModel.hoverinfoItems.indexOf('skip') === -1) {\n if(!d.dragHasMoved && d.potentialClickBand) {\n if(d.parcatsViewModel.hoveron === 'color') {\n emitPointsEventColorHovermode(d.potentialClickBand, 'plotly_click', d3.event.sourceEvent);\n } else {\n emitPointsEventCategoryHovermode(d.potentialClickBand, 'plotly_click', d3.event.sourceEvent);\n }\n }\n }\n\n // Nullify drag states\n // -------------------\n d.model.dragX = null;\n if(d.dragCategoryDisplayInd !== null) {\n var dragCategory = d.parcatsViewModel\n .dimensions[d.dragDimensionDisplayInd]\n .categories[d.dragCategoryDisplayInd];\n\n dragCategory.model.dragY = null;\n d.dragCategoryDisplayInd = null;\n }\n\n d.dragDimensionDisplayInd = null;\n d.parcatsViewModel.dragDimension = null;\n d.dragHasMoved = null;\n d.potentialClickBand = null;\n\n // Update view models\n // ------------------\n updateDimensionViewModels(d.parcatsViewModel);\n updatePathViewModels(d.parcatsViewModel);\n\n // Perform transition\n // ------------------\n var transition = d3.transition()\n .duration(300)\n .ease('cubic-in-out');\n\n transition\n .each(function() {\n updateSvgCategories(d.parcatsViewModel, true);\n updateSvgPaths(d.parcatsViewModel, true);\n })\n .each('end', function() {\n if(anyDimsReordered || anyCatsReordered) {\n // Perform restyle if the order of categories or dimensions changed\n Plotly.restyle(d.parcatsViewModel.graphDiv, restyleData, [traceInd]);\n }\n });\n}\n\n/**\n *\n * @param {ParcatsViewModel} parcatsViewModel\n */\nfunction getTraceIndex(parcatsViewModel) {\n var traceInd;\n var allTraces = parcatsViewModel.graphDiv._fullData;\n for(var i = 0; i < allTraces.length; i++) {\n if(parcatsViewModel.key === allTraces[i].uid) {\n traceInd = i;\n break;\n }\n }\n return traceInd;\n}\n\n/** Update the svg paths for view model\n * @param {ParcatsViewModel} parcatsViewModel\n * @param {boolean} hasTransition Whether to update element with transition\n */\nfunction updateSvgPaths(parcatsViewModel, hasTransition) {\n if(hasTransition === undefined) {\n hasTransition = false;\n }\n\n function transition(selection) {\n return hasTransition ? selection.transition() : selection;\n }\n\n // Update binding\n parcatsViewModel.pathSelection.data(function(d) {\n return d.paths;\n }, key);\n\n // Update paths\n transition(parcatsViewModel.pathSelection).attr('d', function(d) {\n return d.svgD;\n });\n}\n\n/** Update the svg paths for view model\n * @param {ParcatsViewModel} parcatsViewModel\n * @param {boolean} hasTransition Whether to update element with transition\n */\nfunction updateSvgCategories(parcatsViewModel, hasTransition) {\n if(hasTransition === undefined) {\n hasTransition = false;\n }\n\n function transition(selection) {\n return hasTransition ? selection.transition() : selection;\n }\n\n // Update binding\n parcatsViewModel.dimensionSelection\n .data(function(d) {\n return d.dimensions;\n }, key);\n\n var categorySelection = parcatsViewModel.dimensionSelection\n .selectAll('g.category')\n .data(function(d) {return d.categories;}, key);\n\n // Update dimension position\n transition(parcatsViewModel.dimensionSelection)\n .attr('transform', function(d) {\n return 'translate(' + d.x + ', 0)';\n });\n\n // Update category position\n transition(categorySelection)\n .attr('transform', function(d) {\n return 'translate(0, ' + d.y + ')';\n });\n\n var dimLabelSelection = categorySelection.select('.dimlabel');\n\n // ### Update dimension label\n // Only the top-most display category should have the dimension label\n dimLabelSelection\n .text(function(d, i) {\n if(i === 0) {\n // Add dimension label above topmost category\n return d.parcatsViewModel.model.dimensions[d.model.dimensionInd].dimensionLabel;\n } else {\n return null;\n }\n });\n\n // Update category label\n // Categories in the right-most display dimension have their labels on\n // the right, all others on the left\n var catLabelSelection = categorySelection.select('.catlabel');\n catLabelSelection\n .attr('text-anchor',\n function(d) {\n if(catInRightDim(d)) {\n // Place label to the right of category\n return 'start';\n } else {\n // Place label to the left of category\n return 'end';\n }\n })\n .attr('x',\n function(d) {\n if(catInRightDim(d)) {\n // Place label to the right of category\n return d.width + 5;\n } else {\n // Place label to the left of category\n return -5;\n }\n })\n .each(function(d) {\n // Update attriubutes of elements\n var newX;\n var newAnchor;\n if(catInRightDim(d)) {\n // Place label to the right of category\n newX = d.width + 5;\n newAnchor = 'start';\n } else {\n // Place label to the left of category\n newX = -5;\n newAnchor = 'end';\n }\n d3.select(this)\n .selectAll('tspan')\n .attr('x', newX)\n .attr('text-anchor', newAnchor);\n });\n\n // Update bands\n // Initialize color band rects\n var bandSelection = categorySelection\n .selectAll('rect.bandrect')\n .data(\n /** @param {CategoryViewModel} catViewModel*/\n function(catViewModel) {\n return catViewModel.bands;\n }, key);\n\n var bandsSelectionEnter = bandSelection.enter()\n .append('rect')\n .attr('class', 'bandrect')\n .attr('cursor', 'move')\n .attr('stroke-opacity', 0)\n .attr('fill', function(d) {\n return d.color;\n })\n .attr('fill-opacity', 0);\n\n bandSelection\n .attr('fill', function(d) {\n return d.color;\n })\n .attr('width', function(d) {\n return d.width;\n })\n .attr('height', function(d) {\n return d.height;\n })\n .attr('y', function(d) {\n return d.y;\n });\n\n styleBandsNoHover(bandsSelectionEnter);\n\n // Raise bands to the top\n bandSelection.each(function() {Lib.raiseToTop(this);});\n\n // Remove unused bands\n bandSelection.exit().remove();\n}\n\n/**\n * Create a ParcatsViewModel traces\n * @param {Object} graphDiv\n * Top-level graph div element\n * @param {Layout} layout\n * SVG layout object\n * @param {Array.} wrappedParcatsModel\n * Wrapped ParcatsModel for this trace\n * @return {ParcatsViewModel}\n */\nfunction createParcatsViewModel(graphDiv, layout, wrappedParcatsModel) {\n // Unwrap model\n var parcatsModel = wrappedParcatsModel[0];\n\n // Compute margin\n var margin = layout.margin || {l: 80, r: 80, t: 100, b: 80};\n\n // Compute pixel position/extents\n var trace = parcatsModel.trace;\n var domain = trace.domain;\n var figureWidth = layout.width;\n var figureHeight = layout.height;\n var traceWidth = Math.floor(figureWidth * (domain.x[1] - domain.x[0]));\n var traceHeight = Math.floor(figureHeight * (domain.y[1] - domain.y[0]));\n var traceX = domain.x[0] * figureWidth + margin.l;\n var traceY = layout.height - domain.y[1] * layout.height + margin.t;\n\n // Handle path shape\n // -----------------\n var pathShape = trace.line.shape;\n\n // Handle hover info\n // -----------------\n var hoverinfoItems;\n if(trace.hoverinfo === 'all') {\n hoverinfoItems = ['count', 'probability'];\n } else {\n hoverinfoItems = (trace.hoverinfo || '').split('+');\n }\n\n // Construct parcatsViewModel\n // --------------------------\n var parcatsViewModel = {\n trace: trace,\n key: trace.uid,\n model: parcatsModel,\n x: traceX,\n y: traceY,\n width: traceWidth,\n height: traceHeight,\n hoveron: trace.hoveron,\n hoverinfoItems: hoverinfoItems,\n arrangement: trace.arrangement,\n bundlecolors: trace.bundlecolors,\n sortpaths: trace.sortpaths,\n labelfont: trace.labelfont,\n categorylabelfont: trace.tickfont,\n pathShape: pathShape,\n dragDimension: null,\n margin: margin,\n paths: [],\n dimensions: [],\n graphDiv: graphDiv,\n traceSelection: null,\n pathSelection: null,\n dimensionSelection: null\n };\n\n // Update dimension view models if we have at least 1 dimension\n if(parcatsModel.dimensions) {\n updateDimensionViewModels(parcatsViewModel);\n\n // Update path view models if we have at least 2 dimensions\n updatePathViewModels(parcatsViewModel);\n }\n // Inside a categories view model\n return parcatsViewModel;\n}\n\n/**\n * Build the SVG string to represents a parallel categories path\n * @param {Array.} leftXPositions\n * Array of the x positions of the left edge of each dimension (in display order)\n * @param {Array.} pathYs\n * Array of the y positions of the top of the path at each dimension (in display order)\n * @param {Array.} dimWidths\n * Array of the widths of each dimension in display order\n * @param {Number} pathHeight\n * The height of the path in pixels\n * @param {Number} curvature\n * The curvature factor for the path. 0 results in a straight line and values greater than zero result in curved paths\n * @return {string}\n */\nfunction buildSvgPath(leftXPositions, pathYs, dimWidths, pathHeight, curvature) {\n // Compute the x midpoint of each path segment\n var xRefPoints1 = [];\n var xRefPoints2 = [];\n var refInterpolator;\n var d;\n\n for(d = 0; d < dimWidths.length - 1; d++) {\n refInterpolator = d3.interpolateNumber(dimWidths[d] + leftXPositions[d], leftXPositions[d + 1]);\n xRefPoints1.push(refInterpolator(curvature));\n xRefPoints2.push(refInterpolator(1 - curvature));\n }\n\n // Move to top of path on left edge of left-most category\n var svgD = 'M ' + leftXPositions[0] + ',' + pathYs[0];\n\n // Horizontal line to right edge\n svgD += 'l' + dimWidths[0] + ',0 ';\n\n // Horizontal line to right edge\n for(d = 1; d < dimWidths.length; d++) {\n // Curve to left edge of category\n svgD += 'C' + xRefPoints1[d - 1] + ',' + pathYs[d - 1] +\n ' ' + xRefPoints2[d - 1] + ',' + pathYs[d] +\n ' ' + leftXPositions[d] + ',' + pathYs[d];\n\n // svgD += 'L' + leftXPositions[d] + ',' + pathYs[d];\n\n // Horizontal line to right edge\n svgD += 'l' + dimWidths[d] + ',0 ';\n }\n\n // Line down\n svgD += 'l' + '0,' + pathHeight + ' ';\n\n // Line to left edge of right-most category\n svgD += 'l -' + dimWidths[dimWidths.length - 1] + ',0 ';\n\n for(d = dimWidths.length - 2; d >= 0; d--) {\n // Curve to right edge of category\n svgD += 'C' + xRefPoints2[d] + ',' + (pathYs[d + 1] + pathHeight) +\n ' ' + xRefPoints1[d] + ',' + (pathYs[d] + pathHeight) +\n ' ' + (leftXPositions[d] + dimWidths[d]) + ',' + (pathYs[d] + pathHeight);\n\n // svgD += 'L' + (leftXPositions[d] + dimWidths[d]) + ',' + (pathYs[d] + pathHeight);\n\n // Horizontal line to right edge\n svgD += 'l-' + dimWidths[d] + ',0 ';\n }\n\n // Close path\n svgD += 'Z';\n return svgD;\n}\n\n/**\n * Update the path view models based on the dimension view models in a ParcatsViewModel\n *\n * @param {ParcatsViewModel} parcatsViewModel\n * View model for trace\n */\nfunction updatePathViewModels(parcatsViewModel) {\n // Initialize an array of the y position of the top of the next path to be added to each category.\n //\n // nextYPositions[d][c] is the y position of the next path through category with index c of dimension with index d\n var dimensionViewModels = parcatsViewModel.dimensions;\n var parcatsModel = parcatsViewModel.model;\n var nextYPositions = dimensionViewModels.map(\n function(d) {\n return d.categories.map(\n function(c) {\n return c.y;\n });\n });\n\n // Array from category index to category display index for each true dimension index\n var catToDisplayIndPerDim = parcatsViewModel.model.dimensions.map(\n function(d) {\n return d.categories.map(function(c) {return c.displayInd;});\n });\n\n // Array from true dimension index to dimension display index\n var dimToDisplayInd = parcatsViewModel.model.dimensions.map(function(d) {return d.displayInd;});\n var displayToDimInd = parcatsViewModel.dimensions.map(function(d) {return d.model.dimensionInd;});\n\n // Array of the x position of the left edge of the rectangles for each dimension\n var leftXPositions = dimensionViewModels.map(\n function(d) {\n return d.x;\n });\n\n // Compute dimension widths\n var dimWidths = dimensionViewModels.map(function(d) {return d.width;});\n\n // Build sorted Array of PathModel objects\n var pathModels = [];\n for(var p in parcatsModel.paths) {\n if(parcatsModel.paths.hasOwnProperty(p)) {\n pathModels.push(parcatsModel.paths[p]);\n }\n }\n\n // Compute category display inds to use for sorting paths\n function pathDisplayCategoryInds(pathModel) {\n var dimensionInds = pathModel.categoryInds.map(function(catInd, dimInd) {return catToDisplayIndPerDim[dimInd][catInd];});\n var displayInds = displayToDimInd.map(function(dimInd) {\n return dimensionInds[dimInd];\n });\n return displayInds;\n }\n\n // Sort in ascending order by display index array\n pathModels.sort(function(v1, v2) {\n // Build display inds for each path\n var sortArray1 = pathDisplayCategoryInds(v1);\n var sortArray2 = pathDisplayCategoryInds(v2);\n\n // Handle path sort order\n if(parcatsViewModel.sortpaths === 'backward') {\n sortArray1.reverse();\n sortArray2.reverse();\n }\n\n // Append the first value index of the path to break ties\n sortArray1.push(v1.valueInds[0]);\n sortArray2.push(v2.valueInds[0]);\n\n // Handle color bundling\n if(parcatsViewModel.bundlecolors) {\n // Prepend sort array with the raw color value\n sortArray1.unshift(v1.rawColor);\n sortArray2.unshift(v2.rawColor);\n }\n\n // colors equal, sort by display categories\n if(sortArray1 < sortArray2) {\n return -1;\n }\n if(sortArray1 > sortArray2) {\n return 1;\n }\n\n return 0;\n });\n\n // Create path models\n var pathViewModels = new Array(pathModels.length);\n var totalCount = dimensionViewModels[0].model.count;\n var totalHeight = dimensionViewModels[0].categories\n .map(function(c) { return c.height; })\n .reduce(function(v1, v2) { return v1 + v2; });\n\n\n for(var pathNumber = 0; pathNumber < pathModels.length; pathNumber++) {\n var pathModel = pathModels[pathNumber];\n\n var pathHeight;\n if(totalCount > 0) {\n pathHeight = totalHeight * (pathModel.count / totalCount);\n } else {\n pathHeight = 0;\n }\n\n // Build path y coords\n var pathYs = new Array(nextYPositions.length);\n for(var d = 0; d < pathModel.categoryInds.length; d++) {\n var catInd = pathModel.categoryInds[d];\n var catDisplayInd = catToDisplayIndPerDim[d][catInd];\n var dimDisplayInd = dimToDisplayInd[d];\n\n // Update next y position\n pathYs[dimDisplayInd] = nextYPositions[dimDisplayInd][catDisplayInd];\n nextYPositions[dimDisplayInd][catDisplayInd] += pathHeight;\n\n // Update category color information\n var catViewModle = parcatsViewModel.dimensions[dimDisplayInd].categories[catDisplayInd];\n var numBands = catViewModle.bands.length;\n var lastCatBand = catViewModle.bands[numBands - 1];\n\n if(lastCatBand === undefined || pathModel.rawColor !== lastCatBand.rawColor) {\n // Create a new band\n var bandY = lastCatBand === undefined ? 0 : lastCatBand.y + lastCatBand.height;\n catViewModle.bands.push({\n key: bandY,\n color: pathModel.color,\n rawColor: pathModel.rawColor,\n height: pathHeight,\n width: catViewModle.width,\n count: pathModel.count,\n y: bandY,\n categoryViewModel: catViewModle,\n parcatsViewModel: parcatsViewModel\n });\n } else {\n // Extend current band\n var currentBand = catViewModle.bands[numBands - 1];\n currentBand.height += pathHeight;\n currentBand.count += pathModel.count;\n }\n }\n\n // build svg path\n var svgD;\n if(parcatsViewModel.pathShape === 'hspline') {\n svgD = buildSvgPath(leftXPositions, pathYs, dimWidths, pathHeight, 0.5);\n } else {\n svgD = buildSvgPath(leftXPositions, pathYs, dimWidths, pathHeight, 0);\n }\n\n pathViewModels[pathNumber] = {\n key: pathModel.valueInds[0],\n model: pathModel,\n height: pathHeight,\n leftXs: leftXPositions,\n topYs: pathYs,\n dimWidths: dimWidths,\n svgD: svgD,\n parcatsViewModel: parcatsViewModel\n };\n }\n\n parcatsViewModel.paths = pathViewModels;\n\n // * @property key\n // * Unique key for this model\n // * @property {PathModel} model\n // * Source path model\n // * @property {Number} height\n // * Height of this path (pixels)\n // * @property {String} svgD\n // * SVG path \"d\" attribute string\n}\n\n/**\n * Update the dimension view models based on the dimension models in a ParcatsViewModel\n *\n * @param {ParcatsViewModel} parcatsViewModel\n * View model for trace\n */\nfunction updateDimensionViewModels(parcatsViewModel) {\n // Compute dimension ordering\n var dimensionsIndInfo = parcatsViewModel.model.dimensions.map(function(d) {\n return {displayInd: d.displayInd, dimensionInd: d.dimensionInd};\n });\n\n dimensionsIndInfo.sort(function(a, b) {\n return a.displayInd - b.displayInd;\n });\n\n var dimensions = [];\n for(var displayInd in dimensionsIndInfo) {\n var dimensionInd = dimensionsIndInfo[displayInd].dimensionInd;\n var dimModel = parcatsViewModel.model.dimensions[dimensionInd];\n dimensions.push(createDimensionViewModel(parcatsViewModel, dimModel));\n }\n\n parcatsViewModel.dimensions = dimensions;\n}\n\n/**\n * Create a parcats DimensionViewModel\n *\n * @param {ParcatsViewModel} parcatsViewModel\n * View model for trace\n * @param {DimensionModel} dimensionModel\n * @return {DimensionViewModel}\n */\nfunction createDimensionViewModel(parcatsViewModel, dimensionModel) {\n // Compute dimension x position\n var categoryLabelPad = 40;\n var dimWidth = 16;\n var numDimensions = parcatsViewModel.model.dimensions.length;\n var displayInd = dimensionModel.displayInd;\n\n // Compute x coordinate values\n var dimDx;\n var dimX0;\n var dimX;\n\n if(numDimensions > 1) {\n dimDx = (parcatsViewModel.width - 2 * categoryLabelPad - dimWidth) / (numDimensions - 1);\n } else {\n dimDx = 0;\n }\n dimX0 = categoryLabelPad;\n dimX = dimX0 + dimDx * displayInd;\n\n // Compute categories\n var categories = [];\n var maxCats = parcatsViewModel.model.maxCats;\n var numCats = dimensionModel.categories.length;\n var catSpacing = 8;\n var totalCount = dimensionModel.count;\n var totalHeight = parcatsViewModel.height - catSpacing * (maxCats - 1);\n var nextCatHeight;\n var nextCatModel;\n var nextCat;\n var catInd;\n var catDisplayInd;\n\n // Compute starting Y offset\n var nextCatY = (maxCats - numCats) * catSpacing / 2.0;\n\n // Compute category ordering\n var categoryIndInfo = dimensionModel.categories.map(function(c) {\n return {displayInd: c.displayInd, categoryInd: c.categoryInd};\n });\n\n categoryIndInfo.sort(function(a, b) {\n return a.displayInd - b.displayInd;\n });\n\n for(catDisplayInd = 0; catDisplayInd < numCats; catDisplayInd++) {\n catInd = categoryIndInfo[catDisplayInd].categoryInd;\n nextCatModel = dimensionModel.categories[catInd];\n\n if(totalCount > 0) {\n nextCatHeight = (nextCatModel.count / totalCount) * totalHeight;\n } else {\n nextCatHeight = 0;\n }\n\n nextCat = {\n key: nextCatModel.valueInds[0],\n model: nextCatModel,\n width: dimWidth,\n height: nextCatHeight,\n y: nextCatModel.dragY !== null ? nextCatModel.dragY : nextCatY,\n bands: [],\n parcatsViewModel: parcatsViewModel\n };\n\n nextCatY = nextCatY + nextCatHeight + catSpacing;\n categories.push(nextCat);\n }\n\n return {\n key: dimensionModel.dimensionInd,\n x: dimensionModel.dragX !== null ? dimensionModel.dragX : dimX,\n y: 0,\n width: dimWidth,\n model: dimensionModel,\n categories: categories,\n parcatsViewModel: parcatsViewModel,\n dragCategoryDisplayInd: null,\n dragDimensionDisplayInd: null,\n initialDragDimensionDisplayInds: null,\n initialDragCategoryDisplayInds: null,\n dragHasMoved: null,\n potentialClickBand: null\n };\n}\n\n// JSDoc typedefs\n// ==============\n/**\n * @typedef {Object} Layout\n * Object containing svg layout information\n *\n * @property {Number} width (pixels)\n * Usable width for Figure (after margins are removed)\n * @property {Number} height (pixels)\n * Usable height for Figure (after margins are removed)\n * @property {Margin} margin\n * Margin around the Figure (pixels)\n */\n\n/**\n * @typedef {Object} Margin\n * Object containing padding information in pixels\n *\n * @property {Number} t\n * Top margin\n * @property {Number} r\n * Right margin\n * @property {Number} b\n * Bottom margin\n * @property {Number} l\n * Left margin\n */\n\n/**\n * @typedef {Object} Font\n * Object containing font information\n *\n * @property {Number} size: Font size\n * @property {String} color: Font color\n * @property {String} family: Font family\n */\n\n/**\n * @typedef {Object} ParcatsViewModel\n * Object containing calculated parcats view information\n *\n * These are quantities that require Layout information to calculate\n * @property key\n * Unique key for this model\n * @property {ParcatsModel} model\n * Source parcats model\n * @property {Array.} dimensions\n * Array of dimension view models\n * @property {Number} width\n * Width for this trace (pixels)\n * @property {Number} height\n * Height for this trace (pixels)\n * @property {Number} x\n * X position of this trace with respect to the Figure (pixels)\n * @property {Number} y\n * Y position of this trace with respect to the Figure (pixels)\n * @property {String} hoveron\n * Hover interaction mode. One of: 'category', 'color', or 'dimension'\n * @property {Array.} hoverinfoItems\n * Info to display on hover. Array with a combination of 'counts' and/or 'probabilities', or 'none', or 'skip'\n * @property {String} arrangement\n * Category arrangement. One of: 'perpendicular', 'freeform', or 'fixed'\n * @property {Boolean} bundlecolors\n * Whether paths should be sorted so that like colors are bundled together as they pass through categories\n * @property {String} sortpaths\n * If 'forward' then sort paths based on dimensions from left to right. If 'backward' sort based on dimensions\n * from right to left\n * @property {Font} labelfont\n * Font for the dimension labels\n * @property {Font} categorylabelfont\n * Font for the category labels\n * @property {String} pathShape\n * The shape of the paths. Either 'linear' or 'hspline'.\n * @property {DimensionViewModel|null} dragDimension\n * Dimension currently being dragged. Null if no drag in progress\n * @property {Margin} margin\n * Margin around the Figure\n * @property {Object} graphDiv\n * Top-level graph div element\n * @property {Object} traceSelection\n * D3 selection of this view models trace group element\n * @property {Object} pathSelection\n * D3 selection of this view models path elements\n * @property {Object} dimensionSelection\n * D3 selection of this view models dimension group element\n */\n\n/**\n * @typedef {Object} DimensionViewModel\n * Object containing calculated parcats dimension view information\n *\n * These are quantities that require Layout information to calculate\n * @property key\n * Unique key for this model\n * @property {DimensionModel} model\n * Source dimension model\n * @property {Number} x\n * X position of the center of this dimension with respect to the Figure (pixels)\n * @property {Number} y\n * Y position of the top of this dimension with respect to the Figure (pixels)\n * @property {Number} width\n * Width of categories in this dimension (pixels)\n * @property {ParcatsViewModel} parcatsViewModel\n * The parent trace's view model\n * @property {Array.} categories\n * Dimensions category view models\n * @property {Number|null} dragCategoryDisplayInd\n * Display index of category currently being dragged. null if no category is being dragged\n * @property {Number|null} dragDimensionDisplayInd\n * Display index of the dimension being dragged. null if no dimension is being dragged\n * @property {Array.|null} initialDragDimensionDisplayInds\n * Dimensions display indexes at the beginning of the current drag. null if no dimension is being dragged\n * @property {Array.|null} initialDragCategoryDisplayInds\n * Category display indexes for the at the beginning of the current drag. null if no category is being dragged\n * @property {HTMLElement} potentialClickBand\n * Band under mouse when current drag began. If no drag movement takes place then a click will be emitted for this\n * band. Null if not drag in progress.\n * @property {Boolean} dragHasMoved\n * True if there is an active drag and the drag has moved. If drag doesn't move before being ended then\n * this may be interpreted as a click. Null if no drag in progress\n */\n\n/**\n * @typedef {Object} CategoryViewModel\n * Object containing calculated parcats category view information\n *\n * These are quantities that require Layout information to calculate\n * @property key\n * Unique key for this model\n * @property {CategoryModel} model\n * Source category model\n * @property {Number} width\n * Width for this category (pixels)\n * @property {Number} height\n * Height for this category (pixels)\n * @property {Number} y\n * Y position of this cateogry with respect to the Figure (pixels)\n * @property {Array.} bands\n * Array of color bands inside the category\n * @property {ParcatsViewModel} parcatsViewModel\n * The parent trace's view model\n */\n\n/**\n * @typedef {Object} CategoryBandViewModel\n * Object containing calculated category band information. A category band is a region inside a category covering\n * paths of a single color\n *\n * @property key\n * Unique key for this model\n * @property color\n * Band color\n * @property rawColor\n * Raw color value for band\n * @property {Number} width\n * Band width\n * @property {Number} height\n * Band height\n * @property {Number} y\n * Y position of top of the band with respect to the category\n * @property {Number} count\n * The number of samples represented by the band\n * @property {CategoryViewModel} categoryViewModel\n * The parent categorie's view model\n * @property {ParcatsViewModel} parcatsViewModel\n * The parent trace's view model\n */\n\n/**\n * @typedef {Object} PathViewModel\n * Object containing calculated parcats path view information\n *\n * These are quantities that require Layout information to calculate\n * @property key\n * Unique key for this model\n * @property {PathModel} model\n * Source path model\n * @property {Number} height\n * Height of this path (pixels)\n * @property {Array.} leftXs\n * The x position of the left edge of each display dimension\n * @property {Array.} topYs\n * The y position of the top of the path for each display dimension\n * @property {Array.} dimWidths\n * The width of each display dimension\n * @property {String} svgD\n * SVG path \"d\" attribute string\n * @property {ParcatsViewModel} parcatsViewModel\n * The parent trace's view model\n */\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcats/parcats.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcats/plot.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcats/plot.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar parcats = __webpack_require__(/*! ./parcats */ \"./node_modules/plotly.js/src/traces/parcats/parcats.js\");\n\n/**\n * Create / update parcat traces\n *\n * @param {Object} graphDiv\n * @param {Array.} parcatsModels\n */\nmodule.exports = function plot(graphDiv, parcatsModels, transitionOpts, makeOnCompleteCallback) {\n var fullLayout = graphDiv._fullLayout;\n var svg = fullLayout._paper;\n var size = fullLayout._size;\n\n parcats(\n graphDiv,\n svg,\n parcatsModels,\n {\n width: size.w,\n height: size.h,\n margin: {\n t: size.t,\n r: size.r,\n b: size.b,\n l: size.l\n }\n },\n transitionOpts,\n makeOnCompleteCallback\n );\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcats/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcoords/attributes.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcoords/attributes.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar axesAttrs = __webpack_require__(/*! ../../plots/cartesian/layout_attributes */ \"./node_modules/plotly.js/src/plots/cartesian/layout_attributes.js\");\nvar fontAttrs = __webpack_require__(/*! ../../plots/font_attributes */ \"./node_modules/plotly.js/src/plots/font_attributes.js\");\nvar domainAttrs = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").attributes;\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar templatedArray = __webpack_require__(/*! ../../plot_api/plot_template */ \"./node_modules/plotly.js/src/plot_api/plot_template.js\").templatedArray;\n\nmodule.exports = {\n domain: domainAttrs({name: 'parcoords', trace: true, editType: 'plot'}),\n\n labelangle: {\n valType: 'angle',\n dflt: 0,\n \n editType: 'plot',\n \n },\n\n labelside: {\n valType: 'enumerated',\n \n values: ['top', 'bottom'],\n dflt: 'top',\n editType: 'plot',\n \n },\n\n labelfont: fontAttrs({\n editType: 'plot',\n \n }),\n tickfont: fontAttrs({\n editType: 'plot',\n \n }),\n rangefont: fontAttrs({\n editType: 'plot',\n \n }),\n\n dimensions: templatedArray('dimension', {\n label: {\n valType: 'string',\n \n editType: 'plot',\n \n },\n // TODO: better way to determine ordinal vs continuous axes,\n // so users can use tickvals/ticktext with a continuous axis.\n tickvals: extendFlat({}, axesAttrs.tickvals, {\n editType: 'plot',\n \n }),\n ticktext: extendFlat({}, axesAttrs.ticktext, {\n editType: 'plot',\n \n }),\n tickformat: extendFlat({}, axesAttrs.tickformat, {\n editType: 'plot'\n }),\n visible: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'plot',\n \n },\n range: {\n valType: 'info_array',\n \n items: [\n {valType: 'number', editType: 'plot'},\n {valType: 'number', editType: 'plot'}\n ],\n editType: 'plot',\n \n },\n constraintrange: {\n valType: 'info_array',\n \n freeLength: true,\n dimensions: '1-2',\n items: [\n {valType: 'number', editType: 'plot'},\n {valType: 'number', editType: 'plot'}\n ],\n editType: 'plot',\n \n },\n multiselect: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'plot',\n \n },\n values: {\n valType: 'data_array',\n \n editType: 'calc',\n \n },\n editType: 'calc',\n \n }),\n\n line: extendFlat({editType: 'calc'},\n colorScaleAttrs('line', {\n // the default autocolorscale isn't quite usable for parcoords due to context ambiguity around 0 (grey, off-white)\n // autocolorscale therefore defaults to false too, to avoid being overridden by the blue-white-red autocolor palette\n colorscaleDflt: 'Viridis',\n autoColorDflt: false,\n editTypeOverride: 'calc'\n })\n )\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcoords/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcoords/axisbrush.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcoords/axisbrush.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar c = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/parcoords/constants.js\");\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar keyFun = __webpack_require__(/*! ../../lib/gup */ \"./node_modules/plotly.js/src/lib/gup.js\").keyFun;\nvar repeat = __webpack_require__(/*! ../../lib/gup */ \"./node_modules/plotly.js/src/lib/gup.js\").repeat;\nvar sortAsc = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").sorterAsc;\n\nvar snapRatio = c.bar.snapRatio;\nfunction snapOvershoot(v, vAdjacent) { return v * (1 - snapRatio) + vAdjacent * snapRatio; }\n\nvar snapClose = c.bar.snapClose;\nfunction closeToCovering(v, vAdjacent) { return v * (1 - snapClose) + vAdjacent * snapClose; }\n\n// snap for the low end of a range on an ordinal scale\n// on an ordinal scale, always show some overshoot from the exact value,\n// so it's clear we're covering it\n// find the interval we're in, and snap to 1/4 the distance to the next\n// these two could be unified at a slight loss of readability / perf\nfunction ordinalScaleSnap(isHigh, a, v, existingRanges) {\n if(overlappingExisting(v, existingRanges)) return v;\n\n var dir = isHigh ? -1 : 1;\n\n var first = 0;\n var last = a.length - 1;\n if(dir < 0) {\n var tmp = first;\n first = last;\n last = tmp;\n }\n\n var aHere = a[first];\n var aPrev = aHere;\n for(var i = first; dir * i < dir * last; i += dir) {\n var nextI = i + dir;\n var aNext = a[nextI];\n\n // very close to the previous - snap down to it\n if(dir * v < dir * closeToCovering(aHere, aNext)) return snapOvershoot(aHere, aPrev);\n if(dir * v < dir * aNext || nextI === last) return snapOvershoot(aNext, aHere);\n\n aPrev = aHere;\n aHere = aNext;\n }\n}\n\nfunction overlappingExisting(v, existingRanges) {\n for(var i = 0; i < existingRanges.length; i++) {\n if(v >= existingRanges[i][0] && v <= existingRanges[i][1]) return true;\n }\n return false;\n}\n\nfunction barHorizontalSetup(selection) {\n selection\n .attr('x', -c.bar.captureWidth / 2)\n .attr('width', c.bar.captureWidth);\n}\n\nfunction backgroundBarHorizontalSetup(selection) {\n selection\n .attr('visibility', 'visible')\n .style('visibility', 'visible')\n .attr('fill', 'yellow')\n .attr('opacity', 0);\n}\n\nfunction setHighlight(d) {\n if(!d.brush.filterSpecified) {\n return '0,' + d.height;\n }\n\n var pixelRanges = unitToPx(d.brush.filter.getConsolidated(), d.height);\n var dashArray = [0]; // we start with a 0 length selection as filter ranges are inclusive, not exclusive\n var p, sectionHeight, iNext;\n var currentGap = pixelRanges.length ? pixelRanges[0][0] : null;\n for(var i = 0; i < pixelRanges.length; i++) {\n p = pixelRanges[i];\n sectionHeight = p[1] - p[0];\n dashArray.push(currentGap);\n dashArray.push(sectionHeight);\n iNext = i + 1;\n if(iNext < pixelRanges.length) {\n currentGap = pixelRanges[iNext][0] - p[1];\n }\n }\n dashArray.push(d.height);\n // d.height is added at the end to ensure that (1) we have an even number of dasharray points, MDN page says\n // \"If an odd number of values is provided, then the list of values is repeated to yield an even number of values.\"\n // and (2) it's _at least_ as long as the full height (even if range is minuscule and at the bottom) though this\n // may not be necessary, maybe duplicating the last point would do too. But no harm in a longer dasharray than line.\n return dashArray;\n}\n\nfunction unitToPx(unitRanges, height) {\n return unitRanges.map(function(pr) {\n return pr.map(function(v) { return Math.max(0, v * height); }).sort(sortAsc);\n });\n}\n\n// is the cursor over the north, middle, or south of a bar?\n// the end handles extend over the last 10% of the bar\nfunction getRegion(fPix, y) {\n var pad = c.bar.handleHeight;\n if(y > fPix[1] + pad || y < fPix[0] - pad) return;\n if(y >= 0.9 * fPix[1] + 0.1 * fPix[0]) return 'n';\n if(y <= 0.9 * fPix[0] + 0.1 * fPix[1]) return 's';\n return 'ns';\n}\n\nfunction clearCursor() {\n d3.select(document.body)\n .style('cursor', null);\n}\n\nfunction styleHighlight(selection) {\n // stroke-dasharray is used to minimize the number of created DOM nodes, because the requirement calls for up to\n // 1000 individual selections on an axis, and there can be 60 axes per parcoords, and multiple parcoords per\n // dashboard. The technique is similar to https://codepen.io/monfera/pen/rLYqWR and using a `polyline` with\n // multiple sections, or a `path` element via its `d` attribute would also be DOM-sparing alternatives.\n selection.attr('stroke-dasharray', setHighlight);\n}\n\nfunction renderHighlight(root, tweenCallback) {\n var bar = d3.select(root).selectAll('.highlight, .highlight-shadow');\n var barToStyle = tweenCallback ? bar.transition().duration(c.bar.snapDuration).each('end', tweenCallback) : bar;\n styleHighlight(barToStyle);\n}\n\nfunction getInterval(d, y) {\n var b = d.brush;\n var active = b.filterSpecified;\n var closestInterval = NaN;\n var out = {};\n var i;\n\n if(active) {\n var height = d.height;\n var intervals = b.filter.getConsolidated();\n var pixIntervals = unitToPx(intervals, height);\n var hoveredInterval = NaN;\n var previousInterval = NaN;\n var nextInterval = NaN;\n for(i = 0; i <= pixIntervals.length; i++) {\n var p = pixIntervals[i];\n if(p && p[0] <= y && y <= p[1]) {\n // over a bar\n hoveredInterval = i;\n break;\n } else {\n // between bars, or before/after the first/last bar\n previousInterval = i ? i - 1 : NaN;\n if(p && p[0] > y) {\n nextInterval = i;\n break; // no point continuing as intervals are non-overlapping and sorted; could use log search\n }\n }\n }\n\n closestInterval = hoveredInterval;\n if(isNaN(closestInterval)) {\n if(isNaN(previousInterval) || isNaN(nextInterval)) {\n closestInterval = isNaN(previousInterval) ? nextInterval : previousInterval;\n } else {\n closestInterval = (y - pixIntervals[previousInterval][1] < pixIntervals[nextInterval][0] - y) ?\n previousInterval : nextInterval;\n }\n }\n\n if(!isNaN(closestInterval)) {\n var fPix = pixIntervals[closestInterval];\n var region = getRegion(fPix, y);\n\n if(region) {\n out.interval = intervals[closestInterval];\n out.intervalPix = fPix;\n out.region = region;\n }\n }\n }\n\n if(d.ordinal && !out.region) {\n var a = d.unitTickvals;\n var unitLocation = d.unitToPaddedPx.invert(y);\n for(i = 0; i < a.length; i++) {\n var rangei = [\n a[Math.max(i - 1, 0)] * 0.25 + a[i] * 0.75,\n a[Math.min(i + 1, a.length - 1)] * 0.25 + a[i] * 0.75\n ];\n if(unitLocation >= rangei[0] && unitLocation <= rangei[1]) {\n out.clickableOrdinalRange = rangei;\n break;\n }\n }\n }\n\n return out;\n}\n\nfunction dragstart(lThis, d) {\n d3.event.sourceEvent.stopPropagation();\n var y = d.height - d3.mouse(lThis)[1] - 2 * c.verticalPadding;\n var unitLocation = d.unitToPaddedPx.invert(y);\n var b = d.brush;\n var interval = getInterval(d, y);\n var unitRange = interval.interval;\n var s = b.svgBrush;\n s.wasDragged = false; // we start assuming there won't be a drag - useful for reset\n s.grabbingBar = interval.region === 'ns';\n if(s.grabbingBar) {\n var pixelRange = unitRange.map(d.unitToPaddedPx);\n s.grabPoint = y - pixelRange[0] - c.verticalPadding;\n s.barLength = pixelRange[1] - pixelRange[0];\n }\n s.clickableOrdinalRange = interval.clickableOrdinalRange;\n s.stayingIntervals = (d.multiselect && b.filterSpecified) ? b.filter.getConsolidated() : [];\n if(unitRange) {\n s.stayingIntervals = s.stayingIntervals.filter(function(int2) {\n return int2[0] !== unitRange[0] && int2[1] !== unitRange[1];\n });\n }\n s.startExtent = interval.region ? unitRange[interval.region === 's' ? 1 : 0] : unitLocation;\n d.parent.inBrushDrag = true;\n s.brushStartCallback();\n}\n\nfunction drag(lThis, d) {\n d3.event.sourceEvent.stopPropagation();\n var y = d.height - d3.mouse(lThis)[1] - 2 * c.verticalPadding;\n var s = d.brush.svgBrush;\n s.wasDragged = true;\n s._dragging = true;\n\n if(s.grabbingBar) { // moving the bar\n s.newExtent = [y - s.grabPoint, y + s.barLength - s.grabPoint].map(d.unitToPaddedPx.invert);\n } else { // south/north drag or new bar creation\n s.newExtent = [s.startExtent, d.unitToPaddedPx.invert(y)].sort(sortAsc);\n }\n\n d.brush.filterSpecified = true;\n s.extent = s.stayingIntervals.concat([s.newExtent]);\n s.brushCallback(d);\n renderHighlight(lThis.parentNode);\n}\n\nfunction dragend(lThis, d) {\n var brush = d.brush;\n var filter = brush.filter;\n var s = brush.svgBrush;\n\n if(!s._dragging) { // i.e. click\n // mock zero drag\n mousemove(lThis, d);\n drag(lThis, d);\n // remember it is a click not a drag\n d.brush.svgBrush.wasDragged = false;\n }\n s._dragging = false;\n\n var e = d3.event;\n e.sourceEvent.stopPropagation();\n var grabbingBar = s.grabbingBar;\n s.grabbingBar = false;\n s.grabLocation = undefined;\n d.parent.inBrushDrag = false;\n clearCursor(); // instead of clearing, a nicer thing would be to set it according to current location\n if(!s.wasDragged) { // a click+release on the same spot (ie. w/o dragging) means a bar or full reset\n s.wasDragged = undefined; // logic-wise unneeded, just shows `wasDragged` has no longer a meaning\n if(s.clickableOrdinalRange) {\n if(brush.filterSpecified && d.multiselect) {\n s.extent.push(s.clickableOrdinalRange);\n } else {\n s.extent = [s.clickableOrdinalRange];\n brush.filterSpecified = true;\n }\n } else if(grabbingBar) {\n s.extent = s.stayingIntervals;\n if(s.extent.length === 0) {\n brushClear(brush);\n }\n } else {\n brushClear(brush);\n }\n s.brushCallback(d);\n renderHighlight(lThis.parentNode);\n s.brushEndCallback(brush.filterSpecified ? filter.getConsolidated() : []);\n return; // no need to fuse intervals or snap to ordinals, so we can bail early\n }\n\n var mergeIntervals = function() {\n // Key piece of logic: once the button is released, possibly overlapping intervals will be fused:\n // Here it's done immediately on click release while on ordinal snap transition it's done at the end\n filter.set(filter.getConsolidated());\n };\n\n if(d.ordinal) {\n var a = d.unitTickvals;\n if(a[a.length - 1] < a[0]) a.reverse();\n s.newExtent = [\n ordinalScaleSnap(0, a, s.newExtent[0], s.stayingIntervals),\n ordinalScaleSnap(1, a, s.newExtent[1], s.stayingIntervals)\n ];\n var hasNewExtent = s.newExtent[1] > s.newExtent[0];\n s.extent = s.stayingIntervals.concat(hasNewExtent ? [s.newExtent] : []);\n if(!s.extent.length) {\n brushClear(brush);\n }\n s.brushCallback(d);\n if(hasNewExtent) {\n // merging intervals post the snap tween\n renderHighlight(lThis.parentNode, mergeIntervals);\n } else {\n // if no new interval, don't animate, just redraw the highlight immediately\n mergeIntervals();\n renderHighlight(lThis.parentNode);\n }\n } else {\n mergeIntervals(); // merging intervals immediately\n }\n s.brushEndCallback(brush.filterSpecified ? filter.getConsolidated() : []);\n}\n\nfunction mousemove(lThis, d) {\n var y = d.height - d3.mouse(lThis)[1] - 2 * c.verticalPadding;\n var interval = getInterval(d, y);\n\n var cursor = 'crosshair';\n if(interval.clickableOrdinalRange) cursor = 'pointer';\n else if(interval.region) cursor = interval.region + '-resize';\n d3.select(document.body)\n .style('cursor', cursor);\n}\n\nfunction attachDragBehavior(selection) {\n // There's some fiddling with pointer cursor styling so that the cursor preserves its shape while dragging a brush\n // even if the cursor strays from the interacting bar, which is bound to happen as bars are thin and the user\n // will inevitably leave the hotspot strip. In this regard, it does something similar to what the D3 brush would do.\n selection\n .on('mousemove', function(d) {\n d3.event.preventDefault();\n if(!d.parent.inBrushDrag) mousemove(this, d);\n })\n .on('mouseleave', function(d) {\n if(!d.parent.inBrushDrag) clearCursor();\n })\n .call(d3.behavior.drag()\n .on('dragstart', function(d) { dragstart(this, d); })\n .on('drag', function(d) { drag(this, d); })\n .on('dragend', function(d) { dragend(this, d); })\n );\n}\n\nfunction startAsc(a, b) { return a[0] - b[0]; }\n\nfunction renderAxisBrush(axisBrush) {\n var background = axisBrush.selectAll('.background').data(repeat);\n\n background.enter()\n .append('rect')\n .classed('background', true)\n .call(barHorizontalSetup)\n .call(backgroundBarHorizontalSetup)\n .style('pointer-events', 'auto') // parent pointer events are disabled; we must have it to register events\n .attr('transform', 'translate(0 ' + c.verticalPadding + ')');\n\n background\n .call(attachDragBehavior)\n .attr('height', function(d) {\n return d.height - c.verticalPadding;\n });\n\n var highlightShadow = axisBrush.selectAll('.highlight-shadow').data(repeat); // we have a set here, can't call it `extent`\n\n highlightShadow.enter()\n .append('line')\n .classed('highlight-shadow', true)\n .attr('x', -c.bar.width / 2)\n .attr('stroke-width', c.bar.width + c.bar.strokeWidth)\n .attr('stroke', c.bar.strokeColor)\n .attr('opacity', c.bar.strokeOpacity)\n .attr('stroke-linecap', 'butt');\n\n highlightShadow\n .attr('y1', function(d) { return d.height; })\n .call(styleHighlight);\n\n var highlight = axisBrush.selectAll('.highlight').data(repeat); // we have a set here, can't call it `extent`\n\n highlight.enter()\n .append('line')\n .classed('highlight', true)\n .attr('x', -c.bar.width / 2)\n .attr('stroke-width', c.bar.width - c.bar.strokeWidth)\n .attr('stroke', c.bar.fillColor)\n .attr('opacity', c.bar.fillOpacity)\n .attr('stroke-linecap', 'butt');\n\n highlight\n .attr('y1', function(d) { return d.height; })\n .call(styleHighlight);\n}\n\nfunction ensureAxisBrush(axisOverlays) {\n var axisBrush = axisOverlays.selectAll('.' + c.cn.axisBrush)\n .data(repeat, keyFun);\n\n axisBrush.enter()\n .append('g')\n .classed(c.cn.axisBrush, true);\n\n renderAxisBrush(axisBrush);\n}\n\nfunction getBrushExtent(brush) {\n return brush.svgBrush.extent.map(function(e) {return e.slice();});\n}\n\nfunction brushClear(brush) {\n brush.filterSpecified = false;\n brush.svgBrush.extent = [[-Infinity, Infinity]];\n}\n\nfunction axisBrushMoved(callback) {\n return function axisBrushMoved(dimension) {\n var brush = dimension.brush;\n var extent = getBrushExtent(brush);\n var newExtent = extent.slice();\n brush.filter.set(newExtent);\n callback();\n };\n}\n\nfunction dedupeRealRanges(intervals) {\n // Fuses elements of intervals if they overlap, yielding discontiguous intervals, results.length <= intervals.length\n // Currently uses closed intervals, ie. dedupeRealRanges([[400, 800], [300, 400]]) -> [300, 800]\n var queue = intervals.slice();\n var result = [];\n var currentInterval;\n var current = queue.shift();\n while(current) { // [].shift === undefined, so we don't descend into an empty array\n currentInterval = current.slice();\n while((current = queue.shift()) && current[0] <= /* right-open interval would need `<` */ currentInterval[1]) {\n currentInterval[1] = Math.max(currentInterval[1], current[1]);\n }\n result.push(currentInterval);\n }\n return result;\n}\n\nfunction makeFilter() {\n var filter = [];\n var consolidated;\n var bounds;\n return {\n set: function(a) {\n filter = a\n .map(function(d) { return d.slice().sort(sortAsc); })\n .sort(startAsc);\n\n // handle unselected case\n if(filter.length === 1 &&\n filter[0][0] === -Infinity &&\n filter[0][1] === Infinity) {\n filter = [[0, -1]];\n }\n\n consolidated = dedupeRealRanges(filter);\n bounds = filter.reduce(function(p, n) {\n return [Math.min(p[0], n[0]), Math.max(p[1], n[1])];\n }, [Infinity, -Infinity]);\n },\n get: function() { return filter.slice(); },\n getConsolidated: function() { return consolidated; },\n getBounds: function() { return bounds; }\n };\n}\n\nfunction makeBrush(state, rangeSpecified, initialRange, brushStartCallback, brushCallback, brushEndCallback) {\n var filter = makeFilter();\n filter.set(initialRange);\n return {\n filter: filter,\n filterSpecified: rangeSpecified, // there's a difference between not filtering and filtering a non-proper subset\n svgBrush: {\n extent: [], // this is where the svgBrush writes contents into\n brushStartCallback: brushStartCallback,\n brushCallback: axisBrushMoved(brushCallback),\n brushEndCallback: brushEndCallback\n }\n };\n}\n\n// for use by supplyDefaults, but it needed tons of pieces from here so\n// seemed to make more sense just to put the whole routine here\nfunction cleanRanges(ranges, dimension) {\n if(Array.isArray(ranges[0])) {\n ranges = ranges.map(function(ri) { return ri.sort(sortAsc); });\n\n if(!dimension.multiselect) ranges = [ranges[0]];\n else ranges = dedupeRealRanges(ranges.sort(startAsc));\n } else ranges = [ranges.sort(sortAsc)];\n\n // ordinal snapping\n if(dimension.tickvals) {\n var sortedTickVals = dimension.tickvals.slice().sort(sortAsc);\n ranges = ranges.map(function(ri) {\n var rSnapped = [\n ordinalScaleSnap(0, sortedTickVals, ri[0], []),\n ordinalScaleSnap(1, sortedTickVals, ri[1], [])\n ];\n if(rSnapped[1] > rSnapped[0]) return rSnapped;\n })\n .filter(function(ri) { return ri; });\n\n if(!ranges.length) return;\n }\n return ranges.length > 1 ? ranges : ranges[0];\n}\n\nmodule.exports = {\n makeBrush: makeBrush,\n ensureAxisBrush: ensureAxisBrush,\n cleanRanges: cleanRanges\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcoords/axisbrush.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcoords/base_plot.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcoords/base_plot.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar getModuleCalcData = __webpack_require__(/*! ../../plots/get_data */ \"./node_modules/plotly.js/src/plots/get_data.js\").getModuleCalcData;\nvar parcoordsPlot = __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/parcoords/plot.js\");\nvar xmlnsNamespaces = __webpack_require__(/*! ../../constants/xmlns_namespaces */ \"./node_modules/plotly.js/src/constants/xmlns_namespaces.js\");\n\nexports.name = 'parcoords';\n\nexports.plot = function(gd) {\n var calcData = getModuleCalcData(gd.calcdata, 'parcoords')[0];\n if(calcData.length) parcoordsPlot(gd, calcData);\n};\n\nexports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {\n var hadParcoords = (oldFullLayout._has && oldFullLayout._has('parcoords'));\n var hasParcoords = (newFullLayout._has && newFullLayout._has('parcoords'));\n\n if(hadParcoords && !hasParcoords) {\n oldFullLayout._paperdiv.selectAll('.parcoords').remove();\n oldFullLayout._glimages.selectAll('*').remove();\n }\n};\n\nexports.toSVG = function(gd) {\n var imageRoot = gd._fullLayout._glimages;\n var root = d3.select(gd).selectAll('.svg-container');\n var canvases = root.filter(function(d, i) {return i === root.size() - 1;})\n .selectAll('.gl-canvas-context, .gl-canvas-focus');\n\n function canvasToImage() {\n var canvas = this;\n var imageData = canvas.toDataURL('image/png');\n var image = imageRoot.append('svg:image');\n\n image.attr({\n xmlns: xmlnsNamespaces.svg,\n 'xlink:href': imageData,\n preserveAspectRatio: 'none',\n x: 0,\n y: 0,\n width: canvas.width,\n height: canvas.height\n });\n }\n\n canvases.each(canvasToImage);\n\n // Chrome / Safari bug workaround - browser apparently loses connection to the defined pattern\n // Without the workaround, these browsers 'lose' the filter brush styling (color etc.) after a snapshot\n // on a subsequent interaction.\n // Firefox works fine without this workaround\n window.setTimeout(function() {\n d3.selectAll('#filterBarPattern')\n .attr('id', 'filterBarPattern');\n }, 60);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcoords/base_plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcoords/calc.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcoords/calc.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isArrayOrTypedArray = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").isArrayOrTypedArray;\nvar Colorscale = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\");\nvar wrap = __webpack_require__(/*! ../../lib/gup */ \"./node_modules/plotly.js/src/lib/gup.js\").wrap;\n\nmodule.exports = function calc(gd, trace) {\n var lineColor;\n var cscale;\n\n if(Colorscale.hasColorscale(trace, 'line') && isArrayOrTypedArray(trace.line.color)) {\n lineColor = trace.line.color;\n cscale = Colorscale.extractOpts(trace.line).colorscale;\n\n Colorscale.calc(gd, trace, {\n vals: lineColor,\n containerStr: 'line',\n cLetter: 'c'\n });\n } else {\n lineColor = constHalf(trace._length);\n cscale = [[0, trace.line.color], [1, trace.line.color]];\n }\n\n return wrap({lineColor: lineColor, cscale: cscale});\n};\n\nfunction constHalf(len) {\n var out = new Array(len);\n for(var i = 0; i < len; i++) {\n out[i] = 0.5;\n }\n return out;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcoords/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcoords/constants.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcoords/constants.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nmodule.exports = {\n maxDimensionCount: 60, // this cannot be increased without WebGL code refactoring\n overdrag: 45,\n verticalPadding: 2, // otherwise, horizontal lines on top or bottom are of lower width\n tickDistance: 50,\n canvasPixelRatio: 1,\n blockLineCount: 5000,\n layers: ['contextLineLayer', 'focusLineLayer', 'pickLineLayer'],\n axisTitleOffset: 28,\n axisExtentOffset: 10,\n deselectedLineColor: '#777',\n bar: {\n width: 4, // Visible width of the filter bar\n captureWidth: 10, // Mouse-sensitive width for interaction (Fitts law)\n fillColor: 'magenta', // Color of the filter bar fill\n fillOpacity: 1, // Filter bar fill opacity\n snapDuration: 150, // tween duration in ms for brush snap for ordinal axes\n snapRatio: 0.25, // ratio of bar extension relative to the distance between two adjacent ordinal values\n snapClose: 0.01, // fraction of inter-value distance to snap to the closer one, even if you're not over it\n strokeColor: 'white', // Color of the filter bar side lines\n strokeOpacity: 1, // Filter bar side stroke opacity\n strokeWidth: 1, // Filter bar side stroke width in pixels\n handleHeight: 8, // Height of the filter bar vertical resize areas on top and bottom\n handleOpacity: 1, // Opacity of the filter bar vertical resize areas on top and bottom\n handleOverlap: 0 // A larger than 0 value causes overlaps with the filter bar, represented as pixels\n },\n cn: {\n axisExtentText: 'axis-extent-text',\n parcoordsLineLayers: 'parcoords-line-layers',\n parcoordsLineLayer: 'parcoords-lines',\n parcoords: 'parcoords',\n parcoordsControlView: 'parcoords-control-view',\n yAxis: 'y-axis',\n axisOverlays: 'axis-overlays',\n axis: 'axis',\n axisHeading: 'axis-heading',\n axisTitle: 'axis-title',\n axisExtent: 'axis-extent',\n axisExtentTop: 'axis-extent-top',\n axisExtentTopText: 'axis-extent-top-text',\n axisExtentBottom: 'axis-extent-bottom',\n axisExtentBottomText: 'axis-extent-bottom-text',\n axisBrush: 'axis-brush'\n },\n id: {\n filterBarPattern: 'filter-bar-pattern'\n\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcoords/constants.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcoords/defaults.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcoords/defaults.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar hasColorscale = __webpack_require__(/*! ../../components/colorscale/helpers */ \"./node_modules/plotly.js/src/components/colorscale/helpers.js\").hasColorscale;\nvar colorscaleDefaults = __webpack_require__(/*! ../../components/colorscale/defaults */ \"./node_modules/plotly.js/src/components/colorscale/defaults.js\");\nvar handleDomainDefaults = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").defaults;\nvar handleArrayContainerDefaults = __webpack_require__(/*! ../../plots/array_container_defaults */ \"./node_modules/plotly.js/src/plots/array_container_defaults.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\n\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/parcoords/attributes.js\");\nvar axisBrush = __webpack_require__(/*! ./axisbrush */ \"./node_modules/plotly.js/src/traces/parcoords/axisbrush.js\");\nvar maxDimensionCount = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/parcoords/constants.js\").maxDimensionCount;\nvar mergeLength = __webpack_require__(/*! ./merge_length */ \"./node_modules/plotly.js/src/traces/parcoords/merge_length.js\");\n\nfunction handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce) {\n var lineColor = coerce('line.color', defaultColor);\n\n if(hasColorscale(traceIn, 'line') && Lib.isArrayOrTypedArray(lineColor)) {\n if(lineColor.length) {\n coerce('line.colorscale');\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: 'line.', cLetter: 'c'});\n // TODO: I think it would be better to keep showing lines beyond the last line color\n // but I'm not sure what color to give these lines - probably black or white\n // depending on the background color?\n return lineColor.length;\n } else {\n traceOut.line.color = defaultColor;\n }\n }\n return Infinity;\n}\n\nfunction dimensionDefaults(dimensionIn, dimensionOut, parentOut, opts) {\n function coerce(attr, dflt) {\n return Lib.coerce(dimensionIn, dimensionOut, attributes.dimensions, attr, dflt);\n }\n\n var values = coerce('values');\n var visible = coerce('visible');\n if(!(values && values.length)) {\n visible = dimensionOut.visible = false;\n }\n\n if(visible) {\n coerce('label');\n coerce('tickvals');\n coerce('ticktext');\n coerce('tickformat');\n var range = coerce('range');\n\n dimensionOut._ax = {\n _id: 'y',\n type: 'linear',\n showexponent: 'all',\n exponentformat: 'B',\n range: range\n };\n\n Axes.setConvert(dimensionOut._ax, opts.layout);\n\n coerce('multiselect');\n var constraintRange = coerce('constraintrange');\n if(constraintRange) {\n dimensionOut.constraintrange = axisBrush.cleanRanges(constraintRange, dimensionOut);\n }\n }\n}\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var dimensionsIn = traceIn.dimensions;\n if(Array.isArray(dimensionsIn) && dimensionsIn.length > maxDimensionCount) {\n Lib.log('parcoords traces support up to ' + maxDimensionCount + ' dimensions at the moment');\n dimensionsIn.splice(maxDimensionCount);\n }\n\n var dimensions = handleArrayContainerDefaults(traceIn, traceOut, {\n name: 'dimensions',\n layout: layout,\n handleItemDefaults: dimensionDefaults\n });\n\n var len = handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);\n\n handleDomainDefaults(traceOut, layout, coerce);\n\n if(!Array.isArray(dimensions) || !dimensions.length) {\n traceOut.visible = false;\n }\n\n mergeLength(traceOut, dimensions, 'values', len);\n\n // make default font size 10px (default is 12),\n // scale linearly with global font size\n var fontDflt = {\n family: layout.font.family,\n size: Math.round(layout.font.size / 1.2),\n color: layout.font.color\n };\n\n Lib.coerceFont(coerce, 'labelfont', fontDflt);\n Lib.coerceFont(coerce, 'tickfont', fontDflt);\n Lib.coerceFont(coerce, 'rangefont', fontDflt);\n\n coerce('labelangle');\n coerce('labelside');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcoords/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcoords/helpers.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcoords/helpers.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isTypedArray = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").isTypedArray;\n\nexports.convertTypedArray = function(a) {\n return isTypedArray(a) ? Array.prototype.slice.call(a) : a;\n};\n\nexports.isOrdinal = function(dimension) {\n return !!dimension.tickvals;\n};\n\nexports.isVisible = function(dimension) {\n return dimension.visible || !('visible' in dimension);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcoords/helpers.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcoords/index.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcoords/index.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/parcoords/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/parcoords/defaults.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/parcoords/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/parcoords/plot.js\"),\n colorbar: {\n container: 'line',\n min: 'cmin',\n max: 'cmax'\n },\n\n moduleType: 'trace',\n name: 'parcoords',\n basePlotModule: __webpack_require__(/*! ./base_plot */ \"./node_modules/plotly.js/src/traces/parcoords/base_plot.js\"),\n categories: ['gl', 'regl', 'noOpacity', 'noHover'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcoords/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcoords/lines.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcoords/lines.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar glslify = __webpack_require__(/*! glslify */ \"./node_modules/glslify/browser.js\");\nvar vertexShaderSource = glslify([\"precision highp float;\\n#define GLSLIFY 1\\n\\nvarying vec4 fragColor;\\n\\nattribute vec4 p01_04, p05_08, p09_12, p13_16,\\n p17_20, p21_24, p25_28, p29_32,\\n p33_36, p37_40, p41_44, p45_48,\\n p49_52, p53_56, p57_60, colors;\\n\\nuniform mat4 dim0A, dim1A, dim0B, dim1B, dim0C, dim1C, dim0D, dim1D,\\n loA, hiA, loB, hiB, loC, hiC, loD, hiD;\\n\\nuniform vec2 resolution, viewBoxPos, viewBoxSize;\\nuniform sampler2D mask, palette;\\nuniform float maskHeight;\\nuniform float drwLayer; // 0: context, 1: focus, 2: pick\\nuniform vec4 contextColor;\\n\\nbool isPick = (drwLayer > 1.5);\\nbool isContext = (drwLayer < 0.5);\\n\\nconst vec4 ZEROS = vec4(0.0, 0.0, 0.0, 0.0);\\nconst vec4 UNITS = vec4(1.0, 1.0, 1.0, 1.0);\\n\\nfloat val(mat4 p, mat4 v) {\\n return dot(matrixCompMult(p, v) * UNITS, UNITS);\\n}\\n\\nfloat axisY(float ratio, mat4 A, mat4 B, mat4 C, mat4 D) {\\n float y1 = val(A, dim0A) + val(B, dim0B) + val(C, dim0C) + val(D, dim0D);\\n float y2 = val(A, dim1A) + val(B, dim1B) + val(C, dim1C) + val(D, dim1D);\\n return y1 * (1.0 - ratio) + y2 * ratio;\\n}\\n\\nint iMod(int a, int b) {\\n return a - b * (a / b);\\n}\\n\\nbool fOutside(float p, float lo, float hi) {\\n return (lo < hi) && (lo > p || p > hi);\\n}\\n\\nbool vOutside(vec4 p, vec4 lo, vec4 hi) {\\n return (\\n fOutside(p[0], lo[0], hi[0]) ||\\n fOutside(p[1], lo[1], hi[1]) ||\\n fOutside(p[2], lo[2], hi[2]) ||\\n fOutside(p[3], lo[3], hi[3])\\n );\\n}\\n\\nbool mOutside(mat4 p, mat4 lo, mat4 hi) {\\n return (\\n vOutside(p[0], lo[0], hi[0]) ||\\n vOutside(p[1], lo[1], hi[1]) ||\\n vOutside(p[2], lo[2], hi[2]) ||\\n vOutside(p[3], lo[3], hi[3])\\n );\\n}\\n\\nbool outsideBoundingBox(mat4 A, mat4 B, mat4 C, mat4 D) {\\n return mOutside(A, loA, hiA) ||\\n mOutside(B, loB, hiB) ||\\n mOutside(C, loC, hiC) ||\\n mOutside(D, loD, hiD);\\n}\\n\\nbool outsideRasterMask(mat4 A, mat4 B, mat4 C, mat4 D) {\\n mat4 pnts[4];\\n pnts[0] = A;\\n pnts[1] = B;\\n pnts[2] = C;\\n pnts[3] = D;\\n\\n for(int i = 0; i < 4; ++i) {\\n for(int j = 0; j < 4; ++j) {\\n for(int k = 0; k < 4; ++k) {\\n if(0 == iMod(\\n int(255.0 * texture2D(mask,\\n vec2(\\n (float(i * 2 + j / 2) + 0.5) / 8.0,\\n (pnts[i][j][k] * (maskHeight - 1.0) + 1.0) / maskHeight\\n ))[3]\\n ) / int(pow(2.0, float(iMod(j * 4 + k, 8)))),\\n 2\\n )) return true;\\n }\\n }\\n }\\n return false;\\n}\\n\\nvec4 position(bool isContext, float v, mat4 A, mat4 B, mat4 C, mat4 D) {\\n float x = 0.5 * sign(v) + 0.5;\\n float y = axisY(x, A, B, C, D);\\n float z = 1.0 - abs(v);\\n\\n z += isContext ? 0.0 : 2.0 * float(\\n outsideBoundingBox(A, B, C, D) ||\\n outsideRasterMask(A, B, C, D)\\n );\\n\\n return vec4(\\n 2.0 * (vec2(x, y) * viewBoxSize + viewBoxPos) / resolution - 1.0,\\n z,\\n 1.0\\n );\\n}\\n\\nvoid main() {\\n mat4 A = mat4(p01_04, p05_08, p09_12, p13_16);\\n mat4 B = mat4(p17_20, p21_24, p25_28, p29_32);\\n mat4 C = mat4(p33_36, p37_40, p41_44, p45_48);\\n mat4 D = mat4(p49_52, p53_56, p57_60, ZEROS);\\n\\n float v = colors[3];\\n\\n gl_Position = position(isContext, v, A, B, C, D);\\n\\n fragColor =\\n isContext ? vec4(contextColor) :\\n isPick ? vec4(colors.rgb, 1.0) : texture2D(palette, vec2(abs(v), 0.5));\\n}\\n\"]);\nvar fragmentShaderSource = glslify([\"precision highp float;\\n#define GLSLIFY 1\\n\\nvarying vec4 fragColor;\\n\\nvoid main() {\\n gl_FragColor = fragColor;\\n}\\n\"]);\nvar maxDim = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/parcoords/constants.js\").maxDimensionCount;\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\n// don't change; otherwise near/far plane lines are lost\nvar depthLimitEpsilon = 1e-6;\n\n// precision of multiselect is the full range divided into this many parts\nvar maskHeight = 2048;\n\nvar dummyPixel = new Uint8Array(4);\nvar dataPixel = new Uint8Array(4);\n\nvar paletteTextureConfig = {\n shape: [256, 1],\n format: 'rgba',\n type: 'uint8',\n mag: 'nearest',\n min: 'nearest'\n};\n\nfunction ensureDraw(regl) {\n regl.read({\n x: 0,\n y: 0,\n width: 1,\n height: 1,\n data: dummyPixel\n });\n}\n\nfunction clear(regl, x, y, width, height) {\n var gl = regl._gl;\n gl.enable(gl.SCISSOR_TEST);\n gl.scissor(x, y, width, height);\n regl.clear({color: [0, 0, 0, 0], depth: 1}); // clearing is done in scissored panel only\n}\n\nfunction renderBlock(regl, glAes, renderState, blockLineCount, sampleCount, item) {\n var rafKey = item.key;\n\n function render(blockNumber) {\n var count = Math.min(blockLineCount, sampleCount - blockNumber * blockLineCount);\n\n if(blockNumber === 0) {\n // stop drawing possibly stale glyphs before clearing\n window.cancelAnimationFrame(renderState.currentRafs[rafKey]);\n delete renderState.currentRafs[rafKey];\n clear(regl, item.scissorX, item.scissorY, item.scissorWidth, item.viewBoxSize[1]);\n }\n\n if(renderState.clearOnly) {\n return;\n }\n\n item.count = 2 * count;\n item.offset = 2 * blockNumber * blockLineCount;\n glAes(item);\n\n if(blockNumber * blockLineCount + count < sampleCount) {\n renderState.currentRafs[rafKey] = window.requestAnimationFrame(function() {\n render(blockNumber + 1);\n });\n }\n\n renderState.drawCompleted = false;\n }\n\n if(!renderState.drawCompleted) {\n ensureDraw(regl);\n renderState.drawCompleted = true;\n }\n\n // start with rendering item 0; recursion handles the rest\n render(0);\n}\n\nfunction adjustDepth(d) {\n // WebGL matrix operations use floats with limited precision, potentially causing a number near a border of [0, 1]\n // to end up slightly outside the border. With an epsilon, we reduce the chance that a line gets clipped by the\n // near or the far plane.\n return Math.max(depthLimitEpsilon, Math.min(1 - depthLimitEpsilon, d));\n}\n\nfunction palette(unitToColor, opacity) {\n var result = new Array(256);\n for(var i = 0; i < 256; i++) {\n result[i] = unitToColor(i / 255).concat(opacity);\n }\n return result;\n}\n\n// Maps the sample index [0...sampleCount - 1] to a range of [0, 1] as the shader expects colors in the [0, 1] range.\n// but first it shifts the sample index by 0, 8 or 16 bits depending on rgbIndex [0..2]\n// with the end result that each line will be of a unique color, making it possible for the pick handler\n// to uniquely identify which line is hovered over (bijective mapping).\n// The inverse, i.e. readPixel is invoked from 'parcoords.js'\nfunction calcPickColor(i, rgbIndex) {\n return (i >>> 8 * rgbIndex) % 256 / 255;\n}\n\nfunction makePoints(sampleCount, dims, color) {\n var points = new Array(sampleCount * (maxDim + 4));\n var n = 0;\n for(var i = 0; i < sampleCount; i++) {\n for(var k = 0; k < maxDim; k++) {\n points[n++] = (k < dims.length) ? dims[k].paddedUnitValues[i] : 0.5;\n }\n points[n++] = calcPickColor(i, 2);\n points[n++] = calcPickColor(i, 1);\n points[n++] = calcPickColor(i, 0);\n points[n++] = adjustDepth(color[i]);\n }\n return points;\n}\n\nfunction makeVecAttr(vecIndex, sampleCount, points) {\n var pointPairs = new Array(sampleCount * 8);\n var n = 0;\n for(var i = 0; i < sampleCount; i++) {\n for(var j = 0; j < 2; j++) {\n for(var k = 0; k < 4; k++) {\n var q = vecIndex * 4 + k;\n var v = points[i * 64 + q];\n if(q === 63 && j === 0) {\n v *= -1;\n }\n pointPairs[n++] = v;\n }\n }\n }\n return pointPairs;\n}\n\nfunction pad2(num) {\n var s = '0' + num;\n return s.substr(s.length - 2);\n}\n\nfunction getAttrName(i) {\n return (i < maxDim) ? 'p' + pad2(i + 1) + '_' + pad2(i + 4) : 'colors';\n}\n\nfunction setAttributes(attributes, sampleCount, points) {\n for(var i = 0; i <= maxDim; i += 4) {\n attributes[getAttrName(i)](makeVecAttr(i / 4, sampleCount, points));\n }\n}\n\nfunction emptyAttributes(regl) {\n var attributes = {};\n for(var i = 0; i <= maxDim; i += 4) {\n attributes[getAttrName(i)] = regl.buffer({usage: 'dynamic', type: 'float', data: new Uint8Array(0)});\n }\n return attributes;\n}\n\nfunction makeItem(model, leftmost, rightmost, itemNumber, i0, i1, x, y, panelSizeX, panelSizeY, crossfilterDimensionIndex, drwLayer, constraints) {\n var dims = [[], []];\n for(var k = 0; k < 64; k++) {\n dims[0][k] = (k === i0) ? 1 : 0;\n dims[1][k] = (k === i1) ? 1 : 0;\n }\n\n var overdrag = model.lines.canvasOverdrag;\n var domain = model.domain;\n var canvasWidth = model.canvasWidth;\n var canvasHeight = model.canvasHeight;\n\n var deselectedLinesColor = model.deselectedLines.color;\n\n var itemModel = Lib.extendFlat({\n key: crossfilterDimensionIndex,\n resolution: [canvasWidth, canvasHeight],\n viewBoxPos: [x + overdrag, y],\n viewBoxSize: [panelSizeX, panelSizeY],\n i0: i0,\n i1: i1,\n\n dim0A: dims[0].slice(0, 16),\n dim0B: dims[0].slice(16, 32),\n dim0C: dims[0].slice(32, 48),\n dim0D: dims[0].slice(48, 64),\n dim1A: dims[1].slice(0, 16),\n dim1B: dims[1].slice(16, 32),\n dim1C: dims[1].slice(32, 48),\n dim1D: dims[1].slice(48, 64),\n\n drwLayer: drwLayer,\n contextColor: [\n deselectedLinesColor[0] / 255,\n deselectedLinesColor[1] / 255,\n deselectedLinesColor[2] / 255,\n deselectedLinesColor[3] < 1 ?\n deselectedLinesColor[3] :\n Math.max(1 / 255, Math.pow(1 / model.lines.color.length, 1 / 3))\n ],\n\n scissorX: (itemNumber === leftmost ? 0 : x + overdrag) + (model.pad.l - overdrag) + model.layoutWidth * domain.x[0],\n scissorWidth: (itemNumber === rightmost ? canvasWidth - x + overdrag : panelSizeX + 0.5) + (itemNumber === leftmost ? x + overdrag : 0),\n scissorY: y + model.pad.b + model.layoutHeight * domain.y[0],\n scissorHeight: panelSizeY,\n\n viewportX: model.pad.l - overdrag + model.layoutWidth * domain.x[0],\n viewportY: model.pad.b + model.layoutHeight * domain.y[0],\n viewportWidth: canvasWidth,\n viewportHeight: canvasHeight\n }, constraints);\n\n return itemModel;\n}\n\nfunction expandedPixelRange(bounds) {\n var dh = maskHeight - 1;\n var a = Math.max(0, Math.floor(bounds[0] * dh), 0);\n var b = Math.min(dh, Math.ceil(bounds[1] * dh), dh);\n return [\n Math.min(a, b),\n Math.max(a, b)\n ];\n}\n\nmodule.exports = function(canvasGL, d) {\n // context & pick describe which canvas we're talking about - won't change with new data\n var isContext = d.context;\n var isPick = d.pick;\n\n var regl = d.regl;\n\n var renderState = {\n currentRafs: {},\n drawCompleted: true,\n clearOnly: false\n };\n\n // state to be set by update and used later\n var model;\n var vm;\n var initialDims;\n var sampleCount;\n var attributes = emptyAttributes(regl);\n var maskTexture;\n var paletteTexture = regl.texture(paletteTextureConfig);\n\n var prevAxisOrder = [];\n\n update(d);\n\n var glAes = regl({\n\n profile: false,\n\n blend: {\n enable: isContext,\n func: {\n srcRGB: 'src alpha',\n dstRGB: 'one minus src alpha',\n srcAlpha: 1,\n dstAlpha: 1 // 'one minus src alpha'\n },\n equation: {\n rgb: 'add',\n alpha: 'add'\n },\n color: [0, 0, 0, 0]\n },\n\n depth: {\n enable: !isContext,\n mask: true,\n func: 'less',\n range: [0, 1]\n },\n\n // for polygons\n cull: {\n enable: true,\n face: 'back'\n },\n\n scissor: {\n enable: true,\n box: {\n x: regl.prop('scissorX'),\n y: regl.prop('scissorY'),\n width: regl.prop('scissorWidth'),\n height: regl.prop('scissorHeight')\n }\n },\n\n viewport: {\n x: regl.prop('viewportX'),\n y: regl.prop('viewportY'),\n width: regl.prop('viewportWidth'),\n height: regl.prop('viewportHeight')\n },\n\n dither: false,\n\n vert: vertexShaderSource,\n\n frag: fragmentShaderSource,\n\n primitive: 'lines',\n lineWidth: 1,\n attributes: attributes,\n uniforms: {\n resolution: regl.prop('resolution'),\n viewBoxPos: regl.prop('viewBoxPos'),\n viewBoxSize: regl.prop('viewBoxSize'),\n dim0A: regl.prop('dim0A'),\n dim1A: regl.prop('dim1A'),\n dim0B: regl.prop('dim0B'),\n dim1B: regl.prop('dim1B'),\n dim0C: regl.prop('dim0C'),\n dim1C: regl.prop('dim1C'),\n dim0D: regl.prop('dim0D'),\n dim1D: regl.prop('dim1D'),\n loA: regl.prop('loA'),\n hiA: regl.prop('hiA'),\n loB: regl.prop('loB'),\n hiB: regl.prop('hiB'),\n loC: regl.prop('loC'),\n hiC: regl.prop('hiC'),\n loD: regl.prop('loD'),\n hiD: regl.prop('hiD'),\n palette: paletteTexture,\n contextColor: regl.prop('contextColor'),\n mask: regl.prop('maskTexture'),\n drwLayer: regl.prop('drwLayer'),\n maskHeight: regl.prop('maskHeight')\n },\n offset: regl.prop('offset'),\n count: regl.prop('count')\n });\n\n function update(dNew) {\n model = dNew.model;\n vm = dNew.viewModel;\n initialDims = vm.dimensions.slice();\n sampleCount = initialDims[0] ? initialDims[0].values.length : 0;\n\n var lines = model.lines;\n var color = isPick ? lines.color.map(function(_, i) {return i / lines.color.length;}) : lines.color;\n\n var points = makePoints(sampleCount, initialDims, color);\n setAttributes(attributes, sampleCount, points);\n\n if(!isContext && !isPick) {\n paletteTexture = regl.texture(Lib.extendFlat({\n data: palette(model.unitToColor, 255)\n }, paletteTextureConfig));\n }\n }\n\n function makeConstraints(isContext) {\n var i, j, k;\n\n var limits = [[], []];\n for(k = 0; k < 64; k++) {\n var p = (!isContext && k < initialDims.length) ?\n initialDims[k].brush.filter.getBounds() : [-Infinity, Infinity];\n\n limits[0][k] = p[0];\n limits[1][k] = p[1];\n }\n\n var len = maskHeight * 8;\n var mask = new Array(len);\n for(i = 0; i < len; i++) {\n mask[i] = 255;\n }\n if(!isContext) {\n for(i = 0; i < initialDims.length; i++) {\n var u = i % 8;\n var v = (i - u) / 8;\n var bitMask = Math.pow(2, u);\n var dim = initialDims[i];\n var ranges = dim.brush.filter.get();\n if(ranges.length < 2) continue; // bail if the bounding box based filter is sufficient\n\n var prevEnd = expandedPixelRange(ranges[0])[1];\n for(j = 1; j < ranges.length; j++) {\n var nextRange = expandedPixelRange(ranges[j]);\n for(k = prevEnd + 1; k < nextRange[0]; k++) {\n mask[k * 8 + v] &= ~bitMask;\n }\n prevEnd = Math.max(prevEnd, nextRange[1]);\n }\n }\n }\n\n var textureData = {\n // 8 units x 8 bits = 64 bits, just sufficient for the almost 64 dimensions we support\n shape: [8, maskHeight],\n format: 'alpha',\n type: 'uint8',\n mag: 'nearest',\n min: 'nearest',\n data: mask\n };\n if(maskTexture) maskTexture(textureData);\n else maskTexture = regl.texture(textureData);\n\n return {\n maskTexture: maskTexture,\n maskHeight: maskHeight,\n loA: limits[0].slice(0, 16),\n loB: limits[0].slice(16, 32),\n loC: limits[0].slice(32, 48),\n loD: limits[0].slice(48, 64),\n hiA: limits[1].slice(0, 16),\n hiB: limits[1].slice(16, 32),\n hiC: limits[1].slice(32, 48),\n hiD: limits[1].slice(48, 64),\n };\n }\n\n function renderGLParcoords(panels, setChanged, clearOnly) {\n var panelCount = panels.length;\n var i;\n\n var leftmost;\n var rightmost;\n var lowestX = Infinity;\n var highestX = -Infinity;\n\n for(i = 0; i < panelCount; i++) {\n if(panels[i].dim0.canvasX < lowestX) {\n lowestX = panels[i].dim0.canvasX;\n leftmost = i;\n }\n if(panels[i].dim1.canvasX > highestX) {\n highestX = panels[i].dim1.canvasX;\n rightmost = i;\n }\n }\n\n if(panelCount === 0) {\n // clear canvas here, as the panel iteration below will not enter the loop body\n clear(regl, 0, 0, model.canvasWidth, model.canvasHeight);\n }\n var constraints = makeConstraints(isContext);\n\n for(i = 0; i < panelCount; i++) {\n var p = panels[i];\n var i0 = p.dim0.crossfilterDimensionIndex;\n var i1 = p.dim1.crossfilterDimensionIndex;\n var x = p.canvasX;\n var y = p.canvasY;\n var nextX = x + p.panelSizeX;\n if(setChanged ||\n !prevAxisOrder[i0] ||\n prevAxisOrder[i0][0] !== x ||\n prevAxisOrder[i0][1] !== nextX\n ) {\n prevAxisOrder[i0] = [x, nextX];\n\n var item = makeItem(\n model,\n leftmost, rightmost, i, i0, i1, x, y,\n p.panelSizeX, p.panelSizeY,\n p.dim0.crossfilterDimensionIndex,\n isContext ? 0 : isPick ? 2 : 1,\n constraints\n );\n\n renderState.clearOnly = clearOnly;\n\n var blockLineCount = setChanged ? model.lines.blockLineCount : sampleCount;\n renderBlock(\n regl, glAes, renderState, blockLineCount, sampleCount, item\n );\n }\n }\n }\n\n function readPixel(canvasX, canvasY) {\n regl.read({\n x: canvasX,\n y: canvasY,\n width: 1,\n height: 1,\n data: dataPixel\n });\n return dataPixel;\n }\n\n function readPixels(canvasX, canvasY, width, height) {\n var pixelArray = new Uint8Array(4 * width * height);\n regl.read({\n x: canvasX,\n y: canvasY,\n width: width,\n height: height,\n data: pixelArray\n });\n return pixelArray;\n }\n\n function destroy() {\n canvasGL.style['pointer-events'] = 'none';\n paletteTexture.destroy();\n if(maskTexture) maskTexture.destroy();\n for(var k in attributes) attributes[k].destroy();\n }\n\n return {\n render: renderGLParcoords,\n readPixel: readPixel,\n readPixels: readPixels,\n destroy: destroy,\n update: update\n };\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcoords/lines.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcoords/merge_length.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcoords/merge_length.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n/**\n * mergeLength: set trace length as the minimum of all dimension data lengths\n * and propagates this length into each dimension\n *\n * @param {object} traceOut: the fullData trace\n * @param {Array(object)} dimensions: array of dimension objects\n * @param {string} dataAttr: the attribute of each dimension containing the data\n * @param {integer} len: an already-existing length from other attributes\n */\nmodule.exports = function(traceOut, dimensions, dataAttr, len) {\n if(!len) len = Infinity;\n var i, dimi;\n for(i = 0; i < dimensions.length; i++) {\n dimi = dimensions[i];\n if(dimi.visible) len = Math.min(len, dimi[dataAttr].length);\n }\n if(len === Infinity) len = 0;\n\n traceOut._length = len;\n for(i = 0; i < dimensions.length; i++) {\n dimi = dimensions[i];\n if(dimi.visible) dimi._length = len;\n }\n\n return len;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcoords/merge_length.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcoords/parcoords.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcoords/parcoords.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar rgba = __webpack_require__(/*! color-rgba */ \"./node_modules/color-rgba/index.js\");\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar svgTextUtils = __webpack_require__(/*! ../../lib/svg_text_utils */ \"./node_modules/plotly.js/src/lib/svg_text_utils.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar Colorscale = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\");\n\nvar gup = __webpack_require__(/*! ../../lib/gup */ \"./node_modules/plotly.js/src/lib/gup.js\");\nvar keyFun = gup.keyFun;\nvar repeat = gup.repeat;\nvar unwrap = gup.unwrap;\n\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/traces/parcoords/helpers.js\");\nvar c = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/parcoords/constants.js\");\nvar brush = __webpack_require__(/*! ./axisbrush */ \"./node_modules/plotly.js/src/traces/parcoords/axisbrush.js\");\nvar lineLayerMaker = __webpack_require__(/*! ./lines */ \"./node_modules/plotly.js/src/traces/parcoords/lines.js\");\n\nfunction findExtreme(fn, values, len) {\n return Lib.aggNums(fn, null, values, len);\n}\n\nfunction findExtremes(values, len) {\n return fixExtremes(\n findExtreme(Math.min, values, len),\n findExtreme(Math.max, values, len)\n );\n}\n\nfunction dimensionExtent(dimension) {\n var range = dimension.range;\n return range ?\n fixExtremes(range[0], range[1]) :\n findExtremes(dimension.values, dimension._length);\n}\n\nfunction fixExtremes(lo, hi) {\n if(isNaN(lo) || !isFinite(lo)) {\n lo = 0;\n }\n\n if(isNaN(hi) || !isFinite(hi)) {\n hi = 0;\n }\n\n // avoid a degenerate (zero-width) domain\n if(lo === hi) {\n if(lo === 0) {\n // no use to multiplying zero, so add/subtract in this case\n lo -= 1;\n hi += 1;\n } else {\n // this keeps the range in the order of magnitude of the data\n lo *= 0.9;\n hi *= 1.1;\n }\n }\n\n return [lo, hi];\n}\n\nfunction toText(formatter, texts) {\n if(texts) {\n return function(v, i) {\n var text = texts[i];\n if(text === null || text === undefined) return formatter(v);\n return text;\n };\n }\n return formatter;\n}\n\nfunction domainScale(height, padding, dimension, tickvals, ticktext) {\n var extent = dimensionExtent(dimension);\n if(tickvals) {\n return d3.scale.ordinal()\n .domain(tickvals.map(toText(d3.format(dimension.tickformat), ticktext)))\n .range(tickvals\n .map(function(d) {\n var unitVal = (d - extent[0]) / (extent[1] - extent[0]);\n return (height - padding + unitVal * (2 * padding - height));\n })\n );\n }\n return d3.scale.linear()\n .domain(extent)\n .range([height - padding, padding]);\n}\n\nfunction unitToPaddedPx(height, padding) {\n return d3.scale.linear().range([padding, height - padding]);\n}\n\nfunction domainToPaddedUnitScale(dimension, padFraction) {\n return d3.scale.linear()\n .domain(dimensionExtent(dimension))\n .range([padFraction, 1 - padFraction]);\n}\n\nfunction ordinalScale(dimension) {\n if(!dimension.tickvals) return;\n\n var extent = dimensionExtent(dimension);\n return d3.scale.ordinal()\n .domain(dimension.tickvals)\n .range(dimension.tickvals.map(function(d) {\n return (d - extent[0]) / (extent[1] - extent[0]);\n }));\n}\n\nfunction unitToColorScale(cscale) {\n var colorStops = cscale.map(function(d) { return d[0]; });\n var colorTuples = cscale.map(function(d) {\n var RGBA = rgba(d[1]);\n return d3.rgb('rgb(' + RGBA[0] + ',' + RGBA[1] + ',' + RGBA[2] + ')');\n });\n var prop = function(n) { return function(o) { return o[n]; }; };\n\n // We can't use d3 color interpolation as we may have non-uniform color palette raster\n // (various color stop distances).\n var polylinearUnitScales = 'rgb'.split('').map(function(key) {\n return d3.scale.linear()\n .clamp(true)\n .domain(colorStops)\n .range(colorTuples.map(prop(key)));\n });\n\n return function(d) {\n return polylinearUnitScales.map(function(s) {\n return s(d);\n });\n };\n}\n\nfunction someFiltersActive(view) {\n return view.dimensions.some(function(p) {\n return p.brush.filterSpecified;\n });\n}\n\nfunction model(layout, d, i) {\n var cd0 = unwrap(d);\n var trace = cd0.trace;\n var lineColor = helpers.convertTypedArray(cd0.lineColor);\n var line = trace.line;\n var deselectedLines = {color: rgba(c.deselectedLineColor)};\n var cOpts = Colorscale.extractOpts(line);\n var cscale = cOpts.reversescale ? Colorscale.flipScale(cd0.cscale) : cd0.cscale;\n var domain = trace.domain;\n var dimensions = trace.dimensions;\n var width = layout.width;\n var labelAngle = trace.labelangle;\n var labelSide = trace.labelside;\n var labelFont = trace.labelfont;\n var tickFont = trace.tickfont;\n var rangeFont = trace.rangefont;\n\n var lines = Lib.extendDeepNoArrays({}, line, {\n color: lineColor.map(d3.scale.linear().domain(\n dimensionExtent({\n values: lineColor,\n range: [cOpts.min, cOpts.max],\n _length: trace._length\n })\n )),\n blockLineCount: c.blockLineCount,\n canvasOverdrag: c.overdrag * c.canvasPixelRatio\n });\n\n var groupWidth = Math.floor(width * (domain.x[1] - domain.x[0]));\n var groupHeight = Math.floor(layout.height * (domain.y[1] - domain.y[0]));\n\n var pad = layout.margin || {l: 80, r: 80, t: 100, b: 80};\n var rowContentWidth = groupWidth;\n var rowHeight = groupHeight;\n\n return {\n key: i,\n colCount: dimensions.filter(helpers.isVisible).length,\n dimensions: dimensions,\n tickDistance: c.tickDistance,\n unitToColor: unitToColorScale(cscale),\n lines: lines,\n deselectedLines: deselectedLines,\n labelAngle: labelAngle,\n labelSide: labelSide,\n labelFont: labelFont,\n tickFont: tickFont,\n rangeFont: rangeFont,\n layoutWidth: width,\n layoutHeight: layout.height,\n domain: domain,\n translateX: domain.x[0] * width,\n translateY: layout.height - domain.y[1] * layout.height,\n pad: pad,\n canvasWidth: rowContentWidth * c.canvasPixelRatio + 2 * lines.canvasOverdrag,\n canvasHeight: rowHeight * c.canvasPixelRatio,\n width: rowContentWidth,\n height: rowHeight,\n canvasPixelRatio: c.canvasPixelRatio\n };\n}\n\nfunction viewModel(state, callbacks, model) {\n var width = model.width;\n var height = model.height;\n var dimensions = model.dimensions;\n var canvasPixelRatio = model.canvasPixelRatio;\n\n var xScale = function(d) {return width * d / Math.max(1, model.colCount - 1);};\n\n var unitPad = c.verticalPadding / height;\n var _unitToPaddedPx = unitToPaddedPx(height, c.verticalPadding);\n\n var vm = {\n key: model.key,\n xScale: xScale,\n model: model,\n inBrushDrag: false // consider factoring it out and putting it in a centralized global-ish gesture state object\n };\n\n var uniqueKeys = {};\n\n vm.dimensions = dimensions.filter(helpers.isVisible).map(function(dimension, i) {\n var domainToPaddedUnit = domainToPaddedUnitScale(dimension, unitPad);\n var foundKey = uniqueKeys[dimension.label];\n uniqueKeys[dimension.label] = (foundKey || 0) + 1;\n var key = dimension.label + (foundKey ? '__' + foundKey : '');\n var specifiedConstraint = dimension.constraintrange;\n var filterRangeSpecified = specifiedConstraint && specifiedConstraint.length;\n if(filterRangeSpecified && !Array.isArray(specifiedConstraint[0])) {\n specifiedConstraint = [specifiedConstraint];\n }\n var filterRange = filterRangeSpecified ?\n specifiedConstraint.map(function(d) { return d.map(domainToPaddedUnit); }) :\n [[-Infinity, Infinity]];\n var brushMove = function() {\n var p = vm;\n p.focusLayer && p.focusLayer.render(p.panels, true);\n var filtersActive = someFiltersActive(p);\n if(!state.contextShown() && filtersActive) {\n p.contextLayer && p.contextLayer.render(p.panels, true);\n state.contextShown(true);\n } else if(state.contextShown() && !filtersActive) {\n p.contextLayer && p.contextLayer.render(p.panels, true, true);\n state.contextShown(false);\n }\n };\n\n var truncatedValues = dimension.values;\n if(truncatedValues.length > dimension._length) {\n truncatedValues = truncatedValues.slice(0, dimension._length);\n }\n\n var tickvals = dimension.tickvals;\n var ticktext;\n function makeTickItem(v, i) { return {val: v, text: ticktext[i]}; }\n function sortTickItem(a, b) { return a.val - b.val; }\n if(Array.isArray(tickvals) && tickvals.length) {\n ticktext = dimension.ticktext;\n\n // ensure ticktext and tickvals have same length\n if(!Array.isArray(ticktext) || !ticktext.length) {\n ticktext = tickvals.map(d3.format(dimension.tickformat));\n } else if(ticktext.length > tickvals.length) {\n ticktext = ticktext.slice(0, tickvals.length);\n } else if(tickvals.length > ticktext.length) {\n tickvals = tickvals.slice(0, ticktext.length);\n }\n\n // check if we need to sort tickvals/ticktext\n for(var j = 1; j < tickvals.length; j++) {\n if(tickvals[j] < tickvals[j - 1]) {\n var tickItems = tickvals.map(makeTickItem).sort(sortTickItem);\n for(var k = 0; k < tickvals.length; k++) {\n tickvals[k] = tickItems[k].val;\n ticktext[k] = tickItems[k].text;\n }\n break;\n }\n }\n } else tickvals = undefined;\n\n truncatedValues = helpers.convertTypedArray(truncatedValues);\n\n return {\n key: key,\n label: dimension.label,\n tickFormat: dimension.tickformat,\n tickvals: tickvals,\n ticktext: ticktext,\n ordinal: helpers.isOrdinal(dimension),\n multiselect: dimension.multiselect,\n xIndex: i,\n crossfilterDimensionIndex: i,\n visibleIndex: dimension._index,\n height: height,\n values: truncatedValues,\n paddedUnitValues: truncatedValues.map(domainToPaddedUnit),\n unitTickvals: tickvals && tickvals.map(domainToPaddedUnit),\n xScale: xScale,\n x: xScale(i),\n canvasX: xScale(i) * canvasPixelRatio,\n unitToPaddedPx: _unitToPaddedPx,\n domainScale: domainScale(height, c.verticalPadding, dimension, tickvals, ticktext),\n ordinalScale: ordinalScale(dimension),\n parent: vm,\n model: model,\n brush: brush.makeBrush(\n state,\n filterRangeSpecified,\n filterRange,\n function() {\n state.linePickActive(false);\n },\n brushMove,\n function(f) {\n vm.focusLayer.render(vm.panels, true);\n vm.pickLayer && vm.pickLayer.render(vm.panels, true);\n state.linePickActive(true);\n if(callbacks && callbacks.filterChanged) {\n var invScale = domainToPaddedUnit.invert;\n\n // update gd.data as if a Plotly.restyle were fired\n var newRanges = f.map(function(r) {\n return r.map(invScale).sort(Lib.sorterAsc);\n }).sort(function(a, b) { return a[0] - b[0]; });\n callbacks.filterChanged(vm.key, dimension._index, newRanges);\n }\n }\n )\n };\n });\n\n return vm;\n}\n\nfunction styleExtentTexts(selection) {\n selection\n .classed(c.cn.axisExtentText, true)\n .attr('text-anchor', 'middle')\n .style('cursor', 'default')\n .style('user-select', 'none');\n}\n\nfunction parcoordsInteractionState() {\n var linePickActive = true;\n var contextShown = false;\n return {\n linePickActive: function(val) {return arguments.length ? linePickActive = !!val : linePickActive;},\n contextShown: function(val) {return arguments.length ? contextShown = !!val : contextShown;}\n };\n}\n\nfunction calcTilt(angle, position) {\n var dir = (position === 'top') ? 1 : -1;\n var radians = angle * Math.PI / 180;\n var dx = Math.sin(radians);\n var dy = Math.cos(radians);\n return {\n dir: dir,\n dx: dx,\n dy: dy,\n degrees: angle\n };\n}\n\nfunction updatePanelLayout(yAxis, vm) {\n var panels = vm.panels || (vm.panels = []);\n var data = yAxis.data();\n for(var i = 0; i < data.length - 1; i++) {\n var p = panels[i] || (panels[i] = {});\n var dim0 = data[i];\n var dim1 = data[i + 1];\n p.dim0 = dim0;\n p.dim1 = dim1;\n p.canvasX = dim0.canvasX;\n p.panelSizeX = dim1.canvasX - dim0.canvasX;\n p.panelSizeY = vm.model.canvasHeight;\n p.y = 0;\n p.canvasY = 0;\n }\n}\n\nfunction calcAllTicks(cd) {\n for(var i = 0; i < cd.length; i++) {\n for(var j = 0; j < cd[i].length; j++) {\n var trace = cd[i][j].trace;\n var dimensions = trace.dimensions;\n\n for(var k = 0; k < dimensions.length; k++) {\n var values = dimensions[k].values;\n var dim = dimensions[k]._ax;\n\n if(dim) {\n if(!dim.range) {\n dim.range = findExtremes(values, trace._length);\n } else {\n dim.range = fixExtremes(dim.range[0], dim.range[1]);\n }\n\n if(!dim.dtick) {\n dim.dtick = 0.01 * (Math.abs(dim.range[1] - dim.range[0]) || 1);\n }\n\n dim.tickformat = dimensions[k].tickformat;\n Axes.calcTicks(dim);\n dim.cleanRange();\n }\n }\n }\n }\n}\n\nfunction linearFormat(dim, v) {\n return Axes.tickText(dim._ax, v, false).text;\n}\n\nfunction extremeText(d, isTop) {\n if(d.ordinal) return '';\n var domain = d.domainScale.domain();\n var v = (domain[isTop ? domain.length - 1 : 0]);\n\n return linearFormat(d.model.dimensions[d.visibleIndex], v);\n}\n\n\nmodule.exports = function parcoords(gd, cdModule, layout, callbacks) {\n var fullLayout = gd._fullLayout;\n var svg = fullLayout._toppaper;\n var glContainer = fullLayout._glcontainer;\n\n calcAllTicks(cdModule);\n\n var state = parcoordsInteractionState();\n\n var vm = cdModule\n .filter(function(d) { return unwrap(d).trace.visible; })\n .map(model.bind(0, layout))\n .map(viewModel.bind(0, state, callbacks));\n\n glContainer.each(function(d, i) {\n return Lib.extendFlat(d, vm[i]);\n });\n\n var glLayers = glContainer.selectAll('.gl-canvas')\n .each(function(d) {\n // FIXME: figure out how to handle multiple instances\n d.viewModel = vm[0];\n d.model = d.viewModel ? d.viewModel.model : null;\n });\n\n var lastHovered = null;\n\n var pickLayer = glLayers.filter(function(d) {return d.pick;});\n\n // emit hover / unhover event\n pickLayer\n .style('pointer-events', 'auto')\n .on('mousemove', function(d) {\n if(state.linePickActive() && d.lineLayer && callbacks && callbacks.hover) {\n var event = d3.event;\n var cw = this.width;\n var ch = this.height;\n var pointer = d3.mouse(this);\n var x = pointer[0];\n var y = pointer[1];\n\n if(x < 0 || y < 0 || x >= cw || y >= ch) {\n return;\n }\n var pixel = d.lineLayer.readPixel(x, ch - 1 - y);\n var found = pixel[3] !== 0;\n // inverse of the calcPickColor in `lines.js`; detailed comment there\n var curveNumber = found ? pixel[2] + 256 * (pixel[1] + 256 * pixel[0]) : null;\n var eventData = {\n x: x,\n y: y,\n clientX: event.clientX,\n clientY: event.clientY,\n dataIndex: d.model.key,\n curveNumber: curveNumber\n };\n if(curveNumber !== lastHovered) { // don't unnecessarily repeat the same hit (or miss)\n if(found) {\n callbacks.hover(eventData);\n } else if(callbacks.unhover) {\n callbacks.unhover(eventData);\n }\n lastHovered = curveNumber;\n }\n }\n });\n\n glLayers\n .style('opacity', function(d) {return d.pick ? 0 : 1;});\n\n svg.style('background', 'rgba(255, 255, 255, 0)');\n var controlOverlay = svg.selectAll('.' + c.cn.parcoords)\n .data(vm, keyFun);\n\n controlOverlay.exit().remove();\n\n controlOverlay.enter()\n .append('g')\n .classed(c.cn.parcoords, true)\n .style('shape-rendering', 'crispEdges')\n .style('pointer-events', 'none');\n\n controlOverlay.attr('transform', function(d) {\n return 'translate(' + d.model.translateX + ',' + d.model.translateY + ')';\n });\n\n var parcoordsControlView = controlOverlay.selectAll('.' + c.cn.parcoordsControlView)\n .data(repeat, keyFun);\n\n parcoordsControlView.enter()\n .append('g')\n .classed(c.cn.parcoordsControlView, true);\n\n parcoordsControlView.attr('transform', function(d) {\n return 'translate(' + d.model.pad.l + ',' + d.model.pad.t + ')';\n });\n\n var yAxis = parcoordsControlView.selectAll('.' + c.cn.yAxis)\n .data(function(p) { return p.dimensions; }, keyFun);\n\n yAxis.enter()\n .append('g')\n .classed(c.cn.yAxis, true);\n\n parcoordsControlView.each(function(p) {\n updatePanelLayout(yAxis, p);\n });\n\n glLayers\n .each(function(d) {\n if(d.viewModel) {\n if(!d.lineLayer || callbacks) { // recreate in case of having callbacks e.g. restyle. Should we test for callback to be a restyle?\n d.lineLayer = lineLayerMaker(this, d);\n } else d.lineLayer.update(d);\n\n if(d.key || d.key === 0) d.viewModel[d.key] = d.lineLayer;\n\n var setChanged = (!d.context || // don't update background\n callbacks); // unless there is a callback on the context layer. Should we test the callback?\n\n d.lineLayer.render(d.viewModel.panels, setChanged);\n }\n });\n\n yAxis.attr('transform', function(d) {\n return 'translate(' + d.xScale(d.xIndex) + ', 0)';\n });\n\n // drag column for reordering columns\n yAxis.call(d3.behavior.drag()\n .origin(function(d) { return d; })\n .on('drag', function(d) {\n var p = d.parent;\n state.linePickActive(false);\n d.x = Math.max(-c.overdrag, Math.min(d.model.width + c.overdrag, d3.event.x));\n d.canvasX = d.x * d.model.canvasPixelRatio;\n yAxis\n .sort(function(a, b) { return a.x - b.x; })\n .each(function(e, i) {\n e.xIndex = i;\n e.x = d === e ? e.x : e.xScale(e.xIndex);\n e.canvasX = e.x * e.model.canvasPixelRatio;\n });\n\n updatePanelLayout(yAxis, p);\n\n yAxis.filter(function(e) { return Math.abs(d.xIndex - e.xIndex) !== 0; })\n .attr('transform', function(d) { return 'translate(' + d.xScale(d.xIndex) + ', 0)'; });\n d3.select(this).attr('transform', 'translate(' + d.x + ', 0)');\n yAxis.each(function(e, i0, i1) { if(i1 === d.parent.key) p.dimensions[i0] = e; });\n p.contextLayer && p.contextLayer.render(p.panels, false, !someFiltersActive(p));\n p.focusLayer.render && p.focusLayer.render(p.panels);\n })\n .on('dragend', function(d) {\n var p = d.parent;\n d.x = d.xScale(d.xIndex);\n d.canvasX = d.x * d.model.canvasPixelRatio;\n updatePanelLayout(yAxis, p);\n d3.select(this)\n .attr('transform', function(d) { return 'translate(' + d.x + ', 0)'; });\n p.contextLayer && p.contextLayer.render(p.panels, false, !someFiltersActive(p));\n p.focusLayer && p.focusLayer.render(p.panels);\n p.pickLayer && p.pickLayer.render(p.panels, true);\n state.linePickActive(true);\n\n if(callbacks && callbacks.axesMoved) {\n callbacks.axesMoved(p.key, p.dimensions.map(function(e) {return e.crossfilterDimensionIndex;}));\n }\n })\n );\n\n yAxis.exit()\n .remove();\n\n var axisOverlays = yAxis.selectAll('.' + c.cn.axisOverlays)\n .data(repeat, keyFun);\n\n axisOverlays.enter()\n .append('g')\n .classed(c.cn.axisOverlays, true);\n\n axisOverlays.selectAll('.' + c.cn.axis).remove();\n\n var axis = axisOverlays.selectAll('.' + c.cn.axis)\n .data(repeat, keyFun);\n\n axis.enter()\n .append('g')\n .classed(c.cn.axis, true);\n\n axis\n .each(function(d) {\n var wantedTickCount = d.model.height / d.model.tickDistance;\n var scale = d.domainScale;\n var sdom = scale.domain();\n d3.select(this)\n .call(d3.svg.axis()\n .orient('left')\n .tickSize(4)\n .outerTickSize(2)\n .ticks(wantedTickCount, d.tickFormat) // works for continuous scales only...\n .tickValues(d.ordinal ? // and this works for ordinal scales\n sdom :\n null)\n .tickFormat(function(v) {\n return helpers.isOrdinal(d) ? v : linearFormat(d.model.dimensions[d.visibleIndex], v);\n })\n .scale(scale));\n Drawing.font(axis.selectAll('text'), d.model.tickFont);\n });\n\n axis.selectAll('.domain, .tick>line')\n .attr('fill', 'none')\n .attr('stroke', 'black')\n .attr('stroke-opacity', 0.25)\n .attr('stroke-width', '1px');\n\n axis.selectAll('text')\n .style('text-shadow', '1px 1px 1px #fff, -1px -1px 1px #fff, 1px -1px 1px #fff, -1px 1px 1px #fff')\n .style('cursor', 'default')\n .style('user-select', 'none');\n\n var axisHeading = axisOverlays.selectAll('.' + c.cn.axisHeading)\n .data(repeat, keyFun);\n\n axisHeading.enter()\n .append('g')\n .classed(c.cn.axisHeading, true);\n\n var axisTitle = axisHeading.selectAll('.' + c.cn.axisTitle)\n .data(repeat, keyFun);\n\n axisTitle.enter()\n .append('text')\n .classed(c.cn.axisTitle, true)\n .attr('text-anchor', 'middle')\n .style('cursor', 'ew-resize')\n .style('user-select', 'none')\n .style('pointer-events', 'auto');\n\n axisTitle\n .text(function(d) { return d.label; })\n .each(function(d) {\n var e = d3.select(this);\n Drawing.font(e, d.model.labelFont);\n svgTextUtils.convertToTspans(e, gd);\n })\n .attr('transform', function(d) {\n var tilt = calcTilt(d.model.labelAngle, d.model.labelSide);\n var r = c.axisTitleOffset;\n return (\n (tilt.dir > 0 ? '' : 'translate(0,' + (2 * r + d.model.height) + ')') +\n 'rotate(' + tilt.degrees + ')' +\n 'translate(' + (-r * tilt.dx) + ',' + (-r * tilt.dy) + ')'\n );\n })\n .attr('text-anchor', function(d) {\n var tilt = calcTilt(d.model.labelAngle, d.model.labelSide);\n var adx = Math.abs(tilt.dx);\n var ady = Math.abs(tilt.dy);\n\n if(2 * adx > ady) {\n return (tilt.dir * tilt.dx < 0) ? 'start' : 'end';\n } else {\n return 'middle';\n }\n });\n\n var axisExtent = axisOverlays.selectAll('.' + c.cn.axisExtent)\n .data(repeat, keyFun);\n\n axisExtent.enter()\n .append('g')\n .classed(c.cn.axisExtent, true);\n\n var axisExtentTop = axisExtent.selectAll('.' + c.cn.axisExtentTop)\n .data(repeat, keyFun);\n\n axisExtentTop.enter()\n .append('g')\n .classed(c.cn.axisExtentTop, true);\n\n axisExtentTop\n .attr('transform', 'translate(' + 0 + ',' + -c.axisExtentOffset + ')');\n\n var axisExtentTopText = axisExtentTop.selectAll('.' + c.cn.axisExtentTopText)\n .data(repeat, keyFun);\n\n axisExtentTopText.enter()\n .append('text')\n .classed(c.cn.axisExtentTopText, true)\n .call(styleExtentTexts);\n\n axisExtentTopText\n .text(function(d) { return extremeText(d, true); })\n .each(function(d) { Drawing.font(d3.select(this), d.model.rangeFont); });\n\n var axisExtentBottom = axisExtent.selectAll('.' + c.cn.axisExtentBottom)\n .data(repeat, keyFun);\n\n axisExtentBottom.enter()\n .append('g')\n .classed(c.cn.axisExtentBottom, true);\n\n axisExtentBottom\n .attr('transform', function(d) {\n return 'translate(' + 0 + ',' + (d.model.height + c.axisExtentOffset) + ')';\n });\n\n var axisExtentBottomText = axisExtentBottom.selectAll('.' + c.cn.axisExtentBottomText)\n .data(repeat, keyFun);\n\n axisExtentBottomText.enter()\n .append('text')\n .classed(c.cn.axisExtentBottomText, true)\n .attr('dy', '0.75em')\n .call(styleExtentTexts);\n\n axisExtentBottomText\n .text(function(d) { return extremeText(d, false); })\n .each(function(d) { Drawing.font(d3.select(this), d.model.rangeFont); });\n\n brush.ensureAxisBrush(axisOverlays);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcoords/parcoords.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/parcoords/plot.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/parcoords/plot.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar parcoords = __webpack_require__(/*! ./parcoords */ \"./node_modules/plotly.js/src/traces/parcoords/parcoords.js\");\nvar prepareRegl = __webpack_require__(/*! ../../lib/prepare_regl */ \"./node_modules/plotly.js/src/lib/prepare_regl.js\");\nvar isVisible = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/traces/parcoords/helpers.js\").isVisible;\n\nfunction newIndex(visibleIndices, orig, dim) {\n var origIndex = orig.indexOf(dim);\n var currentIndex = visibleIndices.indexOf(origIndex);\n if(currentIndex === -1) {\n // invisible dimensions initially go to the end\n currentIndex += orig.length;\n }\n return currentIndex;\n}\n\nfunction sorter(visibleIndices, orig) {\n return function sorter(d1, d2) {\n return (\n newIndex(visibleIndices, orig, d1) -\n newIndex(visibleIndices, orig, d2)\n );\n };\n}\n\nmodule.exports = function plot(gd, cdModule) {\n var fullLayout = gd._fullLayout;\n\n var success = prepareRegl(gd);\n if(!success) return;\n\n var currentDims = {};\n var initialDims = {};\n var fullIndices = {};\n var inputIndices = {};\n\n var size = fullLayout._size;\n\n cdModule.forEach(function(d, i) {\n var trace = d[0].trace;\n fullIndices[i] = trace.index;\n var iIn = inputIndices[i] = trace._fullInput.index;\n currentDims[i] = gd.data[iIn].dimensions;\n initialDims[i] = gd.data[iIn].dimensions.slice();\n });\n\n var filterChanged = function(i, initialDimIndex, newRanges) {\n // Have updated `constraintrange` data on `gd.data` and raise `Plotly.restyle` event\n // without having to incur heavy UI blocking due to an actual `Plotly.restyle` call\n\n var dim = initialDims[i][initialDimIndex];\n var newConstraints = newRanges.map(function(r) { return r.slice(); });\n\n // Store constraint range in preGUI\n // This one doesn't work if it's stored in pieces in _storeDirectGUIEdit\n // because it's an array of variable dimensionality. So store the whole\n // thing at once manually.\n var aStr = 'dimensions[' + initialDimIndex + '].constraintrange';\n var preGUI = fullLayout._tracePreGUI[gd._fullData[fullIndices[i]]._fullInput.uid];\n if(preGUI[aStr] === undefined) {\n var initialVal = dim.constraintrange;\n preGUI[aStr] = initialVal || null;\n }\n\n var fullDimension = gd._fullData[fullIndices[i]].dimensions[initialDimIndex];\n\n if(!newConstraints.length) {\n delete dim.constraintrange;\n delete fullDimension.constraintrange;\n newConstraints = null;\n } else {\n if(newConstraints.length === 1) newConstraints = newConstraints[0];\n dim.constraintrange = newConstraints;\n fullDimension.constraintrange = newConstraints.slice();\n // wrap in another array for restyle event data\n newConstraints = [newConstraints];\n }\n\n var restyleData = {};\n restyleData[aStr] = newConstraints;\n gd.emit('plotly_restyle', [restyleData, [inputIndices[i]]]);\n };\n\n var hover = function(eventData) {\n gd.emit('plotly_hover', eventData);\n };\n\n var unhover = function(eventData) {\n gd.emit('plotly_unhover', eventData);\n };\n\n var axesMoved = function(i, visibleIndices) {\n // Have updated order data on `gd.data` and raise `Plotly.restyle` event\n // without having to incur heavy UI blocking due to an actual `Plotly.restyle` call\n\n // drag&drop sorting of the visible dimensions\n var orig = sorter(visibleIndices, initialDims[i].filter(isVisible));\n currentDims[i].sort(orig);\n\n // invisible dimensions are not interpreted in the context of drag&drop sorting as an invisible dimension\n // cannot be dragged; they're interspersed into their original positions by this subsequent merging step\n initialDims[i].filter(function(d) {return !isVisible(d);})\n .sort(function(d) {\n // subsequent splicing to be done left to right, otherwise indices may be incorrect\n return initialDims[i].indexOf(d);\n })\n .forEach(function(d) {\n currentDims[i].splice(currentDims[i].indexOf(d), 1); // remove from the end\n currentDims[i].splice(initialDims[i].indexOf(d), 0, d); // insert at original index\n });\n\n // TODO: we can't really store this part of the interaction state\n // directly as below, since it incudes data arrays. If we want to\n // persist column order we may have to do something special for this\n // case to just store the order itself.\n // Registry.call('_storeDirectGUIEdit',\n // gd.data[inputIndices[i]],\n // fullLayout._tracePreGUI[gd._fullData[fullIndices[i]]._fullInput.uid],\n // {dimensions: currentDims[i]}\n // );\n\n gd.emit('plotly_restyle', [{dimensions: [currentDims[i]]}, [inputIndices[i]]]);\n };\n\n parcoords(\n gd,\n cdModule,\n { // layout\n width: size.w,\n height: size.h,\n margin: {\n t: size.t,\n r: size.r,\n b: size.b,\n l: size.l\n }\n },\n { // callbacks\n filterChanged: filterChanged,\n hover: hover,\n unhover: unhover,\n axesMoved: axesMoved\n }\n );\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/parcoords/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/pie/attributes.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/pie/attributes.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar domainAttrs = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").attributes;\nvar fontAttrs = __webpack_require__(/*! ../../plots/font_attributes */ \"./node_modules/plotly.js/src/plots/font_attributes.js\");\nvar colorAttrs = __webpack_require__(/*! ../../components/color/attributes */ \"./node_modules/plotly.js/src/components/color/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar texttemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").texttemplateAttrs;\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nvar textFontAttrs = fontAttrs({\n editType: 'plot',\n arrayOk: true,\n colorEditType: 'plot',\n \n});\n\nmodule.exports = {\n labels: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n // equivalent of x0 and dx, if label is missing\n label0: {\n valType: 'number',\n \n dflt: 0,\n editType: 'calc',\n \n },\n dlabel: {\n valType: 'number',\n \n dflt: 1,\n editType: 'calc',\n \n },\n\n values: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n\n marker: {\n colors: {\n valType: 'data_array', // TODO 'color_array' ?\n editType: 'calc',\n \n },\n\n line: {\n color: {\n valType: 'color',\n \n dflt: colorAttrs.defaultLine,\n arrayOk: true,\n editType: 'style',\n \n },\n width: {\n valType: 'number',\n \n min: 0,\n dflt: 0,\n arrayOk: true,\n editType: 'style',\n \n },\n editType: 'calc'\n },\n editType: 'calc'\n },\n\n text: {\n valType: 'data_array',\n editType: 'plot',\n \n },\n hovertext: {\n valType: 'string',\n \n dflt: '',\n arrayOk: true,\n editType: 'style',\n \n },\n\n// 'see eg:'\n// 'https://www.e-education.psu.edu/natureofgeoinfo/sites/www.e-education.psu.edu.natureofgeoinfo/files/image/hisp_pies.gif',\n// '(this example involves a map too - may someday be a whole trace type',\n// 'of its own. but the point is the size of the whole pie is important.)'\n scalegroup: {\n valType: 'string',\n \n dflt: '',\n editType: 'calc',\n \n },\n\n // labels (legend is handled by plots.attributes.showlegend and layout.hiddenlabels)\n textinfo: {\n valType: 'flaglist',\n \n flags: ['label', 'text', 'value', 'percent'],\n extras: ['none'],\n editType: 'calc',\n \n },\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {\n flags: ['label', 'text', 'value', 'percent', 'name']\n }),\n hovertemplate: hovertemplateAttrs({}, {\n keys: ['label', 'color', 'value', 'percent', 'text']\n }),\n texttemplate: texttemplateAttrs({editType: 'plot'}, {\n keys: ['label', 'color', 'value', 'percent', 'text']\n }),\n textposition: {\n valType: 'enumerated',\n \n values: ['inside', 'outside', 'auto', 'none'],\n dflt: 'auto',\n arrayOk: true,\n editType: 'plot',\n \n },\n textfont: extendFlat({}, textFontAttrs, {\n \n }),\n insidetextorientation: {\n valType: 'enumerated',\n \n values: ['horizontal', 'radial', 'tangential', 'auto'],\n dflt: 'auto',\n editType: 'plot',\n \n },\n insidetextfont: extendFlat({}, textFontAttrs, {\n \n }),\n outsidetextfont: extendFlat({}, textFontAttrs, {\n \n }),\n automargin: {\n valType: 'boolean',\n dflt: false,\n \n editType: 'plot',\n \n },\n\n title: {\n text: {\n valType: 'string',\n dflt: '',\n \n editType: 'plot',\n \n },\n font: extendFlat({}, textFontAttrs, {\n \n }),\n position: {\n valType: 'enumerated',\n values: [\n 'top left', 'top center', 'top right',\n 'middle center',\n 'bottom left', 'bottom center', 'bottom right'\n ],\n \n editType: 'plot',\n \n },\n\n editType: 'plot'\n },\n\n // position and shape\n domain: domainAttrs({name: 'pie', trace: true, editType: 'calc'}),\n\n hole: {\n valType: 'number',\n \n min: 0,\n max: 1,\n dflt: 0,\n editType: 'calc',\n \n },\n\n // ordering and direction\n sort: {\n valType: 'boolean',\n \n dflt: true,\n editType: 'calc',\n \n },\n direction: {\n /**\n * there are two common conventions, both of which place the first\n * (largest, if sorted) slice with its left edge at 12 o'clock but\n * succeeding slices follow either cw or ccw from there.\n *\n * see http://visage.co/data-visualization-101-pie-charts/\n */\n valType: 'enumerated',\n values: ['clockwise', 'counterclockwise'],\n \n dflt: 'counterclockwise',\n editType: 'calc',\n \n },\n rotation: {\n valType: 'number',\n \n min: -360,\n max: 360,\n dflt: 0,\n editType: 'calc',\n \n },\n\n pull: {\n valType: 'number',\n \n min: 0,\n max: 1,\n dflt: 0,\n arrayOk: true,\n editType: 'calc',\n \n },\n\n _deprecated: {\n title: {\n valType: 'string',\n dflt: '',\n \n editType: 'calc',\n \n },\n titlefont: extendFlat({}, textFontAttrs, {\n \n }),\n titleposition: {\n valType: 'enumerated',\n values: [\n 'top left', 'top center', 'top right',\n 'middle center',\n 'bottom left', 'bottom center', 'bottom right'\n ],\n \n editType: 'calc',\n \n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/pie/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/pie/base_plot.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/pie/base_plot.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar plots = __webpack_require__(/*! ../../plots/plots */ \"./node_modules/plotly.js/src/plots/plots.js\");\n\nexports.name = 'pie';\n\nexports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) {\n plots.plotBasePlot(exports.name, gd, traces, transitionOpts, makeOnCompleteCallback);\n};\n\nexports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {\n plots.cleanBasePlot(exports.name, newFullData, newFullLayout, oldFullData, oldFullLayout);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/pie/base_plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/pie/calc.js":
-/*!*******************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/pie/calc.js ***!
- \*******************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\nvar tinycolor = __webpack_require__(/*! tinycolor2 */ \"./node_modules/tinycolor2/tinycolor.js\");\n\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\n\nvar extendedColorWayList = {};\n\nfunction calc(gd, trace) {\n var cd = [];\n\n var fullLayout = gd._fullLayout;\n var hiddenLabels = fullLayout.hiddenlabels || [];\n\n var labels = trace.labels;\n var colors = trace.marker.colors || [];\n var vals = trace.values;\n var len = trace._length;\n var hasValues = trace._hasValues && len;\n\n var i, pt;\n\n if(trace.dlabel) {\n labels = new Array(len);\n for(i = 0; i < len; i++) {\n labels[i] = String(trace.label0 + i * trace.dlabel);\n }\n }\n\n var allThisTraceLabels = {};\n var pullColor = makePullColorFn(fullLayout['_' + trace.type + 'colormap']);\n var vTotal = 0;\n var isAggregated = false;\n\n for(i = 0; i < len; i++) {\n var v, label, hidden;\n if(hasValues) {\n v = vals[i];\n if(!isNumeric(v)) continue;\n v = +v;\n if(v < 0) continue;\n } else v = 1;\n\n label = labels[i];\n if(label === undefined || label === '') label = i;\n label = String(label);\n\n var thisLabelIndex = allThisTraceLabels[label];\n if(thisLabelIndex === undefined) {\n allThisTraceLabels[label] = cd.length;\n\n hidden = hiddenLabels.indexOf(label) !== -1;\n\n if(!hidden) vTotal += v;\n\n cd.push({\n v: v,\n label: label,\n color: pullColor(colors[i], label),\n i: i,\n pts: [i],\n hidden: hidden\n });\n } else {\n isAggregated = true;\n\n pt = cd[thisLabelIndex];\n pt.v += v;\n pt.pts.push(i);\n if(!pt.hidden) vTotal += v;\n\n if(pt.color === false && colors[i]) {\n pt.color = pullColor(colors[i], label);\n }\n }\n }\n\n var shouldSort = (trace.type === 'funnelarea') ? isAggregated : trace.sort;\n if(shouldSort) cd.sort(function(a, b) { return b.v - a.v; });\n\n // include the sum of all values in the first point\n if(cd[0]) cd[0].vTotal = vTotal;\n\n return cd;\n}\n\nfunction makePullColorFn(colorMap) {\n return function pullColor(color, id) {\n if(!color) return false;\n\n color = tinycolor(color);\n if(!color.isValid()) return false;\n\n color = Color.addOpacity(color, color.getAlpha());\n if(!colorMap[id]) colorMap[id] = color;\n\n return color;\n };\n}\n\n/*\n * `calc` filled in (and collated) explicit colors.\n * Now we need to propagate these explicit colors to other traces,\n * and fill in default colors.\n * This is done after sorting, so we pick defaults\n * in the order slices will be displayed\n */\nfunction crossTraceCalc(gd, plotinfo) { // TODO: should we name the second argument opts?\n var desiredType = (plotinfo || {}).type;\n if(!desiredType) desiredType = 'pie';\n\n var fullLayout = gd._fullLayout;\n var calcdata = gd.calcdata;\n var colorWay = fullLayout[desiredType + 'colorway'];\n var colorMap = fullLayout['_' + desiredType + 'colormap'];\n\n if(fullLayout['extend' + desiredType + 'colors']) {\n colorWay = generateExtendedColors(colorWay, extendedColorWayList);\n }\n var dfltColorCount = 0;\n\n for(var i = 0; i < calcdata.length; i++) {\n var cd = calcdata[i];\n var traceType = cd[0].trace.type;\n if(traceType !== desiredType) continue;\n\n for(var j = 0; j < cd.length; j++) {\n var pt = cd[j];\n if(pt.color === false) {\n // have we seen this label and assigned a color to it in a previous trace?\n if(colorMap[pt.label]) {\n pt.color = colorMap[pt.label];\n } else {\n colorMap[pt.label] = pt.color = colorWay[dfltColorCount % colorWay.length];\n dfltColorCount++;\n }\n }\n }\n }\n}\n\n/**\n * pick a default color from the main default set, augmented by\n * itself lighter then darker before repeating\n */\nfunction generateExtendedColors(colorList, extendedColorWays) {\n var i;\n var colorString = JSON.stringify(colorList);\n var colors = extendedColorWays[colorString];\n if(!colors) {\n colors = colorList.slice();\n\n for(i = 0; i < colorList.length; i++) {\n colors.push(tinycolor(colorList[i]).lighten(20).toHexString());\n }\n\n for(i = 0; i < colorList.length; i++) {\n colors.push(tinycolor(colorList[i]).darken(20).toHexString());\n }\n extendedColorWays[colorString] = colors;\n }\n\n return colors;\n}\n\nmodule.exports = {\n calc: calc,\n crossTraceCalc: crossTraceCalc,\n\n makePullColorFn: makePullColorFn,\n generateExtendedColors: generateExtendedColors\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/pie/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/pie/defaults.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/pie/defaults.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/pie/attributes.js\");\nvar handleDomainDefaults = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").defaults;\nvar handleText = __webpack_require__(/*! ../bar/defaults */ \"./node_modules/plotly.js/src/traces/bar/defaults.js\").handleText;\n\nfunction handleLabelsAndValues(labels, values) {\n var hasLabels = Array.isArray(labels);\n var hasValues = Lib.isArrayOrTypedArray(values);\n var len = Math.min(\n hasLabels ? labels.length : Infinity,\n hasValues ? values.length : Infinity\n );\n\n if(!isFinite(len)) len = 0;\n\n if(len && hasValues) {\n var hasPositive;\n for(var i = 0; i < len; i++) {\n var v = values[i];\n if(isNumeric(v) && v > 0) {\n hasPositive = true;\n break;\n }\n }\n if(!hasPositive) len = 0;\n }\n\n return {\n hasLabels: hasLabels,\n hasValues: hasValues,\n len: len\n };\n}\n\nfunction supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var labels = coerce('labels');\n var values = coerce('values');\n\n var res = handleLabelsAndValues(labels, values);\n var len = res.len;\n traceOut._hasLabels = res.hasLabels;\n traceOut._hasValues = res.hasValues;\n\n if(!traceOut._hasLabels &&\n traceOut._hasValues\n ) {\n coerce('label0');\n coerce('dlabel');\n }\n\n if(!len) {\n traceOut.visible = false;\n return;\n }\n traceOut._length = len;\n\n var lineWidth = coerce('marker.line.width');\n if(lineWidth) coerce('marker.line.color');\n\n coerce('marker.colors');\n\n coerce('scalegroup');\n // TODO: hole needs to be coerced to the same value within a scaleegroup\n\n var textData = coerce('text');\n var textTemplate = coerce('texttemplate');\n var textInfo;\n if(!textTemplate) textInfo = coerce('textinfo', Array.isArray(textData) ? 'text+percent' : 'percent');\n\n coerce('hovertext');\n coerce('hovertemplate');\n\n if(textTemplate || (textInfo && textInfo !== 'none')) {\n var textposition = coerce('textposition');\n handleText(traceIn, traceOut, layout, coerce, textposition, {\n moduleHasSelected: false,\n moduleHasUnselected: false,\n moduleHasConstrain: false,\n moduleHasCliponaxis: false,\n moduleHasTextangle: false,\n moduleHasInsideanchor: false\n });\n\n var hasBoth = Array.isArray(textposition) || textposition === 'auto';\n var hasOutside = hasBoth || textposition === 'outside';\n if(hasOutside) {\n coerce('automargin');\n }\n\n if(textposition === 'inside' || textposition === 'auto' || Array.isArray(textposition)) {\n coerce('insidetextorientation');\n }\n }\n\n handleDomainDefaults(traceOut, layout, coerce);\n\n var hole = coerce('hole');\n var title = coerce('title.text');\n if(title) {\n var titlePosition = coerce('title.position', hole ? 'middle center' : 'top center');\n if(!hole && titlePosition === 'middle center') traceOut.title.position = 'top center';\n Lib.coerceFont(coerce, 'title.font', layout.font);\n }\n\n coerce('sort');\n coerce('direction');\n coerce('rotation');\n coerce('pull');\n}\n\nmodule.exports = {\n handleLabelsAndValues: handleLabelsAndValues,\n supplyDefaults: supplyDefaults\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/pie/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/pie/event_data.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/pie/event_data.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar appendArrayMultiPointValues = __webpack_require__(/*! ../../components/fx/helpers */ \"./node_modules/plotly.js/src/components/fx/helpers.js\").appendArrayMultiPointValues;\n\n// Note: like other eventData routines, this creates the data for hover/unhover/click events\n// but it has a different API and goes through a totally different pathway.\n// So to ensure it doesn't get misused, it's not attached to the Pie module.\nmodule.exports = function eventData(pt, trace) {\n var out = {\n curveNumber: trace.index,\n pointNumbers: pt.pts,\n data: trace._input,\n fullData: trace,\n label: pt.label,\n color: pt.color,\n value: pt.v,\n percent: pt.percent,\n text: pt.text,\n\n // pt.v (and pt.i below) for backward compatibility\n v: pt.v\n };\n\n // Only include pointNumber if it's unambiguous\n if(pt.pts.length === 1) out.pointNumber = out.i = pt.pts[0];\n\n // Add extra data arrays to the output\n // notice that this is the multi-point version ('s' on the end!)\n // so added data will be arrays matching the pointNumbers array.\n appendArrayMultiPointValues(out, trace, pt.pts);\n\n // don't include obsolete fields in new funnelarea traces\n if(trace.type === 'funnelarea') {\n delete out.v;\n delete out.i;\n }\n\n return out;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/pie/event_data.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/pie/helpers.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/pie/helpers.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nexports.formatPiePercent = function formatPiePercent(v, separators) {\n var vRounded = (v * 100).toPrecision(3);\n if(vRounded.lastIndexOf('.') !== -1) {\n vRounded = vRounded.replace(/[.]?0+$/, '');\n }\n return Lib.numSeparate(vRounded, separators) + '%';\n};\n\nexports.formatPieValue = function formatPieValue(v, separators) {\n var vRounded = v.toPrecision(10);\n if(vRounded.lastIndexOf('.') !== -1) {\n vRounded = vRounded.replace(/[.]?0+$/, '');\n }\n return Lib.numSeparate(vRounded, separators);\n};\n\nexports.getFirstFilled = function getFirstFilled(array, indices) {\n if(!Array.isArray(array)) return;\n for(var i = 0; i < indices.length; i++) {\n var v = array[indices[i]];\n if(v || v === 0 || v === '') return v;\n }\n};\n\nexports.castOption = function castOption(item, indices) {\n if(Array.isArray(item)) return exports.getFirstFilled(item, indices);\n else if(item) return item;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/pie/helpers.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/pie/index.js":
-/*!********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/pie/index.js ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/pie/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/pie/defaults.js\").supplyDefaults,\n supplyLayoutDefaults: __webpack_require__(/*! ./layout_defaults */ \"./node_modules/plotly.js/src/traces/pie/layout_defaults.js\"),\n layoutAttributes: __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/pie/layout_attributes.js\"),\n\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/pie/calc.js\").calc,\n crossTraceCalc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/pie/calc.js\").crossTraceCalc,\n\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/pie/plot.js\").plot,\n style: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/pie/style.js\"),\n styleOne: __webpack_require__(/*! ./style_one */ \"./node_modules/plotly.js/src/traces/pie/style_one.js\"),\n\n moduleType: 'trace',\n name: 'pie',\n basePlotModule: __webpack_require__(/*! ./base_plot */ \"./node_modules/plotly.js/src/traces/pie/base_plot.js\"),\n categories: ['pie-like', 'pie', 'showLegend'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/pie/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/pie/layout_attributes.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/pie/layout_attributes.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n hiddenlabels: {\n valType: 'data_array',\n \n editType: 'calc',\n \n },\n piecolorway: {\n valType: 'colorlist',\n \n editType: 'calc',\n \n },\n extendpiecolors: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'calc',\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/pie/layout_attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/pie/layout_defaults.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/pie/layout_defaults.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar layoutAttributes = __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/pie/layout_attributes.js\");\n\nmodule.exports = function supplyLayoutDefaults(layoutIn, layoutOut) {\n function coerce(attr, dflt) {\n return Lib.coerce(layoutIn, layoutOut, layoutAttributes, attr, dflt);\n }\n\n coerce('hiddenlabels');\n coerce('piecolorway', layoutOut.colorway);\n coerce('extendpiecolors');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/pie/layout_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/pie/plot.js":
-/*!*******************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/pie/plot.js ***!
- \*******************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar Plots = __webpack_require__(/*! ../../plots/plots */ \"./node_modules/plotly.js/src/plots/plots.js\");\nvar Fx = __webpack_require__(/*! ../../components/fx */ \"./node_modules/plotly.js/src/components/fx/index.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar svgTextUtils = __webpack_require__(/*! ../../lib/svg_text_utils */ \"./node_modules/plotly.js/src/lib/svg_text_utils.js\");\nvar uniformText = __webpack_require__(/*! ../bar/uniform_text */ \"./node_modules/plotly.js/src/traces/bar/uniform_text.js\");\nvar recordMinTextSize = uniformText.recordMinTextSize;\nvar clearMinTextSize = uniformText.clearMinTextSize;\n\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/traces/pie/helpers.js\");\nvar eventData = __webpack_require__(/*! ./event_data */ \"./node_modules/plotly.js/src/traces/pie/event_data.js\");\nvar isValidTextValue = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").isValidTextValue;\n\nfunction plot(gd, cdModule) {\n var fullLayout = gd._fullLayout;\n var gs = fullLayout._size;\n\n clearMinTextSize('pie', fullLayout);\n\n prerenderTitles(cdModule, gd);\n layoutAreas(cdModule, gs);\n\n var plotGroups = Lib.makeTraceGroups(fullLayout._pielayer, cdModule, 'trace').each(function(cd) {\n var plotGroup = d3.select(this);\n var cd0 = cd[0];\n var trace = cd0.trace;\n\n setCoords(cd);\n\n // TODO: miter might look better but can sometimes cause problems\n // maybe miter with a small-ish stroke-miterlimit?\n plotGroup.attr('stroke-linejoin', 'round');\n\n plotGroup.each(function() {\n var slices = d3.select(this).selectAll('g.slice').data(cd);\n\n slices.enter().append('g')\n .classed('slice', true);\n slices.exit().remove();\n\n var quadrants = [\n [[], []], // y<0: x<0, x>=0\n [[], []] // y>=0: x<0, x>=0\n ];\n var hasOutsideText = false;\n\n slices.each(function(pt, i) {\n if(pt.hidden) {\n d3.select(this).selectAll('path,g').remove();\n return;\n }\n\n // to have consistent event data compared to other traces\n pt.pointNumber = pt.i;\n pt.curveNumber = trace.index;\n\n quadrants[pt.pxmid[1] < 0 ? 0 : 1][pt.pxmid[0] < 0 ? 0 : 1].push(pt);\n\n var cx = cd0.cx;\n var cy = cd0.cy;\n var sliceTop = d3.select(this);\n var slicePath = sliceTop.selectAll('path.surface').data([pt]);\n\n slicePath.enter().append('path')\n .classed('surface', true)\n .style({'pointer-events': 'all'});\n\n sliceTop.call(attachFxHandlers, gd, cd);\n\n if(trace.pull) {\n var pull = +helpers.castOption(trace.pull, pt.pts) || 0;\n if(pull > 0) {\n cx += pull * pt.pxmid[0];\n cy += pull * pt.pxmid[1];\n }\n }\n\n pt.cxFinal = cx;\n pt.cyFinal = cy;\n\n function arc(start, finish, cw, scale) {\n var dx = scale * (finish[0] - start[0]);\n var dy = scale * (finish[1] - start[1]);\n\n return 'a' +\n (scale * cd0.r) + ',' + (scale * cd0.r) + ' 0 ' +\n pt.largeArc + (cw ? ' 1 ' : ' 0 ') + dx + ',' + dy;\n }\n\n var hole = trace.hole;\n if(pt.v === cd0.vTotal) { // 100% fails bcs arc start and end are identical\n var outerCircle = 'M' + (cx + pt.px0[0]) + ',' + (cy + pt.px0[1]) +\n arc(pt.px0, pt.pxmid, true, 1) +\n arc(pt.pxmid, pt.px0, true, 1) + 'Z';\n if(hole) {\n slicePath.attr('d',\n 'M' + (cx + hole * pt.px0[0]) + ',' + (cy + hole * pt.px0[1]) +\n arc(pt.px0, pt.pxmid, false, hole) +\n arc(pt.pxmid, pt.px0, false, hole) +\n 'Z' + outerCircle);\n } else slicePath.attr('d', outerCircle);\n } else {\n var outerArc = arc(pt.px0, pt.px1, true, 1);\n\n if(hole) {\n var rim = 1 - hole;\n slicePath.attr('d',\n 'M' + (cx + hole * pt.px1[0]) + ',' + (cy + hole * pt.px1[1]) +\n arc(pt.px1, pt.px0, false, hole) +\n 'l' + (rim * pt.px0[0]) + ',' + (rim * pt.px0[1]) +\n outerArc +\n 'Z');\n } else {\n slicePath.attr('d',\n 'M' + cx + ',' + cy +\n 'l' + pt.px0[0] + ',' + pt.px0[1] +\n outerArc +\n 'Z');\n }\n }\n\n // add text\n formatSliceLabel(gd, pt, cd0);\n var textPosition = helpers.castOption(trace.textposition, pt.pts);\n var sliceTextGroup = sliceTop.selectAll('g.slicetext')\n .data(pt.text && (textPosition !== 'none') ? [0] : []);\n\n sliceTextGroup.enter().append('g')\n .classed('slicetext', true);\n sliceTextGroup.exit().remove();\n\n sliceTextGroup.each(function() {\n var sliceText = Lib.ensureSingle(d3.select(this), 'text', '', function(s) {\n // prohibit tex interpretation until we can handle\n // tex and regular text together\n s.attr('data-notex', 1);\n });\n\n var font = Lib.ensureUniformFontSize(gd, textPosition === 'outside' ?\n determineOutsideTextFont(trace, pt, fullLayout.font) :\n determineInsideTextFont(trace, pt, fullLayout.font)\n );\n\n sliceText.text(pt.text)\n .attr({\n 'class': 'slicetext',\n transform: '',\n 'text-anchor': 'middle'\n })\n .call(Drawing.font, font)\n .call(svgTextUtils.convertToTspans, gd);\n\n // position the text relative to the slice\n var textBB = Drawing.bBox(sliceText.node());\n var transform;\n\n if(textPosition === 'outside') {\n transform = transformOutsideText(textBB, pt);\n } else {\n transform = transformInsideText(textBB, pt, cd0);\n if(textPosition === 'auto' && transform.scale < 1) {\n var newFont = Lib.ensureUniformFontSize(gd, trace.outsidetextfont);\n\n sliceText.call(Drawing.font, newFont);\n textBB = Drawing.bBox(sliceText.node());\n\n transform = transformOutsideText(textBB, pt);\n }\n }\n\n var textPosAngle = transform.textPosAngle;\n var textXY = textPosAngle === undefined ? pt.pxmid : getCoords(cd0.r, textPosAngle);\n transform.targetX = cx + textXY[0] * transform.rCenter + (transform.x || 0);\n transform.targetY = cy + textXY[1] * transform.rCenter + (transform.y || 0);\n computeTransform(transform, textBB);\n\n // save some stuff to use later ensure no labels overlap\n if(transform.outside) {\n var targetY = transform.targetY;\n pt.yLabelMin = targetY - textBB.height / 2;\n pt.yLabelMid = targetY;\n pt.yLabelMax = targetY + textBB.height / 2;\n pt.labelExtraX = 0;\n pt.labelExtraY = 0;\n hasOutsideText = true;\n }\n\n transform.fontSize = font.size;\n recordMinTextSize(trace.type, transform, fullLayout);\n cd[i].transform = transform;\n\n sliceText.attr('transform', Lib.getTextTransform(transform));\n });\n });\n\n // add the title\n var titleTextGroup = d3.select(this).selectAll('g.titletext')\n .data(trace.title.text ? [0] : []);\n\n titleTextGroup.enter().append('g')\n .classed('titletext', true);\n titleTextGroup.exit().remove();\n\n titleTextGroup.each(function() {\n var titleText = Lib.ensureSingle(d3.select(this), 'text', '', function(s) {\n // prohibit tex interpretation as above\n s.attr('data-notex', 1);\n });\n\n var txt = trace.title.text;\n if(trace._meta) {\n txt = Lib.templateString(txt, trace._meta);\n }\n\n titleText.text(txt)\n .attr({\n 'class': 'titletext',\n transform: '',\n 'text-anchor': 'middle',\n })\n .call(Drawing.font, trace.title.font)\n .call(svgTextUtils.convertToTspans, gd);\n\n var transform;\n\n if(trace.title.position === 'middle center') {\n transform = positionTitleInside(cd0);\n } else {\n transform = positionTitleOutside(cd0, gs);\n }\n\n titleText.attr('transform',\n 'translate(' + transform.x + ',' + transform.y + ')' +\n (transform.scale < 1 ? ('scale(' + transform.scale + ')') : '') +\n 'translate(' + transform.tx + ',' + transform.ty + ')');\n });\n\n // now make sure no labels overlap (at least within one pie)\n if(hasOutsideText) scootLabels(quadrants, trace);\n\n plotTextLines(slices, trace);\n\n if(hasOutsideText && trace.automargin) {\n // TODO if we ever want to improve perf,\n // we could reuse the textBB computed above together\n // with the sliceText transform info\n var traceBbox = Drawing.bBox(plotGroup.node());\n\n var domain = trace.domain;\n var vpw = gs.w * (domain.x[1] - domain.x[0]);\n var vph = gs.h * (domain.y[1] - domain.y[0]);\n var xgap = (0.5 * vpw - cd0.r) / gs.w;\n var ygap = (0.5 * vph - cd0.r) / gs.h;\n\n Plots.autoMargin(gd, 'pie.' + trace.uid + '.automargin', {\n xl: domain.x[0] - xgap,\n xr: domain.x[1] + xgap,\n yb: domain.y[0] - ygap,\n yt: domain.y[1] + ygap,\n l: Math.max(cd0.cx - cd0.r - traceBbox.left, 0),\n r: Math.max(traceBbox.right - (cd0.cx + cd0.r), 0),\n b: Math.max(traceBbox.bottom - (cd0.cy + cd0.r), 0),\n t: Math.max(cd0.cy - cd0.r - traceBbox.top, 0),\n pad: 5\n });\n }\n });\n });\n\n // This is for a bug in Chrome (as of 2015-07-22, and does not affect FF)\n // if insidetextfont and outsidetextfont are different sizes, sometimes the size\n // of an \"em\" gets taken from the wrong element at first so lines are\n // spaced wrong. You just have to tell it to try again later and it gets fixed.\n // I have no idea why we haven't seen this in other contexts. Also, sometimes\n // it gets the initial draw correct but on redraw it gets confused.\n setTimeout(function() {\n plotGroups.selectAll('tspan').each(function() {\n var s = d3.select(this);\n if(s.attr('dy')) s.attr('dy', s.attr('dy'));\n });\n }, 0);\n}\n\n// TODO add support for transition\nfunction plotTextLines(slices, trace) {\n slices.each(function(pt) {\n var sliceTop = d3.select(this);\n\n if(!pt.labelExtraX && !pt.labelExtraY) {\n sliceTop.select('path.textline').remove();\n return;\n }\n\n // first move the text to its new location\n var sliceText = sliceTop.select('g.slicetext text');\n\n pt.transform.targetX += pt.labelExtraX;\n pt.transform.targetY += pt.labelExtraY;\n\n sliceText.attr('transform', Lib.getTextTransform(pt.transform));\n\n // then add a line to the new location\n var lineStartX = pt.cxFinal + pt.pxmid[0];\n var lineStartY = pt.cyFinal + pt.pxmid[1];\n var textLinePath = 'M' + lineStartX + ',' + lineStartY;\n var finalX = (pt.yLabelMax - pt.yLabelMin) * (pt.pxmid[0] < 0 ? -1 : 1) / 4;\n\n if(pt.labelExtraX) {\n var yFromX = pt.labelExtraX * pt.pxmid[1] / pt.pxmid[0];\n var yNet = pt.yLabelMid + pt.labelExtraY - (pt.cyFinal + pt.pxmid[1]);\n\n if(Math.abs(yFromX) > Math.abs(yNet)) {\n textLinePath +=\n 'l' + (yNet * pt.pxmid[0] / pt.pxmid[1]) + ',' + yNet +\n 'H' + (lineStartX + pt.labelExtraX + finalX);\n } else {\n textLinePath += 'l' + pt.labelExtraX + ',' + yFromX +\n 'v' + (yNet - yFromX) +\n 'h' + finalX;\n }\n } else {\n textLinePath +=\n 'V' + (pt.yLabelMid + pt.labelExtraY) +\n 'h' + finalX;\n }\n\n Lib.ensureSingle(sliceTop, 'path', 'textline')\n .call(Color.stroke, trace.outsidetextfont.color)\n .attr({\n 'stroke-width': Math.min(2, trace.outsidetextfont.size / 8),\n d: textLinePath,\n fill: 'none'\n });\n });\n}\n\nfunction attachFxHandlers(sliceTop, gd, cd) {\n var cd0 = cd[0];\n var trace = cd0.trace;\n var cx = cd0.cx;\n var cy = cd0.cy;\n\n // hover state vars\n // have we drawn a hover label, so it should be cleared later\n if(!('_hasHoverLabel' in trace)) trace._hasHoverLabel = false;\n // have we emitted a hover event, so later an unhover event should be emitted\n // note that click events do not depend on this - you can still get them\n // with hovermode: false or if you were earlier dragging, then clicked\n // in the same slice that you moused up in\n if(!('_hasHoverEvent' in trace)) trace._hasHoverEvent = false;\n\n sliceTop.on('mouseover', function(pt) {\n // in case fullLayout or fullData has changed without a replot\n var fullLayout2 = gd._fullLayout;\n var trace2 = gd._fullData[trace.index];\n\n if(gd._dragging || fullLayout2.hovermode === false) return;\n\n var hoverinfo = trace2.hoverinfo;\n if(Array.isArray(hoverinfo)) {\n // super hacky: we need to pull out the *first* hoverinfo from\n // pt.pts, then put it back into an array in a dummy trace\n // and call castHoverinfo on that.\n // TODO: do we want to have Fx.castHoverinfo somehow handle this?\n // it already takes an array for index, for 2D, so this seems tricky.\n hoverinfo = Fx.castHoverinfo({\n hoverinfo: [helpers.castOption(hoverinfo, pt.pts)],\n _module: trace._module\n }, fullLayout2, 0);\n }\n\n if(hoverinfo === 'all') hoverinfo = 'label+text+value+percent+name';\n\n // in case we dragged over the pie from another subplot,\n // or if hover is turned off\n if(trace2.hovertemplate || (hoverinfo !== 'none' && hoverinfo !== 'skip' && hoverinfo)) {\n var rInscribed = pt.rInscribed || 0;\n var hoverCenterX = cx + pt.pxmid[0] * (1 - rInscribed);\n var hoverCenterY = cy + pt.pxmid[1] * (1 - rInscribed);\n var separators = fullLayout2.separators;\n var text = [];\n\n if(hoverinfo && hoverinfo.indexOf('label') !== -1) text.push(pt.label);\n pt.text = helpers.castOption(trace2.hovertext || trace2.text, pt.pts);\n if(hoverinfo && hoverinfo.indexOf('text') !== -1) {\n var tx = pt.text;\n if(Lib.isValidTextValue(tx)) text.push(tx);\n }\n pt.value = pt.v;\n pt.valueLabel = helpers.formatPieValue(pt.v, separators);\n if(hoverinfo && hoverinfo.indexOf('value') !== -1) text.push(pt.valueLabel);\n pt.percent = pt.v / cd0.vTotal;\n pt.percentLabel = helpers.formatPiePercent(pt.percent, separators);\n if(hoverinfo && hoverinfo.indexOf('percent') !== -1) text.push(pt.percentLabel);\n\n var hoverLabel = trace2.hoverlabel;\n var hoverFont = hoverLabel.font;\n\n Fx.loneHover({\n trace: trace,\n x0: hoverCenterX - rInscribed * cd0.r,\n x1: hoverCenterX + rInscribed * cd0.r,\n y: hoverCenterY,\n text: text.join('
'),\n name: (trace2.hovertemplate || hoverinfo.indexOf('name') !== -1) ? trace2.name : undefined,\n idealAlign: pt.pxmid[0] < 0 ? 'left' : 'right',\n color: helpers.castOption(hoverLabel.bgcolor, pt.pts) || pt.color,\n borderColor: helpers.castOption(hoverLabel.bordercolor, pt.pts),\n fontFamily: helpers.castOption(hoverFont.family, pt.pts),\n fontSize: helpers.castOption(hoverFont.size, pt.pts),\n fontColor: helpers.castOption(hoverFont.color, pt.pts),\n nameLength: helpers.castOption(hoverLabel.namelength, pt.pts),\n textAlign: helpers.castOption(hoverLabel.align, pt.pts),\n hovertemplate: helpers.castOption(trace2.hovertemplate, pt.pts),\n hovertemplateLabels: pt,\n eventData: [eventData(pt, trace2)]\n }, {\n container: fullLayout2._hoverlayer.node(),\n outerContainer: fullLayout2._paper.node(),\n gd: gd\n });\n\n trace._hasHoverLabel = true;\n }\n\n trace._hasHoverEvent = true;\n gd.emit('plotly_hover', {\n points: [eventData(pt, trace2)],\n event: d3.event\n });\n });\n\n sliceTop.on('mouseout', function(evt) {\n var fullLayout2 = gd._fullLayout;\n var trace2 = gd._fullData[trace.index];\n var pt = d3.select(this).datum();\n\n if(trace._hasHoverEvent) {\n evt.originalEvent = d3.event;\n gd.emit('plotly_unhover', {\n points: [eventData(pt, trace2)],\n event: d3.event\n });\n trace._hasHoverEvent = false;\n }\n\n if(trace._hasHoverLabel) {\n Fx.loneUnhover(fullLayout2._hoverlayer.node());\n trace._hasHoverLabel = false;\n }\n });\n\n sliceTop.on('click', function(pt) {\n // TODO: this does not support right-click. If we want to support it, we\n // would likely need to change pie to use dragElement instead of straight\n // mapbox event binding. Or perhaps better, make a simple wrapper with the\n // right mousedown, mousemove, and mouseup handlers just for a left/right click\n // mapbox would use this too.\n var fullLayout2 = gd._fullLayout;\n var trace2 = gd._fullData[trace.index];\n\n if(gd._dragging || fullLayout2.hovermode === false) return;\n\n gd._hoverdata = [eventData(pt, trace2)];\n Fx.click(gd, d3.event);\n });\n}\n\nfunction determineOutsideTextFont(trace, pt, layoutFont) {\n var color =\n helpers.castOption(trace.outsidetextfont.color, pt.pts) ||\n helpers.castOption(trace.textfont.color, pt.pts) ||\n layoutFont.color;\n\n var family =\n helpers.castOption(trace.outsidetextfont.family, pt.pts) ||\n helpers.castOption(trace.textfont.family, pt.pts) ||\n layoutFont.family;\n\n var size =\n helpers.castOption(trace.outsidetextfont.size, pt.pts) ||\n helpers.castOption(trace.textfont.size, pt.pts) ||\n layoutFont.size;\n\n return {\n color: color,\n family: family,\n size: size\n };\n}\n\nfunction determineInsideTextFont(trace, pt, layoutFont) {\n var customColor = helpers.castOption(trace.insidetextfont.color, pt.pts);\n if(!customColor && trace._input.textfont) {\n // Why not simply using trace.textfont? Because if not set, it\n // defaults to layout.font which has a default color. But if\n // textfont.color and insidetextfont.color don't supply a value,\n // a contrasting color shall be used.\n customColor = helpers.castOption(trace._input.textfont.color, pt.pts);\n }\n\n var family =\n helpers.castOption(trace.insidetextfont.family, pt.pts) ||\n helpers.castOption(trace.textfont.family, pt.pts) ||\n layoutFont.family;\n\n var size =\n helpers.castOption(trace.insidetextfont.size, pt.pts) ||\n helpers.castOption(trace.textfont.size, pt.pts) ||\n layoutFont.size;\n\n return {\n color: customColor || Color.contrast(pt.color),\n family: family,\n size: size\n };\n}\n\nfunction prerenderTitles(cdModule, gd) {\n var cd0, trace;\n\n // Determine the width and height of the title for each pie.\n for(var i = 0; i < cdModule.length; i++) {\n cd0 = cdModule[i][0];\n trace = cd0.trace;\n\n if(trace.title.text) {\n var txt = trace.title.text;\n if(trace._meta) {\n txt = Lib.templateString(txt, trace._meta);\n }\n\n var dummyTitle = Drawing.tester.append('text')\n .attr('data-notex', 1)\n .text(txt)\n .call(Drawing.font, trace.title.font)\n .call(svgTextUtils.convertToTspans, gd);\n var bBox = Drawing.bBox(dummyTitle.node(), true);\n cd0.titleBox = {\n width: bBox.width,\n height: bBox.height,\n };\n dummyTitle.remove();\n }\n }\n}\n\nfunction transformInsideText(textBB, pt, cd0) {\n var textDiameter = Math.sqrt(textBB.width * textBB.width + textBB.height * textBB.height);\n var halfAngle = pt.halfangle;\n var midAngle = pt.midangle;\n var ring = pt.ring;\n var rInscribed = pt.rInscribed;\n var r = cd0.r || pt.rpx1;\n var orientation = cd0.trace.insidetextorientation;\n var isHorizontal = orientation === 'horizontal';\n var isTangential = orientation === 'tangential';\n var isRadial = orientation === 'radial';\n var isAuto = orientation === 'auto';\n var isCircle = (ring === 1) && (Math.abs(pt.startangle - pt.stopangle) === Math.PI * 2);\n var allTransforms = [];\n var newT;\n\n if(!isAuto) {\n // max size if text is placed (horizontally) at the top or bottom of the arc\n\n var considerCrossing = function(angle, key) {\n if(isCrossing(pt, angle)) {\n var dStart = Math.abs(angle - pt.startangle);\n var dStop = Math.abs(angle - pt.stopangle);\n\n var closestEdge = dStart < dStop ? dStart : dStop;\n\n if(key === 'tan') {\n newT = calcTanTransform(textBB, r, ring, closestEdge, 0);\n } else { // case of 'rad'\n newT = calcRadTransform(textBB, r, ring, closestEdge, Math.PI / 2);\n }\n newT.textPosAngle = angle;\n\n allTransforms.push(newT);\n }\n };\n\n // to cover all cases with trace.rotation added\n var i;\n if(isHorizontal || isTangential) {\n // top\n for(i = 4; i >= -4; i -= 2) considerCrossing(Math.PI * i, 'tan');\n // bottom\n for(i = 4; i >= -4; i -= 2) considerCrossing(Math.PI * (i + 1), 'tan');\n }\n if(isHorizontal || isRadial) {\n // left\n for(i = 4; i >= -4; i -= 2) considerCrossing(Math.PI * (i + 1.5), 'rad');\n // right\n for(i = 4; i >= -4; i -= 2) considerCrossing(Math.PI * (i + 0.5), 'rad');\n }\n }\n\n if(isCircle || isAuto || isHorizontal) {\n // max size text can be inserted inside without rotating it\n // this inscribes the text rectangle in a circle, which is then inscribed\n // in the slice, so it will be an underestimate, which some day we may want\n // to improve so this case can get more use\n newT = {\n scale: rInscribed * r * 2 / textDiameter,\n\n // and the center position and rotation in this case\n rCenter: 1 - rInscribed,\n rotate: 0\n };\n\n newT.textPosAngle = (pt.startangle + pt.stopangle) / 2;\n if(newT.scale >= 1) return newT;\n\n allTransforms.push(newT);\n }\n\n if(isAuto || isRadial) {\n newT = calcRadTransform(textBB, r, ring, halfAngle, midAngle);\n newT.textPosAngle = (pt.startangle + pt.stopangle) / 2;\n allTransforms.push(newT);\n }\n\n if(isAuto || isTangential) {\n newT = calcTanTransform(textBB, r, ring, halfAngle, midAngle);\n newT.textPosAngle = (pt.startangle + pt.stopangle) / 2;\n allTransforms.push(newT);\n }\n\n var id = 0;\n var maxScale = 0;\n for(var k = 0; k < allTransforms.length; k++) {\n var s = allTransforms[k].scale;\n if(maxScale < s) {\n maxScale = s;\n id = k;\n }\n\n if(!isAuto && maxScale >= 1) {\n // respect test order for non-auto options\n break;\n }\n }\n return allTransforms[id];\n}\n\nfunction isCrossing(pt, angle) {\n var start = pt.startangle;\n var stop = pt.stopangle;\n return (\n (start > angle && angle > stop) ||\n (start < angle && angle < stop)\n );\n}\n\nfunction calcRadTransform(textBB, r, ring, halfAngle, midAngle) {\n // max size if text is rotated radially\n var a = textBB.width / textBB.height;\n var s = calcMaxHalfSize(a, halfAngle, r, ring);\n return {\n scale: s * 2 / textBB.height,\n rCenter: calcRCenter(a, s / r),\n rotate: calcRotate(midAngle)\n };\n}\n\nfunction calcTanTransform(textBB, r, ring, halfAngle, midAngle) {\n // max size if text is rotated tangentially\n var a = textBB.height / textBB.width;\n var s = calcMaxHalfSize(a, halfAngle, r, ring);\n return {\n scale: s * 2 / textBB.width,\n rCenter: calcRCenter(a, s / r),\n rotate: calcRotate(midAngle + Math.PI / 2)\n };\n}\n\nfunction calcRCenter(a, b) {\n return Math.cos(b) - a * b;\n}\n\nfunction calcRotate(t) {\n return (180 / Math.PI * t + 720) % 180 - 90;\n}\n\nfunction calcMaxHalfSize(a, halfAngle, r, ring) {\n var q = a + 1 / (2 * Math.tan(halfAngle));\n return r * Math.min(\n 1 / (Math.sqrt(q * q + 0.5) + q),\n ring / (Math.sqrt(a * a + ring / 2) + a)\n );\n}\n\nfunction getInscribedRadiusFraction(pt, cd0) {\n if(pt.v === cd0.vTotal && !cd0.trace.hole) return 1;// special case of 100% with no hole\n\n return Math.min(1 / (1 + 1 / Math.sin(pt.halfangle)), pt.ring / 2);\n}\n\nfunction transformOutsideText(textBB, pt) {\n var x = pt.pxmid[0];\n var y = pt.pxmid[1];\n var dx = textBB.width / 2;\n var dy = textBB.height / 2;\n\n if(x < 0) dx *= -1;\n if(y < 0) dy *= -1;\n\n return {\n scale: 1,\n rCenter: 1,\n rotate: 0,\n x: dx + Math.abs(dy) * (dx > 0 ? 1 : -1) / 2,\n y: dy / (1 + x * x / (y * y)),\n outside: true\n };\n}\n\nfunction positionTitleInside(cd0) {\n var textDiameter =\n Math.sqrt(cd0.titleBox.width * cd0.titleBox.width + cd0.titleBox.height * cd0.titleBox.height);\n return {\n x: cd0.cx,\n y: cd0.cy,\n scale: cd0.trace.hole * cd0.r * 2 / textDiameter,\n tx: 0,\n ty: - cd0.titleBox.height / 2 + cd0.trace.title.font.size\n };\n}\n\nfunction positionTitleOutside(cd0, plotSize) {\n var scaleX = 1;\n var scaleY = 1;\n var maxPull;\n\n var trace = cd0.trace;\n // position of the baseline point of the text box in the plot, before scaling.\n // we anchored the text in the middle, so the baseline is on the bottom middle\n // of the first line of text.\n var topMiddle = {\n x: cd0.cx,\n y: cd0.cy\n };\n // relative translation of the text box after scaling\n var translate = {\n tx: 0,\n ty: 0\n };\n\n // we reason below as if the baseline is the top middle point of the text box.\n // so we must add the font size to approximate the y-coord. of the top.\n // note that this correction must happen after scaling.\n translate.ty += trace.title.font.size;\n maxPull = getMaxPull(trace);\n\n if(trace.title.position.indexOf('top') !== -1) {\n topMiddle.y -= (1 + maxPull) * cd0.r;\n translate.ty -= cd0.titleBox.height;\n } else if(trace.title.position.indexOf('bottom') !== -1) {\n topMiddle.y += (1 + maxPull) * cd0.r;\n }\n\n var rx = applyAspectRatio(cd0.r, cd0.trace.aspectratio);\n\n var maxWidth = plotSize.w * (trace.domain.x[1] - trace.domain.x[0]) / 2;\n if(trace.title.position.indexOf('left') !== -1) {\n // we start the text at the left edge of the pie\n maxWidth = maxWidth + rx;\n topMiddle.x -= (1 + maxPull) * rx;\n translate.tx += cd0.titleBox.width / 2;\n } else if(trace.title.position.indexOf('center') !== -1) {\n maxWidth *= 2;\n } else if(trace.title.position.indexOf('right') !== -1) {\n maxWidth = maxWidth + rx;\n topMiddle.x += (1 + maxPull) * rx;\n translate.tx -= cd0.titleBox.width / 2;\n }\n scaleX = maxWidth / cd0.titleBox.width;\n scaleY = getTitleSpace(cd0, plotSize) / cd0.titleBox.height;\n return {\n x: topMiddle.x,\n y: topMiddle.y,\n scale: Math.min(scaleX, scaleY),\n tx: translate.tx,\n ty: translate.ty\n };\n}\n\nfunction applyAspectRatio(x, aspectratio) {\n return x / ((aspectratio === undefined) ? 1 : aspectratio);\n}\n\nfunction getTitleSpace(cd0, plotSize) {\n var trace = cd0.trace;\n var pieBoxHeight = plotSize.h * (trace.domain.y[1] - trace.domain.y[0]);\n // use at most half of the plot for the title\n return Math.min(cd0.titleBox.height, pieBoxHeight / 2);\n}\n\nfunction getMaxPull(trace) {\n var maxPull = trace.pull;\n if(!maxPull) return 0;\n\n var j;\n if(Array.isArray(maxPull)) {\n maxPull = 0;\n for(j = 0; j < trace.pull.length; j++) {\n if(trace.pull[j] > maxPull) maxPull = trace.pull[j];\n }\n }\n return maxPull;\n}\n\nfunction scootLabels(quadrants, trace) {\n var xHalf, yHalf, equatorFirst, farthestX, farthestY,\n xDiffSign, yDiffSign, thisQuad, oppositeQuad,\n wholeSide, i, thisQuadOutside, firstOppositeOutsidePt;\n\n function topFirst(a, b) { return a.pxmid[1] - b.pxmid[1]; }\n function bottomFirst(a, b) { return b.pxmid[1] - a.pxmid[1]; }\n\n function scootOneLabel(thisPt, prevPt) {\n if(!prevPt) prevPt = {};\n\n var prevOuterY = prevPt.labelExtraY + (yHalf ? prevPt.yLabelMax : prevPt.yLabelMin);\n var thisInnerY = yHalf ? thisPt.yLabelMin : thisPt.yLabelMax;\n var thisOuterY = yHalf ? thisPt.yLabelMax : thisPt.yLabelMin;\n var thisSliceOuterY = thisPt.cyFinal + farthestY(thisPt.px0[1], thisPt.px1[1]);\n var newExtraY = prevOuterY - thisInnerY;\n\n var xBuffer, i, otherPt, otherOuterY, otherOuterX, newExtraX;\n\n // make sure this label doesn't overlap other labels\n // this *only* has us move these labels vertically\n if(newExtraY * yDiffSign > 0) thisPt.labelExtraY = newExtraY;\n\n // make sure this label doesn't overlap any slices\n if(!Array.isArray(trace.pull)) return; // this can only happen with array pulls\n\n for(i = 0; i < wholeSide.length; i++) {\n otherPt = wholeSide[i];\n\n // overlap can only happen if the other point is pulled more than this one\n if(otherPt === thisPt || (\n (helpers.castOption(trace.pull, thisPt.pts) || 0) >=\n (helpers.castOption(trace.pull, otherPt.pts) || 0))\n ) {\n continue;\n }\n\n if((thisPt.pxmid[1] - otherPt.pxmid[1]) * yDiffSign > 0) {\n // closer to the equator - by construction all of these happen first\n // move the text vertically to get away from these slices\n otherOuterY = otherPt.cyFinal + farthestY(otherPt.px0[1], otherPt.px1[1]);\n newExtraY = otherOuterY - thisInnerY - thisPt.labelExtraY;\n\n if(newExtraY * yDiffSign > 0) thisPt.labelExtraY += newExtraY;\n } else if((thisOuterY + thisPt.labelExtraY - thisSliceOuterY) * yDiffSign > 0) {\n // farther from the equator - happens after we've done all the\n // vertical moving we're going to do\n // move horizontally to get away from these more polar slices\n\n // if we're moving horz. based on a slice that's several slices away from this one\n // then we need some extra space for the lines to labels between them\n xBuffer = 3 * xDiffSign * Math.abs(i - wholeSide.indexOf(thisPt));\n\n otherOuterX = otherPt.cxFinal + farthestX(otherPt.px0[0], otherPt.px1[0]);\n newExtraX = otherOuterX + xBuffer - (thisPt.cxFinal + thisPt.pxmid[0]) - thisPt.labelExtraX;\n\n if(newExtraX * xDiffSign > 0) thisPt.labelExtraX += newExtraX;\n }\n }\n }\n\n for(yHalf = 0; yHalf < 2; yHalf++) {\n equatorFirst = yHalf ? topFirst : bottomFirst;\n farthestY = yHalf ? Math.max : Math.min;\n yDiffSign = yHalf ? 1 : -1;\n\n for(xHalf = 0; xHalf < 2; xHalf++) {\n farthestX = xHalf ? Math.max : Math.min;\n xDiffSign = xHalf ? 1 : -1;\n\n // first sort the array\n // note this is a copy of cd, so cd itself doesn't get sorted\n // but we can still modify points in place.\n thisQuad = quadrants[yHalf][xHalf];\n thisQuad.sort(equatorFirst);\n\n oppositeQuad = quadrants[1 - yHalf][xHalf];\n wholeSide = oppositeQuad.concat(thisQuad);\n\n thisQuadOutside = [];\n for(i = 0; i < thisQuad.length; i++) {\n if(thisQuad[i].yLabelMid !== undefined) thisQuadOutside.push(thisQuad[i]);\n }\n\n firstOppositeOutsidePt = false;\n for(i = 0; yHalf && i < oppositeQuad.length; i++) {\n if(oppositeQuad[i].yLabelMid !== undefined) {\n firstOppositeOutsidePt = oppositeQuad[i];\n break;\n }\n }\n\n // each needs to avoid the previous\n for(i = 0; i < thisQuadOutside.length; i++) {\n var prevPt = i && thisQuadOutside[i - 1];\n // bottom half needs to avoid the first label of the top half\n // top half we still need to call scootOneLabel on the first slice\n // so we can avoid other slices, but we don't pass a prevPt\n if(firstOppositeOutsidePt && !i) prevPt = firstOppositeOutsidePt;\n scootOneLabel(thisQuadOutside[i], prevPt);\n }\n }\n }\n}\n\nfunction layoutAreas(cdModule, plotSize) {\n var scaleGroups = [];\n\n // figure out the center and maximum radius\n for(var i = 0; i < cdModule.length; i++) {\n var cd0 = cdModule[i][0];\n var trace = cd0.trace;\n\n var domain = trace.domain;\n var width = plotSize.w * (domain.x[1] - domain.x[0]);\n var height = plotSize.h * (domain.y[1] - domain.y[0]);\n // leave some space for the title, if it will be displayed outside\n if(trace.title.text && trace.title.position !== 'middle center') {\n height -= getTitleSpace(cd0, plotSize);\n }\n\n var rx = width / 2;\n var ry = height / 2;\n if(trace.type === 'funnelarea' && !trace.scalegroup) {\n ry /= trace.aspectratio;\n }\n\n cd0.r = Math.min(rx, ry) / (1 + getMaxPull(trace));\n\n cd0.cx = plotSize.l + plotSize.w * (trace.domain.x[1] + trace.domain.x[0]) / 2;\n cd0.cy = plotSize.t + plotSize.h * (1 - trace.domain.y[0]) - height / 2;\n if(trace.title.text && trace.title.position.indexOf('bottom') !== -1) {\n cd0.cy -= getTitleSpace(cd0, plotSize);\n }\n\n if(trace.scalegroup && scaleGroups.indexOf(trace.scalegroup) === -1) {\n scaleGroups.push(trace.scalegroup);\n }\n }\n\n groupScale(cdModule, scaleGroups);\n}\n\nfunction groupScale(cdModule, scaleGroups) {\n var cd0, i, trace;\n\n // scale those that are grouped\n for(var k = 0; k < scaleGroups.length; k++) {\n var min = Infinity;\n var g = scaleGroups[k];\n\n for(i = 0; i < cdModule.length; i++) {\n cd0 = cdModule[i][0];\n trace = cd0.trace;\n\n if(trace.scalegroup === g) {\n var area;\n if(trace.type === 'pie') {\n area = cd0.r * cd0.r;\n } else if(trace.type === 'funnelarea') {\n var rx, ry;\n\n if(trace.aspectratio > 1) {\n rx = cd0.r;\n ry = rx / trace.aspectratio;\n } else {\n ry = cd0.r;\n rx = ry * trace.aspectratio;\n }\n\n rx *= (1 + trace.baseratio) / 2;\n\n area = rx * ry;\n }\n\n min = Math.min(min, area / cd0.vTotal);\n }\n }\n\n for(i = 0; i < cdModule.length; i++) {\n cd0 = cdModule[i][0];\n trace = cd0.trace;\n if(trace.scalegroup === g) {\n var v = min * cd0.vTotal;\n if(trace.type === 'funnelarea') {\n v /= (1 + trace.baseratio) / 2;\n v /= trace.aspectratio;\n }\n\n cd0.r = Math.sqrt(v);\n }\n }\n }\n}\n\nfunction setCoords(cd) {\n var cd0 = cd[0];\n var r = cd0.r;\n var trace = cd0.trace;\n var currentAngle = trace.rotation * Math.PI / 180;\n var angleFactor = 2 * Math.PI / cd0.vTotal;\n var firstPt = 'px0';\n var lastPt = 'px1';\n\n var i, cdi, currentCoords;\n\n if(trace.direction === 'counterclockwise') {\n for(i = 0; i < cd.length; i++) {\n if(!cd[i].hidden) break; // find the first non-hidden slice\n }\n if(i === cd.length) return; // all slices hidden\n\n currentAngle += angleFactor * cd[i].v;\n angleFactor *= -1;\n firstPt = 'px1';\n lastPt = 'px0';\n }\n\n currentCoords = getCoords(r, currentAngle);\n\n for(i = 0; i < cd.length; i++) {\n cdi = cd[i];\n if(cdi.hidden) continue;\n\n cdi[firstPt] = currentCoords;\n\n cdi.startangle = currentAngle;\n currentAngle += angleFactor * cdi.v / 2;\n cdi.pxmid = getCoords(r, currentAngle);\n cdi.midangle = currentAngle;\n currentAngle += angleFactor * cdi.v / 2;\n currentCoords = getCoords(r, currentAngle);\n cdi.stopangle = currentAngle;\n\n cdi[lastPt] = currentCoords;\n\n cdi.largeArc = (cdi.v > cd0.vTotal / 2) ? 1 : 0;\n\n cdi.halfangle = Math.PI * Math.min(cdi.v / cd0.vTotal, 0.5);\n cdi.ring = 1 - trace.hole;\n cdi.rInscribed = getInscribedRadiusFraction(cdi, cd0);\n }\n}\n\nfunction getCoords(r, angle) {\n return [r * Math.sin(angle), -r * Math.cos(angle)];\n}\n\nfunction formatSliceLabel(gd, pt, cd0) {\n var fullLayout = gd._fullLayout;\n var trace = cd0.trace;\n // look for textemplate\n var texttemplate = trace.texttemplate;\n\n // now insert text\n var textinfo = trace.textinfo;\n if(!texttemplate && textinfo && textinfo !== 'none') {\n var parts = textinfo.split('+');\n var hasFlag = function(flag) { return parts.indexOf(flag) !== -1; };\n var hasLabel = hasFlag('label');\n var hasText = hasFlag('text');\n var hasValue = hasFlag('value');\n var hasPercent = hasFlag('percent');\n\n var separators = fullLayout.separators;\n var text;\n\n text = hasLabel ? [pt.label] : [];\n if(hasText) {\n var tx = helpers.getFirstFilled(trace.text, pt.pts);\n if(isValidTextValue(tx)) text.push(tx);\n }\n if(hasValue) text.push(helpers.formatPieValue(pt.v, separators));\n if(hasPercent) text.push(helpers.formatPiePercent(pt.v / cd0.vTotal, separators));\n pt.text = text.join('
');\n }\n\n function makeTemplateVariables(pt) {\n return {\n label: pt.label,\n value: pt.v,\n valueLabel: helpers.formatPieValue(pt.v, fullLayout.separators),\n percent: pt.v / cd0.vTotal,\n percentLabel: helpers.formatPiePercent(pt.v / cd0.vTotal, fullLayout.separators),\n color: pt.color,\n text: pt.text,\n customdata: Lib.castOption(trace, pt.i, 'customdata')\n };\n }\n\n if(texttemplate) {\n var txt = Lib.castOption(trace, pt.i, 'texttemplate');\n if(!txt) {\n pt.text = '';\n } else {\n var obj = makeTemplateVariables(pt);\n var ptTx = helpers.getFirstFilled(trace.text, pt.pts);\n if(isValidTextValue(ptTx) || ptTx === '') obj.text = ptTx;\n pt.text = Lib.texttemplateString(txt, obj, gd._fullLayout._d3locale, obj, trace._meta || {});\n }\n }\n}\n\nfunction computeTransform(\n transform, // inout\n textBB // in\n) {\n var rotate = transform.rotate;\n var scale = transform.scale;\n if(scale > 1) scale = 1;\n\n var a = rotate * Math.PI / 180;\n var cosA = Math.cos(a);\n var sinA = Math.sin(a);\n var midX = (textBB.left + textBB.right) / 2;\n var midY = (textBB.top + textBB.bottom) / 2;\n transform.textX = midX * cosA - midY * sinA;\n transform.textY = midX * sinA + midY * cosA;\n transform.noCenter = true;\n}\n\nmodule.exports = {\n plot: plot,\n formatSliceLabel: formatSliceLabel,\n transformInsideText: transformInsideText,\n determineInsideTextFont: determineInsideTextFont,\n positionTitleOutside: positionTitleOutside,\n prerenderTitles: prerenderTitles,\n layoutAreas: layoutAreas,\n attachFxHandlers: attachFxHandlers,\n computeTransform: computeTransform\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/pie/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/pie/style.js":
-/*!********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/pie/style.js ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar styleOne = __webpack_require__(/*! ./style_one */ \"./node_modules/plotly.js/src/traces/pie/style_one.js\");\nvar resizeText = __webpack_require__(/*! ../bar/uniform_text */ \"./node_modules/plotly.js/src/traces/bar/uniform_text.js\").resizeText;\n\nmodule.exports = function style(gd) {\n var s = gd._fullLayout._pielayer.selectAll('.trace');\n resizeText(gd, s, 'pie');\n\n s.each(function(cd) {\n var cd0 = cd[0];\n var trace = cd0.trace;\n var traceSelection = d3.select(this);\n\n traceSelection.style({opacity: trace.opacity});\n\n traceSelection.selectAll('path.surface').each(function(pt) {\n d3.select(this).call(styleOne, pt, trace);\n });\n });\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/pie/style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/pie/style_one.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/pie/style_one.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar castOption = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/traces/pie/helpers.js\").castOption;\n\nmodule.exports = function styleOne(s, pt, trace) {\n var line = trace.marker.line;\n var lineColor = castOption(line.color, pt.pts) || Color.defaultLine;\n var lineWidth = castOption(line.width, pt.pts) || 0;\n\n s.style('stroke-width', lineWidth)\n .call(Color.fill, pt.color)\n .call(Color.stroke, lineColor);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/pie/style_one.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/pointcloud/attributes.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/pointcloud/attributes.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar scatterglAttrs = __webpack_require__(/*! ../scatter/attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\");\n\nmodule.exports = {\n x: scatterglAttrs.x,\n y: scatterglAttrs.y,\n xy: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n indices: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n xbounds: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n ybounds: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n text: scatterglAttrs.text,\n marker: {\n color: {\n valType: 'color',\n arrayOk: false,\n \n editType: 'calc',\n \n },\n opacity: {\n valType: 'number',\n min: 0,\n max: 1,\n dflt: 1,\n arrayOk: false,\n \n editType: 'calc',\n \n },\n blend: {\n valType: 'boolean',\n dflt: null,\n \n editType: 'calc',\n \n },\n sizemin: {\n valType: 'number',\n min: 0.1,\n max: 2,\n dflt: 0.5,\n \n editType: 'calc',\n \n },\n sizemax: {\n valType: 'number',\n min: 0.1,\n dflt: 20,\n \n editType: 'calc',\n \n },\n border: {\n color: {\n valType: 'color',\n arrayOk: false,\n \n editType: 'calc',\n \n },\n arearatio: {\n valType: 'number',\n min: 0,\n max: 1,\n dflt: 0,\n \n editType: 'calc',\n \n },\n editType: 'calc'\n },\n editType: 'calc'\n },\n transforms: undefined\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/pointcloud/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/pointcloud/convert.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/pointcloud/convert.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar createPointCloudRenderer = __webpack_require__(/*! gl-pointcloud2d */ \"./node_modules/gl-pointcloud2d/pointcloud2d.js\");\n\nvar str2RGBArray = __webpack_require__(/*! ../../lib/str2rgbarray */ \"./node_modules/plotly.js/src/lib/str2rgbarray.js\");\nvar findExtremes = __webpack_require__(/*! ../../plots/cartesian/autorange */ \"./node_modules/plotly.js/src/plots/cartesian/autorange.js\").findExtremes;\nvar getTraceColor = __webpack_require__(/*! ../scatter/get_trace_color */ \"./node_modules/plotly.js/src/traces/scatter/get_trace_color.js\");\n\nfunction Pointcloud(scene, uid) {\n this.scene = scene;\n this.uid = uid;\n this.type = 'pointcloud';\n\n this.pickXData = [];\n this.pickYData = [];\n this.xData = [];\n this.yData = [];\n this.textLabels = [];\n this.color = 'rgb(0, 0, 0)';\n this.name = '';\n this.hoverinfo = 'all';\n\n this.idToIndex = new Int32Array(0);\n this.bounds = [0, 0, 0, 0];\n\n this.pointcloudOptions = {\n positions: new Float32Array(0),\n idToIndex: this.idToIndex,\n sizemin: 0.5,\n sizemax: 12,\n color: [0, 0, 0, 1],\n areaRatio: 1,\n borderColor: [0, 0, 0, 1]\n };\n this.pointcloud = createPointCloudRenderer(scene.glplot, this.pointcloudOptions);\n this.pointcloud._trace = this; // scene2d requires this prop\n}\n\nvar proto = Pointcloud.prototype;\n\nproto.handlePick = function(pickResult) {\n var index = this.idToIndex[pickResult.pointId];\n\n // prefer the readout from XY, if present\n return {\n trace: this,\n dataCoord: pickResult.dataCoord,\n traceCoord: this.pickXYData ?\n [this.pickXYData[index * 2], this.pickXYData[index * 2 + 1]] :\n [this.pickXData[index], this.pickYData[index]],\n textLabel: Array.isArray(this.textLabels) ?\n this.textLabels[index] :\n this.textLabels,\n color: this.color,\n name: this.name,\n pointIndex: index,\n hoverinfo: this.hoverinfo\n };\n};\n\nproto.update = function(options) {\n this.index = options.index;\n this.textLabels = options.text;\n this.name = options.name;\n this.hoverinfo = options.hoverinfo;\n this.bounds = [Infinity, Infinity, -Infinity, -Infinity];\n\n this.updateFast(options);\n\n this.color = getTraceColor(options, {});\n};\n\nproto.updateFast = function(options) {\n var x = this.xData = this.pickXData = options.x;\n var y = this.yData = this.pickYData = options.y;\n var xy = this.pickXYData = options.xy;\n\n var userBounds = options.xbounds && options.ybounds;\n var index = options.indices;\n\n var len;\n var idToIndex;\n var positions;\n var bounds = this.bounds;\n\n var xx, yy, i;\n\n if(xy) {\n positions = xy;\n\n // dividing xy.length by 2 and truncating to integer if xy.length was not even\n len = xy.length >>> 1;\n\n if(userBounds) {\n bounds[0] = options.xbounds[0];\n bounds[2] = options.xbounds[1];\n bounds[1] = options.ybounds[0];\n bounds[3] = options.ybounds[1];\n } else {\n for(i = 0; i < len; i++) {\n xx = positions[i * 2];\n yy = positions[i * 2 + 1];\n\n if(xx < bounds[0]) bounds[0] = xx;\n if(xx > bounds[2]) bounds[2] = xx;\n if(yy < bounds[1]) bounds[1] = yy;\n if(yy > bounds[3]) bounds[3] = yy;\n }\n }\n\n if(index) {\n idToIndex = index;\n } else {\n idToIndex = new Int32Array(len);\n\n for(i = 0; i < len; i++) {\n idToIndex[i] = i;\n }\n }\n } else {\n len = x.length;\n\n positions = new Float32Array(2 * len);\n idToIndex = new Int32Array(len);\n\n for(i = 0; i < len; i++) {\n xx = x[i];\n yy = y[i];\n\n idToIndex[i] = i;\n\n positions[i * 2] = xx;\n positions[i * 2 + 1] = yy;\n\n if(xx < bounds[0]) bounds[0] = xx;\n if(xx > bounds[2]) bounds[2] = xx;\n if(yy < bounds[1]) bounds[1] = yy;\n if(yy > bounds[3]) bounds[3] = yy;\n }\n }\n\n this.idToIndex = idToIndex;\n this.pointcloudOptions.idToIndex = idToIndex;\n\n this.pointcloudOptions.positions = positions;\n\n var markerColor = str2RGBArray(options.marker.color);\n var borderColor = str2RGBArray(options.marker.border.color);\n var opacity = options.opacity * options.marker.opacity;\n\n markerColor[3] *= opacity;\n this.pointcloudOptions.color = markerColor;\n\n // detect blending from the number of points, if undefined\n // because large data with blending hits performance\n var blend = options.marker.blend;\n if(blend === null) {\n var maxPoints = 100;\n blend = x.length < maxPoints || y.length < maxPoints;\n }\n this.pointcloudOptions.blend = blend;\n\n borderColor[3] *= opacity;\n this.pointcloudOptions.borderColor = borderColor;\n\n var markerSizeMin = options.marker.sizemin;\n var markerSizeMax = Math.max(options.marker.sizemax, options.marker.sizemin);\n this.pointcloudOptions.sizeMin = markerSizeMin;\n this.pointcloudOptions.sizeMax = markerSizeMax;\n this.pointcloudOptions.areaRatio = options.marker.border.arearatio;\n\n this.pointcloud.update(this.pointcloudOptions);\n\n // add item for autorange routine\n var xa = this.scene.xaxis;\n var ya = this.scene.yaxis;\n var pad = markerSizeMax / 2 || 0.5;\n options._extremes[xa._id] = findExtremes(xa, [bounds[0], bounds[2]], {ppad: pad});\n options._extremes[ya._id] = findExtremes(ya, [bounds[1], bounds[3]], {ppad: pad});\n};\n\nproto.dispose = function() {\n this.pointcloud.dispose();\n};\n\nfunction createPointcloud(scene, data) {\n var plot = new Pointcloud(scene, data.uid);\n plot.update(data);\n return plot;\n}\n\nmodule.exports = createPointcloud;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/pointcloud/convert.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/pointcloud/defaults.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/pointcloud/defaults.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/pointcloud/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n coerce('x');\n coerce('y');\n\n coerce('xbounds');\n coerce('ybounds');\n\n if(traceIn.xy && traceIn.xy instanceof Float32Array) {\n traceOut.xy = traceIn.xy;\n }\n\n if(traceIn.indices && traceIn.indices instanceof Int32Array) {\n traceOut.indices = traceIn.indices;\n }\n\n coerce('text');\n coerce('marker.color', defaultColor);\n coerce('marker.opacity');\n coerce('marker.blend');\n coerce('marker.sizemin');\n coerce('marker.sizemax');\n coerce('marker.border.color', defaultColor);\n coerce('marker.border.arearatio');\n\n // disable 1D transforms - that would defeat the purpose of this trace type, performance!\n traceOut._length = null;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/pointcloud/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/pointcloud/index.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/pointcloud/index.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/pointcloud/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/pointcloud/defaults.js\"),\n\n // reuse the Scatter3D 'dummy' calc step so that legends know what to do\n calc: __webpack_require__(/*! ../scatter3d/calc */ \"./node_modules/plotly.js/src/traces/scatter3d/calc.js\"),\n plot: __webpack_require__(/*! ./convert */ \"./node_modules/plotly.js/src/traces/pointcloud/convert.js\"),\n\n moduleType: 'trace',\n name: 'pointcloud',\n basePlotModule: __webpack_require__(/*! ../../plots/gl2d */ \"./node_modules/plotly.js/src/plots/gl2d/index.js\"),\n categories: ['gl', 'gl2d', 'showLegend'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/pointcloud/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sankey/attributes.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sankey/attributes.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar fontAttrs = __webpack_require__(/*! ../../plots/font_attributes */ \"./node_modules/plotly.js/src/plots/font_attributes.js\");\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar colorAttrs = __webpack_require__(/*! ../../components/color/attributes */ \"./node_modules/plotly.js/src/components/color/attributes.js\");\nvar fxAttrs = __webpack_require__(/*! ../../components/fx/attributes */ \"./node_modules/plotly.js/src/components/fx/attributes.js\");\nvar domainAttrs = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").attributes;\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar colorAttributes = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar templatedArray = __webpack_require__(/*! ../../plot_api/plot_template */ \"./node_modules/plotly.js/src/plot_api/plot_template.js\").templatedArray;\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar overrideAll = __webpack_require__(/*! ../../plot_api/edit_types */ \"./node_modules/plotly.js/src/plot_api/edit_types.js\").overrideAll;\n\nvar FORMAT_LINK = __webpack_require__(/*! ../../constants/docs */ \"./node_modules/plotly.js/src/constants/docs.js\").FORMAT_LINK;\n\nvar attrs = module.exports = overrideAll({\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {\n flags: [],\n arrayOk: false,\n \n }),\n hoverlabel: fxAttrs.hoverlabel,\n domain: domainAttrs({name: 'sankey', trace: true}),\n\n orientation: {\n valType: 'enumerated',\n values: ['v', 'h'],\n dflt: 'h',\n \n \n },\n\n valueformat: {\n valType: 'string',\n dflt: '.3s',\n \n \n },\n\n valuesuffix: {\n valType: 'string',\n dflt: '',\n \n \n },\n\n arrangement: {\n valType: 'enumerated',\n values: ['snap', 'perpendicular', 'freeform', 'fixed'],\n dflt: 'snap',\n \n \n },\n\n textfont: fontAttrs({\n \n }),\n\n node: {\n label: {\n valType: 'data_array',\n dflt: [],\n \n \n },\n groups: {\n valType: 'info_array',\n impliedEdits: {'x': [], 'y': []},\n dimensions: 2,\n freeLength: true,\n dflt: [],\n items: {valType: 'number', editType: 'calc'},\n \n \n },\n x: {\n valType: 'data_array',\n dflt: [],\n \n \n },\n y: {\n valType: 'data_array',\n dflt: [],\n \n \n },\n color: {\n valType: 'color',\n \n arrayOk: true,\n \n },\n line: {\n color: {\n valType: 'color',\n \n dflt: colorAttrs.defaultLine,\n arrayOk: true,\n \n },\n width: {\n valType: 'number',\n \n min: 0,\n dflt: 0.5,\n arrayOk: true,\n \n }\n },\n pad: {\n valType: 'number',\n arrayOk: false,\n min: 0,\n dflt: 20,\n \n \n },\n thickness: {\n valType: 'number',\n arrayOk: false,\n min: 1,\n dflt: 20,\n \n \n },\n hoverinfo: {\n valType: 'enumerated',\n values: ['all', 'none', 'skip'],\n dflt: 'all',\n \n \n },\n hoverlabel: fxAttrs.hoverlabel, // needs editType override,\n hovertemplate: hovertemplateAttrs({}, {\n \n keys: ['value', 'label']\n }),\n \n },\n\n link: {\n label: {\n valType: 'data_array',\n dflt: [],\n \n \n },\n color: {\n valType: 'color',\n \n arrayOk: true,\n \n },\n line: {\n color: {\n valType: 'color',\n \n dflt: colorAttrs.defaultLine,\n arrayOk: true,\n \n },\n width: {\n valType: 'number',\n \n min: 0,\n dflt: 0,\n arrayOk: true,\n \n }\n },\n source: {\n valType: 'data_array',\n \n dflt: [],\n \n },\n target: {\n valType: 'data_array',\n \n dflt: [],\n \n },\n value: {\n valType: 'data_array',\n dflt: [],\n \n \n },\n hoverinfo: {\n valType: 'enumerated',\n values: ['all', 'none', 'skip'],\n dflt: 'all',\n \n \n },\n hoverlabel: fxAttrs.hoverlabel, // needs editType override,\n hovertemplate: hovertemplateAttrs({}, {\n \n keys: ['value', 'label']\n }),\n colorscales: templatedArray('concentrationscales', {\n editType: 'calc',\n label: {\n valType: 'string',\n \n editType: 'calc',\n \n dflt: ''\n },\n cmax: {\n valType: 'number',\n \n editType: 'calc',\n dflt: 1,\n \n },\n cmin: {\n valType: 'number',\n \n editType: 'calc',\n dflt: 0,\n \n },\n colorscale: extendFlat(colorAttributes().colorscale, {dflt: [[0, 'white'], [1, 'black']]})\n }),\n \n \n }\n}, 'calc', 'nested');\nattrs.transforms = undefined;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sankey/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sankey/base_plot.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sankey/base_plot.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar overrideAll = __webpack_require__(/*! ../../plot_api/edit_types */ \"./node_modules/plotly.js/src/plot_api/edit_types.js\").overrideAll;\nvar getModuleCalcData = __webpack_require__(/*! ../../plots/get_data */ \"./node_modules/plotly.js/src/plots/get_data.js\").getModuleCalcData;\nvar plot = __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/sankey/plot.js\");\nvar fxAttrs = __webpack_require__(/*! ../../components/fx/layout_attributes */ \"./node_modules/plotly.js/src/components/fx/layout_attributes.js\");\n\nvar setCursor = __webpack_require__(/*! ../../lib/setcursor */ \"./node_modules/plotly.js/src/lib/setcursor.js\");\nvar dragElement = __webpack_require__(/*! ../../components/dragelement */ \"./node_modules/plotly.js/src/components/dragelement/index.js\");\nvar prepSelect = __webpack_require__(/*! ../../plots/cartesian/select */ \"./node_modules/plotly.js/src/plots/cartesian/select.js\").prepSelect;\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\n\nvar SANKEY = 'sankey';\n\nexports.name = SANKEY;\n\nexports.baseLayoutAttrOverrides = overrideAll({\n hoverlabel: fxAttrs.hoverlabel\n}, 'plot', 'nested');\n\nexports.plot = function(gd) {\n var calcData = getModuleCalcData(gd.calcdata, SANKEY)[0];\n plot(gd, calcData);\n exports.updateFx(gd);\n};\n\nexports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {\n var hadPlot = (oldFullLayout._has && oldFullLayout._has(SANKEY));\n var hasPlot = (newFullLayout._has && newFullLayout._has(SANKEY));\n\n if(hadPlot && !hasPlot) {\n oldFullLayout._paperdiv.selectAll('.sankey').remove();\n oldFullLayout._paperdiv.selectAll('.bgsankey').remove();\n }\n};\n\nexports.updateFx = function(gd) {\n for(var i = 0; i < gd._fullData.length; i++) {\n subplotUpdateFx(gd, i);\n }\n};\n\nfunction subplotUpdateFx(gd, index) {\n var trace = gd._fullData[index];\n var fullLayout = gd._fullLayout;\n\n var dragMode = fullLayout.dragmode;\n var cursor = fullLayout.dragmode === 'pan' ? 'move' : 'crosshair';\n var bgRect = trace._bgRect;\n\n if(dragMode === 'pan' || dragMode === 'zoom') return;\n\n setCursor(bgRect, cursor);\n\n var xaxis = {\n _id: 'x',\n c2p: Lib.identity,\n _offset: trace._sankey.translateX,\n _length: trace._sankey.width\n };\n var yaxis = {\n _id: 'y',\n c2p: Lib.identity,\n _offset: trace._sankey.translateY,\n _length: trace._sankey.height\n };\n\n // Note: dragOptions is needed to be declared for all dragmodes because\n // it's the object that holds persistent selection state.\n var dragOptions = {\n gd: gd,\n element: bgRect.node(),\n plotinfo: {\n id: index,\n xaxis: xaxis,\n yaxis: yaxis,\n fillRangeItems: Lib.noop\n },\n subplot: index,\n // create mock x/y axes for hover routine\n xaxes: [xaxis],\n yaxes: [yaxis],\n doneFnCompleted: function(selection) {\n var traceNow = gd._fullData[index];\n var newGroups;\n var oldGroups = traceNow.node.groups.slice();\n var newGroup = [];\n\n function findNode(pt) {\n var nodes = traceNow._sankey.graph.nodes;\n for(var i = 0; i < nodes.length; i++) {\n if(nodes[i].pointNumber === pt) return nodes[i];\n }\n }\n\n for(var j = 0; j < selection.length; j++) {\n var node = findNode(selection[j].pointNumber);\n if(!node) continue;\n\n // If the node represents a group\n if(node.group) {\n // Add all its children to the current selection\n for(var k = 0; k < node.childrenNodes.length; k++) {\n newGroup.push(node.childrenNodes[k].pointNumber);\n }\n // Flag group for removal from existing list of groups\n oldGroups[node.pointNumber - traceNow.node._count] = false;\n } else {\n newGroup.push(node.pointNumber);\n }\n }\n\n newGroups = oldGroups\n .filter(Boolean)\n .concat([newGroup]);\n\n Registry.call('_guiRestyle', gd, {\n 'node.groups': [ newGroups ]\n }, index);\n }\n };\n\n dragOptions.prepFn = function(e, startX, startY) {\n prepSelect(e, startX, startY, dragOptions, dragMode);\n };\n\n dragElement.init(dragOptions);\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sankey/base_plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sankey/calc.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sankey/calc.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar tarjan = __webpack_require__(/*! strongly-connected-components */ \"./node_modules/strongly-connected-components/scc.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar wrap = __webpack_require__(/*! ../../lib/gup */ \"./node_modules/plotly.js/src/lib/gup.js\").wrap;\n\nvar isArrayOrTypedArray = Lib.isArrayOrTypedArray;\nvar isIndex = Lib.isIndex;\nvar Colorscale = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\");\n\nfunction convertToD3Sankey(trace) {\n var nodeSpec = trace.node;\n var linkSpec = trace.link;\n\n var links = [];\n var hasLinkColorArray = isArrayOrTypedArray(linkSpec.color);\n var linkedNodes = {};\n\n var components = {};\n var componentCount = linkSpec.colorscales.length;\n var i;\n for(i = 0; i < componentCount; i++) {\n var cscale = linkSpec.colorscales[i];\n var specs = Colorscale.extractScale(cscale, {cLetter: 'c'});\n var scale = Colorscale.makeColorScaleFunc(specs);\n components[cscale.label] = scale;\n }\n\n var maxNodeId = 0;\n for(i = 0; i < linkSpec.value.length; i++) {\n if(linkSpec.source[i] > maxNodeId) maxNodeId = linkSpec.source[i];\n if(linkSpec.target[i] > maxNodeId) maxNodeId = linkSpec.target[i];\n }\n var nodeCount = maxNodeId + 1;\n trace.node._count = nodeCount;\n\n // Group nodes\n var j;\n var groups = trace.node.groups;\n var groupLookup = {};\n for(i = 0; i < groups.length; i++) {\n var group = groups[i];\n // Build a lookup table to quickly find in which group a node is\n for(j = 0; j < group.length; j++) {\n var nodeIndex = group[j];\n var groupIndex = nodeCount + i;\n if(groupLookup.hasOwnProperty(nodeIndex)) {\n Lib.warn('Node ' + nodeIndex + ' is already part of a group.');\n } else {\n groupLookup[nodeIndex] = groupIndex;\n }\n }\n }\n\n // Process links\n var groupedLinks = {\n source: [],\n target: []\n };\n for(i = 0; i < linkSpec.value.length; i++) {\n var val = linkSpec.value[i];\n // remove negative values, but keep zeros with special treatment\n var source = linkSpec.source[i];\n var target = linkSpec.target[i];\n if(!(val > 0 && isIndex(source, nodeCount) && isIndex(target, nodeCount))) {\n continue;\n }\n\n // Remove links that are within the same group\n if(groupLookup.hasOwnProperty(source) && groupLookup.hasOwnProperty(target) && groupLookup[source] === groupLookup[target]) {\n continue;\n }\n\n // if link targets a node in the group, relink target to that group\n if(groupLookup.hasOwnProperty(target)) {\n target = groupLookup[target];\n }\n\n // if link originates from a node in a group, relink source to that group\n if(groupLookup.hasOwnProperty(source)) {\n source = groupLookup[source];\n }\n\n source = +source;\n target = +target;\n linkedNodes[source] = linkedNodes[target] = true;\n\n var label = '';\n if(linkSpec.label && linkSpec.label[i]) label = linkSpec.label[i];\n\n var concentrationscale = null;\n if(label && components.hasOwnProperty(label)) concentrationscale = components[label];\n\n links.push({\n pointNumber: i,\n label: label,\n color: hasLinkColorArray ? linkSpec.color[i] : linkSpec.color,\n concentrationscale: concentrationscale,\n source: source,\n target: target,\n value: +val\n });\n\n groupedLinks.source.push(source);\n groupedLinks.target.push(target);\n }\n\n // Process nodes\n var totalCount = nodeCount + groups.length;\n var hasNodeColorArray = isArrayOrTypedArray(nodeSpec.color);\n var nodes = [];\n for(i = 0; i < totalCount; i++) {\n if(!linkedNodes[i]) continue;\n var l = nodeSpec.label[i];\n\n nodes.push({\n group: (i > nodeCount - 1),\n childrenNodes: [],\n pointNumber: i,\n label: l,\n color: hasNodeColorArray ? nodeSpec.color[i] : nodeSpec.color\n });\n }\n\n // Check if we have circularity on the resulting graph\n var circular = false;\n if(circularityPresent(totalCount, groupedLinks.source, groupedLinks.target)) {\n circular = true;\n }\n\n return {\n circular: circular,\n links: links,\n nodes: nodes,\n\n // Data structure for groups\n groups: groups,\n groupLookup: groupLookup\n };\n}\n\nfunction circularityPresent(nodeLen, sources, targets) {\n var nodes = Lib.init2dArray(nodeLen, 0);\n\n for(var i = 0; i < Math.min(sources.length, targets.length); i++) {\n if(Lib.isIndex(sources[i], nodeLen) && Lib.isIndex(targets[i], nodeLen)) {\n if(sources[i] === targets[i]) {\n return true; // self-link which is also a scc of one\n }\n nodes[sources[i]].push(targets[i]);\n }\n }\n\n var scc = tarjan(nodes);\n\n // Tarján's strongly connected components algorithm coded by Mikola Lysenko\n // returns at least one non-singular component if there's circularity in the graph\n return scc.components.some(function(c) {\n return c.length > 1;\n });\n}\n\nmodule.exports = function calc(gd, trace) {\n var result = convertToD3Sankey(trace);\n\n return wrap({\n circular: result.circular,\n _nodes: result.nodes,\n _links: result.links,\n\n // Data structure for grouping\n _groups: result.groups,\n _groupLookup: result.groupLookup,\n });\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sankey/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sankey/constants.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sankey/constants.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n nodeTextOffsetHorizontal: 4,\n nodeTextOffsetVertical: 3,\n nodePadAcross: 10,\n sankeyIterations: 50,\n forceIterations: 5,\n forceTicksPerFrame: 10,\n duration: 500,\n ease: 'linear',\n cn: {\n sankey: 'sankey',\n sankeyLinks: 'sankey-links',\n sankeyLink: 'sankey-link',\n sankeyNodeSet: 'sankey-node-set',\n sankeyNode: 'sankey-node',\n nodeRect: 'node-rect',\n nodeCapture: 'node-capture',\n nodeCentered: 'node-entered',\n nodeLabelGuide: 'node-label-guide',\n nodeLabel: 'node-label',\n nodeLabelTextPath: 'node-label-text-path'\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sankey/constants.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sankey/defaults.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sankey/defaults.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/sankey/attributes.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar tinycolor = __webpack_require__(/*! tinycolor2 */ \"./node_modules/tinycolor2/tinycolor.js\");\nvar handleDomainDefaults = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").defaults;\nvar handleHoverLabelDefaults = __webpack_require__(/*! ../../components/fx/hoverlabel_defaults */ \"./node_modules/plotly.js/src/components/fx/hoverlabel_defaults.js\");\nvar Template = __webpack_require__(/*! ../../plot_api/plot_template */ \"./node_modules/plotly.js/src/plot_api/plot_template.js\");\nvar handleArrayContainerDefaults = __webpack_require__(/*! ../../plots/array_container_defaults */ \"./node_modules/plotly.js/src/plots/array_container_defaults.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var hoverlabelDefault = Lib.extendDeep(layout.hoverlabel, traceIn.hoverlabel);\n\n // node attributes\n var nodeIn = traceIn.node;\n var nodeOut = Template.newContainer(traceOut, 'node');\n\n function coerceNode(attr, dflt) {\n return Lib.coerce(nodeIn, nodeOut, attributes.node, attr, dflt);\n }\n coerceNode('label');\n coerceNode('groups');\n coerceNode('x');\n coerceNode('y');\n coerceNode('pad');\n coerceNode('thickness');\n coerceNode('line.color');\n coerceNode('line.width');\n coerceNode('hoverinfo', traceIn.hoverinfo);\n handleHoverLabelDefaults(nodeIn, nodeOut, coerceNode, hoverlabelDefault);\n coerceNode('hovertemplate');\n\n var colors = layout.colorway;\n\n var defaultNodePalette = function(i) {return colors[i % colors.length];};\n\n coerceNode('color', nodeOut.label.map(function(d, i) {\n return Color.addOpacity(defaultNodePalette(i), 0.8);\n }));\n\n // link attributes\n var linkIn = traceIn.link || {};\n var linkOut = Template.newContainer(traceOut, 'link');\n\n function coerceLink(attr, dflt) {\n return Lib.coerce(linkIn, linkOut, attributes.link, attr, dflt);\n }\n coerceLink('label');\n coerceLink('source');\n coerceLink('target');\n coerceLink('value');\n coerceLink('line.color');\n coerceLink('line.width');\n coerceLink('hoverinfo', traceIn.hoverinfo);\n handleHoverLabelDefaults(linkIn, linkOut, coerceLink, hoverlabelDefault);\n coerceLink('hovertemplate');\n\n var defaultLinkColor = tinycolor(layout.paper_bgcolor).getLuminance() < 0.333 ?\n 'rgba(255, 255, 255, 0.6)' :\n 'rgba(0, 0, 0, 0.2)';\n\n coerceLink('color', Lib.repeat(defaultLinkColor, linkOut.value.length));\n\n handleArrayContainerDefaults(linkIn, linkOut, {\n name: 'colorscales',\n handleItemDefaults: concentrationscalesDefaults\n });\n\n handleDomainDefaults(traceOut, layout, coerce);\n\n coerce('orientation');\n coerce('valueformat');\n coerce('valuesuffix');\n\n var dfltArrangement;\n if(nodeOut.x.length && nodeOut.y.length) {\n dfltArrangement = 'freeform';\n }\n coerce('arrangement', dfltArrangement);\n\n Lib.coerceFont(coerce, 'textfont', Lib.extendFlat({}, layout.font));\n\n // disable 1D transforms - arrays here are 1D but their lengths/meanings\n // don't match, between nodes and links\n traceOut._length = null;\n};\n\nfunction concentrationscalesDefaults(In, Out) {\n function coerce(attr, dflt) {\n return Lib.coerce(In, Out, attributes.link.colorscales, attr, dflt);\n }\n\n coerce('label');\n coerce('cmin');\n coerce('cmax');\n coerce('colorscale');\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sankey/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sankey/index.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sankey/index.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/sankey/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/sankey/defaults.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/sankey/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/sankey/plot.js\"),\n\n moduleType: 'trace',\n name: 'sankey',\n basePlotModule: __webpack_require__(/*! ./base_plot */ \"./node_modules/plotly.js/src/traces/sankey/base_plot.js\"),\n selectPoints: __webpack_require__(/*! ./select.js */ \"./node_modules/plotly.js/src/traces/sankey/select.js\"),\n categories: ['noOpacity'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sankey/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sankey/plot.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sankey/plot.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar render = __webpack_require__(/*! ./render */ \"./node_modules/plotly.js/src/traces/sankey/render.js\");\nvar Fx = __webpack_require__(/*! ../../components/fx */ \"./node_modules/plotly.js/src/components/fx/index.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar cn = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/sankey/constants.js\").cn;\n\nvar _ = Lib._;\n\nfunction renderableValuePresent(d) {return d !== '';}\n\nfunction ownTrace(selection, d) {\n return selection.filter(function(s) {return s.key === d.traceId;});\n}\n\nfunction makeTranslucent(element, alpha) {\n d3.select(element)\n .select('path')\n .style('fill-opacity', alpha);\n d3.select(element)\n .select('rect')\n .style('fill-opacity', alpha);\n}\n\nfunction makeTextContrasty(element) {\n d3.select(element)\n .select('text.name')\n .style('fill', 'black');\n}\n\nfunction relatedLinks(d) {\n return function(l) {\n return d.node.sourceLinks.indexOf(l.link) !== -1 || d.node.targetLinks.indexOf(l.link) !== -1;\n };\n}\n\nfunction relatedNodes(l) {\n return function(d) {\n return d.node.sourceLinks.indexOf(l.link) !== -1 || d.node.targetLinks.indexOf(l.link) !== -1;\n };\n}\n\nfunction nodeHoveredStyle(sankeyNode, d, sankey) {\n if(d && sankey) {\n ownTrace(sankey, d)\n .selectAll('.' + cn.sankeyLink)\n .filter(relatedLinks(d))\n .call(linkHoveredStyle.bind(0, d, sankey, false));\n }\n}\n\nfunction nodeNonHoveredStyle(sankeyNode, d, sankey) {\n if(d && sankey) {\n ownTrace(sankey, d)\n .selectAll('.' + cn.sankeyLink)\n .filter(relatedLinks(d))\n .call(linkNonHoveredStyle.bind(0, d, sankey, false));\n }\n}\n\nfunction linkHoveredStyle(d, sankey, visitNodes, sankeyLink) {\n var label = sankeyLink.datum().link.label;\n\n sankeyLink.style('fill-opacity', function(l) {\n if(!l.link.concentrationscale) {\n return 0.4;\n }\n });\n\n if(label) {\n ownTrace(sankey, d)\n .selectAll('.' + cn.sankeyLink)\n .filter(function(l) {return l.link.label === label;})\n .style('fill-opacity', function(l) {\n if(!l.link.concentrationscale) {\n return 0.4;\n }\n });\n }\n\n if(visitNodes) {\n ownTrace(sankey, d)\n .selectAll('.' + cn.sankeyNode)\n .filter(relatedNodes(d))\n .call(nodeHoveredStyle);\n }\n}\n\nfunction linkNonHoveredStyle(d, sankey, visitNodes, sankeyLink) {\n var label = sankeyLink.datum().link.label;\n\n sankeyLink.style('fill-opacity', function(d) {return d.tinyColorAlpha;});\n if(label) {\n ownTrace(sankey, d)\n .selectAll('.' + cn.sankeyLink)\n .filter(function(l) {return l.link.label === label;})\n .style('fill-opacity', function(d) {return d.tinyColorAlpha;});\n }\n\n if(visitNodes) {\n ownTrace(sankey, d)\n .selectAll(cn.sankeyNode)\n .filter(relatedNodes(d))\n .call(nodeNonHoveredStyle);\n }\n}\n\n// does not support array values for now\nfunction castHoverOption(trace, attr) {\n var labelOpts = trace.hoverlabel || {};\n var val = Lib.nestedProperty(labelOpts, attr).get();\n return Array.isArray(val) ? false : val;\n}\n\nmodule.exports = function plot(gd, calcData) {\n var fullLayout = gd._fullLayout;\n var svg = fullLayout._paper;\n var size = fullLayout._size;\n\n // stash initial view\n for(var i = 0; i < gd._fullData.length; i++) {\n if(!gd._fullData[i].visible) continue;\n if(gd._fullData[i].type !== cn.sankey) continue;\n if(!gd._fullData[i]._viewInitial) {\n var node = gd._fullData[i].node;\n gd._fullData[i]._viewInitial = {\n node: {\n groups: node.groups.slice(),\n x: node.x.slice(),\n y: node.y.slice()\n }\n };\n }\n }\n\n var linkSelect = function(element, d) {\n var evt = d.link;\n evt.originalEvent = d3.event;\n gd._hoverdata = [evt];\n Fx.click(gd, { target: true });\n };\n\n var linkHover = function(element, d, sankey) {\n if(gd._fullLayout.hovermode === false) return;\n d3.select(element).call(linkHoveredStyle.bind(0, d, sankey, true));\n if(d.link.trace.link.hoverinfo !== 'skip') {\n d.link.fullData = d.link.trace;\n gd.emit('plotly_hover', {\n event: d3.event,\n points: [d.link]\n });\n }\n };\n\n var sourceLabel = _(gd, 'source:') + ' ';\n var targetLabel = _(gd, 'target:') + ' ';\n var concentrationLabel = _(gd, 'concentration:') + ' ';\n var incomingLabel = _(gd, 'incoming flow count:') + ' ';\n var outgoingLabel = _(gd, 'outgoing flow count:') + ' ';\n\n var linkHoverFollow = function(element, d) {\n if(gd._fullLayout.hovermode === false) return;\n var obj = d.link.trace.link;\n if(obj.hoverinfo === 'none' || obj.hoverinfo === 'skip') return;\n\n var hoverItems = [];\n\n function hoverCenterPosition(link) {\n var hoverCenterX, hoverCenterY;\n if(link.circular) {\n hoverCenterX = (link.circularPathData.leftInnerExtent + link.circularPathData.rightInnerExtent) / 2;\n hoverCenterY = link.circularPathData.verticalFullExtent;\n } else {\n hoverCenterX = (link.source.x1 + link.target.x0) / 2;\n hoverCenterY = (link.y0 + link.y1) / 2;\n }\n var center = [hoverCenterX, hoverCenterY];\n if(link.trace.orientation === 'v') center.reverse();\n center[0] += d.parent.translateX;\n center[1] += d.parent.translateY;\n return center;\n }\n\n // For each related links, create a hoverItem\n var anchorIndex = 0;\n for(var i = 0; i < d.flow.links.length; i++) {\n var link = d.flow.links[i];\n if(gd._fullLayout.hovermode === 'closest' && d.link.pointNumber !== link.pointNumber) continue;\n if(d.link.pointNumber === link.pointNumber) anchorIndex = i;\n link.fullData = link.trace;\n obj = d.link.trace.link;\n var hoverCenter = hoverCenterPosition(link);\n var hovertemplateLabels = {valueLabel: d3.format(d.valueFormat)(link.value) + d.valueSuffix};\n\n hoverItems.push({\n x: hoverCenter[0],\n y: hoverCenter[1],\n name: hovertemplateLabels.valueLabel,\n text: [\n link.label || '',\n sourceLabel + link.source.label,\n targetLabel + link.target.label,\n link.concentrationscale ? concentrationLabel + d3.format('%0.2f')(link.flow.labelConcentration) : ''\n ].filter(renderableValuePresent).join('
'),\n color: castHoverOption(obj, 'bgcolor') || Color.addOpacity(link.color, 1),\n borderColor: castHoverOption(obj, 'bordercolor'),\n fontFamily: castHoverOption(obj, 'font.family'),\n fontSize: castHoverOption(obj, 'font.size'),\n fontColor: castHoverOption(obj, 'font.color'),\n nameLength: castHoverOption(obj, 'namelength'),\n textAlign: castHoverOption(obj, 'align'),\n idealAlign: d3.event.x < hoverCenter[0] ? 'right' : 'left',\n\n hovertemplate: obj.hovertemplate,\n hovertemplateLabels: hovertemplateLabels,\n eventData: [link]\n });\n }\n\n var tooltips = Fx.loneHover(hoverItems, {\n container: fullLayout._hoverlayer.node(),\n outerContainer: fullLayout._paper.node(),\n gd: gd,\n anchorIndex: anchorIndex\n });\n\n tooltips.each(function() {\n var tooltip = this;\n if(!d.link.concentrationscale) {\n makeTranslucent(tooltip, 0.65);\n }\n makeTextContrasty(tooltip);\n });\n };\n\n var linkUnhover = function(element, d, sankey) {\n if(gd._fullLayout.hovermode === false) return;\n d3.select(element).call(linkNonHoveredStyle.bind(0, d, sankey, true));\n if(d.link.trace.link.hoverinfo !== 'skip') {\n d.link.fullData = d.link.trace;\n gd.emit('plotly_unhover', {\n event: d3.event,\n points: [d.link]\n });\n }\n\n Fx.loneUnhover(fullLayout._hoverlayer.node());\n };\n\n var nodeSelect = function(element, d, sankey) {\n var evt = d.node;\n evt.originalEvent = d3.event;\n gd._hoverdata = [evt];\n d3.select(element).call(nodeNonHoveredStyle, d, sankey);\n Fx.click(gd, { target: true });\n };\n\n var nodeHover = function(element, d, sankey) {\n if(gd._fullLayout.hovermode === false) return;\n d3.select(element).call(nodeHoveredStyle, d, sankey);\n if(d.node.trace.node.hoverinfo !== 'skip') {\n d.node.fullData = d.node.trace;\n gd.emit('plotly_hover', {\n event: d3.event,\n points: [d.node]\n });\n }\n };\n\n var nodeHoverFollow = function(element, d) {\n if(gd._fullLayout.hovermode === false) return;\n\n var obj = d.node.trace.node;\n if(obj.hoverinfo === 'none' || obj.hoverinfo === 'skip') return;\n var nodeRect = d3.select(element).select('.' + cn.nodeRect);\n var rootBBox = gd._fullLayout._paperdiv.node().getBoundingClientRect();\n var boundingBox = nodeRect.node().getBoundingClientRect();\n var hoverCenterX0 = boundingBox.left - 2 - rootBBox.left;\n var hoverCenterX1 = boundingBox.right + 2 - rootBBox.left;\n var hoverCenterY = boundingBox.top + boundingBox.height / 4 - rootBBox.top;\n\n var hovertemplateLabels = {valueLabel: d3.format(d.valueFormat)(d.node.value) + d.valueSuffix};\n d.node.fullData = d.node.trace;\n\n var tooltip = Fx.loneHover({\n x0: hoverCenterX0,\n x1: hoverCenterX1,\n y: hoverCenterY,\n name: d3.format(d.valueFormat)(d.node.value) + d.valueSuffix,\n text: [\n d.node.label,\n incomingLabel + d.node.targetLinks.length,\n outgoingLabel + d.node.sourceLinks.length\n ].filter(renderableValuePresent).join('
'),\n color: castHoverOption(obj, 'bgcolor') || d.tinyColorHue,\n borderColor: castHoverOption(obj, 'bordercolor'),\n fontFamily: castHoverOption(obj, 'font.family'),\n fontSize: castHoverOption(obj, 'font.size'),\n fontColor: castHoverOption(obj, 'font.color'),\n nameLength: castHoverOption(obj, 'namelength'),\n textAlign: castHoverOption(obj, 'align'),\n idealAlign: 'left',\n\n hovertemplate: obj.hovertemplate,\n hovertemplateLabels: hovertemplateLabels,\n eventData: [d.node]\n }, {\n container: fullLayout._hoverlayer.node(),\n outerContainer: fullLayout._paper.node(),\n gd: gd\n });\n\n makeTranslucent(tooltip, 0.85);\n makeTextContrasty(tooltip);\n };\n\n var nodeUnhover = function(element, d, sankey) {\n if(gd._fullLayout.hovermode === false) return;\n d3.select(element).call(nodeNonHoveredStyle, d, sankey);\n if(d.node.trace.node.hoverinfo !== 'skip') {\n d.node.fullData = d.node.trace;\n gd.emit('plotly_unhover', {\n event: d3.event,\n points: [d.node]\n });\n }\n\n Fx.loneUnhover(fullLayout._hoverlayer.node());\n };\n\n render(\n gd,\n svg,\n calcData,\n {\n width: size.w,\n height: size.h,\n margin: {\n t: size.t,\n r: size.r,\n b: size.b,\n l: size.l\n }\n },\n {\n linkEvents: {\n hover: linkHover,\n follow: linkHoverFollow,\n unhover: linkUnhover,\n select: linkSelect\n },\n nodeEvents: {\n hover: nodeHover,\n follow: nodeHoverFollow,\n unhover: nodeUnhover,\n select: nodeSelect\n }\n }\n );\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sankey/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sankey/render.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sankey/render.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar c = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/sankey/constants.js\");\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar tinycolor = __webpack_require__(/*! tinycolor2 */ \"./node_modules/tinycolor2/tinycolor.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar d3Sankey = __webpack_require__(/*! @plotly/d3-sankey */ \"./node_modules/@plotly/d3-sankey/index.js\");\nvar d3SankeyCircular = __webpack_require__(/*! @plotly/d3-sankey-circular */ \"./node_modules/@plotly/d3-sankey-circular/dist/d3-sankey-circular.es.js\");\nvar d3Force = __webpack_require__(/*! d3-force */ \"./node_modules/d3-force/src/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar gup = __webpack_require__(/*! ../../lib/gup */ \"./node_modules/plotly.js/src/lib/gup.js\");\nvar keyFun = gup.keyFun;\nvar repeat = gup.repeat;\nvar unwrap = gup.unwrap;\nvar interpolateNumber = __webpack_require__(/*! d3-interpolate */ \"./node_modules/d3-interpolate/src/index.js\").interpolateNumber;\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\n\n// view models\n\nfunction sankeyModel(layout, d, traceIndex) {\n var calcData = unwrap(d);\n var trace = calcData.trace;\n var domain = trace.domain;\n var horizontal = trace.orientation === 'h';\n var nodePad = trace.node.pad;\n var nodeThickness = trace.node.thickness;\n\n var width = layout.width * (domain.x[1] - domain.x[0]);\n var height = layout.height * (domain.y[1] - domain.y[0]);\n\n var nodes = calcData._nodes;\n var links = calcData._links;\n var circular = calcData.circular;\n\n // Select Sankey generator\n var sankey;\n if(circular) {\n sankey = d3SankeyCircular\n .sankeyCircular()\n .circularLinkGap(0);\n } else {\n sankey = d3Sankey.sankey();\n }\n\n sankey\n .iterations(c.sankeyIterations)\n .size(horizontal ? [width, height] : [height, width])\n .nodeWidth(nodeThickness)\n .nodePadding(nodePad)\n .nodeId(function(d) {\n return d.pointNumber;\n })\n .nodes(nodes)\n .links(links);\n\n var graph = sankey();\n\n if(sankey.nodePadding() < nodePad) {\n Lib.warn('node.pad was reduced to ', sankey.nodePadding(), ' to fit within the figure.');\n }\n\n // Counters for nested loops\n var i, j, k;\n\n // Create transient nodes for animations\n for(var nodePointNumber in calcData._groupLookup) {\n var groupIndex = parseInt(calcData._groupLookup[nodePointNumber]);\n\n // Find node representing groupIndex\n var groupingNode;\n\n for(i = 0; i < graph.nodes.length; i++) {\n if(graph.nodes[i].pointNumber === groupIndex) {\n groupingNode = graph.nodes[i];\n break;\n }\n }\n // If groupinNode is undefined, no links are targeting this group\n if(!groupingNode) continue;\n\n var child = {\n pointNumber: parseInt(nodePointNumber),\n x0: groupingNode.x0,\n x1: groupingNode.x1,\n y0: groupingNode.y0,\n y1: groupingNode.y1,\n partOfGroup: true,\n sourceLinks: [],\n targetLinks: []\n };\n\n graph.nodes.unshift(child);\n groupingNode.childrenNodes.unshift(child);\n }\n\n function computeLinkConcentrations() {\n for(i = 0; i < graph.nodes.length; i++) {\n var node = graph.nodes[i];\n // Links connecting the same two nodes are part of a flow\n var flows = {};\n var flowKey;\n var link;\n for(j = 0; j < node.targetLinks.length; j++) {\n link = node.targetLinks[j];\n flowKey = link.source.pointNumber + ':' + link.target.pointNumber;\n if(!flows.hasOwnProperty(flowKey)) flows[flowKey] = [];\n flows[flowKey].push(link);\n }\n\n // Compute statistics for each flow\n var keys = Object.keys(flows);\n for(j = 0; j < keys.length; j++) {\n flowKey = keys[j];\n var flowLinks = flows[flowKey];\n\n // Find the total size of the flow and total size per label\n var total = 0;\n var totalPerLabel = {};\n for(k = 0; k < flowLinks.length; k++) {\n link = flowLinks[k];\n if(!totalPerLabel[link.label]) totalPerLabel[link.label] = 0;\n totalPerLabel[link.label] += link.value;\n total += link.value;\n }\n\n // Find the ratio of the link's value and the size of the flow\n for(k = 0; k < flowLinks.length; k++) {\n link = flowLinks[k];\n link.flow = {\n value: total,\n labelConcentration: totalPerLabel[link.label] / total,\n concentration: link.value / total,\n links: flowLinks\n };\n if(link.concentrationscale) {\n link.color = tinycolor(link.concentrationscale(link.flow.labelConcentration));\n }\n }\n }\n\n // Gather statistics of all links at current node\n var totalOutflow = 0;\n for(j = 0; j < node.sourceLinks.length; j++) {\n totalOutflow += node.sourceLinks[j].value;\n }\n for(j = 0; j < node.sourceLinks.length; j++) {\n link = node.sourceLinks[j];\n link.concentrationOut = link.value / totalOutflow;\n }\n\n var totalInflow = 0;\n for(j = 0; j < node.targetLinks.length; j++) {\n totalInflow += node.targetLinks[j].value;\n }\n\n for(j = 0; j < node.targetLinks.length; j++) {\n link = node.targetLinks[j];\n link.concenrationIn = link.value / totalInflow;\n }\n }\n }\n computeLinkConcentrations();\n\n // Push any overlapping nodes down.\n function resolveCollisionsTopToBottom(columns) {\n columns.forEach(function(nodes) {\n var node;\n var dy;\n var y = 0;\n var n = nodes.length;\n var i;\n nodes.sort(function(a, b) {\n return a.y0 - b.y0;\n });\n for(i = 0; i < n; ++i) {\n node = nodes[i];\n if(node.y0 >= y) {\n // No overlap\n } else {\n dy = (y - node.y0);\n if(dy > 1e-6) node.y0 += dy, node.y1 += dy;\n }\n y = node.y1 + nodePad;\n }\n });\n }\n\n // Group nodes into columns based on their x position\n function snapToColumns(nodes) {\n // Sort nodes by x position\n var orderedNodes = nodes.map(function(n, i) {\n return {\n x0: n.x0,\n index: i\n };\n })\n .sort(function(a, b) {\n return a.x0 - b.x0;\n });\n\n var columns = [];\n var colNumber = -1;\n var colX; // Position of column\n var lastX = -Infinity; // Position of last node\n var dx;\n for(i = 0; i < orderedNodes.length; i++) {\n var node = nodes[orderedNodes[i].index];\n // If the node does not overlap with the last one\n if(node.x0 > lastX + nodeThickness) {\n // Start a new column\n colNumber += 1;\n colX = node.x0;\n }\n lastX = node.x0;\n\n // Add node to its associated column\n if(!columns[colNumber]) columns[colNumber] = [];\n columns[colNumber].push(node);\n\n // Change node's x position to align it with its column\n dx = colX - node.x0;\n node.x0 += dx, node.x1 += dx;\n }\n return columns;\n }\n\n // Force node position\n if(trace.node.x.length && trace.node.y.length) {\n for(i = 0; i < Math.min(trace.node.x.length, trace.node.y.length, graph.nodes.length); i++) {\n if(trace.node.x[i] && trace.node.y[i]) {\n var pos = [trace.node.x[i] * width, trace.node.y[i] * height];\n graph.nodes[i].x0 = pos[0] - nodeThickness / 2;\n graph.nodes[i].x1 = pos[0] + nodeThickness / 2;\n\n var nodeHeight = graph.nodes[i].y1 - graph.nodes[i].y0;\n graph.nodes[i].y0 = pos[1] - nodeHeight / 2;\n graph.nodes[i].y1 = pos[1] + nodeHeight / 2;\n }\n }\n if(trace.arrangement === 'snap') {\n nodes = graph.nodes;\n var columns = snapToColumns(nodes);\n resolveCollisionsTopToBottom(columns);\n }\n // Update links\n sankey.update(graph);\n }\n\n\n return {\n circular: circular,\n key: traceIndex,\n trace: trace,\n guid: Lib.randstr(),\n horizontal: horizontal,\n width: width,\n height: height,\n nodePad: trace.node.pad,\n nodeLineColor: trace.node.line.color,\n nodeLineWidth: trace.node.line.width,\n linkLineColor: trace.link.line.color,\n linkLineWidth: trace.link.line.width,\n valueFormat: trace.valueformat,\n valueSuffix: trace.valuesuffix,\n textFont: trace.textfont,\n translateX: domain.x[0] * layout.width + layout.margin.l,\n translateY: layout.height - domain.y[1] * layout.height + layout.margin.t,\n dragParallel: horizontal ? height : width,\n dragPerpendicular: horizontal ? width : height,\n arrangement: trace.arrangement,\n sankey: sankey,\n graph: graph,\n forceLayouts: {},\n interactionState: {\n dragInProgress: false,\n hovered: false\n }\n };\n}\n\nfunction linkModel(d, l, i) {\n var tc = tinycolor(l.color);\n var basicKey = l.source.label + '|' + l.target.label;\n var key = basicKey + '__' + i;\n\n // for event data\n l.trace = d.trace;\n l.curveNumber = d.trace.index;\n\n return {\n circular: d.circular,\n key: key,\n traceId: d.key,\n pointNumber: l.pointNumber,\n link: l,\n tinyColorHue: Color.tinyRGB(tc),\n tinyColorAlpha: tc.getAlpha(),\n linkPath: linkPath,\n linkLineColor: d.linkLineColor,\n linkLineWidth: d.linkLineWidth,\n valueFormat: d.valueFormat,\n valueSuffix: d.valueSuffix,\n sankey: d.sankey,\n parent: d,\n interactionState: d.interactionState,\n flow: l.flow\n };\n}\n\nfunction createCircularClosedPathString(link) {\n // Using coordinates computed by d3-sankey-circular\n var pathString = '';\n var offset = link.width / 2;\n var coords = link.circularPathData;\n if(link.circularLinkType === 'top') {\n // Top path\n pathString =\n // start at the left of the target node\n 'M ' +\n coords.targetX + ' ' + (coords.targetY + offset) + ' ' +\n 'L' +\n coords.rightInnerExtent + ' ' + (coords.targetY + offset) +\n 'A' +\n (coords.rightLargeArcRadius + offset) + ' ' + (coords.rightSmallArcRadius + offset) + ' 0 0 1 ' +\n (coords.rightFullExtent - offset) + ' ' + (coords.targetY - coords.rightSmallArcRadius) +\n 'L' +\n (coords.rightFullExtent - offset) + ' ' + coords.verticalRightInnerExtent +\n 'A' +\n (coords.rightLargeArcRadius + offset) + ' ' + (coords.rightLargeArcRadius + offset) + ' 0 0 1 ' +\n coords.rightInnerExtent + ' ' + (coords.verticalFullExtent - offset) +\n 'L' +\n coords.leftInnerExtent + ' ' + (coords.verticalFullExtent - offset) +\n 'A' +\n (coords.leftLargeArcRadius + offset) + ' ' + (coords.leftLargeArcRadius + offset) + ' 0 0 1 ' +\n (coords.leftFullExtent + offset) + ' ' + coords.verticalLeftInnerExtent +\n 'L' +\n (coords.leftFullExtent + offset) + ' ' + (coords.sourceY - coords.leftSmallArcRadius) +\n 'A' +\n (coords.leftLargeArcRadius + offset) + ' ' + (coords.leftSmallArcRadius + offset) + ' 0 0 1 ' +\n coords.leftInnerExtent + ' ' + (coords.sourceY + offset) +\n 'L' +\n coords.sourceX + ' ' + (coords.sourceY + offset) +\n\n // Walking back\n 'L' +\n coords.sourceX + ' ' + (coords.sourceY - offset) +\n 'L' +\n coords.leftInnerExtent + ' ' + (coords.sourceY - offset) +\n 'A' +\n (coords.leftLargeArcRadius - offset) + ' ' + (coords.leftSmallArcRadius - offset) + ' 0 0 0 ' +\n (coords.leftFullExtent - offset) + ' ' + (coords.sourceY - coords.leftSmallArcRadius) +\n 'L' +\n (coords.leftFullExtent - offset) + ' ' + coords.verticalLeftInnerExtent +\n 'A' +\n (coords.leftLargeArcRadius - offset) + ' ' + (coords.leftLargeArcRadius - offset) + ' 0 0 0 ' +\n coords.leftInnerExtent + ' ' + (coords.verticalFullExtent + offset) +\n 'L' +\n coords.rightInnerExtent + ' ' + (coords.verticalFullExtent + offset) +\n 'A' +\n (coords.rightLargeArcRadius - offset) + ' ' + (coords.rightLargeArcRadius - offset) + ' 0 0 0 ' +\n (coords.rightFullExtent + offset) + ' ' + coords.verticalRightInnerExtent +\n 'L' +\n (coords.rightFullExtent + offset) + ' ' + (coords.targetY - coords.rightSmallArcRadius) +\n 'A' +\n (coords.rightLargeArcRadius - offset) + ' ' + (coords.rightSmallArcRadius - offset) + ' 0 0 0 ' +\n coords.rightInnerExtent + ' ' + (coords.targetY - offset) +\n 'L' +\n coords.targetX + ' ' + (coords.targetY - offset) +\n 'Z';\n } else {\n // Bottom path\n pathString =\n // start at the left of the target node\n 'M ' +\n coords.targetX + ' ' + (coords.targetY - offset) + ' ' +\n 'L' +\n coords.rightInnerExtent + ' ' + (coords.targetY - offset) +\n 'A' +\n (coords.rightLargeArcRadius + offset) + ' ' + (coords.rightSmallArcRadius + offset) + ' 0 0 0 ' +\n (coords.rightFullExtent - offset) + ' ' + (coords.targetY + coords.rightSmallArcRadius) +\n 'L' +\n (coords.rightFullExtent - offset) + ' ' + coords.verticalRightInnerExtent +\n 'A' +\n (coords.rightLargeArcRadius + offset) + ' ' + (coords.rightLargeArcRadius + offset) + ' 0 0 0 ' +\n coords.rightInnerExtent + ' ' + (coords.verticalFullExtent + offset) +\n 'L' +\n coords.leftInnerExtent + ' ' + (coords.verticalFullExtent + offset) +\n 'A' +\n (coords.leftLargeArcRadius + offset) + ' ' + (coords.leftLargeArcRadius + offset) + ' 0 0 0 ' +\n (coords.leftFullExtent + offset) + ' ' + coords.verticalLeftInnerExtent +\n 'L' +\n (coords.leftFullExtent + offset) + ' ' + (coords.sourceY + coords.leftSmallArcRadius) +\n 'A' +\n (coords.leftLargeArcRadius + offset) + ' ' + (coords.leftSmallArcRadius + offset) + ' 0 0 0 ' +\n coords.leftInnerExtent + ' ' + (coords.sourceY - offset) +\n 'L' +\n coords.sourceX + ' ' + (coords.sourceY - offset) +\n\n // Walking back\n 'L' +\n coords.sourceX + ' ' + (coords.sourceY + offset) +\n 'L' +\n coords.leftInnerExtent + ' ' + (coords.sourceY + offset) +\n 'A' +\n (coords.leftLargeArcRadius - offset) + ' ' + (coords.leftSmallArcRadius - offset) + ' 0 0 1 ' +\n (coords.leftFullExtent - offset) + ' ' + (coords.sourceY + coords.leftSmallArcRadius) +\n 'L' +\n (coords.leftFullExtent - offset) + ' ' + coords.verticalLeftInnerExtent +\n 'A' +\n (coords.leftLargeArcRadius - offset) + ' ' + (coords.leftLargeArcRadius - offset) + ' 0 0 1 ' +\n coords.leftInnerExtent + ' ' + (coords.verticalFullExtent - offset) +\n 'L' +\n coords.rightInnerExtent + ' ' + (coords.verticalFullExtent - offset) +\n 'A' +\n (coords.rightLargeArcRadius - offset) + ' ' + (coords.rightLargeArcRadius - offset) + ' 0 0 1 ' +\n (coords.rightFullExtent + offset) + ' ' + coords.verticalRightInnerExtent +\n 'L' +\n (coords.rightFullExtent + offset) + ' ' + (coords.targetY + coords.rightSmallArcRadius) +\n 'A' +\n (coords.rightLargeArcRadius - offset) + ' ' + (coords.rightSmallArcRadius - offset) + ' 0 0 1 ' +\n coords.rightInnerExtent + ' ' + (coords.targetY + offset) +\n 'L' +\n coords.targetX + ' ' + (coords.targetY + offset) +\n 'Z';\n }\n return pathString;\n}\n\nfunction linkPath() {\n var curvature = 0.5;\n function path(d) {\n if(d.link.circular) {\n return createCircularClosedPathString(d.link);\n } else {\n var x0 = d.link.source.x1;\n var x1 = d.link.target.x0;\n var xi = interpolateNumber(x0, x1);\n var x2 = xi(curvature);\n var x3 = xi(1 - curvature);\n var y0a = d.link.y0 - d.link.width / 2;\n var y0b = d.link.y0 + d.link.width / 2;\n var y1a = d.link.y1 - d.link.width / 2;\n var y1b = d.link.y1 + d.link.width / 2;\n return 'M' + x0 + ',' + y0a +\n 'C' + x2 + ',' + y0a +\n ' ' + x3 + ',' + y1a +\n ' ' + x1 + ',' + y1a +\n 'L' + x1 + ',' + y1b +\n 'C' + x3 + ',' + y1b +\n ' ' + x2 + ',' + y0b +\n ' ' + x0 + ',' + y0b +\n 'Z';\n }\n }\n return path;\n}\n\nfunction nodeModel(d, n) {\n var tc = tinycolor(n.color);\n var zoneThicknessPad = c.nodePadAcross;\n var zoneLengthPad = d.nodePad / 2;\n n.dx = n.x1 - n.x0;\n n.dy = n.y1 - n.y0;\n var visibleThickness = n.dx;\n var visibleLength = Math.max(0.5, n.dy);\n\n var key = 'node_' + n.pointNumber;\n // If it's a group, it's mutable and should be unique\n if(n.group) {\n key = Lib.randstr();\n }\n\n // for event data\n n.trace = d.trace;\n n.curveNumber = d.trace.index;\n\n return {\n index: n.pointNumber,\n key: key,\n partOfGroup: n.partOfGroup || false,\n group: n.group,\n traceId: d.key,\n trace: d.trace,\n node: n,\n nodePad: d.nodePad,\n nodeLineColor: d.nodeLineColor,\n nodeLineWidth: d.nodeLineWidth,\n textFont: d.textFont,\n size: d.horizontal ? d.height : d.width,\n visibleWidth: Math.ceil(visibleThickness),\n visibleHeight: visibleLength,\n zoneX: -zoneThicknessPad,\n zoneY: -zoneLengthPad,\n zoneWidth: visibleThickness + 2 * zoneThicknessPad,\n zoneHeight: visibleLength + 2 * zoneLengthPad,\n labelY: d.horizontal ? n.dy / 2 + 1 : n.dx / 2 + 1,\n left: n.originalLayer === 1,\n sizeAcross: d.width,\n forceLayouts: d.forceLayouts,\n horizontal: d.horizontal,\n darkBackground: tc.getBrightness() <= 128,\n tinyColorHue: Color.tinyRGB(tc),\n tinyColorAlpha: tc.getAlpha(),\n valueFormat: d.valueFormat,\n valueSuffix: d.valueSuffix,\n sankey: d.sankey,\n graph: d.graph,\n arrangement: d.arrangement,\n uniqueNodeLabelPathId: [d.guid, d.key, key].join('_'),\n interactionState: d.interactionState,\n figure: d\n };\n}\n\n// rendering snippets\n\nfunction updateNodePositions(sankeyNode) {\n sankeyNode\n .attr('transform', function(d) {\n return 'translate(' + d.node.x0.toFixed(3) + ', ' + (d.node.y0).toFixed(3) + ')';\n });\n}\n\nfunction updateNodeShapes(sankeyNode) {\n sankeyNode.call(updateNodePositions);\n}\n\nfunction updateShapes(sankeyNode, sankeyLink) {\n sankeyNode.call(updateNodeShapes);\n sankeyLink.attr('d', linkPath());\n}\n\nfunction sizeNode(rect) {\n rect\n .attr('width', function(d) {return d.node.x1 - d.node.x0;})\n .attr('height', function(d) {return d.visibleHeight;});\n}\n\nfunction salientEnough(d) {return (d.link.width > 1 || d.linkLineWidth > 0);}\n\nfunction sankeyTransform(d) {\n var offset = 'translate(' + d.translateX + ',' + d.translateY + ')';\n return offset + (d.horizontal ? 'matrix(1 0 0 1 0 0)' : 'matrix(0 1 1 0 0 0)');\n}\n\nfunction nodeCentering(d) {\n return 'translate(' + (d.horizontal ? 0 : d.labelY) + ' ' + (d.horizontal ? d.labelY : 0) + ')';\n}\n\nfunction textGuidePath(d) {\n return d3.svg.line()([\n [d.horizontal ? (d.left ? -d.sizeAcross : d.visibleWidth + c.nodeTextOffsetHorizontal) : c.nodeTextOffsetHorizontal, 0],\n [d.horizontal ? (d.left ? - c.nodeTextOffsetHorizontal : d.sizeAcross) : d.visibleHeight - c.nodeTextOffsetHorizontal, 0]\n ]);\n}\n\nfunction sankeyInverseTransform(d) {return d.horizontal ? 'matrix(1 0 0 1 0 0)' : 'matrix(0 1 1 0 0 0)';}\nfunction textFlip(d) {return d.horizontal ? 'scale(1 1)' : 'scale(-1 1)';}\nfunction nodeTextColor(d) {return d.darkBackground && !d.horizontal ? 'rgb(255,255,255)' : 'rgb(0,0,0)';}\nfunction nodeTextOffset(d) {return d.horizontal && d.left ? '100%' : '0%';}\n\n// event handling\n\nfunction attachPointerEvents(selection, sankey, eventSet) {\n selection\n .on('.basic', null) // remove any preexisting handlers\n .on('mouseover.basic', function(d) {\n if(!d.interactionState.dragInProgress && !d.partOfGroup) {\n eventSet.hover(this, d, sankey);\n d.interactionState.hovered = [this, d];\n }\n })\n .on('mousemove.basic', function(d) {\n if(!d.interactionState.dragInProgress && !d.partOfGroup) {\n eventSet.follow(this, d);\n d.interactionState.hovered = [this, d];\n }\n })\n .on('mouseout.basic', function(d) {\n if(!d.interactionState.dragInProgress && !d.partOfGroup) {\n eventSet.unhover(this, d, sankey);\n d.interactionState.hovered = false;\n }\n })\n .on('click.basic', function(d) {\n if(d.interactionState.hovered) {\n eventSet.unhover(this, d, sankey);\n d.interactionState.hovered = false;\n }\n if(!d.interactionState.dragInProgress && !d.partOfGroup) {\n eventSet.select(this, d, sankey);\n }\n });\n}\n\nfunction attachDragHandler(sankeyNode, sankeyLink, callbacks, gd) {\n var dragBehavior = d3.behavior.drag()\n .origin(function(d) {\n return {\n x: d.node.x0 + d.visibleWidth / 2,\n y: d.node.y0 + d.visibleHeight / 2\n };\n })\n\n .on('dragstart', function(d) {\n if(d.arrangement === 'fixed') return;\n Lib.ensureSingle(gd._fullLayout._infolayer, 'g', 'dragcover', function(s) {\n gd._fullLayout._dragCover = s;\n });\n Lib.raiseToTop(this);\n d.interactionState.dragInProgress = d.node;\n\n saveCurrentDragPosition(d.node);\n if(d.interactionState.hovered) {\n callbacks.nodeEvents.unhover.apply(0, d.interactionState.hovered);\n d.interactionState.hovered = false;\n }\n if(d.arrangement === 'snap') {\n var forceKey = d.traceId + '|' + d.key;\n if(d.forceLayouts[forceKey]) {\n d.forceLayouts[forceKey].alpha(1);\n } else { // make a forceLayout if needed\n attachForce(sankeyNode, forceKey, d, gd);\n }\n startForce(sankeyNode, sankeyLink, d, forceKey, gd);\n }\n })\n\n .on('drag', function(d) {\n if(d.arrangement === 'fixed') return;\n var x = d3.event.x;\n var y = d3.event.y;\n if(d.arrangement === 'snap') {\n d.node.x0 = x - d.visibleWidth / 2;\n d.node.x1 = x + d.visibleWidth / 2;\n d.node.y0 = y - d.visibleHeight / 2;\n d.node.y1 = y + d.visibleHeight / 2;\n } else {\n if(d.arrangement === 'freeform') {\n d.node.x0 = x - d.visibleWidth / 2;\n d.node.x1 = x + d.visibleWidth / 2;\n }\n y = Math.max(0, Math.min(d.size - d.visibleHeight / 2, y));\n d.node.y0 = y - d.visibleHeight / 2;\n d.node.y1 = y + d.visibleHeight / 2;\n }\n\n saveCurrentDragPosition(d.node);\n if(d.arrangement !== 'snap') {\n d.sankey.update(d.graph);\n updateShapes(sankeyNode.filter(sameLayer(d)), sankeyLink);\n }\n })\n\n .on('dragend', function(d) {\n if(d.arrangement === 'fixed') return;\n d.interactionState.dragInProgress = false;\n for(var i = 0; i < d.node.childrenNodes.length; i++) {\n d.node.childrenNodes[i].x = d.node.x;\n d.node.childrenNodes[i].y = d.node.y;\n }\n if(d.arrangement !== 'snap') persistFinalNodePositions(d, gd);\n });\n\n sankeyNode\n .on('.drag', null) // remove possible previous handlers\n .call(dragBehavior);\n}\n\nfunction attachForce(sankeyNode, forceKey, d, gd) {\n // Attach force to nodes in the same column (same x coordinate)\n switchToForceFormat(d.graph.nodes);\n var nodes = d.graph.nodes\n .filter(function(n) {return n.originalX === d.node.originalX;})\n // Filter out children\n .filter(function(n) {return !n.partOfGroup;});\n d.forceLayouts[forceKey] = d3Force.forceSimulation(nodes)\n .alphaDecay(0)\n .force('collide', d3Force.forceCollide()\n .radius(function(n) {return n.dy / 2 + d.nodePad / 2;})\n .strength(1)\n .iterations(c.forceIterations))\n .force('constrain', snappingForce(sankeyNode, forceKey, nodes, d, gd))\n .stop();\n}\n\nfunction startForce(sankeyNode, sankeyLink, d, forceKey, gd) {\n window.requestAnimationFrame(function faster() {\n var i;\n for(i = 0; i < c.forceTicksPerFrame; i++) {\n d.forceLayouts[forceKey].tick();\n }\n\n var nodes = d.graph.nodes;\n switchToSankeyFormat(nodes);\n\n d.sankey.update(d.graph);\n updateShapes(sankeyNode.filter(sameLayer(d)), sankeyLink);\n\n if(d.forceLayouts[forceKey].alpha() > 0) {\n window.requestAnimationFrame(faster);\n } else {\n // Make sure the final x position is equal to its original value\n // because the force simulation will have numerical error\n var x = d.node.originalX;\n d.node.x0 = x - d.visibleWidth / 2;\n d.node.x1 = x + d.visibleWidth / 2;\n\n persistFinalNodePositions(d, gd);\n }\n });\n}\n\nfunction snappingForce(sankeyNode, forceKey, nodes, d) {\n return function _snappingForce() {\n var maxVelocity = 0;\n for(var i = 0; i < nodes.length; i++) {\n var n = nodes[i];\n if(n === d.interactionState.dragInProgress) { // constrain node position to the dragging pointer\n n.x = n.lastDraggedX;\n n.y = n.lastDraggedY;\n } else {\n n.vx = (n.originalX - n.x) / c.forceTicksPerFrame; // snap to layer\n n.y = Math.min(d.size - n.dy / 2, Math.max(n.dy / 2, n.y)); // constrain to extent\n }\n maxVelocity = Math.max(maxVelocity, Math.abs(n.vx), Math.abs(n.vy));\n }\n if(!d.interactionState.dragInProgress && maxVelocity < 0.1 && d.forceLayouts[forceKey].alpha() > 0) {\n d.forceLayouts[forceKey].alpha(0); // This will stop the animation loop\n }\n };\n}\n\n// basic data utilities\n\nfunction persistFinalNodePositions(d, gd) {\n var x = [];\n var y = [];\n for(var i = 0; i < d.graph.nodes.length; i++) {\n var nodeX = (d.graph.nodes[i].x0 + d.graph.nodes[i].x1) / 2;\n var nodeY = (d.graph.nodes[i].y0 + d.graph.nodes[i].y1) / 2;\n x.push(nodeX / d.figure.width);\n y.push(nodeY / d.figure.height);\n }\n Registry.call('_guiRestyle', gd, {\n 'node.x': [x],\n 'node.y': [y]\n }, d.trace.index)\n .then(function() {\n if(gd._fullLayout._dragCover) gd._fullLayout._dragCover.remove();\n });\n}\n\nfunction persistOriginalPlace(nodes) {\n var distinctLayerPositions = [];\n var i;\n for(i = 0; i < nodes.length; i++) {\n nodes[i].originalX = (nodes[i].x0 + nodes[i].x1) / 2;\n nodes[i].originalY = (nodes[i].y0 + nodes[i].y1) / 2;\n if(distinctLayerPositions.indexOf(nodes[i].originalX) === -1) {\n distinctLayerPositions.push(nodes[i].originalX);\n }\n }\n distinctLayerPositions.sort(function(a, b) {return a - b;});\n for(i = 0; i < nodes.length; i++) {\n nodes[i].originalLayerIndex = distinctLayerPositions.indexOf(nodes[i].originalX);\n nodes[i].originalLayer = nodes[i].originalLayerIndex / (distinctLayerPositions.length - 1);\n }\n}\n\nfunction saveCurrentDragPosition(d) {\n d.lastDraggedX = d.x0 + d.dx / 2;\n d.lastDraggedY = d.y0 + d.dy / 2;\n}\n\nfunction sameLayer(d) {\n return function(n) {return n.node.originalX === d.node.originalX;};\n}\n\nfunction switchToForceFormat(nodes) {\n // force uses x, y as centers\n for(var i = 0; i < nodes.length; i++) {\n nodes[i].y = (nodes[i].y0 + nodes[i].y1) / 2;\n nodes[i].x = (nodes[i].x0 + nodes[i].x1) / 2;\n }\n}\n\nfunction switchToSankeyFormat(nodes) {\n // sankey uses x0, x1, y0, y1\n for(var i = 0; i < nodes.length; i++) {\n nodes[i].y0 = nodes[i].y - nodes[i].dy / 2;\n nodes[i].y1 = nodes[i].y0 + nodes[i].dy;\n\n nodes[i].x0 = nodes[i].x - nodes[i].dx / 2;\n nodes[i].x1 = nodes[i].x0 + nodes[i].dx;\n }\n}\n\n// scene graph\nmodule.exports = function(gd, svg, calcData, layout, callbacks) {\n // To prevent animation on first render\n var firstRender = false;\n Lib.ensureSingle(gd._fullLayout._infolayer, 'g', 'first-render', function() {\n firstRender = true;\n });\n\n // To prevent animation on dragging\n var dragcover = gd._fullLayout._dragCover;\n\n var styledData = calcData\n .filter(function(d) {return unwrap(d).trace.visible;})\n .map(sankeyModel.bind(null, layout));\n\n var sankey = svg.selectAll('.' + c.cn.sankey)\n .data(styledData, keyFun);\n\n sankey.exit()\n .remove();\n\n sankey.enter()\n .append('g')\n .classed(c.cn.sankey, true)\n .style('box-sizing', 'content-box')\n .style('position', 'absolute')\n .style('left', 0)\n .style('shape-rendering', 'geometricPrecision')\n .style('pointer-events', 'auto')\n .attr('transform', sankeyTransform);\n\n sankey.each(function(d, i) {\n gd._fullData[i]._sankey = d;\n // Create dragbox if missing\n var dragboxClassName = 'bgsankey-' + d.trace.uid + '-' + i;\n Lib.ensureSingle(gd._fullLayout._draggers, 'rect', dragboxClassName);\n\n gd._fullData[i]._bgRect = d3.select('.' + dragboxClassName);\n\n // Style dragbox\n gd._fullData[i]._bgRect\n .style('pointer-events', 'all')\n .attr('width', d.width)\n .attr('height', d.height)\n .attr('x', d.translateX)\n .attr('y', d.translateY)\n .classed('bgsankey', true)\n .style({fill: 'transparent', 'stroke-width': 0});\n });\n\n sankey.transition()\n .ease(c.ease).duration(c.duration)\n .attr('transform', sankeyTransform);\n\n var sankeyLinks = sankey.selectAll('.' + c.cn.sankeyLinks)\n .data(repeat, keyFun);\n\n sankeyLinks.enter()\n .append('g')\n .classed(c.cn.sankeyLinks, true)\n .style('fill', 'none');\n\n var sankeyLink = sankeyLinks.selectAll('.' + c.cn.sankeyLink)\n .data(function(d) {\n var links = d.graph.links;\n return links\n .filter(function(l) {return l.value;})\n .map(linkModel.bind(null, d));\n }, keyFun);\n\n sankeyLink\n .enter().append('path')\n .classed(c.cn.sankeyLink, true)\n .call(attachPointerEvents, sankey, callbacks.linkEvents);\n\n sankeyLink\n .style('stroke', function(d) {\n return salientEnough(d) ? Color.tinyRGB(tinycolor(d.linkLineColor)) : d.tinyColorHue;\n })\n .style('stroke-opacity', function(d) {\n return salientEnough(d) ? Color.opacity(d.linkLineColor) : d.tinyColorAlpha;\n })\n .style('fill', function(d) {\n return d.tinyColorHue;\n })\n .style('fill-opacity', function(d) {\n return d.tinyColorAlpha;\n })\n .style('stroke-width', function(d) {\n return salientEnough(d) ? d.linkLineWidth : 1;\n })\n .attr('d', linkPath());\n\n sankeyLink\n .style('opacity', function() { return (gd._context.staticPlot || firstRender || dragcover) ? 1 : 0;})\n .transition()\n .ease(c.ease).duration(c.duration)\n .style('opacity', 1);\n\n sankeyLink.exit()\n .transition()\n .ease(c.ease).duration(c.duration)\n .style('opacity', 0)\n .remove();\n\n var sankeyNodeSet = sankey.selectAll('.' + c.cn.sankeyNodeSet)\n .data(repeat, keyFun);\n\n sankeyNodeSet.enter()\n .append('g')\n .classed(c.cn.sankeyNodeSet, true);\n\n sankeyNodeSet\n .style('cursor', function(d) {\n switch(d.arrangement) {\n case 'fixed': return 'default';\n case 'perpendicular': return 'ns-resize';\n default: return 'move';\n }\n });\n\n var sankeyNode = sankeyNodeSet.selectAll('.' + c.cn.sankeyNode)\n .data(function(d) {\n var nodes = d.graph.nodes;\n persistOriginalPlace(nodes);\n return nodes\n .map(nodeModel.bind(null, d));\n }, keyFun);\n\n sankeyNode.enter()\n .append('g')\n .classed(c.cn.sankeyNode, true)\n .call(updateNodePositions)\n .style('opacity', function(n) { return ((gd._context.staticPlot || firstRender) && !n.partOfGroup) ? 1 : 0;});\n\n sankeyNode\n .call(attachPointerEvents, sankey, callbacks.nodeEvents)\n .call(attachDragHandler, sankeyLink, callbacks, gd); // has to be here as it binds sankeyLink\n\n sankeyNode\n .transition()\n .ease(c.ease).duration(c.duration)\n .call(updateNodePositions)\n .style('opacity', function(n) { return n.partOfGroup ? 0 : 1;});\n\n sankeyNode.exit()\n .transition()\n .ease(c.ease).duration(c.duration)\n .style('opacity', 0)\n .remove();\n\n var nodeRect = sankeyNode.selectAll('.' + c.cn.nodeRect)\n .data(repeat);\n\n nodeRect.enter()\n .append('rect')\n .classed(c.cn.nodeRect, true)\n .call(sizeNode);\n\n nodeRect\n .style('stroke-width', function(d) {return d.nodeLineWidth;})\n .style('stroke', function(d) {return Color.tinyRGB(tinycolor(d.nodeLineColor));})\n .style('stroke-opacity', function(d) {return Color.opacity(d.nodeLineColor);})\n .style('fill', function(d) {return d.tinyColorHue;})\n .style('fill-opacity', function(d) {return d.tinyColorAlpha;});\n\n nodeRect.transition()\n .ease(c.ease).duration(c.duration)\n .call(sizeNode);\n\n var nodeCapture = sankeyNode.selectAll('.' + c.cn.nodeCapture)\n .data(repeat);\n\n nodeCapture.enter()\n .append('rect')\n .classed(c.cn.nodeCapture, true)\n .style('fill-opacity', 0);\n\n nodeCapture\n .attr('x', function(d) {return d.zoneX;})\n .attr('y', function(d) {return d.zoneY;})\n .attr('width', function(d) {return d.zoneWidth;})\n .attr('height', function(d) {return d.zoneHeight;});\n\n var nodeCentered = sankeyNode.selectAll('.' + c.cn.nodeCentered)\n .data(repeat);\n\n nodeCentered.enter()\n .append('g')\n .classed(c.cn.nodeCentered, true)\n .attr('transform', nodeCentering);\n\n nodeCentered\n .transition()\n .ease(c.ease).duration(c.duration)\n .attr('transform', nodeCentering);\n\n var nodeLabelGuide = nodeCentered.selectAll('.' + c.cn.nodeLabelGuide)\n .data(repeat);\n\n nodeLabelGuide.enter()\n .append('path')\n .classed(c.cn.nodeLabelGuide, true)\n .attr('id', function(d) {return d.uniqueNodeLabelPathId;})\n .attr('d', textGuidePath)\n .attr('transform', sankeyInverseTransform);\n\n nodeLabelGuide\n .transition()\n .ease(c.ease).duration(c.duration)\n .attr('d', textGuidePath)\n .attr('transform', sankeyInverseTransform);\n\n var nodeLabel = nodeCentered.selectAll('.' + c.cn.nodeLabel)\n .data(repeat);\n\n nodeLabel.enter()\n .append('text')\n .classed(c.cn.nodeLabel, true)\n .attr('transform', textFlip)\n .style('user-select', 'none')\n .style('cursor', 'default')\n .style('fill', 'black');\n\n nodeLabel\n .style('text-shadow', function(d) {\n return d.horizontal ? '-1px 1px 1px #fff, 1px 1px 1px #fff, 1px -1px 1px #fff, -1px -1px 1px #fff' : 'none';\n })\n .each(function(d) {Drawing.font(nodeLabel, d.textFont);});\n\n nodeLabel\n .transition()\n .ease(c.ease).duration(c.duration)\n .attr('transform', textFlip);\n\n var nodeLabelTextPath = nodeLabel.selectAll('.' + c.cn.nodeLabelTextPath)\n .data(repeat);\n\n nodeLabelTextPath.enter()\n .append('textPath')\n .classed(c.cn.nodeLabelTextPath, true)\n .attr('alignment-baseline', 'middle')\n .attr('xlink:href', function(d) {return '#' + d.uniqueNodeLabelPathId;})\n .attr('startOffset', nodeTextOffset)\n .style('fill', nodeTextColor);\n\n nodeLabelTextPath\n .text(function(d) {return d.horizontal || d.node.dy > 5 ? d.node.label : '';})\n .attr('text-anchor', function(d) {return d.horizontal && d.left ? 'end' : 'start';});\n\n nodeLabelTextPath\n .transition()\n .ease(c.ease).duration(c.duration)\n .attr('startOffset', nodeTextOffset)\n .style('fill', nodeTextColor);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sankey/render.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sankey/select.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sankey/select.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function selectPoints(searchInfo, selectionTester) {\n var cd = searchInfo.cd;\n var selection = [];\n var fullData = cd[0].trace;\n\n var nodes = fullData._sankey.graph.nodes;\n\n for(var i = 0; i < nodes.length; i++) {\n var node = nodes[i];\n if(node.partOfGroup) continue; // Those are invisible\n\n // Position of node's centroid\n var pos = [(node.x0 + node.x1) / 2, (node.y0 + node.y1) / 2];\n\n // Swap x and y if trace is vertical\n if(fullData.orientation === 'v') pos.reverse();\n\n if(selectionTester && selectionTester.contains(pos, false, i, searchInfo)) {\n selection.push({\n pointNumber: node.pointNumber\n // TODO: add eventData\n });\n }\n }\n return selection;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sankey/select.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/arrays_to_calcdata.js":
-/*!*************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/arrays_to_calcdata.js ***!
- \*************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\n\n// arrayOk attributes, merge them into calcdata array\nmodule.exports = function arraysToCalcdata(cd, trace) {\n // so each point knows which index it originally came from\n for(var i = 0; i < cd.length; i++) cd[i].i = i;\n\n Lib.mergeArray(trace.text, cd, 'tx');\n Lib.mergeArray(trace.texttemplate, cd, 'txt');\n Lib.mergeArray(trace.hovertext, cd, 'htx');\n Lib.mergeArray(trace.customdata, cd, 'data');\n Lib.mergeArray(trace.textposition, cd, 'tp');\n if(trace.textfont) {\n Lib.mergeArrayCastPositive(trace.textfont.size, cd, 'ts');\n Lib.mergeArray(trace.textfont.color, cd, 'tc');\n Lib.mergeArray(trace.textfont.family, cd, 'tf');\n }\n\n var marker = trace.marker;\n if(marker) {\n Lib.mergeArrayCastPositive(marker.size, cd, 'ms');\n Lib.mergeArrayCastPositive(marker.opacity, cd, 'mo');\n Lib.mergeArray(marker.symbol, cd, 'mx');\n Lib.mergeArray(marker.color, cd, 'mc');\n\n var markerLine = marker.line;\n if(marker.line) {\n Lib.mergeArray(markerLine.color, cd, 'mlc');\n Lib.mergeArrayCastPositive(markerLine.width, cd, 'mlw');\n }\n\n var markerGradient = marker.gradient;\n if(markerGradient && markerGradient.type !== 'none') {\n Lib.mergeArray(markerGradient.type, cd, 'mgt');\n Lib.mergeArray(markerGradient.color, cd, 'mgc');\n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/arrays_to_calcdata.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/attributes.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/attributes.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar texttemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").texttemplateAttrs;\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar fontAttrs = __webpack_require__(/*! ../../plots/font_attributes */ \"./node_modules/plotly.js/src/plots/font_attributes.js\");\nvar dash = __webpack_require__(/*! ../../components/drawing/attributes */ \"./node_modules/plotly.js/src/components/drawing/attributes.js\").dash;\n\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/scatter/constants.js\");\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nmodule.exports = {\n x: {\n valType: 'data_array',\n editType: 'calc+clearAxisTypes',\n anim: true,\n \n },\n x0: {\n valType: 'any',\n dflt: 0,\n \n editType: 'calc+clearAxisTypes',\n anim: true,\n \n },\n dx: {\n valType: 'number',\n dflt: 1,\n \n editType: 'calc',\n anim: true,\n \n },\n y: {\n valType: 'data_array',\n editType: 'calc+clearAxisTypes',\n anim: true,\n \n },\n y0: {\n valType: 'any',\n dflt: 0,\n \n editType: 'calc+clearAxisTypes',\n anim: true,\n \n },\n dy: {\n valType: 'number',\n dflt: 1,\n \n editType: 'calc',\n anim: true,\n \n },\n\n stackgroup: {\n valType: 'string',\n \n dflt: '',\n editType: 'calc',\n \n },\n orientation: {\n valType: 'enumerated',\n \n values: ['v', 'h'],\n editType: 'calc',\n \n },\n groupnorm: {\n valType: 'enumerated',\n values: ['', 'fraction', 'percent'],\n dflt: '',\n \n editType: 'calc',\n \n },\n stackgaps: {\n valType: 'enumerated',\n values: ['infer zero', 'interpolate'],\n dflt: 'infer zero',\n \n editType: 'calc',\n \n },\n\n text: {\n valType: 'string',\n \n dflt: '',\n arrayOk: true,\n editType: 'calc',\n \n },\n\n texttemplate: texttemplateAttrs({}, {\n\n }),\n hovertext: {\n valType: 'string',\n \n dflt: '',\n arrayOk: true,\n editType: 'style',\n \n },\n mode: {\n valType: 'flaglist',\n flags: ['lines', 'markers', 'text'],\n extras: ['none'],\n \n editType: 'calc',\n \n },\n hoveron: {\n valType: 'flaglist',\n flags: ['points', 'fills'],\n \n editType: 'style',\n \n },\n hovertemplate: hovertemplateAttrs({}, {\n keys: constants.eventDataKeys\n }),\n line: {\n color: {\n valType: 'color',\n \n editType: 'style',\n anim: true,\n \n },\n width: {\n valType: 'number',\n min: 0,\n dflt: 2,\n \n editType: 'style',\n anim: true,\n \n },\n shape: {\n valType: 'enumerated',\n values: ['linear', 'spline', 'hv', 'vh', 'hvh', 'vhv'],\n dflt: 'linear',\n \n editType: 'plot',\n \n },\n smoothing: {\n valType: 'number',\n min: 0,\n max: 1.3,\n dflt: 1,\n \n editType: 'plot',\n \n },\n dash: extendFlat({}, dash, {editType: 'style'}),\n simplify: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'plot',\n \n },\n editType: 'plot'\n },\n\n connectgaps: {\n valType: 'boolean',\n dflt: false,\n \n editType: 'calc',\n \n },\n cliponaxis: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'plot',\n \n },\n\n fill: {\n valType: 'enumerated',\n values: ['none', 'tozeroy', 'tozerox', 'tonexty', 'tonextx', 'toself', 'tonext'],\n \n editType: 'calc',\n \n },\n fillcolor: {\n valType: 'color',\n \n editType: 'style',\n anim: true,\n \n },\n marker: extendFlat({\n symbol: {\n valType: 'enumerated',\n values: Drawing.symbolList,\n dflt: 'circle',\n arrayOk: true,\n \n editType: 'style',\n \n },\n opacity: {\n valType: 'number',\n min: 0,\n max: 1,\n arrayOk: true,\n \n editType: 'style',\n anim: true,\n \n },\n size: {\n valType: 'number',\n min: 0,\n dflt: 6,\n arrayOk: true,\n \n editType: 'calc',\n anim: true,\n \n },\n maxdisplayed: {\n valType: 'number',\n min: 0,\n dflt: 0,\n \n editType: 'plot',\n \n },\n sizeref: {\n valType: 'number',\n dflt: 1,\n \n editType: 'calc',\n \n },\n sizemin: {\n valType: 'number',\n min: 0,\n dflt: 0,\n \n editType: 'calc',\n \n },\n sizemode: {\n valType: 'enumerated',\n values: ['diameter', 'area'],\n dflt: 'diameter',\n \n editType: 'calc',\n \n },\n\n line: extendFlat({\n width: {\n valType: 'number',\n min: 0,\n arrayOk: true,\n \n editType: 'style',\n anim: true,\n \n },\n editType: 'calc'\n },\n colorScaleAttrs('marker.line', {anim: true})\n ),\n gradient: {\n type: {\n valType: 'enumerated',\n values: ['radial', 'horizontal', 'vertical', 'none'],\n arrayOk: true,\n dflt: 'none',\n \n editType: 'calc',\n \n },\n color: {\n valType: 'color',\n arrayOk: true,\n \n editType: 'calc',\n \n },\n editType: 'calc'\n },\n editType: 'calc'\n },\n colorScaleAttrs('marker', {anim: true})\n ),\n selected: {\n marker: {\n opacity: {\n valType: 'number',\n min: 0,\n max: 1,\n \n editType: 'style',\n \n },\n color: {\n valType: 'color',\n \n editType: 'style',\n \n },\n size: {\n valType: 'number',\n min: 0,\n \n editType: 'style',\n \n },\n editType: 'style'\n },\n textfont: {\n color: {\n valType: 'color',\n \n editType: 'style',\n \n },\n editType: 'style'\n },\n editType: 'style'\n },\n unselected: {\n marker: {\n opacity: {\n valType: 'number',\n min: 0,\n max: 1,\n \n editType: 'style',\n \n },\n color: {\n valType: 'color',\n \n editType: 'style',\n \n },\n size: {\n valType: 'number',\n min: 0,\n \n editType: 'style',\n \n },\n editType: 'style'\n },\n textfont: {\n color: {\n valType: 'color',\n \n editType: 'style',\n \n },\n editType: 'style'\n },\n editType: 'style'\n },\n\n textposition: {\n valType: 'enumerated',\n values: [\n 'top left', 'top center', 'top right',\n 'middle left', 'middle center', 'middle right',\n 'bottom left', 'bottom center', 'bottom right'\n ],\n dflt: 'middle center',\n arrayOk: true,\n \n editType: 'calc',\n \n },\n textfont: fontAttrs({\n editType: 'calc',\n colorEditType: 'style',\n arrayOk: true,\n \n }),\n\n r: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n t: {\n valType: 'data_array',\n editType: 'calc',\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/calc.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/calc.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nvar subTypes = __webpack_require__(/*! ./subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar calcColorscale = __webpack_require__(/*! ./colorscale_calc */ \"./node_modules/plotly.js/src/traces/scatter/colorscale_calc.js\");\nvar arraysToCalcdata = __webpack_require__(/*! ./arrays_to_calcdata */ \"./node_modules/plotly.js/src/traces/scatter/arrays_to_calcdata.js\");\nvar calcSelection = __webpack_require__(/*! ./calc_selection */ \"./node_modules/plotly.js/src/traces/scatter/calc_selection.js\");\n\nfunction calc(gd, trace) {\n var fullLayout = gd._fullLayout;\n var xa = Axes.getFromId(gd, trace.xaxis || 'x');\n var ya = Axes.getFromId(gd, trace.yaxis || 'y');\n var x = xa.makeCalcdata(trace, 'x');\n var y = ya.makeCalcdata(trace, 'y');\n var serieslen = trace._length;\n var cd = new Array(serieslen);\n var ids = trace.ids;\n var stackGroupOpts = getStackOpts(trace, fullLayout, xa, ya);\n var interpolateGaps = false;\n var isV, i, j, k, interpolate, vali;\n\n setFirstScatter(fullLayout, trace);\n\n var xAttr = 'x';\n var yAttr = 'y';\n var posAttr;\n if(stackGroupOpts) {\n Lib.pushUnique(stackGroupOpts.traceIndices, trace._expandedIndex);\n isV = stackGroupOpts.orientation === 'v';\n\n // size, like we use for bar\n if(isV) {\n yAttr = 's';\n posAttr = 'x';\n } else {\n xAttr = 's';\n posAttr = 'y';\n }\n interpolate = stackGroupOpts.stackgaps === 'interpolate';\n } else {\n var ppad = calcMarkerSize(trace, serieslen);\n calcAxisExpansion(gd, trace, xa, ya, x, y, ppad);\n }\n\n for(i = 0; i < serieslen; i++) {\n var cdi = cd[i] = {};\n var xValid = isNumeric(x[i]);\n var yValid = isNumeric(y[i]);\n if(xValid && yValid) {\n cdi[xAttr] = x[i];\n cdi[yAttr] = y[i];\n } else if(stackGroupOpts && (isV ? xValid : yValid)) {\n // if we're stacking we need to hold on to all valid positions\n // even with invalid sizes\n\n cdi[posAttr] = isV ? x[i] : y[i];\n cdi.gap = true;\n if(interpolate) {\n cdi.s = BADNUM;\n interpolateGaps = true;\n } else {\n cdi.s = 0;\n }\n } else {\n cdi[xAttr] = cdi[yAttr] = BADNUM;\n }\n\n if(ids) {\n cdi.id = String(ids[i]);\n }\n }\n\n arraysToCalcdata(cd, trace);\n calcColorscale(gd, trace);\n calcSelection(cd, trace);\n\n if(stackGroupOpts) {\n // remove bad positions and sort\n // note that original indices get added to cd in arraysToCalcdata\n i = 0;\n while(i < cd.length) {\n if(cd[i][posAttr] === BADNUM) {\n cd.splice(i, 1);\n } else i++;\n }\n\n Lib.sort(cd, function(a, b) {\n return (a[posAttr] - b[posAttr]) || (a.i - b.i);\n });\n\n if(interpolateGaps) {\n // first fill the beginning with constant from the first point\n i = 0;\n while(i < cd.length - 1 && cd[i].gap) {\n i++;\n }\n vali = cd[i].s;\n if(!vali) vali = cd[i].s = 0; // in case of no data AT ALL in this trace - use 0\n for(j = 0; j < i; j++) {\n cd[j].s = vali;\n }\n // then fill the end with constant from the last point\n k = cd.length - 1;\n while(k > i && cd[k].gap) {\n k--;\n }\n vali = cd[k].s;\n for(j = cd.length - 1; j > k; j--) {\n cd[j].s = vali;\n }\n // now interpolate internal gaps linearly\n while(i < k) {\n i++;\n if(cd[i].gap) {\n j = i + 1;\n while(cd[j].gap) {\n j++;\n }\n var pos0 = cd[i - 1][posAttr];\n var size0 = cd[i - 1].s;\n var m = (cd[j].s - size0) / (cd[j][posAttr] - pos0);\n while(i < j) {\n cd[i].s = size0 + (cd[i][posAttr] - pos0) * m;\n i++;\n }\n }\n }\n }\n }\n\n return cd;\n}\n\nfunction calcAxisExpansion(gd, trace, xa, ya, x, y, ppad) {\n var serieslen = trace._length;\n var fullLayout = gd._fullLayout;\n var xId = xa._id;\n var yId = ya._id;\n var firstScatter = fullLayout._firstScatter[firstScatterGroup(trace)] === trace.uid;\n var stackOrientation = (getStackOpts(trace, fullLayout, xa, ya) || {}).orientation;\n var fill = trace.fill;\n\n // cancel minimum tick spacings (only applies to bars and boxes)\n xa._minDtick = 0;\n ya._minDtick = 0;\n\n // check whether bounds should be tight, padded, extended to zero...\n // most cases both should be padded on both ends, so start with that.\n var xOptions = {padded: true};\n var yOptions = {padded: true};\n\n if(ppad) {\n xOptions.ppad = yOptions.ppad = ppad;\n }\n\n // TODO: text size\n\n var openEnded = serieslen < 2 || (x[0] !== x[serieslen - 1]) || (y[0] !== y[serieslen - 1]);\n\n if(openEnded && (\n (fill === 'tozerox') ||\n ((fill === 'tonextx') && (firstScatter || stackOrientation === 'h'))\n )) {\n // include zero (tight) and extremes (padded) if fill to zero\n // (unless the shape is closed, then it's just filling the shape regardless)\n\n xOptions.tozero = true;\n } else if(!(trace.error_y || {}).visible && (\n // if no error bars, markers or text, or fill to y=0 remove x padding\n\n (fill === 'tonexty' || fill === 'tozeroy') ||\n (!subTypes.hasMarkers(trace) && !subTypes.hasText(trace))\n )) {\n xOptions.padded = false;\n xOptions.ppad = 0;\n }\n\n if(openEnded && (\n (fill === 'tozeroy') ||\n ((fill === 'tonexty') && (firstScatter || stackOrientation === 'v'))\n )) {\n // now check for y - rather different logic, though still mostly padded both ends\n // include zero (tight) and extremes (padded) if fill to zero\n // (unless the shape is closed, then it's just filling the shape regardless)\n\n yOptions.tozero = true;\n } else if(fill === 'tonextx' || fill === 'tozerox') {\n // tight y: any x fill\n\n yOptions.padded = false;\n }\n\n // N.B. asymmetric splom traces call this with blank {} xa or ya\n if(xId) trace._extremes[xId] = Axes.findExtremes(xa, x, xOptions);\n if(yId) trace._extremes[yId] = Axes.findExtremes(ya, y, yOptions);\n}\n\nfunction calcMarkerSize(trace, serieslen) {\n if(!subTypes.hasMarkers(trace)) return;\n\n // Treat size like x or y arrays --- Run d2c\n // this needs to go before ppad computation\n var marker = trace.marker;\n var sizeref = 1.6 * (trace.marker.sizeref || 1);\n var markerTrans;\n\n if(trace.marker.sizemode === 'area') {\n markerTrans = function(v) {\n return Math.max(Math.sqrt((v || 0) / sizeref), 3);\n };\n } else {\n markerTrans = function(v) {\n return Math.max((v || 0) / sizeref, 3);\n };\n }\n\n if(Lib.isArrayOrTypedArray(marker.size)) {\n // I tried auto-type but category and dates dont make much sense.\n var ax = {type: 'linear'};\n Axes.setConvert(ax);\n\n var s = ax.makeCalcdata(trace.marker, 'size');\n\n var sizeOut = new Array(serieslen);\n for(var i = 0; i < serieslen; i++) {\n sizeOut[i] = markerTrans(s[i]);\n }\n return sizeOut;\n } else {\n return markerTrans(marker.size);\n }\n}\n\n/**\n * mark the first scatter trace for each subplot\n * note that scatter and scattergl each get their own first trace\n * note also that I'm doing this during calc rather than supplyDefaults\n * so I don't need to worry about transforms, but if we ever do\n * per-trace calc this will get confused.\n */\nfunction setFirstScatter(fullLayout, trace) {\n var group = firstScatterGroup(trace);\n var firstScatter = fullLayout._firstScatter;\n if(!firstScatter[group]) firstScatter[group] = trace.uid;\n}\n\nfunction firstScatterGroup(trace) {\n var stackGroup = trace.stackgroup;\n return trace.xaxis + trace.yaxis + trace.type +\n (stackGroup ? '-' + stackGroup : '');\n}\n\nfunction getStackOpts(trace, fullLayout, xa, ya) {\n var stackGroup = trace.stackgroup;\n if(!stackGroup) return;\n var stackOpts = fullLayout._scatterStackOpts[xa._id + ya._id][stackGroup];\n var stackAx = stackOpts.orientation === 'v' ? ya : xa;\n // Allow stacking only on numeric axes\n // calc is a little late to be figuring this out, but during supplyDefaults\n // we don't know the axis type yet\n if(stackAx.type === 'linear' || stackAx.type === 'log') return stackOpts;\n}\n\nmodule.exports = {\n calc: calc,\n calcMarkerSize: calcMarkerSize,\n calcAxisExpansion: calcAxisExpansion,\n setFirstScatter: setFirstScatter,\n getStackOpts: getStackOpts\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/calc_selection.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/calc_selection.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nmodule.exports = function calcSelection(cd, trace) {\n if(Lib.isArrayOrTypedArray(trace.selectedpoints)) {\n Lib.tagSelected(cd, trace);\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/calc_selection.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/colorscale_calc.js":
-/*!**********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/colorscale_calc.js ***!
- \**********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar hasColorscale = __webpack_require__(/*! ../../components/colorscale/helpers */ \"./node_modules/plotly.js/src/components/colorscale/helpers.js\").hasColorscale;\nvar calcColorscale = __webpack_require__(/*! ../../components/colorscale/calc */ \"./node_modules/plotly.js/src/components/colorscale/calc.js\");\n\nvar subTypes = __webpack_require__(/*! ./subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\n\nmodule.exports = function calcMarkerColorscale(gd, trace) {\n if(subTypes.hasLines(trace) && hasColorscale(trace, 'line')) {\n calcColorscale(gd, trace, {\n vals: trace.line.color,\n containerStr: 'line',\n cLetter: 'c'\n });\n }\n\n if(subTypes.hasMarkers(trace)) {\n if(hasColorscale(trace, 'marker')) {\n calcColorscale(gd, trace, {\n vals: trace.marker.color,\n containerStr: 'marker',\n cLetter: 'c'\n });\n }\n if(hasColorscale(trace, 'marker.line')) {\n calcColorscale(gd, trace, {\n vals: trace.marker.line.color,\n containerStr: 'marker.line',\n cLetter: 'c'\n });\n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/colorscale_calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/constants.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/constants.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nmodule.exports = {\n PTS_LINESONLY: 20,\n\n // fixed parameters of clustering and clipping algorithms\n\n // fraction of clustering tolerance \"so close we don't even consider it a new point\"\n minTolerance: 0.2,\n // how fast does clustering tolerance increase as you get away from the visible region\n toleranceGrowth: 10,\n\n // number of viewport sizes away from the visible region\n // at which we clip all lines to the perimeter\n maxScreensAway: 20,\n\n eventDataKeys: []\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/constants.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/cross_trace_calc.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/cross_trace_calc.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar calc = __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/scatter/calc.js\");\n\n/*\n * Scatter stacking & normalization calculations\n * runs per subplot, and can handle multiple stacking groups\n */\n\nmodule.exports = function crossTraceCalc(gd, plotinfo) {\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n var subplot = xa._id + ya._id;\n\n var subplotStackOpts = gd._fullLayout._scatterStackOpts[subplot];\n if(!subplotStackOpts) return;\n\n var calcTraces = gd.calcdata;\n\n var i, j, k, i2, cd, cd0, posj, sumj, norm;\n var groupOpts, interpolate, groupnorm, posAttr, valAttr;\n var hasAnyBlanks;\n\n for(var stackGroup in subplotStackOpts) {\n groupOpts = subplotStackOpts[stackGroup];\n var indices = groupOpts.traceIndices;\n\n // can get here with no indices if the stack axis is non-numeric\n if(!indices.length) continue;\n\n interpolate = groupOpts.stackgaps === 'interpolate';\n groupnorm = groupOpts.groupnorm;\n if(groupOpts.orientation === 'v') {\n posAttr = 'x';\n valAttr = 'y';\n } else {\n posAttr = 'y';\n valAttr = 'x';\n }\n hasAnyBlanks = new Array(indices.length);\n for(i = 0; i < hasAnyBlanks.length; i++) {\n hasAnyBlanks[i] = false;\n }\n\n // Collect the complete set of all positions across ALL traces.\n // Start with the first trace, then interleave items from later traces\n // as needed.\n // Fill in mising items as we go.\n cd0 = calcTraces[indices[0]];\n var allPositions = new Array(cd0.length);\n for(i = 0; i < cd0.length; i++) {\n allPositions[i] = cd0[i][posAttr];\n }\n\n for(i = 1; i < indices.length; i++) {\n cd = calcTraces[indices[i]];\n\n for(j = k = 0; j < cd.length; j++) {\n posj = cd[j][posAttr];\n for(; posj > allPositions[k] && k < allPositions.length; k++) {\n // the current trace is missing a position from some previous trace(s)\n insertBlank(cd, j, allPositions[k], i, hasAnyBlanks, interpolate, posAttr);\n j++;\n }\n if(posj !== allPositions[k]) {\n // previous trace(s) are missing a position from the current trace\n for(i2 = 0; i2 < i; i2++) {\n insertBlank(calcTraces[indices[i2]], k, posj, i2, hasAnyBlanks, interpolate, posAttr);\n }\n allPositions.splice(k, 0, posj);\n }\n k++;\n }\n for(; k < allPositions.length; k++) {\n insertBlank(cd, j, allPositions[k], i, hasAnyBlanks, interpolate, posAttr);\n j++;\n }\n }\n\n var serieslen = allPositions.length;\n\n // stack (and normalize)!\n for(j = 0; j < cd0.length; j++) {\n sumj = cd0[j][valAttr] = cd0[j].s;\n for(i = 1; i < indices.length; i++) {\n cd = calcTraces[indices[i]];\n cd[0].trace._rawLength = cd[0].trace._length;\n cd[0].trace._length = serieslen;\n sumj += cd[j].s;\n cd[j][valAttr] = sumj;\n }\n\n if(groupnorm) {\n norm = ((groupnorm === 'fraction') ? sumj : (sumj / 100)) || 1;\n for(i = 0; i < indices.length; i++) {\n var cdj = calcTraces[indices[i]][j];\n cdj[valAttr] /= norm;\n cdj.sNorm = cdj.s / norm;\n }\n }\n }\n\n // autorange\n for(i = 0; i < indices.length; i++) {\n cd = calcTraces[indices[i]];\n var trace = cd[0].trace;\n var ppad = calc.calcMarkerSize(trace, trace._rawLength);\n var arrayPad = Array.isArray(ppad);\n if((ppad && hasAnyBlanks[i]) || arrayPad) {\n var ppadRaw = ppad;\n ppad = new Array(serieslen);\n for(j = 0; j < serieslen; j++) {\n ppad[j] = cd[j].gap ? 0 : (arrayPad ? ppadRaw[cd[j].i] : ppadRaw);\n }\n }\n var x = new Array(serieslen);\n var y = new Array(serieslen);\n for(j = 0; j < serieslen; j++) {\n x[j] = cd[j].x;\n y[j] = cd[j].y;\n }\n calc.calcAxisExpansion(gd, trace, xa, ya, x, y, ppad);\n\n // while we're here (in a loop over all traces in the stack)\n // record the orientation, so hover can find it easily\n cd[0].t.orientation = groupOpts.orientation;\n }\n }\n};\n\nfunction insertBlank(calcTrace, index, position, traceIndex, hasAnyBlanks, interpolate, posAttr) {\n hasAnyBlanks[traceIndex] = true;\n var newEntry = {\n i: null,\n gap: true,\n s: 0\n };\n newEntry[posAttr] = position;\n calcTrace.splice(index, 0, newEntry);\n // Even if we're not interpolating, if one trace has multiple\n // values at the same position and this trace only has one value there,\n // we just duplicate that one value rather than insert a zero.\n // We also make it look like a real point - because it's ambiguous which\n // one really is the real one!\n if(index && position === calcTrace[index - 1][posAttr]) {\n var prevEntry = calcTrace[index - 1];\n newEntry.s = prevEntry.s;\n // TODO is it going to cause any problems to have multiple\n // calcdata points with the same index?\n newEntry.i = prevEntry.i;\n newEntry.gap = prevEntry.gap;\n } else if(interpolate) {\n newEntry.s = getInterp(calcTrace, index, position, posAttr);\n }\n if(!index) {\n // t and trace need to stay on the first cd entry\n calcTrace[0].t = calcTrace[1].t;\n calcTrace[0].trace = calcTrace[1].trace;\n delete calcTrace[1].t;\n delete calcTrace[1].trace;\n }\n}\n\nfunction getInterp(calcTrace, index, position, posAttr) {\n var pt0 = calcTrace[index - 1];\n var pt1 = calcTrace[index + 1];\n if(!pt1) return pt0.s;\n if(!pt0) return pt1.s;\n return pt0.s + (pt1.s - pt0.s) * (position - pt0[posAttr]) / (pt1[posAttr] - pt0[posAttr]);\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/cross_trace_calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/cross_trace_defaults.js":
-/*!***************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/cross_trace_defaults.js ***!
- \***************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\n\n// remove opacity for any trace that has a fill or is filled to\nmodule.exports = function crossTraceDefaults(fullData) {\n for(var i = 0; i < fullData.length; i++) {\n var tracei = fullData[i];\n if(tracei.type !== 'scatter') continue;\n\n var filli = tracei.fill;\n if(filli === 'none' || filli === 'toself') continue;\n\n tracei.opacity = undefined;\n\n if(filli === 'tonexty' || filli === 'tonextx') {\n for(var j = i - 1; j >= 0; j--) {\n var tracej = fullData[j];\n\n if((tracej.type === 'scatter') &&\n (tracej.xaxis === tracei.xaxis) &&\n (tracej.yaxis === tracei.yaxis)) {\n tracej.opacity = undefined;\n break;\n }\n }\n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/cross_trace_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/defaults.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/defaults.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\n\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\");\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/scatter/constants.js\");\nvar subTypes = __webpack_require__(/*! ./subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar handleXYDefaults = __webpack_require__(/*! ./xy_defaults */ \"./node_modules/plotly.js/src/traces/scatter/xy_defaults.js\");\nvar handleStackDefaults = __webpack_require__(/*! ./stack_defaults */ \"./node_modules/plotly.js/src/traces/scatter/stack_defaults.js\");\nvar handleMarkerDefaults = __webpack_require__(/*! ./marker_defaults */ \"./node_modules/plotly.js/src/traces/scatter/marker_defaults.js\");\nvar handleLineDefaults = __webpack_require__(/*! ./line_defaults */ \"./node_modules/plotly.js/src/traces/scatter/line_defaults.js\");\nvar handleLineShapeDefaults = __webpack_require__(/*! ./line_shape_defaults */ \"./node_modules/plotly.js/src/traces/scatter/line_shape_defaults.js\");\nvar handleTextDefaults = __webpack_require__(/*! ./text_defaults */ \"./node_modules/plotly.js/src/traces/scatter/text_defaults.js\");\nvar handleFillColorDefaults = __webpack_require__(/*! ./fillcolor_defaults */ \"./node_modules/plotly.js/src/traces/scatter/fillcolor_defaults.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var len = handleXYDefaults(traceIn, traceOut, layout, coerce);\n if(!len) traceOut.visible = false;\n\n if(!traceOut.visible) return;\n\n var stackGroupOpts = handleStackDefaults(traceIn, traceOut, layout, coerce);\n\n var defaultMode = !stackGroupOpts && (len < constants.PTS_LINESONLY) ?\n 'lines+markers' : 'lines';\n coerce('text');\n coerce('hovertext');\n coerce('mode', defaultMode);\n\n if(subTypes.hasLines(traceOut)) {\n handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);\n handleLineShapeDefaults(traceIn, traceOut, coerce);\n coerce('connectgaps');\n coerce('line.simplify');\n }\n\n if(subTypes.hasMarkers(traceOut)) {\n handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});\n }\n\n if(subTypes.hasText(traceOut)) {\n coerce('texttemplate');\n handleTextDefaults(traceIn, traceOut, layout, coerce);\n }\n\n var dfltHoverOn = [];\n\n if(subTypes.hasMarkers(traceOut) || subTypes.hasText(traceOut)) {\n coerce('cliponaxis');\n coerce('marker.maxdisplayed');\n dfltHoverOn.push('points');\n }\n\n // It's possible for this default to be changed by a later trace.\n // We handle that case in some hacky code inside handleStackDefaults.\n coerce('fill', stackGroupOpts ? stackGroupOpts.fillDflt : 'none');\n if(traceOut.fill !== 'none') {\n handleFillColorDefaults(traceIn, traceOut, defaultColor, coerce);\n if(!subTypes.hasLines(traceOut)) handleLineShapeDefaults(traceIn, traceOut, coerce);\n }\n\n var lineColor = (traceOut.line || {}).color;\n var markerColor = (traceOut.marker || {}).color;\n\n if(traceOut.fill === 'tonext' || traceOut.fill === 'toself') {\n dfltHoverOn.push('fills');\n }\n coerce('hoveron', dfltHoverOn.join('+') || 'points');\n if(traceOut.hoveron !== 'fills') coerce('hovertemplate');\n var errorBarsSupplyDefaults = Registry.getComponentMethod('errorbars', 'supplyDefaults');\n errorBarsSupplyDefaults(traceIn, traceOut, lineColor || markerColor || defaultColor, {axis: 'y'});\n errorBarsSupplyDefaults(traceIn, traceOut, lineColor || markerColor || defaultColor, {axis: 'x', inherit: 'y'});\n\n Lib.coerceSelectionMarkerOpacity(traceOut, coerce);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/fillcolor_defaults.js":
-/*!*************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/fillcolor_defaults.js ***!
- \*************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar isArrayOrTypedArray = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").isArrayOrTypedArray;\n\nmodule.exports = function fillColorDefaults(traceIn, traceOut, defaultColor, coerce) {\n var inheritColorFromMarker = false;\n\n if(traceOut.marker) {\n // don't try to inherit a color array\n var markerColor = traceOut.marker.color;\n var markerLineColor = (traceOut.marker.line || {}).color;\n\n if(markerColor && !isArrayOrTypedArray(markerColor)) {\n inheritColorFromMarker = markerColor;\n } else if(markerLineColor && !isArrayOrTypedArray(markerLineColor)) {\n inheritColorFromMarker = markerLineColor;\n }\n }\n\n coerce('fillcolor', Color.addOpacity(\n (traceOut.line || {}).color ||\n inheritColorFromMarker ||\n defaultColor, 0.5\n ));\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/fillcolor_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/format_labels.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/format_labels.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\n\nmodule.exports = function formatLabels(cdi, trace, fullLayout) {\n var labels = {};\n\n var mockGd = {_fullLayout: fullLayout};\n var xa = Axes.getFromTrace(mockGd, trace, 'x');\n var ya = Axes.getFromTrace(mockGd, trace, 'y');\n\n labels.xLabel = Axes.tickText(xa, cdi.x, true).text;\n labels.yLabel = Axes.tickText(ya, cdi.y, true).text;\n\n return labels;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/format_labels.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/get_trace_color.js":
-/*!**********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/get_trace_color.js ***!
- \**********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar subtypes = __webpack_require__(/*! ./subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\n\n\nmodule.exports = function getTraceColor(trace, di) {\n var lc, tc;\n\n // TODO: text modes\n\n if(trace.mode === 'lines') {\n lc = trace.line.color;\n return (lc && Color.opacity(lc)) ?\n lc : trace.fillcolor;\n } else if(trace.mode === 'none') {\n return trace.fill ? trace.fillcolor : '';\n } else {\n var mc = di.mcc || (trace.marker || {}).color;\n var mlc = di.mlcc || ((trace.marker || {}).line || {}).color;\n\n tc = (mc && Color.opacity(mc)) ? mc :\n (mlc && Color.opacity(mlc) &&\n (di.mlw || ((trace.marker || {}).line || {}).width)) ? mlc : '';\n\n if(tc) {\n // make sure the points aren't TOO transparent\n if(Color.opacity(tc) < 0.3) {\n return Color.addOpacity(tc, 0.3);\n } else return tc;\n } else {\n lc = (trace.line || {}).color;\n return (lc && Color.opacity(lc) &&\n subtypes.hasLines(trace) && trace.line.width) ?\n lc : trace.fillcolor;\n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/get_trace_color.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/hover.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/hover.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Fx = __webpack_require__(/*! ../../components/fx */ \"./node_modules/plotly.js/src/components/fx/index.js\");\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar getTraceColor = __webpack_require__(/*! ./get_trace_color */ \"./node_modules/plotly.js/src/traces/scatter/get_trace_color.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar fillText = Lib.fillText;\n\nmodule.exports = function hoverPoints(pointData, xval, yval, hovermode) {\n var cd = pointData.cd;\n var trace = cd[0].trace;\n var xa = pointData.xa;\n var ya = pointData.ya;\n var xpx = xa.c2p(xval);\n var ypx = ya.c2p(yval);\n var pt = [xpx, ypx];\n var hoveron = trace.hoveron || '';\n var minRad = (trace.mode.indexOf('markers') !== -1) ? 3 : 0.5;\n\n // look for points to hover on first, then take fills only if we\n // didn't find a point\n if(hoveron.indexOf('points') !== -1) {\n var dx = function(di) {\n // dx and dy are used in compare modes - here we want to always\n // prioritize the closest data point, at least as long as markers are\n // the same size or nonexistent, but still try to prioritize small markers too.\n var rad = Math.max(3, di.mrc || 0);\n var kink = 1 - 1 / rad;\n var dxRaw = Math.abs(xa.c2p(di.x) - xpx);\n var d = (dxRaw < rad) ? (kink * dxRaw / rad) : (dxRaw - rad + kink);\n return d;\n };\n var dy = function(di) {\n var rad = Math.max(3, di.mrc || 0);\n var kink = 1 - 1 / rad;\n var dyRaw = Math.abs(ya.c2p(di.y) - ypx);\n return (dyRaw < rad) ? (kink * dyRaw / rad) : (dyRaw - rad + kink);\n };\n var dxy = function(di) {\n // scatter points: d.mrc is the calculated marker radius\n // adjust the distance so if you're inside the marker it\n // always will show up regardless of point size, but\n // prioritize smaller points\n var rad = Math.max(minRad, di.mrc || 0);\n var dx = xa.c2p(di.x) - xpx;\n var dy = ya.c2p(di.y) - ypx;\n return Math.max(Math.sqrt(dx * dx + dy * dy) - rad, 1 - minRad / rad);\n };\n var distfn = Fx.getDistanceFunction(hovermode, dx, dy, dxy);\n\n Fx.getClosest(cd, distfn, pointData);\n\n // skip the rest (for this trace) if we didn't find a close point\n if(pointData.index !== false) {\n // the closest data point\n var di = cd[pointData.index];\n var xc = xa.c2p(di.x, true);\n var yc = ya.c2p(di.y, true);\n var rad = di.mrc || 1;\n\n // now we're done using the whole `calcdata` array, replace the\n // index with the original index (in case of inserted point from\n // stacked area)\n pointData.index = di.i;\n\n var orientation = cd[0].t.orientation;\n // TODO: for scatter and bar, option to show (sub)totals and\n // raw data? Currently stacked and/or normalized bars just show\n // the normalized individual sizes, so that's what I'm doing here\n // for now.\n var sizeVal = orientation && (di.sNorm || di.s);\n var xLabelVal = (orientation === 'h') ? sizeVal : di.x;\n var yLabelVal = (orientation === 'v') ? sizeVal : di.y;\n\n Lib.extendFlat(pointData, {\n color: getTraceColor(trace, di),\n\n x0: xc - rad,\n x1: xc + rad,\n xLabelVal: xLabelVal,\n\n y0: yc - rad,\n y1: yc + rad,\n yLabelVal: yLabelVal,\n\n spikeDistance: dxy(di),\n hovertemplate: trace.hovertemplate\n });\n\n fillText(di, trace, pointData);\n Registry.getComponentMethod('errorbars', 'hoverInfo')(di, trace, pointData);\n\n return [pointData];\n }\n }\n\n // even if hoveron is 'fills', only use it if we have polygons too\n if(hoveron.indexOf('fills') !== -1 && trace._polygons) {\n var polygons = trace._polygons;\n var polygonsIn = [];\n var inside = false;\n var xmin = Infinity;\n var xmax = -Infinity;\n var ymin = Infinity;\n var ymax = -Infinity;\n\n var i, j, polygon, pts, xCross, x0, x1, y0, y1;\n\n for(i = 0; i < polygons.length; i++) {\n polygon = polygons[i];\n // TODO: this is not going to work right for curved edges, it will\n // act as though they're straight. That's probably going to need\n // the elements themselves to capture the events. Worth it?\n if(polygon.contains(pt)) {\n inside = !inside;\n // TODO: need better than just the overall bounding box\n polygonsIn.push(polygon);\n ymin = Math.min(ymin, polygon.ymin);\n ymax = Math.max(ymax, polygon.ymax);\n }\n }\n\n if(inside) {\n // constrain ymin/max to the visible plot, so the label goes\n // at the middle of the piece you can see\n ymin = Math.max(ymin, 0);\n ymax = Math.min(ymax, ya._length);\n\n // find the overall left-most and right-most points of the\n // polygon(s) we're inside at their combined vertical midpoint.\n // This is where we will draw the hover label.\n // Note that this might not be the vertical midpoint of the\n // whole trace, if it's disjoint.\n var yAvg = (ymin + ymax) / 2;\n for(i = 0; i < polygonsIn.length; i++) {\n pts = polygonsIn[i].pts;\n for(j = 1; j < pts.length; j++) {\n y0 = pts[j - 1][1];\n y1 = pts[j][1];\n if((y0 > yAvg) !== (y1 >= yAvg)) {\n x0 = pts[j - 1][0];\n x1 = pts[j][0];\n if(y1 - y0) {\n xCross = x0 + (x1 - x0) * (yAvg - y0) / (y1 - y0);\n xmin = Math.min(xmin, xCross);\n xmax = Math.max(xmax, xCross);\n }\n }\n }\n }\n\n // constrain xmin/max to the visible plot now too\n xmin = Math.max(xmin, 0);\n xmax = Math.min(xmax, xa._length);\n\n // get only fill or line color for the hover color\n var color = Color.defaultLine;\n if(Color.opacity(trace.fillcolor)) color = trace.fillcolor;\n else if(Color.opacity((trace.line || {}).color)) {\n color = trace.line.color;\n }\n\n Lib.extendFlat(pointData, {\n // never let a 2D override 1D type as closest point\n // also: no spikeDistance, it's not allowed for fills\n distance: pointData.maxHoverDistance,\n x0: xmin,\n x1: xmax,\n y0: yAvg,\n y1: yAvg,\n color: color,\n hovertemplate: false\n });\n\n delete pointData.index;\n\n if(trace.text && !Array.isArray(trace.text)) {\n pointData.text = String(trace.text);\n } else pointData.text = trace.name;\n\n return [pointData];\n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/index.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/index.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar subtypes = __webpack_require__(/*! ./subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\n\nmodule.exports = {\n hasLines: subtypes.hasLines,\n hasMarkers: subtypes.hasMarkers,\n hasText: subtypes.hasText,\n isBubble: subtypes.isBubble,\n\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/scatter/defaults.js\"),\n crossTraceDefaults: __webpack_require__(/*! ./cross_trace_defaults */ \"./node_modules/plotly.js/src/traces/scatter/cross_trace_defaults.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/scatter/calc.js\").calc,\n crossTraceCalc: __webpack_require__(/*! ./cross_trace_calc */ \"./node_modules/plotly.js/src/traces/scatter/cross_trace_calc.js\"),\n arraysToCalcdata: __webpack_require__(/*! ./arrays_to_calcdata */ \"./node_modules/plotly.js/src/traces/scatter/arrays_to_calcdata.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/scatter/plot.js\"),\n colorbar: __webpack_require__(/*! ./marker_colorbar */ \"./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js\"),\n formatLabels: __webpack_require__(/*! ./format_labels */ \"./node_modules/plotly.js/src/traces/scatter/format_labels.js\"),\n style: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/scatter/style.js\").style,\n styleOnSelect: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/scatter/style.js\").styleOnSelect,\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/scatter/hover.js\"),\n selectPoints: __webpack_require__(/*! ./select */ \"./node_modules/plotly.js/src/traces/scatter/select.js\"),\n animatable: true,\n\n moduleType: 'trace',\n name: 'scatter',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: [\n 'cartesian', 'svg', 'symbols', 'errorBarsOK', 'showLegend', 'scatter-like',\n 'zoomScale'\n ],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/line_defaults.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/line_defaults.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isArrayOrTypedArray = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").isArrayOrTypedArray;\nvar hasColorscale = __webpack_require__(/*! ../../components/colorscale/helpers */ \"./node_modules/plotly.js/src/components/colorscale/helpers.js\").hasColorscale;\nvar colorscaleDefaults = __webpack_require__(/*! ../../components/colorscale/defaults */ \"./node_modules/plotly.js/src/components/colorscale/defaults.js\");\n\nmodule.exports = function lineDefaults(traceIn, traceOut, defaultColor, layout, coerce, opts) {\n var markerColor = (traceIn.marker || {}).color;\n\n coerce('line.color', defaultColor);\n\n if(hasColorscale(traceIn, 'line')) {\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: 'line.', cLetter: 'c'});\n } else {\n var lineColorDflt = (isArrayOrTypedArray(markerColor) ? false : markerColor) || defaultColor;\n coerce('line.color', lineColorDflt);\n }\n\n coerce('line.width');\n if(!(opts || {}).noDash) coerce('line.dash');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/line_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/line_points.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/line_points.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar numConstants = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\");\nvar BADNUM = numConstants.BADNUM;\nvar LOG_CLIP = numConstants.LOG_CLIP;\nvar LOG_CLIP_PLUS = LOG_CLIP + 0.5;\nvar LOG_CLIP_MINUS = LOG_CLIP - 0.5;\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar segmentsIntersect = Lib.segmentsIntersect;\nvar constrain = Lib.constrain;\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/scatter/constants.js\");\n\n\nmodule.exports = function linePoints(d, opts) {\n var xa = opts.xaxis;\n var ya = opts.yaxis;\n var xLog = xa.type === 'log';\n var yLog = ya.type === 'log';\n var xLen = xa._length;\n var yLen = ya._length;\n var connectGaps = opts.connectGaps;\n var baseTolerance = opts.baseTolerance;\n var shape = opts.shape;\n var linear = shape === 'linear';\n var fill = opts.fill && opts.fill !== 'none';\n var segments = [];\n var minTolerance = constants.minTolerance;\n var len = d.length;\n var pts = new Array(len);\n var pti = 0;\n\n var i;\n\n // pt variables are pixel coordinates [x,y] of one point\n // these four are the outputs of clustering on a line\n var clusterStartPt, clusterEndPt, clusterHighPt, clusterLowPt;\n\n // \"this\" is the next point we're considering adding to the cluster\n var thisPt;\n\n // did we encounter the high point first, then a low point, or vice versa?\n var clusterHighFirst;\n\n // the first two points in the cluster determine its unit vector\n // so the second is always in the \"High\" direction\n var clusterUnitVector;\n\n // the pixel delta from clusterStartPt\n var thisVector;\n\n // val variables are (signed) pixel distances along the cluster vector\n var clusterRefDist, clusterHighVal, clusterLowVal, thisVal;\n\n // deviation variables are (signed) pixel distances normal to the cluster vector\n var clusterMinDeviation, clusterMaxDeviation, thisDeviation;\n\n // turn one calcdata point into pixel coordinates\n function getPt(index) {\n var di = d[index];\n if(!di) return false;\n var x = opts.linearized ? xa.l2p(di.x) : xa.c2p(di.x);\n var y = opts.linearized ? ya.l2p(di.y) : ya.c2p(di.y);\n\n // if non-positive log values, set them VERY far off-screen\n // so the line looks essentially straight from the previous point.\n if(x === BADNUM) {\n if(xLog) x = xa.c2p(di.x, true);\n if(x === BADNUM) return false;\n // If BOTH were bad log values, make the line follow a constant\n // exponent rather than a constant slope\n if(yLog && y === BADNUM) {\n x *= Math.abs(xa._m * yLen * (xa._m > 0 ? LOG_CLIP_PLUS : LOG_CLIP_MINUS) /\n (ya._m * xLen * (ya._m > 0 ? LOG_CLIP_PLUS : LOG_CLIP_MINUS)));\n }\n x *= 1000;\n }\n if(y === BADNUM) {\n if(yLog) y = ya.c2p(di.y, true);\n if(y === BADNUM) return false;\n y *= 1000;\n }\n return [x, y];\n }\n\n function crossesViewport(xFrac0, yFrac0, xFrac1, yFrac1) {\n var dx = xFrac1 - xFrac0;\n var dy = yFrac1 - yFrac0;\n var dx0 = 0.5 - xFrac0;\n var dy0 = 0.5 - yFrac0;\n var norm2 = dx * dx + dy * dy;\n var dot = dx * dx0 + dy * dy0;\n if(dot > 0 && dot < norm2) {\n var cross = dx0 * dy - dy0 * dx;\n if(cross * cross < norm2) return true;\n }\n }\n\n var latestXFrac, latestYFrac;\n // if we're off-screen, increase tolerance over baseTolerance\n function getTolerance(pt, nextPt) {\n var xFrac = pt[0] / xLen;\n var yFrac = pt[1] / yLen;\n var offScreenFraction = Math.max(0, -xFrac, xFrac - 1, -yFrac, yFrac - 1);\n if(offScreenFraction && (latestXFrac !== undefined) &&\n crossesViewport(xFrac, yFrac, latestXFrac, latestYFrac)\n ) {\n offScreenFraction = 0;\n }\n if(offScreenFraction && nextPt &&\n crossesViewport(xFrac, yFrac, nextPt[0] / xLen, nextPt[1] / yLen)\n ) {\n offScreenFraction = 0;\n }\n\n return (1 + constants.toleranceGrowth * offScreenFraction) * baseTolerance;\n }\n\n function ptDist(pt1, pt2) {\n var dx = pt1[0] - pt2[0];\n var dy = pt1[1] - pt2[1];\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n // last bit of filtering: clip paths that are VERY far off-screen\n // so we don't get near the browser's hard limit (+/- 2^29 px in Chrome and FF)\n\n var maxScreensAway = constants.maxScreensAway;\n\n // find the intersections between the segment from pt1 to pt2\n // and the large rectangle maxScreensAway around the viewport\n // if one of pt1 and pt2 is inside and the other outside, there\n // will be only one intersection.\n // if both are outside there will be 0 or 2 intersections\n // (or 1 if it's right at a corner - we'll treat that like 0)\n // returns an array of intersection pts\n var xEdge0 = -xLen * maxScreensAway;\n var xEdge1 = xLen * (1 + maxScreensAway);\n var yEdge0 = -yLen * maxScreensAway;\n var yEdge1 = yLen * (1 + maxScreensAway);\n var edges = [\n [xEdge0, yEdge0, xEdge1, yEdge0],\n [xEdge1, yEdge0, xEdge1, yEdge1],\n [xEdge1, yEdge1, xEdge0, yEdge1],\n [xEdge0, yEdge1, xEdge0, yEdge0]\n ];\n var xEdge, yEdge, lastXEdge, lastYEdge, lastFarPt, edgePt;\n\n // for linear line shape, edge intersections should be linearly interpolated\n // spline uses this too, which isn't precisely correct but is actually pretty\n // good, because Catmull-Rom weights far-away points less in creating the curvature\n function getLinearEdgeIntersections(pt1, pt2) {\n var out = [];\n var ptCount = 0;\n for(var i = 0; i < 4; i++) {\n var edge = edges[i];\n var ptInt = segmentsIntersect(\n pt1[0], pt1[1], pt2[0], pt2[1],\n edge[0], edge[1], edge[2], edge[3]\n );\n if(ptInt && (!ptCount ||\n Math.abs(ptInt.x - out[0][0]) > 1 ||\n Math.abs(ptInt.y - out[0][1]) > 1\n )) {\n ptInt = [ptInt.x, ptInt.y];\n // if we have 2 intersections, make sure the closest one to pt1 comes first\n if(ptCount && ptDist(ptInt, pt1) < ptDist(out[0], pt1)) out.unshift(ptInt);\n else out.push(ptInt);\n ptCount++;\n }\n }\n return out;\n }\n\n function onlyConstrainedPoint(pt) {\n if(pt[0] < xEdge0 || pt[0] > xEdge1 || pt[1] < yEdge0 || pt[1] > yEdge1) {\n return [constrain(pt[0], xEdge0, xEdge1), constrain(pt[1], yEdge0, yEdge1)];\n }\n }\n\n function sameEdge(pt1, pt2) {\n if(pt1[0] === pt2[0] && (pt1[0] === xEdge0 || pt1[0] === xEdge1)) return true;\n if(pt1[1] === pt2[1] && (pt1[1] === yEdge0 || pt1[1] === yEdge1)) return true;\n }\n\n // for line shapes hv and vh, movement in the two dimensions is decoupled,\n // so all we need to do is constrain each dimension independently\n function getHVEdgeIntersections(pt1, pt2) {\n var out = [];\n var ptInt1 = onlyConstrainedPoint(pt1);\n var ptInt2 = onlyConstrainedPoint(pt2);\n if(ptInt1 && ptInt2 && sameEdge(ptInt1, ptInt2)) return out;\n\n if(ptInt1) out.push(ptInt1);\n if(ptInt2) out.push(ptInt2);\n return out;\n }\n\n // hvh and vhv we sometimes have to move one of the intersection points\n // out BEYOND the clipping rect, by a maximum of a factor of 2, so that\n // the midpoint line is drawn in the right place\n function getABAEdgeIntersections(dim, limit0, limit1) {\n return function(pt1, pt2) {\n var ptInt1 = onlyConstrainedPoint(pt1);\n var ptInt2 = onlyConstrainedPoint(pt2);\n\n var out = [];\n if(ptInt1 && ptInt2 && sameEdge(ptInt1, ptInt2)) return out;\n\n if(ptInt1) out.push(ptInt1);\n if(ptInt2) out.push(ptInt2);\n\n var midShift = 2 * Lib.constrain((pt1[dim] + pt2[dim]) / 2, limit0, limit1) -\n ((ptInt1 || pt1)[dim] + (ptInt2 || pt2)[dim]);\n if(midShift) {\n var ptToAlter;\n if(ptInt1 && ptInt2) {\n ptToAlter = (midShift > 0 === ptInt1[dim] > ptInt2[dim]) ? ptInt1 : ptInt2;\n } else ptToAlter = ptInt1 || ptInt2;\n\n ptToAlter[dim] += midShift;\n }\n\n return out;\n };\n }\n\n var getEdgeIntersections;\n if(shape === 'linear' || shape === 'spline') {\n getEdgeIntersections = getLinearEdgeIntersections;\n } else if(shape === 'hv' || shape === 'vh') {\n getEdgeIntersections = getHVEdgeIntersections;\n } else if(shape === 'hvh') getEdgeIntersections = getABAEdgeIntersections(0, xEdge0, xEdge1);\n else if(shape === 'vhv') getEdgeIntersections = getABAEdgeIntersections(1, yEdge0, yEdge1);\n\n // a segment pt1->pt2 entirely outside the nearby region:\n // find the corner it gets closest to touching\n function getClosestCorner(pt1, pt2) {\n var dx = pt2[0] - pt1[0];\n var m = (pt2[1] - pt1[1]) / dx;\n var b = (pt1[1] * pt2[0] - pt2[1] * pt1[0]) / dx;\n\n if(b > 0) return [m > 0 ? xEdge0 : xEdge1, yEdge1];\n else return [m > 0 ? xEdge1 : xEdge0, yEdge0];\n }\n\n function updateEdge(pt) {\n var x = pt[0];\n var y = pt[1];\n var xSame = x === pts[pti - 1][0];\n var ySame = y === pts[pti - 1][1];\n // duplicate point?\n if(xSame && ySame) return;\n if(pti > 1) {\n // backtracking along an edge?\n var xSame2 = x === pts[pti - 2][0];\n var ySame2 = y === pts[pti - 2][1];\n if(xSame && (x === xEdge0 || x === xEdge1) && xSame2) {\n if(ySame2) pti--; // backtracking exactly - drop prev pt and don't add\n else pts[pti - 1] = pt; // not exact: replace the prev pt\n } else if(ySame && (y === yEdge0 || y === yEdge1) && ySame2) {\n if(xSame2) pti--;\n else pts[pti - 1] = pt;\n } else pts[pti++] = pt;\n } else pts[pti++] = pt;\n }\n\n function updateEdgesForReentry(pt) {\n // if we're outside the nearby region and going back in,\n // we may need to loop around a corner point\n if(pts[pti - 1][0] !== pt[0] && pts[pti - 1][1] !== pt[1]) {\n updateEdge([lastXEdge, lastYEdge]);\n }\n updateEdge(pt);\n lastFarPt = null;\n lastXEdge = lastYEdge = 0;\n }\n\n function addPt(pt) {\n latestXFrac = pt[0] / xLen;\n latestYFrac = pt[1] / yLen;\n // Are we more than maxScreensAway off-screen any direction?\n // if so, clip to this box, but in such a way that on-screen\n // drawing is unchanged\n xEdge = (pt[0] < xEdge0) ? xEdge0 : (pt[0] > xEdge1) ? xEdge1 : 0;\n yEdge = (pt[1] < yEdge0) ? yEdge0 : (pt[1] > yEdge1) ? yEdge1 : 0;\n if(xEdge || yEdge) {\n if(!pti) {\n // to get fills right - if first point is far, push it toward the\n // screen in whichever direction(s) are far\n\n pts[pti++] = [xEdge || pt[0], yEdge || pt[1]];\n } else if(lastFarPt) {\n // both this point and the last are outside the nearby region\n // check if we're crossing the nearby region\n var intersections = getEdgeIntersections(lastFarPt, pt);\n if(intersections.length > 1) {\n updateEdgesForReentry(intersections[0]);\n pts[pti++] = intersections[1];\n }\n } else {\n // we're leaving the nearby region - add the point where we left it\n\n edgePt = getEdgeIntersections(pts[pti - 1], pt)[0];\n pts[pti++] = edgePt;\n }\n\n var lastPt = pts[pti - 1];\n if(xEdge && yEdge && (lastPt[0] !== xEdge || lastPt[1] !== yEdge)) {\n // we've gone out beyond a new corner: add the corner too\n // so that the next point will take the right winding\n if(lastFarPt) {\n if(lastXEdge !== xEdge && lastYEdge !== yEdge) {\n if(lastXEdge && lastYEdge) {\n // we've gone around to an opposite corner - we\n // need to add the correct extra corner\n // in order to get the right winding\n updateEdge(getClosestCorner(lastFarPt, pt));\n } else {\n // we're coming from a far edge - the extra corner\n // we need is determined uniquely by the sectors\n updateEdge([lastXEdge || xEdge, lastYEdge || yEdge]);\n }\n } else if(lastXEdge && lastYEdge) {\n updateEdge([lastXEdge, lastYEdge]);\n }\n }\n updateEdge([xEdge, yEdge]);\n } else if((lastXEdge - xEdge) && (lastYEdge - yEdge)) {\n // we're coming from an edge or far corner to an edge - again the\n // extra corner we need is uniquely determined by the sectors\n updateEdge([xEdge || lastXEdge, yEdge || lastYEdge]);\n }\n lastFarPt = pt;\n lastXEdge = xEdge;\n lastYEdge = yEdge;\n } else {\n if(lastFarPt) {\n // this point is in range but the previous wasn't: add its entry pt first\n updateEdgesForReentry(getEdgeIntersections(lastFarPt, pt)[0]);\n }\n\n pts[pti++] = pt;\n }\n }\n\n // loop over ALL points in this trace\n for(i = 0; i < len; i++) {\n clusterStartPt = getPt(i);\n if(!clusterStartPt) continue;\n\n pti = 0;\n lastFarPt = null;\n addPt(clusterStartPt);\n\n // loop over one segment of the trace\n for(i++; i < len; i++) {\n clusterHighPt = getPt(i);\n if(!clusterHighPt) {\n if(connectGaps) continue;\n else break;\n }\n\n // can't decimate if nonlinear line shape\n // TODO: we *could* decimate [hv]{2,3} shapes if we restricted clusters to horz or vert again\n // but spline would be verrry awkward to decimate\n if(!linear || !opts.simplify) {\n addPt(clusterHighPt);\n continue;\n }\n\n var nextPt = getPt(i + 1);\n\n clusterRefDist = ptDist(clusterHighPt, clusterStartPt);\n\n // #3147 - always include the very first and last points for fills\n if(!(fill && (pti === 0 || pti === len - 1)) &&\n clusterRefDist < getTolerance(clusterHighPt, nextPt) * minTolerance) continue;\n\n clusterUnitVector = [\n (clusterHighPt[0] - clusterStartPt[0]) / clusterRefDist,\n (clusterHighPt[1] - clusterStartPt[1]) / clusterRefDist\n ];\n\n clusterLowPt = clusterStartPt;\n clusterHighVal = clusterRefDist;\n clusterLowVal = clusterMinDeviation = clusterMaxDeviation = 0;\n clusterHighFirst = false;\n clusterEndPt = clusterHighPt;\n\n // loop over one cluster of points that collapse onto one line\n for(i++; i < d.length; i++) {\n thisPt = nextPt;\n nextPt = getPt(i + 1);\n if(!thisPt) {\n if(connectGaps) continue;\n else break;\n }\n thisVector = [\n thisPt[0] - clusterStartPt[0],\n thisPt[1] - clusterStartPt[1]\n ];\n // cross product (or dot with normal to the cluster vector)\n thisDeviation = thisVector[0] * clusterUnitVector[1] - thisVector[1] * clusterUnitVector[0];\n clusterMinDeviation = Math.min(clusterMinDeviation, thisDeviation);\n clusterMaxDeviation = Math.max(clusterMaxDeviation, thisDeviation);\n\n if(clusterMaxDeviation - clusterMinDeviation > getTolerance(thisPt, nextPt)) break;\n\n clusterEndPt = thisPt;\n thisVal = thisVector[0] * clusterUnitVector[0] + thisVector[1] * clusterUnitVector[1];\n\n if(thisVal > clusterHighVal) {\n clusterHighVal = thisVal;\n clusterHighPt = thisPt;\n clusterHighFirst = false;\n } else if(thisVal < clusterLowVal) {\n clusterLowVal = thisVal;\n clusterLowPt = thisPt;\n clusterHighFirst = true;\n }\n }\n\n // insert this cluster into pts\n // we've already inserted the start pt, now check if we have high and low pts\n if(clusterHighFirst) {\n addPt(clusterHighPt);\n if(clusterEndPt !== clusterLowPt) addPt(clusterLowPt);\n } else {\n if(clusterLowPt !== clusterStartPt) addPt(clusterLowPt);\n if(clusterEndPt !== clusterHighPt) addPt(clusterHighPt);\n }\n // and finally insert the end pt\n addPt(clusterEndPt);\n\n // have we reached the end of this segment?\n if(i >= d.length || !thisPt) break;\n\n // otherwise we have an out-of-cluster point to insert as next clusterStartPt\n addPt(thisPt);\n clusterStartPt = thisPt;\n }\n\n // to get fills right - repeat what we did at the start\n if(lastFarPt) updateEdge([lastXEdge || lastFarPt[0], lastYEdge || lastFarPt[1]]);\n\n segments.push(pts.slice(0, pti));\n }\n\n return segments;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/line_points.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/line_shape_defaults.js":
-/*!**************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/line_shape_defaults.js ***!
- \**************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\n\n// common to 'scatter' and 'scatterternary'\nmodule.exports = function handleLineShapeDefaults(traceIn, traceOut, coerce) {\n var shape = coerce('line.shape');\n if(shape === 'spline') coerce('line.smoothing');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/line_shape_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/link_traces.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/link_traces.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar LINKEDFILLS = {tonextx: 1, tonexty: 1, tonext: 1};\n\nmodule.exports = function linkTraces(gd, plotinfo, cdscatter) {\n var trace, i, group, prevtrace, groupIndex;\n\n // first sort traces to keep stacks & filled-together groups together\n var groupIndices = {};\n var needsSort = false;\n var prevGroupIndex = -1;\n var nextGroupIndex = 0;\n var prevUnstackedGroupIndex = -1;\n for(i = 0; i < cdscatter.length; i++) {\n trace = cdscatter[i][0].trace;\n group = trace.stackgroup || '';\n if(group) {\n if(group in groupIndices) {\n groupIndex = groupIndices[group];\n } else {\n groupIndex = groupIndices[group] = nextGroupIndex;\n nextGroupIndex++;\n }\n } else if(trace.fill in LINKEDFILLS && prevUnstackedGroupIndex >= 0) {\n groupIndex = prevUnstackedGroupIndex;\n } else {\n groupIndex = prevUnstackedGroupIndex = nextGroupIndex;\n nextGroupIndex++;\n }\n\n if(groupIndex < prevGroupIndex) needsSort = true;\n trace._groupIndex = prevGroupIndex = groupIndex;\n }\n\n var cdscatterSorted = cdscatter.slice();\n if(needsSort) {\n cdscatterSorted.sort(function(a, b) {\n var traceA = a[0].trace;\n var traceB = b[0].trace;\n return (traceA._groupIndex - traceB._groupIndex) ||\n (traceA.index - traceB.index);\n });\n }\n\n // now link traces to each other\n var prevtraces = {};\n for(i = 0; i < cdscatterSorted.length; i++) {\n trace = cdscatterSorted[i][0].trace;\n group = trace.stackgroup || '';\n\n // Note: The check which ensures all cdscatter here are for the same axis and\n // are either cartesian or scatterternary has been removed. This code assumes\n // the passed scattertraces have been filtered to the proper plot types and\n // the proper subplots.\n if(trace.visible === true) {\n trace._nexttrace = null;\n\n if(trace.fill in LINKEDFILLS) {\n prevtrace = prevtraces[group];\n trace._prevtrace = prevtrace || null;\n\n if(prevtrace) {\n prevtrace._nexttrace = trace;\n }\n }\n\n trace._ownfill = (trace.fill && (\n trace.fill.substr(0, 6) === 'tozero' ||\n trace.fill === 'toself' ||\n (trace.fill.substr(0, 2) === 'to' && !trace._prevtrace)\n ));\n\n prevtraces[group] = trace;\n } else {\n trace._prevtrace = trace._nexttrace = trace._ownfill = null;\n }\n }\n\n return cdscatterSorted;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/link_traces.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/make_bubble_size_func.js":
-/*!****************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/make_bubble_size_func.js ***!
- \****************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\n\n// used in the drawing step for 'scatter' and 'scattegeo' and\n// in the convert step for 'scatter3d'\nmodule.exports = function makeBubbleSizeFn(trace) {\n var marker = trace.marker;\n var sizeRef = marker.sizeref || 1;\n var sizeMin = marker.sizemin || 0;\n\n // for bubble charts, allow scaling the provided value linearly\n // and by area or diameter.\n // Note this only applies to the array-value sizes\n\n var baseFn = (marker.sizemode === 'area') ?\n function(v) { return Math.sqrt(v / sizeRef); } :\n function(v) { return v / sizeRef; };\n\n // TODO add support for position/negative bubbles?\n // TODO add 'sizeoffset' attribute?\n return function(v) {\n var baseSize = baseFn(v / 2);\n\n // don't show non-numeric and negative sizes\n return (isNumeric(baseSize) && (baseSize > 0)) ?\n Math.max(baseSize, sizeMin) :\n 0;\n };\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/make_bubble_size_func.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js":
-/*!**********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js ***!
- \**********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nmodule.exports = {\n container: 'marker',\n min: 'cmin',\n max: 'cmax'\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/marker_defaults.js":
-/*!**********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/marker_defaults.js ***!
- \**********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar hasColorscale = __webpack_require__(/*! ../../components/colorscale/helpers */ \"./node_modules/plotly.js/src/components/colorscale/helpers.js\").hasColorscale;\nvar colorscaleDefaults = __webpack_require__(/*! ../../components/colorscale/defaults */ \"./node_modules/plotly.js/src/components/colorscale/defaults.js\");\n\nvar subTypes = __webpack_require__(/*! ./subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\n\n/*\n * opts: object of flags to control features not all marker users support\n * noLine: caller does not support marker lines\n * gradient: caller supports gradients\n * noSelect: caller does not support selected/unselected attribute containers\n */\nmodule.exports = function markerDefaults(traceIn, traceOut, defaultColor, layout, coerce, opts) {\n var isBubble = subTypes.isBubble(traceIn);\n var lineColor = (traceIn.line || {}).color;\n var defaultMLC;\n\n opts = opts || {};\n\n // marker.color inherit from line.color (even if line.color is an array)\n if(lineColor) defaultColor = lineColor;\n\n coerce('marker.symbol');\n coerce('marker.opacity', isBubble ? 0.7 : 1);\n coerce('marker.size');\n\n coerce('marker.color', defaultColor);\n if(hasColorscale(traceIn, 'marker')) {\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: 'marker.', cLetter: 'c'});\n }\n\n if(!opts.noSelect) {\n coerce('selected.marker.color');\n coerce('unselected.marker.color');\n coerce('selected.marker.size');\n coerce('unselected.marker.size');\n }\n\n if(!opts.noLine) {\n // if there's a line with a different color than the marker, use\n // that line color as the default marker line color\n // (except when it's an array)\n // mostly this is for transparent markers to behave nicely\n if(lineColor && !Array.isArray(lineColor) && (traceOut.marker.color !== lineColor)) {\n defaultMLC = lineColor;\n } else if(isBubble) defaultMLC = Color.background;\n else defaultMLC = Color.defaultLine;\n\n coerce('marker.line.color', defaultMLC);\n if(hasColorscale(traceIn, 'marker.line')) {\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: 'marker.line.', cLetter: 'c'});\n }\n\n coerce('marker.line.width', isBubble ? 1 : 0);\n }\n\n if(isBubble) {\n coerce('marker.sizeref');\n coerce('marker.sizemin');\n coerce('marker.sizemode');\n }\n\n if(opts.gradient) {\n var gradientType = coerce('marker.gradient.type');\n if(gradientType !== 'none') {\n coerce('marker.gradient.color');\n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/marker_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/plot.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/plot.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar ensureSingle = Lib.ensureSingle;\nvar identity = Lib.identity;\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\n\nvar subTypes = __webpack_require__(/*! ./subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar linePoints = __webpack_require__(/*! ./line_points */ \"./node_modules/plotly.js/src/traces/scatter/line_points.js\");\nvar linkTraces = __webpack_require__(/*! ./link_traces */ \"./node_modules/plotly.js/src/traces/scatter/link_traces.js\");\nvar polygonTester = __webpack_require__(/*! ../../lib/polygon */ \"./node_modules/plotly.js/src/lib/polygon.js\").tester;\n\nmodule.exports = function plot(gd, plotinfo, cdscatter, scatterLayer, transitionOpts, makeOnCompleteCallback) {\n var join, onComplete;\n\n // If transition config is provided, then it is only a partial replot and traces not\n // updated are removed.\n var isFullReplot = !transitionOpts;\n var hasTransition = !!transitionOpts && transitionOpts.duration > 0;\n\n // Link traces so the z-order of fill layers is correct\n var cdscatterSorted = linkTraces(gd, plotinfo, cdscatter);\n\n join = scatterLayer.selectAll('g.trace')\n .data(cdscatterSorted, function(d) { return d[0].trace.uid; });\n\n // Append new traces:\n join.enter().append('g')\n .attr('class', function(d) {\n return 'trace scatter trace' + d[0].trace.uid;\n })\n .style('stroke-miterlimit', 2);\n join.order();\n\n createFills(gd, join, plotinfo);\n\n if(hasTransition) {\n if(makeOnCompleteCallback) {\n // If it was passed a callback to register completion, make a callback. If\n // this is created, then it must be executed on completion, otherwise the\n // pos-transition redraw will not execute:\n onComplete = makeOnCompleteCallback();\n }\n\n var transition = d3.transition()\n .duration(transitionOpts.duration)\n .ease(transitionOpts.easing)\n .each('end', function() {\n onComplete && onComplete();\n })\n .each('interrupt', function() {\n onComplete && onComplete();\n });\n\n transition.each(function() {\n // Must run the selection again since otherwise enters/updates get grouped together\n // and these get executed out of order. Except we need them in order!\n scatterLayer.selectAll('g.trace').each(function(d, i) {\n plotOne(gd, i, plotinfo, d, cdscatterSorted, this, transitionOpts);\n });\n });\n } else {\n join.each(function(d, i) {\n plotOne(gd, i, plotinfo, d, cdscatterSorted, this, transitionOpts);\n });\n }\n\n if(isFullReplot) {\n join.exit().remove();\n }\n\n // remove paths that didn't get used\n scatterLayer.selectAll('path:not([d])').remove();\n};\n\nfunction createFills(gd, traceJoin, plotinfo) {\n traceJoin.each(function(d) {\n var fills = ensureSingle(d3.select(this), 'g', 'fills');\n Drawing.setClipUrl(fills, plotinfo.layerClipId, gd);\n\n var trace = d[0].trace;\n\n var fillData = [];\n if(trace._ownfill) fillData.push('_ownFill');\n if(trace._nexttrace) fillData.push('_nextFill');\n\n var fillJoin = fills.selectAll('g').data(fillData, identity);\n\n fillJoin.enter().append('g');\n\n fillJoin.exit()\n .each(function(d) { trace[d] = null; })\n .remove();\n\n fillJoin.order().each(function(d) {\n // make a path element inside the fill group, just so\n // we can give it its own data later on and the group can\n // keep its simple '_*Fill' data\n trace[d] = ensureSingle(d3.select(this), 'path', 'js-fill');\n });\n });\n}\n\nfunction plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transitionOpts) {\n var i;\n\n // Since this has been reorganized and we're executing this on individual traces,\n // we need to pass it the full list of cdscatter as well as this trace's index (idx)\n // since it does an internal n^2 loop over comparisons with other traces:\n selectMarkers(gd, idx, plotinfo, cdscatter, cdscatterAll);\n\n var hasTransition = !!transitionOpts && transitionOpts.duration > 0;\n\n function transition(selection) {\n return hasTransition ? selection.transition() : selection;\n }\n\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n\n var trace = cdscatter[0].trace;\n var line = trace.line;\n var tr = d3.select(element);\n\n var errorBarGroup = ensureSingle(tr, 'g', 'errorbars');\n var lines = ensureSingle(tr, 'g', 'lines');\n var points = ensureSingle(tr, 'g', 'points');\n var text = ensureSingle(tr, 'g', 'text');\n\n // error bars are at the bottom\n Registry.getComponentMethod('errorbars', 'plot')(gd, errorBarGroup, plotinfo, transitionOpts);\n\n if(trace.visible !== true) return;\n\n transition(tr).style('opacity', trace.opacity);\n\n // BUILD LINES AND FILLS\n var ownFillEl3, tonext;\n var ownFillDir = trace.fill.charAt(trace.fill.length - 1);\n if(ownFillDir !== 'x' && ownFillDir !== 'y') ownFillDir = '';\n\n // store node for tweaking by selectPoints\n cdscatter[0][plotinfo.isRangePlot ? 'nodeRangePlot3' : 'node3'] = tr;\n\n var prevRevpath = '';\n var prevPolygons = [];\n var prevtrace = trace._prevtrace;\n\n if(prevtrace) {\n prevRevpath = prevtrace._prevRevpath || '';\n tonext = prevtrace._nextFill;\n prevPolygons = prevtrace._polygons;\n }\n\n var thispath;\n var thisrevpath;\n // fullpath is all paths for this curve, joined together straight\n // across gaps, for filling\n var fullpath = '';\n // revpath is fullpath reversed, for fill-to-next\n var revpath = '';\n // functions for converting a point array to a path\n var pathfn, revpathbase, revpathfn;\n // variables used before and after the data join\n var pt0, lastSegment, pt1, thisPolygons;\n\n // initialize line join data / method\n var segments = [];\n var makeUpdate = Lib.noop;\n\n ownFillEl3 = trace._ownFill;\n\n if(subTypes.hasLines(trace) || trace.fill !== 'none') {\n if(tonext) {\n // This tells .style which trace to use for fill information:\n tonext.datum(cdscatter);\n }\n\n if(['hv', 'vh', 'hvh', 'vhv'].indexOf(line.shape) !== -1) {\n pathfn = Drawing.steps(line.shape);\n revpathbase = Drawing.steps(\n line.shape.split('').reverse().join('')\n );\n } else if(line.shape === 'spline') {\n pathfn = revpathbase = function(pts) {\n var pLast = pts[pts.length - 1];\n if(pts.length > 1 && pts[0][0] === pLast[0] && pts[0][1] === pLast[1]) {\n // identical start and end points: treat it as a\n // closed curve so we don't get a kink\n return Drawing.smoothclosed(pts.slice(1), line.smoothing);\n } else {\n return Drawing.smoothopen(pts, line.smoothing);\n }\n };\n } else {\n pathfn = revpathbase = function(pts) {\n return 'M' + pts.join('L');\n };\n }\n\n revpathfn = function(pts) {\n // note: this is destructive (reverses pts in place) so can't use pts after this\n return revpathbase(pts.reverse());\n };\n\n segments = linePoints(cdscatter, {\n xaxis: xa,\n yaxis: ya,\n connectGaps: trace.connectgaps,\n baseTolerance: Math.max(line.width || 1, 3) / 4,\n shape: line.shape,\n simplify: line.simplify,\n fill: trace.fill\n });\n\n // since we already have the pixel segments here, use them to make\n // polygons for hover on fill\n // TODO: can we skip this if hoveron!=fills? That would mean we\n // need to redraw when you change hoveron...\n thisPolygons = trace._polygons = new Array(segments.length);\n for(i = 0; i < segments.length; i++) {\n trace._polygons[i] = polygonTester(segments[i]);\n }\n\n if(segments.length) {\n pt0 = segments[0][0];\n lastSegment = segments[segments.length - 1];\n pt1 = lastSegment[lastSegment.length - 1];\n }\n\n makeUpdate = function(isEnter) {\n return function(pts) {\n thispath = pathfn(pts);\n thisrevpath = revpathfn(pts);\n if(!fullpath) {\n fullpath = thispath;\n revpath = thisrevpath;\n } else if(ownFillDir) {\n fullpath += 'L' + thispath.substr(1);\n revpath = thisrevpath + ('L' + revpath.substr(1));\n } else {\n fullpath += 'Z' + thispath;\n revpath = thisrevpath + 'Z' + revpath;\n }\n\n if(subTypes.hasLines(trace) && pts.length > 1) {\n var el = d3.select(this);\n\n // This makes the coloring work correctly:\n el.datum(cdscatter);\n\n if(isEnter) {\n transition(el.style('opacity', 0)\n .attr('d', thispath)\n .call(Drawing.lineGroupStyle))\n .style('opacity', 1);\n } else {\n var sel = transition(el);\n sel.attr('d', thispath);\n Drawing.singleLineStyle(cdscatter, sel);\n }\n }\n };\n };\n }\n\n var lineJoin = lines.selectAll('.js-line').data(segments);\n\n transition(lineJoin.exit())\n .style('opacity', 0)\n .remove();\n\n lineJoin.each(makeUpdate(false));\n\n lineJoin.enter().append('path')\n .classed('js-line', true)\n .style('vector-effect', 'non-scaling-stroke')\n .call(Drawing.lineGroupStyle)\n .each(makeUpdate(true));\n\n Drawing.setClipUrl(lineJoin, plotinfo.layerClipId, gd);\n\n function clearFill(selection) {\n transition(selection).attr('d', 'M0,0Z');\n }\n\n if(segments.length) {\n if(ownFillEl3) {\n ownFillEl3.datum(cdscatter);\n if(pt0 && pt1) {\n if(ownFillDir) {\n if(ownFillDir === 'y') {\n pt0[1] = pt1[1] = ya.c2p(0, true);\n } else if(ownFillDir === 'x') {\n pt0[0] = pt1[0] = xa.c2p(0, true);\n }\n\n // fill to zero: full trace path, plus extension of\n // the endpoints to the appropriate axis\n // For the sake of animations, wrap the points around so that\n // the points on the axes are the first two points. Otherwise\n // animations get a little crazy if the number of points changes.\n transition(ownFillEl3).attr('d', 'M' + pt1 + 'L' + pt0 + 'L' + fullpath.substr(1))\n .call(Drawing.singleFillStyle);\n } else {\n // fill to self: just join the path to itself\n transition(ownFillEl3).attr('d', fullpath + 'Z')\n .call(Drawing.singleFillStyle);\n }\n }\n } else if(tonext) {\n if(trace.fill.substr(0, 6) === 'tonext' && fullpath && prevRevpath) {\n // fill to next: full trace path, plus the previous path reversed\n if(trace.fill === 'tonext') {\n // tonext: for use by concentric shapes, like manually constructed\n // contours, we just add the two paths closed on themselves.\n // This makes strange results if one path is *not* entirely\n // inside the other, but then that is a strange usage.\n transition(tonext).attr('d', fullpath + 'Z' + prevRevpath + 'Z')\n .call(Drawing.singleFillStyle);\n } else {\n // tonextx/y: for now just connect endpoints with lines. This is\n // the correct behavior if the endpoints are at the same value of\n // y/x, but if they *aren't*, we should ideally do more complicated\n // things depending on whether the new endpoint projects onto the\n // existing curve or off the end of it\n transition(tonext).attr('d', fullpath + 'L' + prevRevpath.substr(1) + 'Z')\n .call(Drawing.singleFillStyle);\n }\n trace._polygons = trace._polygons.concat(prevPolygons);\n } else {\n clearFill(tonext);\n trace._polygons = null;\n }\n }\n trace._prevRevpath = revpath;\n trace._prevPolygons = thisPolygons;\n } else {\n if(ownFillEl3) clearFill(ownFillEl3);\n else if(tonext) clearFill(tonext);\n trace._polygons = trace._prevRevpath = trace._prevPolygons = null;\n }\n\n\n function visFilter(d) {\n return d.filter(function(v) { return !v.gap && v.vis; });\n }\n\n function visFilterWithGaps(d) {\n return d.filter(function(v) { return v.vis; });\n }\n\n function gapFilter(d) {\n return d.filter(function(v) { return !v.gap; });\n }\n\n function keyFunc(d) {\n return d.id;\n }\n\n // Returns a function if the trace is keyed, otherwise returns undefined\n function getKeyFunc(trace) {\n if(trace.ids) {\n return keyFunc;\n }\n }\n\n function hideFilter() {\n return false;\n }\n\n function makePoints(points, text, cdscatter) {\n var join, selection, hasNode;\n\n var trace = cdscatter[0].trace;\n var showMarkers = subTypes.hasMarkers(trace);\n var showText = subTypes.hasText(trace);\n\n var keyFunc = getKeyFunc(trace);\n var markerFilter = hideFilter;\n var textFilter = hideFilter;\n\n if(showMarkers || showText) {\n var showFilter = identity;\n // if we're stacking, \"infer zero\" gap mode gets markers in the\n // gap points - because we've inferred a zero there - but other\n // modes (currently \"interpolate\", later \"interrupt\" hopefully)\n // we don't draw generated markers\n var stackGroup = trace.stackgroup;\n var isInferZero = stackGroup && (\n gd._fullLayout._scatterStackOpts[xa._id + ya._id][stackGroup].stackgaps === 'infer zero');\n if(trace.marker.maxdisplayed || trace._needsCull) {\n showFilter = isInferZero ? visFilterWithGaps : visFilter;\n } else if(stackGroup && !isInferZero) {\n showFilter = gapFilter;\n }\n\n if(showMarkers) markerFilter = showFilter;\n if(showText) textFilter = showFilter;\n }\n\n // marker points\n\n selection = points.selectAll('path.point');\n\n join = selection.data(markerFilter, keyFunc);\n\n var enter = join.enter().append('path')\n .classed('point', true);\n\n if(hasTransition) {\n enter\n .call(Drawing.pointStyle, trace, gd)\n .call(Drawing.translatePoints, xa, ya)\n .style('opacity', 0)\n .transition()\n .style('opacity', 1);\n }\n\n join.order();\n\n var styleFns;\n if(showMarkers) {\n styleFns = Drawing.makePointStyleFns(trace);\n }\n\n join.each(function(d) {\n var el = d3.select(this);\n var sel = transition(el);\n hasNode = Drawing.translatePoint(d, sel, xa, ya);\n\n if(hasNode) {\n Drawing.singlePointStyle(d, sel, trace, styleFns, gd);\n\n if(plotinfo.layerClipId) {\n Drawing.hideOutsideRangePoint(d, sel, xa, ya, trace.xcalendar, trace.ycalendar);\n }\n\n if(trace.customdata) {\n el.classed('plotly-customdata', d.data !== null && d.data !== undefined);\n }\n } else {\n sel.remove();\n }\n });\n\n if(hasTransition) {\n join.exit().transition()\n .style('opacity', 0)\n .remove();\n } else {\n join.exit().remove();\n }\n\n // text points\n selection = text.selectAll('g');\n join = selection.data(textFilter, keyFunc);\n\n // each text needs to go in its own 'g' in case\n // it gets converted to mathjax\n join.enter().append('g').classed('textpoint', true).append('text');\n\n join.order();\n\n join.each(function(d) {\n var g = d3.select(this);\n var sel = transition(g.select('text'));\n hasNode = Drawing.translatePoint(d, sel, xa, ya);\n\n if(hasNode) {\n if(plotinfo.layerClipId) {\n Drawing.hideOutsideRangePoint(d, g, xa, ya, trace.xcalendar, trace.ycalendar);\n }\n } else {\n g.remove();\n }\n });\n\n join.selectAll('text')\n .call(Drawing.textPointStyle, trace, gd)\n .each(function(d) {\n // This just *has* to be totally custom becuase of SVG text positioning :(\n // It's obviously copied from translatePoint; we just can't use that\n var x = xa.c2p(d.x);\n var y = ya.c2p(d.y);\n\n d3.select(this).selectAll('tspan.line').each(function() {\n transition(d3.select(this)).attr({x: x, y: y});\n });\n });\n\n join.exit().remove();\n }\n\n points.datum(cdscatter);\n text.datum(cdscatter);\n makePoints(points, text, cdscatter);\n\n // lastly, clip points groups of `cliponaxis !== false` traces\n // on `plotinfo._hasClipOnAxisFalse === true` subplots\n var hasClipOnAxisFalse = trace.cliponaxis === false;\n var clipUrl = hasClipOnAxisFalse ? null : plotinfo.layerClipId;\n Drawing.setClipUrl(points, clipUrl, gd);\n Drawing.setClipUrl(text, clipUrl, gd);\n}\n\nfunction selectMarkers(gd, idx, plotinfo, cdscatter, cdscatterAll) {\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n var xr = d3.extent(Lib.simpleMap(xa.range, xa.r2c));\n var yr = d3.extent(Lib.simpleMap(ya.range, ya.r2c));\n\n var trace = cdscatter[0].trace;\n if(!subTypes.hasMarkers(trace)) return;\n // if marker.maxdisplayed is used, select a maximum of\n // mnum markers to show, from the set that are in the viewport\n var mnum = trace.marker.maxdisplayed;\n\n // TODO: remove some as we get away from the viewport?\n if(mnum === 0) return;\n\n var cd = cdscatter.filter(function(v) {\n return v.x >= xr[0] && v.x <= xr[1] && v.y >= yr[0] && v.y <= yr[1];\n });\n var inc = Math.ceil(cd.length / mnum);\n var tnum = 0;\n cdscatterAll.forEach(function(cdj, j) {\n var tracei = cdj[0].trace;\n if(subTypes.hasMarkers(tracei) &&\n tracei.marker.maxdisplayed > 0 && j < idx) {\n tnum++;\n }\n });\n\n // if multiple traces use maxdisplayed, stagger which markers we\n // display this formula offsets successive traces by 1/3 of the\n // increment, adding an extra small amount after each triplet so\n // it's not quite periodic\n var i0 = Math.round(tnum * inc / 3 + Math.floor(tnum / 3) * inc / 7.1);\n\n // for error bars: save in cd which markers to show\n // so we don't have to repeat this\n cdscatter.forEach(function(v) { delete v.vis; });\n cd.forEach(function(v, i) {\n if(Math.round((i + i0) % inc) === 0) v.vis = true;\n });\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/select.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/select.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar subtypes = __webpack_require__(/*! ./subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\n\nmodule.exports = function selectPoints(searchInfo, selectionTester) {\n var cd = searchInfo.cd;\n var xa = searchInfo.xaxis;\n var ya = searchInfo.yaxis;\n var selection = [];\n var trace = cd[0].trace;\n var i;\n var di;\n var x;\n var y;\n\n var hasOnlyLines = (!subtypes.hasMarkers(trace) && !subtypes.hasText(trace));\n if(hasOnlyLines) return [];\n\n if(selectionTester === false) { // clear selection\n for(i = 0; i < cd.length; i++) {\n cd[i].selected = 0;\n }\n } else {\n for(i = 0; i < cd.length; i++) {\n di = cd[i];\n x = xa.c2p(di.x);\n y = ya.c2p(di.y);\n\n if((di.i !== null) && selectionTester.contains([x, y], false, i, searchInfo)) {\n selection.push({\n pointNumber: di.i,\n x: xa.c2d(di.x),\n y: ya.c2d(di.y)\n });\n di.selected = 1;\n } else {\n di.selected = 0;\n }\n }\n }\n\n return selection;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/select.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/stack_defaults.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/stack_defaults.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar perStackAttrs = ['orientation', 'groupnorm', 'stackgaps'];\n\nmodule.exports = function handleStackDefaults(traceIn, traceOut, layout, coerce) {\n var stackOpts = layout._scatterStackOpts;\n\n var stackGroup = coerce('stackgroup');\n if(stackGroup) {\n // use independent stacking options per subplot\n var subplot = traceOut.xaxis + traceOut.yaxis;\n var subplotStackOpts = stackOpts[subplot];\n if(!subplotStackOpts) subplotStackOpts = stackOpts[subplot] = {};\n\n var groupOpts = subplotStackOpts[stackGroup];\n var firstTrace = false;\n if(groupOpts) {\n groupOpts.traces.push(traceOut);\n } else {\n groupOpts = subplotStackOpts[stackGroup] = {\n // keep track of trace indices for use during stacking calculations\n // this will be filled in during `calc` and used during `crossTraceCalc`\n // so it's OK if we don't recreate it during a non-calc edit\n traceIndices: [],\n // Hold on to the whole set of prior traces\n // First one is most important, so we can clear defaults\n // there if we find explicit values only in later traces.\n // We're only going to *use* the values stored in groupOpts,\n // but for the editor and validate we want things self-consistent\n // The full set of traces is used only to fix `fill` default if\n // we find `orientation: 'h'` beyond the first trace\n traces: [traceOut]\n };\n firstTrace = true;\n }\n // TODO: how is this going to work with groupby transforms?\n // in principle it should be OK I guess, as long as explicit group styles\n // don't override explicit base-trace styles?\n\n var dflts = {\n orientation: (traceOut.x && !traceOut.y) ? 'h' : 'v'\n };\n\n for(var i = 0; i < perStackAttrs.length; i++) {\n var attr = perStackAttrs[i];\n var attrFound = attr + 'Found';\n if(!groupOpts[attrFound]) {\n var traceHasAttr = traceIn[attr] !== undefined;\n var isOrientation = attr === 'orientation';\n if(traceHasAttr || firstTrace) {\n groupOpts[attr] = coerce(attr, dflts[attr]);\n\n if(isOrientation) {\n groupOpts.fillDflt = groupOpts[attr] === 'h' ?\n 'tonextx' : 'tonexty';\n }\n\n if(traceHasAttr) {\n // Note: this will show a value here even if it's invalid\n // in which case it will revert to default.\n groupOpts[attrFound] = true;\n\n // Note: only one trace in the stack will get a _fullData\n // entry for a given stack-wide attribute. If no traces\n // (or the first trace) specify that attribute, the\n // first trace will get it. If the first trace does NOT\n // specify it but some later trace does, then it gets\n // removed from the first trace and only included in the\n // one that specified it. This is mostly important for\n // editors (that want to see the full values to know\n // what settings are available) and Plotly.react diffing.\n // Editors may want to use fullLayout._scatterStackOpts\n // directly and make these settings available from all\n // traces in the stack... then set the new value into\n // the first trace, and clear all later traces.\n if(!firstTrace) {\n delete groupOpts.traces[0][attr];\n\n // orientation can affect default fill of previous traces\n if(isOrientation) {\n for(var j = 0; j < groupOpts.traces.length - 1; j++) {\n var trace2 = groupOpts.traces[j];\n if(trace2._input.fill !== trace2.fill) {\n trace2.fill = groupOpts.fillDflt;\n }\n }\n }\n }\n }\n }\n }\n }\n return groupOpts;\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/stack_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/style.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/style.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\n\nfunction style(gd) {\n var s = d3.select(gd).selectAll('g.trace.scatter');\n\n s.style('opacity', function(d) {\n return d[0].trace.opacity;\n });\n\n s.selectAll('g.points').each(function(d) {\n var sel = d3.select(this);\n var trace = d.trace || d[0].trace;\n stylePoints(sel, trace, gd);\n });\n\n s.selectAll('g.text').each(function(d) {\n var sel = d3.select(this);\n var trace = d.trace || d[0].trace;\n styleText(sel, trace, gd);\n });\n\n s.selectAll('g.trace path.js-line')\n .call(Drawing.lineGroupStyle);\n\n s.selectAll('g.trace path.js-fill')\n .call(Drawing.fillGroupStyle);\n\n Registry.getComponentMethod('errorbars', 'style')(s);\n}\n\nfunction stylePoints(sel, trace, gd) {\n Drawing.pointStyle(sel.selectAll('path.point'), trace, gd);\n}\n\nfunction styleText(sel, trace, gd) {\n Drawing.textPointStyle(sel.selectAll('text'), trace, gd);\n}\n\nfunction styleOnSelect(gd, cd, sel) {\n var trace = cd[0].trace;\n\n if(trace.selectedpoints) {\n Drawing.selectedPointStyle(sel.selectAll('path.point'), trace);\n Drawing.selectedTextStyle(sel.selectAll('text'), trace);\n } else {\n stylePoints(sel, trace, gd);\n styleText(sel, trace, gd);\n }\n}\n\nmodule.exports = {\n style: style,\n stylePoints: stylePoints,\n styleText: styleText,\n styleOnSelect: styleOnSelect\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/subtypes.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/subtypes.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nmodule.exports = {\n hasLines: function(trace) {\n return trace.visible && trace.mode &&\n trace.mode.indexOf('lines') !== -1;\n },\n\n hasMarkers: function(trace) {\n return trace.visible && (\n (trace.mode && trace.mode.indexOf('markers') !== -1) ||\n // until splom implements 'mode'\n trace.type === 'splom'\n );\n },\n\n hasText: function(trace) {\n return trace.visible && trace.mode &&\n trace.mode.indexOf('text') !== -1;\n },\n\n isBubble: function(trace) {\n return Lib.isPlainObject(trace.marker) &&\n Lib.isArrayOrTypedArray(trace.marker.size);\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/subtypes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/text_defaults.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/text_defaults.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\n/*\n * opts: object of flags to control features not all text users support\n * noSelect: caller does not support selected/unselected attribute containers\n */\nmodule.exports = function(traceIn, traceOut, layout, coerce, opts) {\n opts = opts || {};\n\n coerce('textposition');\n Lib.coerceFont(coerce, 'textfont', layout.font);\n\n if(!opts.noSelect) {\n coerce('selected.textfont.color');\n coerce('unselected.textfont.color');\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/text_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter/xy_defaults.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter/xy_defaults.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\n\nmodule.exports = function handleXYDefaults(traceIn, traceOut, layout, coerce) {\n var x = coerce('x');\n var y = coerce('y');\n var len;\n\n var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleTraceDefaults');\n handleCalendarDefaults(traceIn, traceOut, ['x', 'y'], layout);\n\n if(x) {\n var xlen = Lib.minRowLength(x);\n if(y) {\n len = Math.min(xlen, Lib.minRowLength(y));\n } else {\n len = xlen;\n coerce('y0');\n coerce('dy');\n }\n } else {\n if(!y) return 0;\n\n len = Lib.minRowLength(y);\n coerce('x0');\n coerce('dx');\n }\n\n traceOut._length = len;\n\n return len;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter/xy_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter3d/attributes.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter3d/attributes.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar scatterAttrs = __webpack_require__(/*! ../scatter/attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\");\nvar colorAttributes = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar texttemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").texttemplateAttrs;\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar DASHES = __webpack_require__(/*! ../../constants/gl3d_dashes */ \"./node_modules/plotly.js/src/constants/gl3d_dashes.js\");\n\nvar MARKER_SYMBOLS = __webpack_require__(/*! ../../constants/gl3d_markers */ \"./node_modules/plotly.js/src/constants/gl3d_markers.js\");\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar overrideAll = __webpack_require__(/*! ../../plot_api/edit_types */ \"./node_modules/plotly.js/src/plot_api/edit_types.js\").overrideAll;\n\nvar scatterLineAttrs = scatterAttrs.line;\nvar scatterMarkerAttrs = scatterAttrs.marker;\nvar scatterMarkerLineAttrs = scatterMarkerAttrs.line;\n\nvar lineAttrs = extendFlat({\n width: scatterLineAttrs.width,\n dash: {\n valType: 'enumerated',\n values: Object.keys(DASHES),\n dflt: 'solid',\n \n \n }\n}, colorAttributes('line'));\n\nfunction makeProjectionAttr(axLetter) {\n return {\n show: {\n valType: 'boolean',\n \n dflt: false,\n \n },\n opacity: {\n valType: 'number',\n \n min: 0,\n max: 1,\n dflt: 1,\n \n },\n scale: {\n valType: 'number',\n \n min: 0,\n max: 10,\n dflt: 2 / 3,\n \n }\n };\n}\n\nvar attrs = module.exports = overrideAll({\n x: scatterAttrs.x,\n y: scatterAttrs.y,\n z: {\n valType: 'data_array',\n \n },\n\n text: extendFlat({}, scatterAttrs.text, {\n \n }),\n texttemplate: texttemplateAttrs({}, {\n\n }),\n hovertext: extendFlat({}, scatterAttrs.hovertext, {\n \n }),\n hovertemplate: hovertemplateAttrs(),\n\n mode: extendFlat({}, scatterAttrs.mode, // shouldn't this be on-par with 2D?\n {dflt: 'lines+markers'}),\n surfaceaxis: {\n valType: 'enumerated',\n \n values: [-1, 0, 1, 2],\n dflt: -1,\n \n },\n surfacecolor: {\n valType: 'color',\n \n \n },\n projection: {\n x: makeProjectionAttr('x'),\n y: makeProjectionAttr('y'),\n z: makeProjectionAttr('z')\n },\n\n connectgaps: scatterAttrs.connectgaps,\n line: lineAttrs,\n\n marker: extendFlat({ // Parity with scatter.js?\n symbol: {\n valType: 'enumerated',\n values: Object.keys(MARKER_SYMBOLS),\n \n dflt: 'circle',\n arrayOk: true,\n \n },\n size: extendFlat({}, scatterMarkerAttrs.size, {dflt: 8}),\n sizeref: scatterMarkerAttrs.sizeref,\n sizemin: scatterMarkerAttrs.sizemin,\n sizemode: scatterMarkerAttrs.sizemode,\n opacity: extendFlat({}, scatterMarkerAttrs.opacity, {\n arrayOk: false,\n \n }),\n colorbar: scatterMarkerAttrs.colorbar,\n\n line: extendFlat({\n width: extendFlat({}, scatterMarkerLineAttrs.width, {arrayOk: false})\n },\n colorAttributes('marker.line')\n )\n },\n colorAttributes('marker')\n ),\n\n textposition: extendFlat({}, scatterAttrs.textposition, {dflt: 'top center'}),\n textfont: {\n color: scatterAttrs.textfont.color,\n size: scatterAttrs.textfont.size,\n family: extendFlat({}, scatterAttrs.textfont.family, {arrayOk: false})\n },\n\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo)\n}, 'calc', 'nested');\n\nattrs.x.editType = attrs.y.editType = attrs.z.editType = 'calc+clearAxisTypes';\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter3d/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter3d/calc.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter3d/calc.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar arraysToCalcdata = __webpack_require__(/*! ../scatter/arrays_to_calcdata */ \"./node_modules/plotly.js/src/traces/scatter/arrays_to_calcdata.js\");\nvar calcColorscale = __webpack_require__(/*! ../scatter/colorscale_calc */ \"./node_modules/plotly.js/src/traces/scatter/colorscale_calc.js\");\n\n/**\n * This is a kludge to put the array attributes into\n * calcdata the way Scatter.plot does, so that legends and\n * popovers know what to do with them.\n */\nmodule.exports = function calc(gd, trace) {\n var cd = [{x: false, y: false, trace: trace, t: {}}];\n\n arraysToCalcdata(cd, trace);\n calcColorscale(gd, trace);\n\n return cd;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter3d/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter3d/calc_errors.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter3d/calc_errors.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\n\nfunction calculateAxisErrors(data, params, scaleFactor, axis) {\n if(!params || !params.visible) return null;\n\n var computeError = Registry.getComponentMethod('errorbars', 'makeComputeError')(params);\n var result = new Array(data.length);\n\n for(var i = 0; i < data.length; i++) {\n var errors = computeError(+data[i], i);\n\n if(axis.type === 'log') {\n var point = axis.c2l(data[i]);\n var min = data[i] - errors[0];\n var max = data[i] + errors[1];\n\n result[i] = [\n (axis.c2l(min, true) - point) * scaleFactor,\n (axis.c2l(max, true) - point) * scaleFactor\n ];\n\n // Keep track of the lower error bound which isn't negative!\n if(min > 0) {\n var lower = axis.c2l(min);\n if(!axis._lowerLogErrorBound) axis._lowerLogErrorBound = lower;\n axis._lowerErrorBound = Math.min(axis._lowerLogErrorBound, lower);\n }\n } else {\n result[i] = [\n -errors[0] * scaleFactor,\n errors[1] * scaleFactor\n ];\n }\n }\n\n return result;\n}\n\nfunction dataLength(array) {\n for(var i = 0; i < array.length; i++) {\n if(array[i]) return array[i].length;\n }\n return 0;\n}\n\nfunction calculateErrors(data, scaleFactor, sceneLayout) {\n var errors = [\n calculateAxisErrors(data.x, data.error_x, scaleFactor[0], sceneLayout.xaxis),\n calculateAxisErrors(data.y, data.error_y, scaleFactor[1], sceneLayout.yaxis),\n calculateAxisErrors(data.z, data.error_z, scaleFactor[2], sceneLayout.zaxis)\n ];\n\n var n = dataLength(errors);\n if(n === 0) return null;\n\n var errorBounds = new Array(n);\n\n for(var i = 0; i < n; i++) {\n var bound = [[0, 0, 0], [0, 0, 0]];\n\n for(var j = 0; j < 3; j++) {\n if(errors[j]) {\n for(var k = 0; k < 2; k++) {\n bound[k][j] = errors[j][i][k];\n }\n }\n }\n\n errorBounds[i] = bound;\n }\n\n return errorBounds;\n}\n\nmodule.exports = calculateErrors;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter3d/calc_errors.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter3d/convert.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter3d/convert.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar createLinePlot = __webpack_require__(/*! gl-line3d */ \"./node_modules/gl-line3d/lines.js\");\nvar createScatterPlot = __webpack_require__(/*! gl-scatter3d */ \"./node_modules/gl-scatter3d/pointcloud.js\");\nvar createErrorBars = __webpack_require__(/*! gl-error3d */ \"./node_modules/gl-error3d/errorbars.js\");\nvar createMesh = __webpack_require__(/*! gl-mesh3d */ \"./node_modules/gl-mesh3d/mesh.js\");\nvar triangulate = __webpack_require__(/*! delaunay-triangulate */ \"./node_modules/delaunay-triangulate/triangulate.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar str2RgbaArray = __webpack_require__(/*! ../../lib/str2rgbarray */ \"./node_modules/plotly.js/src/lib/str2rgbarray.js\");\nvar formatColor = __webpack_require__(/*! ../../lib/gl_format_color */ \"./node_modules/plotly.js/src/lib/gl_format_color.js\").formatColor;\nvar makeBubbleSizeFn = __webpack_require__(/*! ../scatter/make_bubble_size_func */ \"./node_modules/plotly.js/src/traces/scatter/make_bubble_size_func.js\");\nvar DASH_PATTERNS = __webpack_require__(/*! ../../constants/gl3d_dashes */ \"./node_modules/plotly.js/src/constants/gl3d_dashes.js\");\nvar MARKER_SYMBOLS = __webpack_require__(/*! ../../constants/gl3d_markers */ \"./node_modules/plotly.js/src/constants/gl3d_markers.js\");\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar appendArrayPointValue = __webpack_require__(/*! ../../components/fx/helpers */ \"./node_modules/plotly.js/src/components/fx/helpers.js\").appendArrayPointValue;\n\nvar calculateError = __webpack_require__(/*! ./calc_errors */ \"./node_modules/plotly.js/src/traces/scatter3d/calc_errors.js\");\n\nfunction LineWithMarkers(scene, uid) {\n this.scene = scene;\n this.uid = uid;\n this.linePlot = null;\n this.scatterPlot = null;\n this.errorBars = null;\n this.textMarkers = null;\n this.delaunayMesh = null;\n this.color = null;\n this.mode = '';\n this.dataPoints = [];\n this.axesBounds = [\n [-Infinity, -Infinity, -Infinity],\n [Infinity, Infinity, Infinity]\n ];\n this.textLabels = null;\n this.data = null;\n}\n\nvar proto = LineWithMarkers.prototype;\n\nproto.handlePick = function(selection) {\n if(selection.object &&\n (selection.object === this.linePlot ||\n selection.object === this.delaunayMesh ||\n selection.object === this.textMarkers ||\n selection.object === this.scatterPlot)\n ) {\n var ind = selection.index = selection.data.index;\n\n if(selection.object.highlight) {\n selection.object.highlight(null);\n }\n if(this.scatterPlot) {\n selection.object = this.scatterPlot;\n this.scatterPlot.highlight(selection.data);\n }\n\n selection.textLabel = '';\n if(this.textLabels) {\n if(Array.isArray(this.textLabels)) {\n if(this.textLabels[ind] || this.textLabels[ind] === 0) {\n selection.textLabel = this.textLabels[ind];\n }\n } else {\n selection.textLabel = this.textLabels;\n }\n }\n\n selection.traceCoordinate = [\n this.data.x[ind],\n this.data.y[ind],\n this.data.z[ind]\n ];\n\n return true;\n }\n};\n\nfunction constructDelaunay(points, color, axis) {\n var u = (axis + 1) % 3;\n var v = (axis + 2) % 3;\n var filteredPoints = [];\n var filteredIds = [];\n var i;\n\n for(i = 0; i < points.length; ++i) {\n var p = points[i];\n if(isNaN(p[u]) || !isFinite(p[u]) ||\n isNaN(p[v]) || !isFinite(p[v])) {\n continue;\n }\n filteredPoints.push([p[u], p[v]]);\n filteredIds.push(i);\n }\n var cells = triangulate(filteredPoints);\n for(i = 0; i < cells.length; ++i) {\n var c = cells[i];\n for(var j = 0; j < c.length; ++j) {\n c[j] = filteredIds[c[j]];\n }\n }\n return {\n positions: points,\n cells: cells,\n meshColor: color\n };\n}\n\nfunction calculateErrorParams(errors) {\n var capSize = [0.0, 0.0, 0.0];\n var color = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];\n var lineWidth = [1.0, 1.0, 1.0];\n\n for(var i = 0; i < 3; i++) {\n var e = errors[i];\n\n if(e && e.copy_zstyle !== false && errors[2].visible !== false) e = errors[2];\n if(!e || !e.visible) continue;\n\n capSize[i] = e.width / 2; // ballpark rescaling\n color[i] = str2RgbaArray(e.color);\n lineWidth[i] = e.thickness;\n }\n\n return {capSize: capSize, color: color, lineWidth: lineWidth};\n}\n\nfunction parseAlignmentX(a) {\n if(a === null || a === undefined) return 0;\n\n return (a.indexOf('left') > -1) ? -1 :\n (a.indexOf('right') > -1) ? 1 : 0;\n}\n\nfunction parseAlignmentY(a) {\n if(a === null || a === undefined) return 0;\n\n return (a.indexOf('top') > -1) ? -1 :\n (a.indexOf('bottom') > -1) ? 1 : 0;\n}\n\nfunction calculateTextOffset(tp) {\n // Read out text properties\n\n var defaultAlignmentX = 0;\n var defaultAlignmentY = 0;\n\n var textOffset = [\n defaultAlignmentX,\n defaultAlignmentY\n ];\n\n if(Array.isArray(tp)) {\n for(var i = 0; i < tp.length; i++) {\n textOffset[i] = [\n defaultAlignmentX,\n defaultAlignmentY\n ];\n if(tp[i]) {\n textOffset[i][0] = parseAlignmentX(tp[i]);\n textOffset[i][1] = parseAlignmentY(tp[i]);\n }\n }\n } else {\n textOffset[0] = parseAlignmentX(tp);\n textOffset[1] = parseAlignmentY(tp);\n }\n\n return textOffset;\n}\n\n\nfunction calculateSize(sizeIn, sizeFn) {\n // rough parity with Plotly 2D markers\n return sizeFn(sizeIn * 4);\n}\n\nfunction calculateSymbol(symbolIn) {\n return MARKER_SYMBOLS[symbolIn];\n}\n\nfunction formatParam(paramIn, len, calculate, dflt, extraFn) {\n var paramOut = null;\n\n if(Lib.isArrayOrTypedArray(paramIn)) {\n paramOut = [];\n\n for(var i = 0; i < len; i++) {\n if(paramIn[i] === undefined) paramOut[i] = dflt;\n else paramOut[i] = calculate(paramIn[i], extraFn);\n }\n } else paramOut = calculate(paramIn, Lib.identity);\n\n return paramOut;\n}\n\n\nfunction convertPlotlyOptions(scene, data) {\n var points = [];\n var sceneLayout = scene.fullSceneLayout;\n var scaleFactor = scene.dataScale;\n var xaxis = sceneLayout.xaxis;\n var yaxis = sceneLayout.yaxis;\n var zaxis = sceneLayout.zaxis;\n var marker = data.marker;\n var line = data.line;\n var x = data.x || [];\n var y = data.y || [];\n var z = data.z || [];\n var len = x.length;\n var xcalendar = data.xcalendar;\n var ycalendar = data.ycalendar;\n var zcalendar = data.zcalendar;\n var xc, yc, zc;\n var params, i;\n var text;\n\n // Convert points\n for(i = 0; i < len; i++) {\n // sanitize numbers and apply transforms based on axes.type\n xc = xaxis.d2l(x[i], 0, xcalendar) * scaleFactor[0];\n yc = yaxis.d2l(y[i], 0, ycalendar) * scaleFactor[1];\n zc = zaxis.d2l(z[i], 0, zcalendar) * scaleFactor[2];\n\n points[i] = [xc, yc, zc];\n }\n\n // convert text\n if(Array.isArray(data.text)) text = data.text;\n else if(data.text !== undefined) {\n text = new Array(len);\n for(i = 0; i < len; i++) text[i] = data.text;\n }\n\n function formatter(axName, val) {\n var ax = sceneLayout[axName];\n return Axes.tickText(ax, ax.d2l(val), true).text;\n }\n\n // check texttemplate\n var texttemplate = data.texttemplate;\n if(texttemplate) {\n var fullLayout = scene.fullLayout;\n var d3locale = fullLayout._d3locale;\n var isArray = Array.isArray(texttemplate);\n var N = isArray ? Math.min(texttemplate.length, len) : len;\n var txt = isArray ?\n function(i) { return texttemplate[i]; } :\n function() { return texttemplate; };\n\n text = new Array(N);\n\n for(i = 0; i < N; i++) {\n var d = {x: x[i], y: y[i], z: z[i]};\n var labels = {\n xLabel: formatter('xaxis', x[i]),\n yLabel: formatter('yaxis', y[i]),\n zLabel: formatter('zaxis', z[i])\n };\n var pointValues = {};\n appendArrayPointValue(pointValues, data, i);\n var meta = data._meta || {};\n text[i] = Lib.texttemplateString(txt(i), labels, d3locale, pointValues, d, meta);\n }\n }\n\n // Build object parameters\n params = {\n position: points,\n mode: data.mode,\n text: text\n };\n\n if('line' in data) {\n params.lineColor = formatColor(line, 1, len);\n params.lineWidth = line.width;\n params.lineDashes = line.dash;\n }\n\n if('marker' in data) {\n var sizeFn = makeBubbleSizeFn(data);\n\n params.scatterColor = formatColor(marker, 1, len);\n params.scatterSize = formatParam(marker.size, len, calculateSize, 20, sizeFn);\n params.scatterMarker = formatParam(marker.symbol, len, calculateSymbol, '●');\n params.scatterLineWidth = marker.line.width; // arrayOk === false\n params.scatterLineColor = formatColor(marker.line, 1, len);\n params.scatterAngle = 0;\n }\n\n if('textposition' in data) {\n params.textOffset = calculateTextOffset(data.textposition);\n params.textColor = formatColor(data.textfont, 1, len);\n params.textSize = formatParam(data.textfont.size, len, Lib.identity, 12);\n params.textFont = data.textfont.family; // arrayOk === false\n params.textAngle = 0;\n }\n\n var dims = ['x', 'y', 'z'];\n params.project = [false, false, false];\n params.projectScale = [1, 1, 1];\n params.projectOpacity = [1, 1, 1];\n for(i = 0; i < 3; ++i) {\n var projection = data.projection[dims[i]];\n if((params.project[i] = projection.show)) {\n params.projectOpacity[i] = projection.opacity;\n params.projectScale[i] = projection.scale;\n }\n }\n\n params.errorBounds = calculateError(data, scaleFactor, sceneLayout);\n\n var errorParams = calculateErrorParams([data.error_x, data.error_y, data.error_z]);\n params.errorColor = errorParams.color;\n params.errorLineWidth = errorParams.lineWidth;\n params.errorCapSize = errorParams.capSize;\n\n params.delaunayAxis = data.surfaceaxis;\n params.delaunayColor = str2RgbaArray(data.surfacecolor);\n\n return params;\n}\n\nfunction arrayToColor(color) {\n if(Array.isArray(color)) {\n var c = color[0];\n\n if(Array.isArray(c)) color = c;\n\n return 'rgb(' + color.slice(0, 3).map(function(x) {\n return Math.round(x * 255);\n }) + ')';\n }\n\n return null;\n}\n\nproto.update = function(data) {\n var gl = this.scene.glplot.gl;\n var lineOptions;\n var scatterOptions;\n var errorOptions;\n var textOptions;\n var dashPattern = DASH_PATTERNS.solid;\n\n // Save data\n this.data = data;\n\n // Run data conversion\n var options = convertPlotlyOptions(this.scene, data);\n\n if('mode' in options) {\n this.mode = options.mode;\n }\n if('lineDashes' in options) {\n if(options.lineDashes in DASH_PATTERNS) {\n dashPattern = DASH_PATTERNS[options.lineDashes];\n }\n }\n\n this.color = arrayToColor(options.scatterColor) ||\n arrayToColor(options.lineColor);\n\n // Save data points\n this.dataPoints = options.position;\n\n lineOptions = {\n gl: this.scene.glplot.gl,\n position: options.position,\n color: options.lineColor,\n lineWidth: options.lineWidth || 1,\n dashes: dashPattern[0],\n dashScale: dashPattern[1],\n opacity: data.opacity,\n connectGaps: data.connectgaps\n };\n\n if(this.mode.indexOf('lines') !== -1) {\n if(this.linePlot) this.linePlot.update(lineOptions);\n else {\n this.linePlot = createLinePlot(lineOptions);\n this.linePlot._trace = this;\n this.scene.glplot.add(this.linePlot);\n }\n } else if(this.linePlot) {\n this.scene.glplot.remove(this.linePlot);\n this.linePlot.dispose();\n this.linePlot = null;\n }\n\n // N.B. marker.opacity must be a scalar for performance\n var scatterOpacity = data.opacity;\n if(data.marker && data.marker.opacity) scatterOpacity *= data.marker.opacity;\n\n scatterOptions = {\n gl: this.scene.glplot.gl,\n position: options.position,\n color: options.scatterColor,\n size: options.scatterSize,\n glyph: options.scatterMarker,\n opacity: scatterOpacity,\n orthographic: true,\n lineWidth: options.scatterLineWidth,\n lineColor: options.scatterLineColor,\n project: options.project,\n projectScale: options.projectScale,\n projectOpacity: options.projectOpacity\n };\n\n if(this.mode.indexOf('markers') !== -1) {\n if(this.scatterPlot) this.scatterPlot.update(scatterOptions);\n else {\n this.scatterPlot = createScatterPlot(scatterOptions);\n this.scatterPlot._trace = this;\n this.scatterPlot.highlightScale = 1;\n this.scene.glplot.add(this.scatterPlot);\n }\n } else if(this.scatterPlot) {\n this.scene.glplot.remove(this.scatterPlot);\n this.scatterPlot.dispose();\n this.scatterPlot = null;\n }\n\n textOptions = {\n gl: this.scene.glplot.gl,\n position: options.position,\n glyph: options.text,\n color: options.textColor,\n size: options.textSize,\n angle: options.textAngle,\n alignment: options.textOffset,\n font: options.textFont,\n orthographic: true,\n lineWidth: 0,\n project: false,\n opacity: data.opacity\n };\n\n this.textLabels = data.hovertext || data.text;\n\n if(this.mode.indexOf('text') !== -1) {\n if(this.textMarkers) this.textMarkers.update(textOptions);\n else {\n this.textMarkers = createScatterPlot(textOptions);\n this.textMarkers._trace = this;\n this.textMarkers.highlightScale = 1;\n this.scene.glplot.add(this.textMarkers);\n }\n } else if(this.textMarkers) {\n this.scene.glplot.remove(this.textMarkers);\n this.textMarkers.dispose();\n this.textMarkers = null;\n }\n\n errorOptions = {\n gl: this.scene.glplot.gl,\n position: options.position,\n color: options.errorColor,\n error: options.errorBounds,\n lineWidth: options.errorLineWidth,\n capSize: options.errorCapSize,\n opacity: data.opacity\n };\n if(this.errorBars) {\n if(options.errorBounds) {\n this.errorBars.update(errorOptions);\n } else {\n this.scene.glplot.remove(this.errorBars);\n this.errorBars.dispose();\n this.errorBars = null;\n }\n } else if(options.errorBounds) {\n this.errorBars = createErrorBars(errorOptions);\n this.errorBars._trace = this;\n this.scene.glplot.add(this.errorBars);\n }\n\n if(options.delaunayAxis >= 0) {\n var delaunayOptions = constructDelaunay(\n options.position,\n options.delaunayColor,\n options.delaunayAxis\n );\n delaunayOptions.opacity = data.opacity;\n\n if(this.delaunayMesh) {\n this.delaunayMesh.update(delaunayOptions);\n } else {\n delaunayOptions.gl = gl;\n this.delaunayMesh = createMesh(delaunayOptions);\n this.delaunayMesh._trace = this;\n this.scene.glplot.add(this.delaunayMesh);\n }\n } else if(this.delaunayMesh) {\n this.scene.glplot.remove(this.delaunayMesh);\n this.delaunayMesh.dispose();\n this.delaunayMesh = null;\n }\n};\n\nproto.dispose = function() {\n if(this.linePlot) {\n this.scene.glplot.remove(this.linePlot);\n this.linePlot.dispose();\n }\n if(this.scatterPlot) {\n this.scene.glplot.remove(this.scatterPlot);\n this.scatterPlot.dispose();\n }\n if(this.errorBars) {\n this.scene.glplot.remove(this.errorBars);\n this.errorBars.dispose();\n }\n if(this.textMarkers) {\n this.scene.glplot.remove(this.textMarkers);\n this.textMarkers.dispose();\n }\n if(this.delaunayMesh) {\n this.scene.glplot.remove(this.delaunayMesh);\n this.delaunayMesh.dispose();\n }\n};\n\nfunction createLineWithMarkers(scene, data) {\n var plot = new LineWithMarkers(scene, data.uid);\n plot.update(data);\n return plot;\n}\n\nmodule.exports = createLineWithMarkers;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter3d/convert.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter3d/defaults.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter3d/defaults.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar subTypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar handleMarkerDefaults = __webpack_require__(/*! ../scatter/marker_defaults */ \"./node_modules/plotly.js/src/traces/scatter/marker_defaults.js\");\nvar handleLineDefaults = __webpack_require__(/*! ../scatter/line_defaults */ \"./node_modules/plotly.js/src/traces/scatter/line_defaults.js\");\nvar handleTextDefaults = __webpack_require__(/*! ../scatter/text_defaults */ \"./node_modules/plotly.js/src/traces/scatter/text_defaults.js\");\n\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scatter3d/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var len = handleXYZDefaults(traceIn, traceOut, coerce, layout);\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n coerce('mode');\n\n if(subTypes.hasLines(traceOut)) {\n coerce('connectgaps');\n handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);\n }\n\n if(subTypes.hasMarkers(traceOut)) {\n handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {noSelect: true});\n }\n\n if(subTypes.hasText(traceOut)) {\n coerce('texttemplate');\n handleTextDefaults(traceIn, traceOut, layout, coerce, {noSelect: true});\n }\n\n var lineColor = (traceOut.line || {}).color;\n var markerColor = (traceOut.marker || {}).color;\n if(coerce('surfaceaxis') >= 0) coerce('surfacecolor', lineColor || markerColor);\n\n var dims = ['x', 'y', 'z'];\n for(var i = 0; i < 3; ++i) {\n var projection = 'projection.' + dims[i];\n if(coerce(projection + '.show')) {\n coerce(projection + '.opacity');\n coerce(projection + '.scale');\n }\n }\n\n var errorBarsSupplyDefaults = Registry.getComponentMethod('errorbars', 'supplyDefaults');\n errorBarsSupplyDefaults(traceIn, traceOut, lineColor || markerColor || defaultColor, {axis: 'z'});\n errorBarsSupplyDefaults(traceIn, traceOut, lineColor || markerColor || defaultColor, {axis: 'y', inherit: 'z'});\n errorBarsSupplyDefaults(traceIn, traceOut, lineColor || markerColor || defaultColor, {axis: 'x', inherit: 'z'});\n};\n\nfunction handleXYZDefaults(traceIn, traceOut, coerce, layout) {\n var len = 0;\n var x = coerce('x');\n var y = coerce('y');\n var z = coerce('z');\n\n var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleTraceDefaults');\n handleCalendarDefaults(traceIn, traceOut, ['x', 'y', 'z'], layout);\n\n if(x && y && z) {\n // TODO: what happens if one is missing?\n len = Math.min(x.length, y.length, z.length);\n traceOut._length = traceOut._xlength = traceOut._ylength = traceOut._zlength = len;\n }\n\n return len;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter3d/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatter3d/index.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatter3d/index.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n plot: __webpack_require__(/*! ./convert */ \"./node_modules/plotly.js/src/traces/scatter3d/convert.js\"),\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scatter3d/attributes.js\"),\n markerSymbols: __webpack_require__(/*! ../../constants/gl3d_markers */ \"./node_modules/plotly.js/src/constants/gl3d_markers.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/scatter3d/defaults.js\"),\n colorbar: [\n {\n container: 'marker',\n min: 'cmin',\n max: 'cmax'\n }, {\n container: 'line',\n min: 'cmin',\n max: 'cmax'\n }\n ],\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/scatter3d/calc.js\"),\n\n moduleType: 'trace',\n name: 'scatter3d',\n basePlotModule: __webpack_require__(/*! ../../plots/gl3d */ \"./node_modules/plotly.js/src/plots/gl3d/index.js\"),\n categories: ['gl3d', 'symbols', 'showLegend', 'scatter-like'],\n meta: {\n \n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatter3d/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattercarpet/attributes.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattercarpet/attributes.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar scatterAttrs = __webpack_require__(/*! ../scatter/attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\");\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar texttemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").texttemplateAttrs;\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nvar scatterMarkerAttrs = scatterAttrs.marker;\nvar scatterLineAttrs = scatterAttrs.line;\nvar scatterMarkerLineAttrs = scatterMarkerAttrs.line;\n\nmodule.exports = {\n carpet: {\n valType: 'string',\n \n editType: 'calc',\n \n },\n a: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n b: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n mode: extendFlat({}, scatterAttrs.mode, {dflt: 'markers'}),\n text: extendFlat({}, scatterAttrs.text, {\n \n }),\n texttemplate: texttemplateAttrs({editType: 'plot'}, {\n keys: ['a', 'b', 'text']\n }),\n hovertext: extendFlat({}, scatterAttrs.hovertext, {\n \n }),\n line: {\n color: scatterLineAttrs.color,\n width: scatterLineAttrs.width,\n dash: scatterLineAttrs.dash,\n shape: extendFlat({}, scatterLineAttrs.shape,\n {values: ['linear', 'spline']}),\n smoothing: scatterLineAttrs.smoothing,\n editType: 'calc'\n },\n connectgaps: scatterAttrs.connectgaps,\n fill: extendFlat({}, scatterAttrs.fill, {\n values: ['none', 'toself', 'tonext'],\n dflt: 'none',\n \n }),\n fillcolor: scatterAttrs.fillcolor,\n marker: extendFlat({\n symbol: scatterMarkerAttrs.symbol,\n opacity: scatterMarkerAttrs.opacity,\n maxdisplayed: scatterMarkerAttrs.maxdisplayed,\n size: scatterMarkerAttrs.size,\n sizeref: scatterMarkerAttrs.sizeref,\n sizemin: scatterMarkerAttrs.sizemin,\n sizemode: scatterMarkerAttrs.sizemode,\n line: extendFlat({\n width: scatterMarkerLineAttrs.width,\n editType: 'calc'\n },\n colorScaleAttrs('marker.line')\n ),\n gradient: scatterMarkerAttrs.gradient,\n editType: 'calc'\n },\n colorScaleAttrs('marker')\n ),\n\n textfont: scatterAttrs.textfont,\n textposition: scatterAttrs.textposition,\n\n selected: scatterAttrs.selected,\n unselected: scatterAttrs.unselected,\n\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {\n flags: ['a', 'b', 'text', 'name']\n }),\n hoveron: scatterAttrs.hoveron,\n hovertemplate: hovertemplateAttrs()\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattercarpet/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattercarpet/calc.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattercarpet/calc.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\nvar calcColorscale = __webpack_require__(/*! ../scatter/colorscale_calc */ \"./node_modules/plotly.js/src/traces/scatter/colorscale_calc.js\");\nvar arraysToCalcdata = __webpack_require__(/*! ../scatter/arrays_to_calcdata */ \"./node_modules/plotly.js/src/traces/scatter/arrays_to_calcdata.js\");\nvar calcSelection = __webpack_require__(/*! ../scatter/calc_selection */ \"./node_modules/plotly.js/src/traces/scatter/calc_selection.js\");\nvar calcMarkerSize = __webpack_require__(/*! ../scatter/calc */ \"./node_modules/plotly.js/src/traces/scatter/calc.js\").calcMarkerSize;\nvar lookupCarpet = __webpack_require__(/*! ../carpet/lookup_carpetid */ \"./node_modules/plotly.js/src/traces/carpet/lookup_carpetid.js\");\n\nmodule.exports = function calc(gd, trace) {\n var carpet = trace._carpetTrace = lookupCarpet(gd, trace);\n if(!carpet || !carpet.visible || carpet.visible === 'legendonly') return;\n var i;\n\n // Transfer this over from carpet before plotting since this is a necessary\n // condition in order for cartesian to actually plot this trace:\n trace.xaxis = carpet.xaxis;\n trace.yaxis = carpet.yaxis;\n\n // make the calcdata array\n var serieslen = trace._length;\n var cd = new Array(serieslen);\n var a, b;\n var needsCull = false;\n for(i = 0; i < serieslen; i++) {\n a = trace.a[i];\n b = trace.b[i];\n if(isNumeric(a) && isNumeric(b)) {\n var xy = carpet.ab2xy(+a, +b, true);\n var visible = carpet.isVisible(+a, +b);\n if(!visible) needsCull = true;\n cd[i] = {x: xy[0], y: xy[1], a: a, b: b, vis: visible};\n } else cd[i] = {x: false, y: false};\n }\n\n trace._needsCull = needsCull;\n\n cd[0].carpet = carpet;\n cd[0].trace = trace;\n\n calcMarkerSize(trace, serieslen);\n calcColorscale(gd, trace);\n arraysToCalcdata(cd, trace);\n calcSelection(cd, trace);\n\n return cd;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattercarpet/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattercarpet/defaults.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattercarpet/defaults.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar constants = __webpack_require__(/*! ../scatter/constants */ \"./node_modules/plotly.js/src/traces/scatter/constants.js\");\nvar subTypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar handleMarkerDefaults = __webpack_require__(/*! ../scatter/marker_defaults */ \"./node_modules/plotly.js/src/traces/scatter/marker_defaults.js\");\nvar handleLineDefaults = __webpack_require__(/*! ../scatter/line_defaults */ \"./node_modules/plotly.js/src/traces/scatter/line_defaults.js\");\nvar handleLineShapeDefaults = __webpack_require__(/*! ../scatter/line_shape_defaults */ \"./node_modules/plotly.js/src/traces/scatter/line_shape_defaults.js\");\nvar handleTextDefaults = __webpack_require__(/*! ../scatter/text_defaults */ \"./node_modules/plotly.js/src/traces/scatter/text_defaults.js\");\nvar handleFillColorDefaults = __webpack_require__(/*! ../scatter/fillcolor_defaults */ \"./node_modules/plotly.js/src/traces/scatter/fillcolor_defaults.js\");\n\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scattercarpet/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n coerce('carpet');\n\n // XXX: Don't hard code this\n traceOut.xaxis = 'x';\n traceOut.yaxis = 'y';\n\n var a = coerce('a');\n var b = coerce('b');\n var len = Math.min(a.length, b.length);\n\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n traceOut._length = len;\n\n coerce('text');\n coerce('texttemplate');\n coerce('hovertext');\n\n var defaultMode = len < constants.PTS_LINESONLY ? 'lines+markers' : 'lines';\n coerce('mode', defaultMode);\n\n if(subTypes.hasLines(traceOut)) {\n handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);\n handleLineShapeDefaults(traceIn, traceOut, coerce);\n coerce('connectgaps');\n }\n\n if(subTypes.hasMarkers(traceOut)) {\n handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});\n }\n\n if(subTypes.hasText(traceOut)) {\n handleTextDefaults(traceIn, traceOut, layout, coerce);\n }\n\n var dfltHoverOn = [];\n\n if(subTypes.hasMarkers(traceOut) || subTypes.hasText(traceOut)) {\n coerce('marker.maxdisplayed');\n dfltHoverOn.push('points');\n }\n\n coerce('fill');\n if(traceOut.fill !== 'none') {\n handleFillColorDefaults(traceIn, traceOut, defaultColor, coerce);\n if(!subTypes.hasLines(traceOut)) handleLineShapeDefaults(traceIn, traceOut, coerce);\n }\n\n if(traceOut.fill === 'tonext' || traceOut.fill === 'toself') {\n dfltHoverOn.push('fills');\n }\n\n var hoverOn = coerce('hoveron', dfltHoverOn.join('+') || 'points');\n if(hoverOn !== 'fills') coerce('hovertemplate');\n\n Lib.coerceSelectionMarkerOpacity(traceOut, coerce);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattercarpet/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattercarpet/event_data.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattercarpet/event_data.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function eventData(out, pt, trace, cd, pointNumber) {\n var cdi = cd[pointNumber];\n\n out.a = cdi.a;\n out.b = cdi.b;\n out.y = cdi.y;\n\n return out;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattercarpet/event_data.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattercarpet/format_labels.js":
-/*!**************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattercarpet/format_labels.js ***!
- \**************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function formatLabels(cdi, trace) {\n var labels = {};\n\n var carpet = trace._carpet;\n var ij = carpet.ab2ij([cdi.a, cdi.b]);\n var i0 = Math.floor(ij[0]);\n var ti = ij[0] - i0;\n var j0 = Math.floor(ij[1]);\n var tj = ij[1] - j0;\n var xy = carpet.evalxy([], i0, j0, ti, tj);\n\n labels.yLabel = xy[1].toFixed(3);\n\n return labels;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattercarpet/format_labels.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattercarpet/hover.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattercarpet/hover.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar scatterHover = __webpack_require__(/*! ../scatter/hover */ \"./node_modules/plotly.js/src/traces/scatter/hover.js\");\nvar fillText = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").fillText;\n\nmodule.exports = function hoverPoints(pointData, xval, yval, hovermode) {\n var scatterPointData = scatterHover(pointData, xval, yval, hovermode);\n if(!scatterPointData || scatterPointData[0].index === false) return;\n\n var newPointData = scatterPointData[0];\n\n // if hovering on a fill, we don't show any point data so the label is\n // unchanged from what scatter gives us - except that it needs to\n // be constrained to the trianglular plot area, not just the rectangular\n // area defined by the synthetic x and y axes\n // TODO: in some cases the vertical middle of the shape is not within\n // the triangular viewport at all, so the label can become disconnected\n // from the shape entirely. But calculating what portion of the shape\n // is actually visible, as constrained by the diagonal axis lines, is not\n // so easy and anyway we lost the information we would have needed to do\n // this inside scatterHover.\n if(newPointData.index === undefined) {\n var yFracUp = 1 - (newPointData.y0 / pointData.ya._length);\n var xLen = pointData.xa._length;\n var xMin = xLen * yFracUp / 2;\n var xMax = xLen - xMin;\n newPointData.x0 = Math.max(Math.min(newPointData.x0, xMax), xMin);\n newPointData.x1 = Math.max(Math.min(newPointData.x1, xMax), xMin);\n return scatterPointData;\n }\n\n var cdi = newPointData.cd[newPointData.index];\n\n newPointData.a = cdi.a;\n newPointData.b = cdi.b;\n\n newPointData.xLabelVal = undefined;\n newPointData.yLabelVal = undefined;\n // TODO: nice formatting, and label by axis title, for a, b, and c?\n\n var trace = newPointData.trace;\n var carpet = trace._carpet;\n\n var labels = trace._module.formatLabels(cdi, trace);\n newPointData.yLabel = labels.yLabel;\n\n delete newPointData.text;\n var text = [];\n\n function textPart(ax, val) {\n var prefix;\n\n if(ax.labelprefix && ax.labelprefix.length > 0) {\n prefix = ax.labelprefix.replace(/ = $/, '');\n } else {\n prefix = ax._hovertitle;\n }\n\n text.push(prefix + ': ' + val.toFixed(3) + ax.labelsuffix);\n }\n\n\n if(!trace.hovertemplate) {\n var hoverinfo = cdi.hi || trace.hoverinfo;\n var parts = hoverinfo.split('+');\n\n if(parts.indexOf('all') !== -1) parts = ['a', 'b', 'text'];\n if(parts.indexOf('a') !== -1) textPart(carpet.aaxis, cdi.a);\n if(parts.indexOf('b') !== -1) textPart(carpet.baxis, cdi.b);\n\n text.push('y: ' + newPointData.yLabel);\n\n if(parts.indexOf('text') !== -1) {\n fillText(cdi, trace, text);\n }\n\n newPointData.extraText = text.join('
');\n }\n\n return scatterPointData;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattercarpet/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattercarpet/index.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattercarpet/index.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scattercarpet/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/scattercarpet/defaults.js\"),\n colorbar: __webpack_require__(/*! ../scatter/marker_colorbar */ \"./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js\"),\n formatLabels: __webpack_require__(/*! ./format_labels */ \"./node_modules/plotly.js/src/traces/scattercarpet/format_labels.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/scattercarpet/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/scattercarpet/plot.js\"),\n style: __webpack_require__(/*! ../scatter/style */ \"./node_modules/plotly.js/src/traces/scatter/style.js\").style,\n styleOnSelect: __webpack_require__(/*! ../scatter/style */ \"./node_modules/plotly.js/src/traces/scatter/style.js\").styleOnSelect,\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/scattercarpet/hover.js\"),\n selectPoints: __webpack_require__(/*! ../scatter/select */ \"./node_modules/plotly.js/src/traces/scatter/select.js\"),\n eventData: __webpack_require__(/*! ./event_data */ \"./node_modules/plotly.js/src/traces/scattercarpet/event_data.js\"),\n\n moduleType: 'trace',\n name: 'scattercarpet',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['svg', 'carpet', 'symbols', 'showLegend', 'carpetDependent', 'zoomScale'],\n meta: {\n \n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattercarpet/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattercarpet/plot.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattercarpet/plot.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar scatterPlot = __webpack_require__(/*! ../scatter/plot */ \"./node_modules/plotly.js/src/traces/scatter/plot.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\n\nmodule.exports = function plot(gd, plotinfoproxy, data, layer) {\n var i, trace, node;\n\n var carpet = data[0][0].carpet;\n // mimic cartesian plotinfo\n var plotinfo = {\n xaxis: Axes.getFromId(gd, carpet.xaxis || 'x'),\n yaxis: Axes.getFromId(gd, carpet.yaxis || 'y'),\n plot: plotinfoproxy.plot,\n };\n\n scatterPlot(gd, plotinfo, data, layer);\n\n for(i = 0; i < data.length; i++) {\n trace = data[i][0].trace;\n\n // Note: .select is adequate but seems to mutate the node data,\n // which is at least a bit suprising and causes problems elsewhere\n node = layer.selectAll('g.trace' + trace.uid + ' .js-line');\n\n // Note: it would be more efficient if this didn't need to be applied\n // separately to all scattercarpet traces, but that would require\n // lots of reorganization of scatter traces that is otherwise not\n // necessary. That makes this a potential optimization.\n Drawing.setClipUrl(node, data[i][0].carpet._clipPathId, gd);\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattercarpet/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergeo/attributes.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergeo/attributes.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar texttemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").texttemplateAttrs;\nvar scatterAttrs = __webpack_require__(/*! ../scatter/attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\");\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar colorAttributes = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar dash = __webpack_require__(/*! ../../components/drawing/attributes */ \"./node_modules/plotly.js/src/components/drawing/attributes.js\").dash;\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar overrideAll = __webpack_require__(/*! ../../plot_api/edit_types */ \"./node_modules/plotly.js/src/plot_api/edit_types.js\").overrideAll;\n\nvar scatterMarkerAttrs = scatterAttrs.marker;\nvar scatterLineAttrs = scatterAttrs.line;\nvar scatterMarkerLineAttrs = scatterMarkerAttrs.line;\n\nmodule.exports = overrideAll({\n lon: {\n valType: 'data_array',\n \n },\n lat: {\n valType: 'data_array',\n \n },\n\n locations: {\n valType: 'data_array',\n \n },\n locationmode: {\n valType: 'enumerated',\n values: ['ISO-3', 'USA-states', 'country names', 'geojson-id'],\n \n dflt: 'ISO-3',\n \n },\n\n geojson: {\n valType: 'any',\n \n editType: 'calc',\n \n },\n featureidkey: {\n valType: 'string',\n \n editType: 'calc',\n dflt: 'id',\n \n },\n\n mode: extendFlat({}, scatterAttrs.mode, {dflt: 'markers'}),\n\n text: extendFlat({}, scatterAttrs.text, {\n \n }),\n texttemplate: texttemplateAttrs({editType: 'plot'}, {\n keys: ['lat', 'lon', 'location', 'text']\n }),\n hovertext: extendFlat({}, scatterAttrs.hovertext, {\n \n }),\n\n textfont: scatterAttrs.textfont,\n textposition: scatterAttrs.textposition,\n\n line: {\n color: scatterLineAttrs.color,\n width: scatterLineAttrs.width,\n dash: dash\n },\n connectgaps: scatterAttrs.connectgaps,\n\n marker: extendFlat({\n symbol: scatterMarkerAttrs.symbol,\n opacity: scatterMarkerAttrs.opacity,\n size: scatterMarkerAttrs.size,\n sizeref: scatterMarkerAttrs.sizeref,\n sizemin: scatterMarkerAttrs.sizemin,\n sizemode: scatterMarkerAttrs.sizemode,\n colorbar: scatterMarkerAttrs.colorbar,\n line: extendFlat({\n width: scatterMarkerLineAttrs.width\n },\n colorAttributes('marker.line')\n ),\n gradient: scatterMarkerAttrs.gradient\n },\n colorAttributes('marker')\n ),\n\n fill: {\n valType: 'enumerated',\n values: ['none', 'toself'],\n dflt: 'none',\n \n \n },\n fillcolor: scatterAttrs.fillcolor,\n\n selected: scatterAttrs.selected,\n unselected: scatterAttrs.unselected,\n\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {\n flags: ['lon', 'lat', 'location', 'text', 'name']\n }),\n hovertemplate: hovertemplateAttrs(),\n}, 'calc', 'nested');\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergeo/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergeo/calc.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergeo/calc.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nvar calcMarkerColorscale = __webpack_require__(/*! ../scatter/colorscale_calc */ \"./node_modules/plotly.js/src/traces/scatter/colorscale_calc.js\");\nvar arraysToCalcdata = __webpack_require__(/*! ../scatter/arrays_to_calcdata */ \"./node_modules/plotly.js/src/traces/scatter/arrays_to_calcdata.js\");\nvar calcSelection = __webpack_require__(/*! ../scatter/calc_selection */ \"./node_modules/plotly.js/src/traces/scatter/calc_selection.js\");\n\nvar _ = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\")._;\n\nfunction isNonBlankString(v) {\n return v && typeof v === 'string';\n}\n\nmodule.exports = function calc(gd, trace) {\n var hasLocationData = Array.isArray(trace.locations);\n var len = hasLocationData ? trace.locations.length : trace._length;\n var calcTrace = new Array(len);\n\n var isValidLoc;\n if(trace.geojson) {\n isValidLoc = function(v) { return isNonBlankString(v) || isNumeric(v); };\n } else {\n isValidLoc = isNonBlankString;\n }\n\n for(var i = 0; i < len; i++) {\n var calcPt = calcTrace[i] = {};\n\n if(hasLocationData) {\n var loc = trace.locations[i];\n calcPt.loc = isValidLoc(loc) ? loc : null;\n } else {\n var lon = trace.lon[i];\n var lat = trace.lat[i];\n\n if(isNumeric(lon) && isNumeric(lat)) calcPt.lonlat = [+lon, +lat];\n else calcPt.lonlat = [BADNUM, BADNUM];\n }\n }\n\n arraysToCalcdata(calcTrace, trace);\n calcMarkerColorscale(gd, trace);\n calcSelection(calcTrace, trace);\n\n if(len) {\n calcTrace[0].t = {\n labels: {\n lat: _(gd, 'lat:') + ' ',\n lon: _(gd, 'lon:') + ' '\n }\n };\n }\n\n return calcTrace;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergeo/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergeo/defaults.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergeo/defaults.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar subTypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar handleMarkerDefaults = __webpack_require__(/*! ../scatter/marker_defaults */ \"./node_modules/plotly.js/src/traces/scatter/marker_defaults.js\");\nvar handleLineDefaults = __webpack_require__(/*! ../scatter/line_defaults */ \"./node_modules/plotly.js/src/traces/scatter/line_defaults.js\");\nvar handleTextDefaults = __webpack_require__(/*! ../scatter/text_defaults */ \"./node_modules/plotly.js/src/traces/scatter/text_defaults.js\");\nvar handleFillColorDefaults = __webpack_require__(/*! ../scatter/fillcolor_defaults */ \"./node_modules/plotly.js/src/traces/scatter/fillcolor_defaults.js\");\n\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scattergeo/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var locations = coerce('locations');\n var len;\n\n if(locations && locations.length) {\n var geojson = coerce('geojson');\n var locationmodeDflt;\n if((typeof geojson === 'string' && geojson !== '') || Lib.isPlainObject(geojson)) {\n locationmodeDflt = 'geojson-id';\n }\n\n var locationMode = coerce('locationmode', locationmodeDflt);\n\n if(locationMode === 'geojson-id') {\n coerce('featureidkey');\n }\n\n len = locations.length;\n } else {\n var lon = coerce('lon') || [];\n var lat = coerce('lat') || [];\n len = Math.min(lon.length, lat.length);\n }\n\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n traceOut._length = len;\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n coerce('mode');\n\n if(subTypes.hasLines(traceOut)) {\n handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);\n coerce('connectgaps');\n }\n\n if(subTypes.hasMarkers(traceOut)) {\n handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});\n }\n\n if(subTypes.hasText(traceOut)) {\n coerce('texttemplate');\n handleTextDefaults(traceIn, traceOut, layout, coerce);\n }\n\n coerce('fill');\n if(traceOut.fill !== 'none') {\n handleFillColorDefaults(traceIn, traceOut, defaultColor, coerce);\n }\n\n Lib.coerceSelectionMarkerOpacity(traceOut, coerce);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergeo/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergeo/event_data.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergeo/event_data.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\n\nmodule.exports = function eventData(out, pt, trace, cd, pointNumber) {\n out.lon = pt.lon;\n out.lat = pt.lat;\n out.location = pt.loc ? pt.loc : null;\n\n // include feature properties from input geojson\n var cdi = cd[pointNumber];\n if(cdi.fIn && cdi.fIn.properties) {\n out.properties = cdi.fIn.properties;\n }\n\n return out;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergeo/event_data.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergeo/format_labels.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergeo/format_labels.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\n\nmodule.exports = function formatLabels(cdi, trace, fullLayout) {\n var labels = {};\n\n var geo = fullLayout[trace.geo]._subplot;\n var ax = geo.mockAxis;\n var lonlat = cdi.lonlat;\n labels.lonLabel = Axes.tickText(ax, ax.c2l(lonlat[0]), true).text;\n labels.latLabel = Axes.tickText(ax, ax.c2l(lonlat[1]), true).text;\n\n return labels;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergeo/format_labels.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergeo/hover.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergeo/hover.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Fx = __webpack_require__(/*! ../../components/fx */ \"./node_modules/plotly.js/src/components/fx/index.js\");\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nvar getTraceColor = __webpack_require__(/*! ../scatter/get_trace_color */ \"./node_modules/plotly.js/src/traces/scatter/get_trace_color.js\");\nvar fillText = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").fillText;\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scattergeo/attributes.js\");\n\nmodule.exports = function hoverPoints(pointData, xval, yval) {\n var cd = pointData.cd;\n var trace = cd[0].trace;\n var xa = pointData.xa;\n var ya = pointData.ya;\n var geo = pointData.subplot;\n\n var isLonLatOverEdges = geo.projection.isLonLatOverEdges;\n var project = geo.project;\n\n function distFn(d) {\n var lonlat = d.lonlat;\n\n if(lonlat[0] === BADNUM) return Infinity;\n if(isLonLatOverEdges(lonlat)) return Infinity;\n\n var pt = project(lonlat);\n var px = project([xval, yval]);\n var dx = Math.abs(pt[0] - px[0]);\n var dy = Math.abs(pt[1] - px[1]);\n var rad = Math.max(3, d.mrc || 0);\n\n // N.B. d.mrc is the calculated marker radius\n // which is only set for trace with 'markers' mode.\n\n return Math.max(Math.sqrt(dx * dx + dy * dy) - rad, 1 - 3 / rad);\n }\n\n Fx.getClosest(cd, distFn, pointData);\n\n // skip the rest (for this trace) if we didn't find a close point\n if(pointData.index === false) return;\n\n var di = cd[pointData.index];\n var lonlat = di.lonlat;\n var pos = [xa.c2p(lonlat), ya.c2p(lonlat)];\n var rad = di.mrc || 1;\n\n pointData.x0 = pos[0] - rad;\n pointData.x1 = pos[0] + rad;\n pointData.y0 = pos[1] - rad;\n pointData.y1 = pos[1] + rad;\n\n pointData.loc = di.loc;\n pointData.lon = lonlat[0];\n pointData.lat = lonlat[1];\n\n var fullLayout = {};\n fullLayout[trace.geo] = {_subplot: geo};\n var labels = trace._module.formatLabels(di, trace, fullLayout);\n pointData.lonLabel = labels.lonLabel;\n pointData.latLabel = labels.latLabel;\n\n pointData.color = getTraceColor(trace, di);\n pointData.extraText = getExtraText(trace, di, pointData, cd[0].t.labels);\n pointData.hovertemplate = trace.hovertemplate;\n\n return [pointData];\n};\n\nfunction getExtraText(trace, pt, pointData, labels) {\n if(trace.hovertemplate) return;\n\n var hoverinfo = pt.hi || trace.hoverinfo;\n\n var parts = hoverinfo === 'all' ?\n attributes.hoverinfo.flags :\n hoverinfo.split('+');\n\n var hasLocation = parts.indexOf('location') !== -1 && Array.isArray(trace.locations);\n var hasLon = (parts.indexOf('lon') !== -1);\n var hasLat = (parts.indexOf('lat') !== -1);\n var hasText = (parts.indexOf('text') !== -1);\n var text = [];\n\n function format(val) { return val + '\\u00B0'; }\n\n if(hasLocation) {\n text.push(pt.loc);\n } else if(hasLon && hasLat) {\n text.push('(' + format(pointData.lonLabel) + ', ' + format(pointData.latLabel) + ')');\n } else if(hasLon) {\n text.push(labels.lon + format(pointData.lonLabel));\n } else if(hasLat) {\n text.push(labels.lat + format(pointData.latLabel));\n }\n\n if(hasText) {\n fillText(pt, trace, text);\n }\n\n return text.join('
');\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergeo/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergeo/index.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergeo/index.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scattergeo/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/scattergeo/defaults.js\"),\n colorbar: __webpack_require__(/*! ../scatter/marker_colorbar */ \"./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js\"),\n formatLabels: __webpack_require__(/*! ./format_labels */ \"./node_modules/plotly.js/src/traces/scattergeo/format_labels.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/scattergeo/calc.js\"),\n calcGeoJSON: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/scattergeo/plot.js\").calcGeoJSON,\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/scattergeo/plot.js\").plot,\n style: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/scattergeo/style.js\"),\n styleOnSelect: __webpack_require__(/*! ../scatter/style */ \"./node_modules/plotly.js/src/traces/scatter/style.js\").styleOnSelect,\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/scattergeo/hover.js\"),\n eventData: __webpack_require__(/*! ./event_data */ \"./node_modules/plotly.js/src/traces/scattergeo/event_data.js\"),\n selectPoints: __webpack_require__(/*! ./select */ \"./node_modules/plotly.js/src/traces/scattergeo/select.js\"),\n\n moduleType: 'trace',\n name: 'scattergeo',\n basePlotModule: __webpack_require__(/*! ../../plots/geo */ \"./node_modules/plotly.js/src/plots/geo/index.js\"),\n categories: ['geo', 'symbols', 'showLegend', 'scatter-like'],\n meta: {\n \n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergeo/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergeo/plot.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergeo/plot.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar getTopojsonFeatures = __webpack_require__(/*! ../../lib/topojson_utils */ \"./node_modules/plotly.js/src/lib/topojson_utils.js\").getTopojsonFeatures;\nvar geoJsonUtils = __webpack_require__(/*! ../../lib/geojson_utils */ \"./node_modules/plotly.js/src/lib/geojson_utils.js\");\nvar geoUtils = __webpack_require__(/*! ../../lib/geo_location_utils */ \"./node_modules/plotly.js/src/lib/geo_location_utils.js\");\nvar findExtremes = __webpack_require__(/*! ../../plots/cartesian/autorange */ \"./node_modules/plotly.js/src/plots/cartesian/autorange.js\").findExtremes;\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nvar calcMarkerSize = __webpack_require__(/*! ../scatter/calc */ \"./node_modules/plotly.js/src/traces/scatter/calc.js\").calcMarkerSize;\nvar subTypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar style = __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/scattergeo/style.js\");\n\nfunction plot(gd, geo, calcData) {\n var scatterLayer = geo.layers.frontplot.select('.scatterlayer');\n var gTraces = Lib.makeTraceGroups(scatterLayer, calcData, 'trace scattergeo');\n\n function removeBADNUM(d, node) {\n if(d.lonlat[0] === BADNUM) {\n d3.select(node).remove();\n }\n }\n\n // TODO find a way to order the inner nodes on update\n gTraces.selectAll('*').remove();\n\n gTraces.each(function(calcTrace) {\n var s = d3.select(this);\n var trace = calcTrace[0].trace;\n\n if(subTypes.hasLines(trace) || trace.fill !== 'none') {\n var lineCoords = geoJsonUtils.calcTraceToLineCoords(calcTrace);\n\n var lineData = (trace.fill !== 'none') ?\n geoJsonUtils.makePolygon(lineCoords) :\n geoJsonUtils.makeLine(lineCoords);\n\n s.selectAll('path.js-line')\n .data([{geojson: lineData, trace: trace}])\n .enter().append('path')\n .classed('js-line', true)\n .style('stroke-miterlimit', 2);\n }\n\n if(subTypes.hasMarkers(trace)) {\n s.selectAll('path.point')\n .data(Lib.identity)\n .enter().append('path')\n .classed('point', true)\n .each(function(calcPt) { removeBADNUM(calcPt, this); });\n }\n\n if(subTypes.hasText(trace)) {\n s.selectAll('g')\n .data(Lib.identity)\n .enter().append('g')\n .append('text')\n .each(function(calcPt) { removeBADNUM(calcPt, this); });\n }\n\n // call style here within topojson request callback\n style(gd, calcTrace);\n });\n}\n\nfunction calcGeoJSON(calcTrace, fullLayout) {\n var trace = calcTrace[0].trace;\n var geoLayout = fullLayout[trace.geo];\n var geo = geoLayout._subplot;\n var len = trace._length;\n var i, calcPt;\n\n if(Array.isArray(trace.locations)) {\n var locationmode = trace.locationmode;\n var features = locationmode === 'geojson-id' ?\n geoUtils.extractTraceFeature(calcTrace) :\n getTopojsonFeatures(trace, geo.topojson);\n\n for(i = 0; i < len; i++) {\n calcPt = calcTrace[i];\n\n var feature = locationmode === 'geojson-id' ?\n calcPt.fOut :\n geoUtils.locationToFeature(locationmode, calcPt.loc, features);\n\n calcPt.lonlat = feature ? feature.properties.ct : [BADNUM, BADNUM];\n }\n }\n\n var opts = {padded: true};\n var lonArray;\n var latArray;\n\n if(geoLayout.fitbounds === 'geojson' && trace.locationmode === 'geojson-id') {\n var bboxGeojson = geoUtils.computeBbox(geoUtils.getTraceGeojson(trace));\n lonArray = [bboxGeojson[0], bboxGeojson[2]];\n latArray = [bboxGeojson[1], bboxGeojson[3]];\n } else {\n lonArray = new Array(len);\n latArray = new Array(len);\n for(i = 0; i < len; i++) {\n calcPt = calcTrace[i];\n lonArray[i] = calcPt.lonlat[0];\n latArray[i] = calcPt.lonlat[1];\n }\n\n opts.ppad = calcMarkerSize(trace, len);\n }\n\n trace._extremes.lon = findExtremes(geoLayout.lonaxis._ax, lonArray, opts);\n trace._extremes.lat = findExtremes(geoLayout.lataxis._ax, latArray, opts);\n}\n\nmodule.exports = {\n calcGeoJSON: calcGeoJSON,\n plot: plot\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergeo/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergeo/select.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergeo/select.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar subtypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nmodule.exports = function selectPoints(searchInfo, selectionTester) {\n var cd = searchInfo.cd;\n var xa = searchInfo.xaxis;\n var ya = searchInfo.yaxis;\n var selection = [];\n var trace = cd[0].trace;\n\n var di, lonlat, x, y, i;\n\n var hasOnlyLines = (!subtypes.hasMarkers(trace) && !subtypes.hasText(trace));\n if(hasOnlyLines) return [];\n\n if(selectionTester === false) {\n for(i = 0; i < cd.length; i++) {\n cd[i].selected = 0;\n }\n } else {\n for(i = 0; i < cd.length; i++) {\n di = cd[i];\n lonlat = di.lonlat;\n\n // some projection types can't handle BADNUMs\n if(lonlat[0] === BADNUM) continue;\n\n x = xa.c2p(lonlat);\n y = ya.c2p(lonlat);\n\n if(selectionTester.contains([x, y], null, i, searchInfo)) {\n selection.push({\n pointNumber: i,\n lon: lonlat[0],\n lat: lonlat[1]\n });\n di.selected = 1;\n } else {\n di.selected = 0;\n }\n }\n }\n\n return selection;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergeo/select.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergeo/style.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergeo/style.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\n\nvar scatterStyle = __webpack_require__(/*! ../scatter/style */ \"./node_modules/plotly.js/src/traces/scatter/style.js\");\nvar stylePoints = scatterStyle.stylePoints;\nvar styleText = scatterStyle.styleText;\n\nmodule.exports = function style(gd, calcTrace) {\n if(calcTrace) styleTrace(gd, calcTrace);\n};\n\nfunction styleTrace(gd, calcTrace) {\n var trace = calcTrace[0].trace;\n var s = calcTrace[0].node3;\n\n s.style('opacity', calcTrace[0].trace.opacity);\n\n stylePoints(s, trace, gd);\n styleText(s, trace, gd);\n\n // this part is incompatible with Drawing.lineGroupStyle\n s.selectAll('path.js-line')\n .style('fill', 'none')\n .each(function(d) {\n var path = d3.select(this);\n var trace = d.trace;\n var line = trace.line || {};\n\n path.call(Color.stroke, line.color)\n .call(Drawing.dashLine, line.dash || '', line.width || 0);\n\n if(trace.fill !== 'none') {\n path.call(Color.fill, trace.fillcolor);\n }\n });\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergeo/style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergl/attributes.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergl/attributes.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar scatterAttrs = __webpack_require__(/*! ../scatter/attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\");\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar overrideAll = __webpack_require__(/*! ../../plot_api/edit_types */ \"./node_modules/plotly.js/src/plot_api/edit_types.js\").overrideAll;\nvar DASHES = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/scattergl/constants.js\").DASHES;\n\nvar scatterLineAttrs = scatterAttrs.line;\nvar scatterMarkerAttrs = scatterAttrs.marker;\nvar scatterMarkerLineAttrs = scatterMarkerAttrs.line;\n\nvar attrs = module.exports = overrideAll({\n x: scatterAttrs.x,\n x0: scatterAttrs.x0,\n dx: scatterAttrs.dx,\n y: scatterAttrs.y,\n y0: scatterAttrs.y0,\n dy: scatterAttrs.dy,\n\n text: scatterAttrs.text,\n hovertext: scatterAttrs.hovertext,\n\n textposition: scatterAttrs.textposition,\n textfont: scatterAttrs.textfont,\n\n mode: {\n valType: 'flaglist',\n flags: ['lines', 'markers', 'text'],\n extras: ['none'],\n \n \n },\n line: {\n color: scatterLineAttrs.color,\n width: scatterLineAttrs.width,\n shape: {\n valType: 'enumerated',\n values: ['linear', 'hv', 'vh', 'hvh', 'vhv'],\n dflt: 'linear',\n \n editType: 'plot',\n \n },\n dash: {\n valType: 'enumerated',\n values: Object.keys(DASHES),\n dflt: 'solid',\n \n \n }\n },\n marker: extendFlat({}, colorScaleAttrs('marker'), {\n symbol: scatterMarkerAttrs.symbol,\n size: scatterMarkerAttrs.size,\n sizeref: scatterMarkerAttrs.sizeref,\n sizemin: scatterMarkerAttrs.sizemin,\n sizemode: scatterMarkerAttrs.sizemode,\n opacity: scatterMarkerAttrs.opacity,\n colorbar: scatterMarkerAttrs.colorbar,\n line: extendFlat({}, colorScaleAttrs('marker.line'), {\n width: scatterMarkerLineAttrs.width\n })\n }),\n connectgaps: scatterAttrs.connectgaps,\n fill: extendFlat({}, scatterAttrs.fill, {dflt: 'none'}),\n fillcolor: scatterAttrs.fillcolor,\n\n // no hoveron\n\n selected: {\n marker: scatterAttrs.selected.marker,\n textfont: scatterAttrs.selected.textfont\n },\n unselected: {\n marker: scatterAttrs.unselected.marker,\n textfont: scatterAttrs.unselected.textfont\n },\n\n opacity: baseAttrs.opacity\n\n}, 'calc', 'nested');\n\nattrs.x.editType = attrs.y.editType = attrs.x0.editType = attrs.y0.editType = 'calc+clearAxisTypes';\nattrs.hovertemplate = scatterAttrs.hovertemplate;\nattrs.texttemplate = scatterAttrs.texttemplate;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergl/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergl/calc.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergl/calc.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar cluster = __webpack_require__(/*! point-cluster */ \"./node_modules/point-cluster/index.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar AxisIDs = __webpack_require__(/*! ../../plots/cartesian/axis_ids */ \"./node_modules/plotly.js/src/plots/cartesian/axis_ids.js\");\nvar findExtremes = __webpack_require__(/*! ../../plots/cartesian/autorange */ \"./node_modules/plotly.js/src/plots/cartesian/autorange.js\").findExtremes;\n\nvar scatterCalc = __webpack_require__(/*! ../scatter/calc */ \"./node_modules/plotly.js/src/traces/scatter/calc.js\");\nvar calcMarkerSize = scatterCalc.calcMarkerSize;\nvar calcAxisExpansion = scatterCalc.calcAxisExpansion;\nvar setFirstScatter = scatterCalc.setFirstScatter;\nvar calcColorscale = __webpack_require__(/*! ../scatter/colorscale_calc */ \"./node_modules/plotly.js/src/traces/scatter/colorscale_calc.js\");\nvar convert = __webpack_require__(/*! ./convert */ \"./node_modules/plotly.js/src/traces/scattergl/convert.js\");\nvar sceneUpdate = __webpack_require__(/*! ./scene_update */ \"./node_modules/plotly.js/src/traces/scattergl/scene_update.js\");\n\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\nvar TOO_MANY_POINTS = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/scattergl/constants.js\").TOO_MANY_POINTS;\n\nmodule.exports = function calc(gd, trace) {\n var fullLayout = gd._fullLayout;\n var xa = AxisIDs.getFromId(gd, trace.xaxis);\n var ya = AxisIDs.getFromId(gd, trace.yaxis);\n var subplot = fullLayout._plots[trace.xaxis + trace.yaxis];\n var len = trace._length;\n var hasTooManyPoints = len >= TOO_MANY_POINTS;\n var len2 = len * 2;\n var stash = {};\n var i, xx, yy;\n\n var x = trace._x = xa.makeCalcdata(trace, 'x');\n var y = trace._y = ya.makeCalcdata(trace, 'y');\n\n // we need hi-precision for scatter2d,\n // regl-scatter2d uses NaNs for bad/missing values\n var positions = new Array(len2);\n for(i = 0; i < len; i++) {\n xx = x[i];\n yy = y[i];\n positions[i * 2] = xx === BADNUM ? NaN : xx;\n positions[i * 2 + 1] = yy === BADNUM ? NaN : yy;\n }\n\n if(xa.type === 'log') {\n for(i = 0; i < len2; i += 2) {\n positions[i] = xa.c2l(positions[i]);\n }\n }\n if(ya.type === 'log') {\n for(i = 1; i < len2; i += 2) {\n positions[i] = ya.c2l(positions[i]);\n }\n }\n\n // we don't build a tree for log axes since it takes long to convert log2px\n // and it is also\n if(hasTooManyPoints && (xa.type !== 'log' && ya.type !== 'log')) {\n // FIXME: delegate this to webworker\n stash.tree = cluster(positions);\n } else {\n var ids = stash.ids = new Array(len);\n for(i = 0; i < len; i++) {\n ids[i] = i;\n }\n }\n\n // create scene options and scene\n calcColorscale(gd, trace);\n var opts = sceneOptions(gd, subplot, trace, positions, x, y);\n var scene = sceneUpdate(gd, subplot);\n\n // Reuse SVG scatter axis expansion routine.\n // For graphs with very large number of points and array marker.size,\n // use average marker size instead to speed things up.\n setFirstScatter(fullLayout, trace);\n var ppad;\n if(!hasTooManyPoints) {\n ppad = calcMarkerSize(trace, len);\n } else if(opts.marker) {\n ppad = 2 * (opts.marker.sizeAvg || Math.max(opts.marker.size, 3));\n }\n calcAxisExpansion(gd, trace, xa, ya, x, y, ppad);\n if(opts.errorX) expandForErrorBars(trace, xa, opts.errorX);\n if(opts.errorY) expandForErrorBars(trace, ya, opts.errorY);\n\n // set flags to create scene renderers\n if(opts.fill && !scene.fill2d) scene.fill2d = true;\n if(opts.marker && !scene.scatter2d) scene.scatter2d = true;\n if(opts.line && !scene.line2d) scene.line2d = true;\n if((opts.errorX || opts.errorY) && !scene.error2d) scene.error2d = true;\n if(opts.text && !scene.glText) scene.glText = true;\n if(opts.marker) opts.marker.snap = len;\n\n scene.lineOptions.push(opts.line);\n scene.errorXOptions.push(opts.errorX);\n scene.errorYOptions.push(opts.errorY);\n scene.fillOptions.push(opts.fill);\n scene.markerOptions.push(opts.marker);\n scene.markerSelectedOptions.push(opts.markerSel);\n scene.markerUnselectedOptions.push(opts.markerUnsel);\n scene.textOptions.push(opts.text);\n scene.textSelectedOptions.push(opts.textSel);\n scene.textUnselectedOptions.push(opts.textUnsel);\n scene.selectBatch.push([]);\n scene.unselectBatch.push([]);\n\n stash._scene = scene;\n stash.index = scene.count;\n stash.x = x;\n stash.y = y;\n stash.positions = positions;\n scene.count++;\n\n return [{x: false, y: false, t: stash, trace: trace}];\n};\n\nfunction expandForErrorBars(trace, ax, opts) {\n var extremes = trace._extremes[ax._id];\n var errExt = findExtremes(ax, opts._bnds, {padded: true});\n extremes.min = extremes.min.concat(errExt.min);\n extremes.max = extremes.max.concat(errExt.max);\n}\n\nfunction sceneOptions(gd, subplot, trace, positions, x, y) {\n var opts = convert.style(gd, trace);\n\n if(opts.marker) {\n opts.marker.positions = positions;\n }\n\n if(opts.line && positions.length > 1) {\n Lib.extendFlat(\n opts.line,\n convert.linePositions(gd, trace, positions)\n );\n }\n\n if(opts.errorX || opts.errorY) {\n var errors = convert.errorBarPositions(gd, trace, positions, x, y);\n\n if(opts.errorX) {\n Lib.extendFlat(opts.errorX, errors.x);\n }\n if(opts.errorY) {\n Lib.extendFlat(opts.errorY, errors.y);\n }\n }\n\n if(opts.text) {\n Lib.extendFlat(\n opts.text,\n {positions: positions},\n convert.textPosition(gd, trace, opts.text, opts.marker)\n );\n Lib.extendFlat(\n opts.textSel,\n {positions: positions},\n convert.textPosition(gd, trace, opts.text, opts.markerSel)\n );\n Lib.extendFlat(\n opts.textUnsel,\n {positions: positions},\n convert.textPosition(gd, trace, opts.text, opts.markerUnsel)\n );\n }\n\n return opts;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergl/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergl/constants.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergl/constants.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar SYMBOL_SIZE = 20;\n\nmodule.exports = {\n TOO_MANY_POINTS: 1e5,\n\n SYMBOL_SDF_SIZE: 200,\n SYMBOL_SIZE: SYMBOL_SIZE,\n SYMBOL_STROKE: SYMBOL_SIZE / 20,\n\n DOT_RE: /-dot/,\n OPEN_RE: /-open/,\n\n DASHES: {\n solid: [1],\n dot: [1, 1],\n dash: [4, 1],\n longdash: [8, 1],\n dashdot: [4, 1, 1, 1],\n longdashdot: [8, 1, 1, 1]\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergl/constants.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergl/convert.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergl/convert.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\nvar svgSdf = __webpack_require__(/*! svg-path-sdf */ \"./node_modules/svg-path-sdf/index.js\");\nvar rgba = __webpack_require__(/*! color-normalize */ \"./node_modules/color-normalize/index.js\");\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar AxisIDs = __webpack_require__(/*! ../../plots/cartesian/axis_ids */ \"./node_modules/plotly.js/src/plots/cartesian/axis_ids.js\");\n\nvar formatColor = __webpack_require__(/*! ../../lib/gl_format_color */ \"./node_modules/plotly.js/src/lib/gl_format_color.js\").formatColor;\nvar subTypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar makeBubbleSizeFn = __webpack_require__(/*! ../scatter/make_bubble_size_func */ \"./node_modules/plotly.js/src/traces/scatter/make_bubble_size_func.js\");\n\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/traces/scattergl/helpers.js\");\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/scattergl/constants.js\");\nvar DESELECTDIM = __webpack_require__(/*! ../../constants/interactions */ \"./node_modules/plotly.js/src/constants/interactions.js\").DESELECTDIM;\n\nvar TEXTOFFSETSIGN = {\n start: 1, left: 1, end: -1, right: -1, middle: 0, center: 0, bottom: 1, top: -1\n};\n\nvar appendArrayPointValue = __webpack_require__(/*! ../../components/fx/helpers */ \"./node_modules/plotly.js/src/components/fx/helpers.js\").appendArrayPointValue;\n\nfunction convertStyle(gd, trace) {\n var i;\n\n var opts = {\n marker: undefined,\n markerSel: undefined,\n markerUnsel: undefined,\n line: undefined,\n fill: undefined,\n errorX: undefined,\n errorY: undefined,\n text: undefined,\n textSel: undefined,\n textUnsel: undefined\n };\n\n if(trace.visible !== true) return opts;\n\n if(subTypes.hasText(trace)) {\n opts.text = convertTextStyle(gd, trace);\n opts.textSel = convertTextSelection(gd, trace, trace.selected);\n opts.textUnsel = convertTextSelection(gd, trace, trace.unselected);\n }\n\n if(subTypes.hasMarkers(trace)) {\n opts.marker = convertMarkerStyle(trace);\n opts.markerSel = convertMarkerSelection(trace, trace.selected);\n opts.markerUnsel = convertMarkerSelection(trace, trace.unselected);\n\n if(!trace.unselected && Lib.isArrayOrTypedArray(trace.marker.opacity)) {\n var mo = trace.marker.opacity;\n opts.markerUnsel.opacity = new Array(mo.length);\n for(i = 0; i < mo.length; i++) {\n opts.markerUnsel.opacity[i] = DESELECTDIM * mo[i];\n }\n }\n }\n\n if(subTypes.hasLines(trace)) {\n opts.line = {\n overlay: true,\n thickness: trace.line.width,\n color: trace.line.color,\n opacity: trace.opacity\n };\n\n var dashes = (constants.DASHES[trace.line.dash] || [1]).slice();\n for(i = 0; i < dashes.length; ++i) {\n dashes[i] *= trace.line.width;\n }\n opts.line.dashes = dashes;\n }\n\n if(trace.error_x && trace.error_x.visible) {\n opts.errorX = convertErrorBarStyle(trace, trace.error_x);\n }\n\n if(trace.error_y && trace.error_y.visible) {\n opts.errorY = convertErrorBarStyle(trace, trace.error_y);\n }\n\n if(!!trace.fill && trace.fill !== 'none') {\n opts.fill = {\n closed: true,\n fill: trace.fillcolor,\n thickness: 0\n };\n }\n\n return opts;\n}\n\nfunction convertTextStyle(gd, trace) {\n var fullLayout = gd._fullLayout;\n var count = trace._length;\n var textfontIn = trace.textfont;\n var textpositionIn = trace.textposition;\n var textPos = Array.isArray(textpositionIn) ? textpositionIn : [textpositionIn];\n var tfc = textfontIn.color;\n var tfs = textfontIn.size;\n var tff = textfontIn.family;\n var optsOut = {};\n var i;\n\n var texttemplate = trace.texttemplate;\n if(texttemplate) {\n optsOut.text = [];\n\n var d3locale = fullLayout._d3locale;\n var isArray = Array.isArray(texttemplate);\n var N = isArray ? Math.min(texttemplate.length, count) : count;\n var txt = isArray ?\n function(i) { return texttemplate[i]; } :\n function() { return texttemplate; };\n\n for(i = 0; i < N; i++) {\n var d = {i: i};\n var labels = trace._module.formatLabels(d, trace, fullLayout);\n var pointValues = {};\n appendArrayPointValue(pointValues, trace, i);\n var meta = trace._meta || {};\n optsOut.text.push(Lib.texttemplateString(txt(i), labels, d3locale, pointValues, d, meta));\n }\n } else {\n if(Array.isArray(trace.text) && trace.text.length < count) {\n // if text array is shorter, we'll need to append to it, so let's slice to prevent mutating\n optsOut.text = trace.text.slice();\n } else {\n optsOut.text = trace.text;\n }\n }\n // pad text array with empty strings\n if(Array.isArray(optsOut.text)) {\n for(i = optsOut.text.length; i < count; i++) {\n optsOut.text[i] = '';\n }\n }\n\n optsOut.opacity = trace.opacity;\n optsOut.font = {};\n optsOut.align = [];\n optsOut.baseline = [];\n\n for(i = 0; i < textPos.length; i++) {\n var tp = textPos[i].split(/\\s+/);\n\n switch(tp[1]) {\n case 'left':\n optsOut.align.push('right');\n break;\n case 'right':\n optsOut.align.push('left');\n break;\n default:\n optsOut.align.push(tp[1]);\n }\n switch(tp[0]) {\n case 'top':\n optsOut.baseline.push('bottom');\n break;\n case 'bottom':\n optsOut.baseline.push('top');\n break;\n default:\n optsOut.baseline.push(tp[0]);\n }\n }\n\n if(Array.isArray(tfc)) {\n optsOut.color = new Array(count);\n for(i = 0; i < count; i++) {\n optsOut.color[i] = tfc[i];\n }\n } else {\n optsOut.color = tfc;\n }\n\n if(Lib.isArrayOrTypedArray(tfs) || Array.isArray(tff)) {\n // if any textfont param is array - make render a batch\n optsOut.font = new Array(count);\n for(i = 0; i < count; i++) {\n var fonti = optsOut.font[i] = {};\n\n fonti.size = (\n Lib.isTypedArray(tfs) ? tfs[i] :\n Array.isArray(tfs) ? (\n isNumeric(tfs[i]) ? tfs[i] : 0\n ) : tfs\n );\n\n fonti.family = Array.isArray(tff) ? tff[i] : tff;\n }\n } else {\n // if both are single values, make render fast single-value\n optsOut.font = {size: tfs, family: tff};\n }\n\n return optsOut;\n}\n\n\nfunction convertMarkerStyle(trace) {\n var count = trace._length;\n var optsIn = trace.marker;\n var optsOut = {};\n var i;\n\n var multiSymbol = Lib.isArrayOrTypedArray(optsIn.symbol);\n var multiColor = Lib.isArrayOrTypedArray(optsIn.color);\n var multiLineColor = Lib.isArrayOrTypedArray(optsIn.line.color);\n var multiOpacity = Lib.isArrayOrTypedArray(optsIn.opacity);\n var multiSize = Lib.isArrayOrTypedArray(optsIn.size);\n var multiLineWidth = Lib.isArrayOrTypedArray(optsIn.line.width);\n\n var isOpen;\n if(!multiSymbol) isOpen = helpers.isOpenSymbol(optsIn.symbol);\n\n // prepare colors\n if(multiSymbol || multiColor || multiLineColor || multiOpacity) {\n optsOut.colors = new Array(count);\n optsOut.borderColors = new Array(count);\n\n var colors = formatColor(optsIn, optsIn.opacity, count);\n var borderColors = formatColor(optsIn.line, optsIn.opacity, count);\n\n if(!Array.isArray(borderColors[0])) {\n var borderColor = borderColors;\n borderColors = Array(count);\n for(i = 0; i < count; i++) {\n borderColors[i] = borderColor;\n }\n }\n if(!Array.isArray(colors[0])) {\n var color = colors;\n colors = Array(count);\n for(i = 0; i < count; i++) {\n colors[i] = color;\n }\n }\n\n optsOut.colors = colors;\n optsOut.borderColors = borderColors;\n\n for(i = 0; i < count; i++) {\n if(multiSymbol) {\n var symbol = optsIn.symbol[i];\n isOpen = helpers.isOpenSymbol(symbol);\n }\n if(isOpen) {\n borderColors[i] = colors[i].slice();\n colors[i] = colors[i].slice();\n colors[i][3] = 0;\n }\n }\n\n optsOut.opacity = trace.opacity;\n } else {\n if(isOpen) {\n optsOut.color = rgba(optsIn.color, 'uint8');\n optsOut.color[3] = 0;\n optsOut.borderColor = rgba(optsIn.color, 'uint8');\n } else {\n optsOut.color = rgba(optsIn.color, 'uint8');\n optsOut.borderColor = rgba(optsIn.line.color, 'uint8');\n }\n\n optsOut.opacity = trace.opacity * optsIn.opacity;\n }\n\n // prepare symbols\n if(multiSymbol) {\n optsOut.markers = new Array(count);\n for(i = 0; i < count; i++) {\n optsOut.markers[i] = getSymbolSdf(optsIn.symbol[i]);\n }\n } else {\n optsOut.marker = getSymbolSdf(optsIn.symbol);\n }\n\n // prepare sizes\n var markerSizeFunc = makeBubbleSizeFn(trace);\n var s;\n\n if(multiSize || multiLineWidth) {\n var sizes = optsOut.sizes = new Array(count);\n var borderSizes = optsOut.borderSizes = new Array(count);\n var sizeTotal = 0;\n var sizeAvg;\n\n if(multiSize) {\n for(i = 0; i < count; i++) {\n sizes[i] = markerSizeFunc(optsIn.size[i]);\n sizeTotal += sizes[i];\n }\n sizeAvg = sizeTotal / count;\n } else {\n s = markerSizeFunc(optsIn.size);\n for(i = 0; i < count; i++) {\n sizes[i] = s;\n }\n }\n\n // See https://github.com/plotly/plotly.js/pull/1781#discussion_r121820798\n if(multiLineWidth) {\n for(i = 0; i < count; i++) {\n borderSizes[i] = optsIn.line.width[i] / 2;\n }\n } else {\n s = optsIn.line.width / 2;\n for(i = 0; i < count; i++) {\n borderSizes[i] = s;\n }\n }\n\n optsOut.sizeAvg = sizeAvg;\n } else {\n optsOut.size = markerSizeFunc(optsIn && optsIn.size || 10);\n optsOut.borderSizes = markerSizeFunc(optsIn.line.width);\n }\n\n return optsOut;\n}\n\nfunction convertMarkerSelection(trace, target) {\n var optsIn = trace.marker;\n var optsOut = {};\n\n if(!target) return optsOut;\n\n if(target.marker && target.marker.symbol) {\n optsOut = convertMarkerStyle(Lib.extendFlat({}, optsIn, target.marker));\n } else if(target.marker) {\n if(target.marker.size) optsOut.size = target.marker.size / 2;\n if(target.marker.color) optsOut.colors = target.marker.color;\n if(target.marker.opacity !== undefined) optsOut.opacity = target.marker.opacity;\n }\n\n return optsOut;\n}\n\nfunction convertTextSelection(gd, trace, target) {\n var optsOut = {};\n\n if(!target) return optsOut;\n\n if(target.textfont) {\n var optsIn = {\n opacity: 1,\n text: trace.text,\n texttemplate: trace.texttemplate,\n textposition: trace.textposition,\n textfont: Lib.extendFlat({}, trace.textfont)\n };\n if(target.textfont) {\n Lib.extendFlat(optsIn.textfont, target.textfont);\n }\n optsOut = convertTextStyle(gd, optsIn);\n }\n\n return optsOut;\n}\n\nfunction convertErrorBarStyle(trace, target) {\n var optsOut = {\n capSize: target.width * 2,\n lineWidth: target.thickness,\n color: target.color\n };\n\n if(target.copy_ystyle) {\n optsOut = trace.error_y;\n }\n\n return optsOut;\n}\n\nvar SYMBOL_SDF_SIZE = constants.SYMBOL_SDF_SIZE;\nvar SYMBOL_SIZE = constants.SYMBOL_SIZE;\nvar SYMBOL_STROKE = constants.SYMBOL_STROKE;\nvar SYMBOL_SDF = {};\nvar SYMBOL_SVG_CIRCLE = Drawing.symbolFuncs[0](SYMBOL_SIZE * 0.05);\n\nfunction getSymbolSdf(symbol) {\n if(symbol === 'circle') return null;\n\n var symbolPath, symbolSdf;\n var symbolNumber = Drawing.symbolNumber(symbol);\n var symbolFunc = Drawing.symbolFuncs[symbolNumber % 100];\n var symbolNoDot = !!Drawing.symbolNoDot[symbolNumber % 100];\n var symbolNoFill = !!Drawing.symbolNoFill[symbolNumber % 100];\n\n var isDot = helpers.isDotSymbol(symbol);\n\n // get symbol sdf from cache or generate it\n if(SYMBOL_SDF[symbol]) return SYMBOL_SDF[symbol];\n\n if(isDot && !symbolNoDot) {\n symbolPath = symbolFunc(SYMBOL_SIZE * 1.1) + SYMBOL_SVG_CIRCLE;\n } else {\n symbolPath = symbolFunc(SYMBOL_SIZE);\n }\n\n symbolSdf = svgSdf(symbolPath, {\n w: SYMBOL_SDF_SIZE,\n h: SYMBOL_SDF_SIZE,\n viewBox: [-SYMBOL_SIZE, -SYMBOL_SIZE, SYMBOL_SIZE, SYMBOL_SIZE],\n stroke: symbolNoFill ? SYMBOL_STROKE : -SYMBOL_STROKE\n });\n SYMBOL_SDF[symbol] = symbolSdf;\n\n return symbolSdf || null;\n}\n\nfunction convertLinePositions(gd, trace, positions) {\n var len = positions.length;\n var count = len / 2;\n var linePositions;\n var i;\n\n if(subTypes.hasLines(trace) && count) {\n if(trace.line.shape === 'hv') {\n linePositions = [];\n for(i = 0; i < count - 1; i++) {\n if(isNaN(positions[i * 2]) || isNaN(positions[i * 2 + 1])) {\n linePositions.push(NaN, NaN, NaN, NaN);\n } else {\n linePositions.push(positions[i * 2], positions[i * 2 + 1]);\n if(!isNaN(positions[i * 2 + 2]) && !isNaN(positions[i * 2 + 3])) {\n linePositions.push(positions[i * 2 + 2], positions[i * 2 + 1]);\n } else {\n linePositions.push(NaN, NaN);\n }\n }\n }\n linePositions.push(positions[len - 2], positions[len - 1]);\n } else if(trace.line.shape === 'hvh') {\n linePositions = [];\n for(i = 0; i < count - 1; i++) {\n if(isNaN(positions[i * 2]) || isNaN(positions[i * 2 + 1]) || isNaN(positions[i * 2 + 2]) || isNaN(positions[i * 2 + 3])) {\n if(!isNaN(positions[i * 2]) && !isNaN(positions[i * 2 + 1])) {\n linePositions.push(positions[i * 2], positions[i * 2 + 1]);\n } else {\n linePositions.push(NaN, NaN);\n }\n linePositions.push(NaN, NaN);\n } else {\n var midPtX = (positions[i * 2] + positions[i * 2 + 2]) / 2;\n linePositions.push(\n positions[i * 2],\n positions[i * 2 + 1],\n midPtX,\n positions[i * 2 + 1],\n midPtX,\n positions[i * 2 + 3]\n );\n }\n }\n linePositions.push(positions[len - 2], positions[len - 1]);\n } else if(trace.line.shape === 'vhv') {\n linePositions = [];\n for(i = 0; i < count - 1; i++) {\n if(isNaN(positions[i * 2]) || isNaN(positions[i * 2 + 1]) || isNaN(positions[i * 2 + 2]) || isNaN(positions[i * 2 + 3])) {\n if(!isNaN(positions[i * 2]) && !isNaN(positions[i * 2 + 1])) {\n linePositions.push(positions[i * 2], positions[i * 2 + 1]);\n } else {\n linePositions.push(NaN, NaN);\n }\n linePositions.push(NaN, NaN);\n } else {\n var midPtY = (positions[i * 2 + 1] + positions[i * 2 + 3]) / 2;\n linePositions.push(\n positions[i * 2],\n positions[i * 2 + 1],\n positions[i * 2],\n midPtY,\n positions[i * 2 + 2],\n midPtY\n );\n }\n }\n linePositions.push(positions[len - 2], positions[len - 1]);\n } else if(trace.line.shape === 'vh') {\n linePositions = [];\n for(i = 0; i < count - 1; i++) {\n if(isNaN(positions[i * 2]) || isNaN(positions[i * 2 + 1])) {\n linePositions.push(NaN, NaN, NaN, NaN);\n } else {\n linePositions.push(positions[i * 2], positions[i * 2 + 1]);\n if(!isNaN(positions[i * 2 + 2]) && !isNaN(positions[i * 2 + 3])) {\n linePositions.push(positions[i * 2], positions[i * 2 + 3]);\n } else {\n linePositions.push(NaN, NaN);\n }\n }\n }\n linePositions.push(positions[len - 2], positions[len - 1]);\n } else {\n linePositions = positions;\n }\n }\n\n // If we have data with gaps, we ought to use rect joins\n // FIXME: get rid of this\n var hasNaN = false;\n for(i = 0; i < linePositions.length; i++) {\n if(isNaN(linePositions[i])) {\n hasNaN = true;\n break;\n }\n }\n\n var join = (hasNaN || linePositions.length > constants.TOO_MANY_POINTS) ? 'rect' :\n subTypes.hasMarkers(trace) ? 'rect' : 'round';\n\n // fill gaps\n if(hasNaN && trace.connectgaps) {\n var lastX = linePositions[0];\n var lastY = linePositions[1];\n\n for(i = 0; i < linePositions.length; i += 2) {\n if(isNaN(linePositions[i]) || isNaN(linePositions[i + 1])) {\n linePositions[i] = lastX;\n linePositions[i + 1] = lastY;\n } else {\n lastX = linePositions[i];\n lastY = linePositions[i + 1];\n }\n }\n }\n\n return {\n join: join,\n positions: linePositions\n };\n}\n\nfunction convertErrorBarPositions(gd, trace, positions, x, y) {\n var makeComputeError = Registry.getComponentMethod('errorbars', 'makeComputeError');\n var xa = AxisIDs.getFromId(gd, trace.xaxis);\n var ya = AxisIDs.getFromId(gd, trace.yaxis);\n var count = positions.length / 2;\n var out = {};\n\n function convertOneAxis(coords, ax) {\n var axLetter = ax._id.charAt(0);\n var opts = trace['error_' + axLetter];\n\n if(opts && opts.visible && (ax.type === 'linear' || ax.type === 'log')) {\n var computeError = makeComputeError(opts);\n var pOffset = {x: 0, y: 1}[axLetter];\n var eOffset = {x: [0, 1, 2, 3], y: [2, 3, 0, 1]}[axLetter];\n var errors = new Float64Array(4 * count);\n var minShoe = Infinity;\n var maxHat = -Infinity;\n\n for(var i = 0, j = 0; i < count; i++, j += 4) {\n var dc = coords[i];\n\n if(isNumeric(dc)) {\n var dl = positions[i * 2 + pOffset];\n var vals = computeError(dc, i);\n var lv = vals[0];\n var hv = vals[1];\n\n if(isNumeric(lv) && isNumeric(hv)) {\n var shoe = dc - lv;\n var hat = dc + hv;\n\n errors[j + eOffset[0]] = dl - ax.c2l(shoe);\n errors[j + eOffset[1]] = ax.c2l(hat) - dl;\n errors[j + eOffset[2]] = 0;\n errors[j + eOffset[3]] = 0;\n\n minShoe = Math.min(minShoe, dc - lv);\n maxHat = Math.max(maxHat, dc + hv);\n }\n }\n }\n\n out[axLetter] = {\n positions: positions,\n errors: errors,\n _bnds: [minShoe, maxHat]\n };\n }\n }\n\n convertOneAxis(x, xa);\n convertOneAxis(y, ya);\n return out;\n}\n\nfunction convertTextPosition(gd, trace, textOpts, markerOpts) {\n var count = trace._length;\n var out = {};\n var i;\n\n // corresponds to textPointPosition from component.drawing\n if(subTypes.hasMarkers(trace)) {\n var fontOpts = textOpts.font;\n var align = textOpts.align;\n var baseline = textOpts.baseline;\n out.offset = new Array(count);\n\n for(i = 0; i < count; i++) {\n var ms = markerOpts.sizes ? markerOpts.sizes[i] : markerOpts.size;\n var fs = Array.isArray(fontOpts) ? fontOpts[i].size : fontOpts.size;\n\n var a = Array.isArray(align) ?\n (align.length > 1 ? align[i] : align[0]) :\n align;\n var b = Array.isArray(baseline) ?\n (baseline.length > 1 ? baseline[i] : baseline[0]) :\n baseline;\n\n var hSign = TEXTOFFSETSIGN[a];\n var vSign = TEXTOFFSETSIGN[b];\n var xPad = ms ? ms / 0.8 + 1 : 0;\n var yPad = -vSign * xPad - vSign * 0.5;\n out.offset[i] = [hSign * xPad / fs, yPad / fs];\n }\n }\n\n return out;\n}\n\nmodule.exports = {\n style: convertStyle,\n\n markerStyle: convertMarkerStyle,\n markerSelection: convertMarkerSelection,\n\n linePositions: convertLinePositions,\n errorBarPositions: convertErrorBarPositions,\n textPosition: convertTextPosition\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergl/convert.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergl/defaults.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergl/defaults.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\n\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/traces/scattergl/helpers.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scattergl/attributes.js\");\nvar constants = __webpack_require__(/*! ../scatter/constants */ \"./node_modules/plotly.js/src/traces/scatter/constants.js\");\nvar subTypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar handleXYDefaults = __webpack_require__(/*! ../scatter/xy_defaults */ \"./node_modules/plotly.js/src/traces/scatter/xy_defaults.js\");\nvar handleMarkerDefaults = __webpack_require__(/*! ../scatter/marker_defaults */ \"./node_modules/plotly.js/src/traces/scatter/marker_defaults.js\");\nvar handleLineDefaults = __webpack_require__(/*! ../scatter/line_defaults */ \"./node_modules/plotly.js/src/traces/scatter/line_defaults.js\");\nvar handleFillColorDefaults = __webpack_require__(/*! ../scatter/fillcolor_defaults */ \"./node_modules/plotly.js/src/traces/scatter/fillcolor_defaults.js\");\nvar handleTextDefaults = __webpack_require__(/*! ../scatter/text_defaults */ \"./node_modules/plotly.js/src/traces/scatter/text_defaults.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var isOpen = traceIn.marker ? helpers.isOpenSymbol(traceIn.marker.symbol) : false;\n var isBubble = subTypes.isBubble(traceIn);\n\n var len = handleXYDefaults(traceIn, traceOut, layout, coerce);\n if(!len) {\n traceOut.visible = false;\n return;\n }\n var defaultMode = len < constants.PTS_LINESONLY ? 'lines+markers' : 'lines';\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n coerce('mode', defaultMode);\n\n if(subTypes.hasLines(traceOut)) {\n coerce('connectgaps');\n handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);\n coerce('line.shape');\n }\n\n if(subTypes.hasMarkers(traceOut)) {\n handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce);\n coerce('marker.line.width', isOpen || isBubble ? 1 : 0);\n }\n\n if(subTypes.hasText(traceOut)) {\n coerce('texttemplate');\n handleTextDefaults(traceIn, traceOut, layout, coerce);\n }\n\n var lineColor = (traceOut.line || {}).color;\n var markerColor = (traceOut.marker || {}).color;\n\n coerce('fill');\n if(traceOut.fill !== 'none') {\n handleFillColorDefaults(traceIn, traceOut, defaultColor, coerce);\n }\n\n var errorBarsSupplyDefaults = Registry.getComponentMethod('errorbars', 'supplyDefaults');\n errorBarsSupplyDefaults(traceIn, traceOut, lineColor || markerColor || defaultColor, {axis: 'y'});\n errorBarsSupplyDefaults(traceIn, traceOut, lineColor || markerColor || defaultColor, {axis: 'x', inherit: 'y'});\n\n Lib.coerceSelectionMarkerOpacity(traceOut, coerce);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergl/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergl/edit_style.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergl/edit_style.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\n\nvar DESELECTDIM = __webpack_require__(/*! ../../constants/interactions */ \"./node_modules/plotly.js/src/constants/interactions.js\").DESELECTDIM;\n\nfunction styleTextSelection(cd) {\n var cd0 = cd[0];\n var trace = cd0.trace;\n var stash = cd0.t;\n var scene = stash._scene;\n var index = stash.index;\n var els = scene.selectBatch[index];\n var unels = scene.unselectBatch[index];\n var baseOpts = scene.textOptions[index];\n var selOpts = scene.textSelectedOptions[index] || {};\n var unselOpts = scene.textUnselectedOptions[index] || {};\n var opts = Lib.extendFlat({}, baseOpts);\n var i, j;\n\n if(els.length || unels.length) {\n var stc = selOpts.color;\n var utc = unselOpts.color;\n var base = baseOpts.color;\n var hasArrayBase = Array.isArray(base);\n opts.color = new Array(trace._length);\n\n for(i = 0; i < els.length; i++) {\n j = els[i];\n opts.color[j] = stc || (hasArrayBase ? base[j] : base);\n }\n for(i = 0; i < unels.length; i++) {\n j = unels[i];\n var basej = hasArrayBase ? base[j] : base;\n opts.color[j] = utc ? utc :\n stc ? basej : Color.addOpacity(basej, DESELECTDIM);\n }\n }\n\n scene.glText[index].update(opts);\n}\n\nmodule.exports = {\n styleTextSelection: styleTextSelection\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergl/edit_style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergl/format_labels.js":
-/*!**********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergl/format_labels.js ***!
- \**********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar scatterFormatLabels = __webpack_require__(/*! ../scatter/format_labels */ \"./node_modules/plotly.js/src/traces/scatter/format_labels.js\");\n\nmodule.exports = function formatLabels(cdi, trace, fullLayout) {\n var i = cdi.i;\n if(!('x' in cdi)) cdi.x = trace._x[i];\n if(!('y' in cdi)) cdi.y = trace._y[i];\n return scatterFormatLabels(cdi, trace, fullLayout);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergl/format_labels.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergl/helpers.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergl/helpers.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/scattergl/constants.js\");\n\nexports.isOpenSymbol = function(symbol) {\n return (typeof symbol === 'string') ?\n constants.OPEN_RE.test(symbol) :\n symbol % 200 > 100;\n};\n\nexports.isDotSymbol = function(symbol) {\n return (typeof symbol === 'string') ?\n constants.DOT_RE.test(symbol) :\n symbol > 200;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergl/helpers.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergl/hover.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergl/hover.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar getTraceColor = __webpack_require__(/*! ../scatter/get_trace_color */ \"./node_modules/plotly.js/src/traces/scatter/get_trace_color.js\");\n\nfunction hoverPoints(pointData, xval, yval, hovermode) {\n var cd = pointData.cd;\n var stash = cd[0].t;\n var trace = cd[0].trace;\n var xa = pointData.xa;\n var ya = pointData.ya;\n var x = stash.x;\n var y = stash.y;\n var xpx = xa.c2p(xval);\n var ypx = ya.c2p(yval);\n var maxDistance = pointData.distance;\n var ids;\n\n // FIXME: make sure this is a proper way to calc search radius\n if(stash.tree) {\n var xl = xa.p2c(xpx - maxDistance);\n var xr = xa.p2c(xpx + maxDistance);\n var yl = ya.p2c(ypx - maxDistance);\n var yr = ya.p2c(ypx + maxDistance);\n\n if(hovermode === 'x') {\n ids = stash.tree.range(\n Math.min(xl, xr), Math.min(ya._rl[0], ya._rl[1]),\n Math.max(xl, xr), Math.max(ya._rl[0], ya._rl[1])\n );\n } else {\n ids = stash.tree.range(\n Math.min(xl, xr), Math.min(yl, yr),\n Math.max(xl, xr), Math.max(yl, yr)\n );\n }\n } else {\n ids = stash.ids;\n }\n\n // pick the id closest to the point\n // note that point possibly may not be found\n var id, ptx, pty, i, dx, dy, dist, dxy;\n\n var minDist = maxDistance;\n if(hovermode === 'x') {\n for(i = 0; i < ids.length; i++) {\n ptx = x[ids[i]];\n dx = Math.abs(xa.c2p(ptx) - xpx);\n if(dx < minDist) {\n minDist = dx;\n dy = ya.c2p(y[ids[i]]) - ypx;\n dxy = Math.sqrt(dx * dx + dy * dy);\n id = ids[i];\n }\n }\n } else {\n for(i = ids.length - 1; i > -1; i--) {\n ptx = x[ids[i]];\n pty = y[ids[i]];\n dx = xa.c2p(ptx) - xpx;\n dy = ya.c2p(pty) - ypx;\n\n dist = Math.sqrt(dx * dx + dy * dy);\n if(dist < minDist) {\n minDist = dxy = dist;\n id = ids[i];\n }\n }\n }\n\n pointData.index = id;\n pointData.distance = minDist;\n pointData.dxy = dxy;\n\n if(id === undefined) return [pointData];\n\n return [calcHover(pointData, x, y, trace)];\n}\n\nfunction calcHover(pointData, x, y, trace) {\n var xa = pointData.xa;\n var ya = pointData.ya;\n var minDist = pointData.distance;\n var dxy = pointData.dxy;\n var id = pointData.index;\n\n // the closest data point\n var di = {\n pointNumber: id,\n x: x[id],\n y: y[id]\n };\n\n // that is single-item arrays_to_calcdata excerpt, since we are doing it for a single point and we don't have to do it beforehead for 1e6 points\n di.tx = Array.isArray(trace.text) ? trace.text[id] : trace.text;\n di.htx = Array.isArray(trace.hovertext) ? trace.hovertext[id] : trace.hovertext;\n di.data = Array.isArray(trace.customdata) ? trace.customdata[id] : trace.customdata;\n di.tp = Array.isArray(trace.textposition) ? trace.textposition[id] : trace.textposition;\n\n var font = trace.textfont;\n if(font) {\n di.ts = Lib.isArrayOrTypedArray(font.size) ? font.size[id] : font.size;\n di.tc = Array.isArray(font.color) ? font.color[id] : font.color;\n di.tf = Array.isArray(font.family) ? font.family[id] : font.family;\n }\n\n var marker = trace.marker;\n if(marker) {\n di.ms = Lib.isArrayOrTypedArray(marker.size) ? marker.size[id] : marker.size;\n di.mo = Lib.isArrayOrTypedArray(marker.opacity) ? marker.opacity[id] : marker.opacity;\n di.mx = Lib.isArrayOrTypedArray(marker.symbol) ? marker.symbol[id] : marker.symbol;\n di.mc = Lib.isArrayOrTypedArray(marker.color) ? marker.color[id] : marker.color;\n }\n\n var line = marker && marker.line;\n if(line) {\n di.mlc = Array.isArray(line.color) ? line.color[id] : line.color;\n di.mlw = Lib.isArrayOrTypedArray(line.width) ? line.width[id] : line.width;\n }\n\n var grad = marker && marker.gradient;\n if(grad && grad.type !== 'none') {\n di.mgt = Array.isArray(grad.type) ? grad.type[id] : grad.type;\n di.mgc = Array.isArray(grad.color) ? grad.color[id] : grad.color;\n }\n\n var xp = xa.c2p(di.x, true);\n var yp = ya.c2p(di.y, true);\n var rad = di.mrc || 1;\n\n var hoverlabel = trace.hoverlabel;\n\n if(hoverlabel) {\n di.hbg = Array.isArray(hoverlabel.bgcolor) ? hoverlabel.bgcolor[id] : hoverlabel.bgcolor;\n di.hbc = Array.isArray(hoverlabel.bordercolor) ? hoverlabel.bordercolor[id] : hoverlabel.bordercolor;\n di.hts = Lib.isArrayOrTypedArray(hoverlabel.font.size) ? hoverlabel.font.size[id] : hoverlabel.font.size;\n di.htc = Array.isArray(hoverlabel.font.color) ? hoverlabel.font.color[id] : hoverlabel.font.color;\n di.htf = Array.isArray(hoverlabel.font.family) ? hoverlabel.font.family[id] : hoverlabel.font.family;\n di.hnl = Lib.isArrayOrTypedArray(hoverlabel.namelength) ? hoverlabel.namelength[id] : hoverlabel.namelength;\n }\n var hoverinfo = trace.hoverinfo;\n if(hoverinfo) {\n di.hi = Array.isArray(hoverinfo) ? hoverinfo[id] : hoverinfo;\n }\n\n var hovertemplate = trace.hovertemplate;\n if(hovertemplate) {\n di.ht = Array.isArray(hovertemplate) ? hovertemplate[id] : hovertemplate;\n }\n\n var fakeCd = {};\n fakeCd[pointData.index] = di;\n\n var pointData2 = Lib.extendFlat({}, pointData, {\n color: getTraceColor(trace, di),\n\n x0: xp - rad,\n x1: xp + rad,\n xLabelVal: di.x,\n\n y0: yp - rad,\n y1: yp + rad,\n yLabelVal: di.y,\n\n cd: fakeCd,\n distance: minDist,\n spikeDistance: dxy,\n\n hovertemplate: di.ht\n });\n\n if(di.htx) pointData2.text = di.htx;\n else if(di.tx) pointData2.text = di.tx;\n else if(trace.text) pointData2.text = trace.text;\n\n Lib.fillText(di, trace, pointData2);\n Registry.getComponentMethod('errorbars', 'hoverInfo')(di, trace, pointData2);\n\n return pointData2;\n}\n\nmodule.exports = {\n hoverPoints: hoverPoints,\n calcHover: calcHover\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergl/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergl/index.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergl/index.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar hover = __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/scattergl/hover.js\");\n\nmodule.exports = {\n moduleType: 'trace',\n name: 'scattergl',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['gl', 'regl', 'cartesian', 'symbols', 'errorBarsOK', 'showLegend', 'scatter-like'],\n\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scattergl/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/scattergl/defaults.js\"),\n crossTraceDefaults: __webpack_require__(/*! ../scatter/cross_trace_defaults */ \"./node_modules/plotly.js/src/traces/scatter/cross_trace_defaults.js\"),\n colorbar: __webpack_require__(/*! ../scatter/marker_colorbar */ \"./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js\"),\n formatLabels: __webpack_require__(/*! ./format_labels */ \"./node_modules/plotly.js/src/traces/scattergl/format_labels.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/scattergl/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/scattergl/plot.js\"),\n hoverPoints: hover.hoverPoints,\n selectPoints: __webpack_require__(/*! ./select */ \"./node_modules/plotly.js/src/traces/scattergl/select.js\"),\n\n meta: {\n \n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergl/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergl/plot.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergl/plot.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar createScatter = __webpack_require__(/*! regl-scatter2d */ \"./node_modules/regl-scatter2d/bundle.js\");\nvar createLine = __webpack_require__(/*! regl-line2d */ \"./node_modules/regl-line2d/index.js\");\nvar createError = __webpack_require__(/*! regl-error2d */ \"./node_modules/regl-error2d/index.js\");\nvar Text = __webpack_require__(/*! gl-text */ \"./node_modules/gl-text/dist.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar prepareRegl = __webpack_require__(/*! ../../lib/prepare_regl */ \"./node_modules/plotly.js/src/lib/prepare_regl.js\");\n\nvar subTypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar linkTraces = __webpack_require__(/*! ../scatter/link_traces */ \"./node_modules/plotly.js/src/traces/scatter/link_traces.js\");\n\nvar styleTextSelection = __webpack_require__(/*! ./edit_style */ \"./node_modules/plotly.js/src/traces/scattergl/edit_style.js\").styleTextSelection;\n\nfunction getViewport(fullLayout, xaxis, yaxis) {\n var gs = fullLayout._size;\n var width = fullLayout.width;\n var height = fullLayout.height;\n return [\n gs.l + xaxis.domain[0] * gs.w,\n gs.b + yaxis.domain[0] * gs.h,\n (width - gs.r) - (1 - xaxis.domain[1]) * gs.w,\n (height - gs.t) - (1 - yaxis.domain[1]) * gs.h\n ];\n}\n\nmodule.exports = function plot(gd, subplot, cdata) {\n if(!cdata.length) return;\n\n var fullLayout = gd._fullLayout;\n var scene = subplot._scene;\n var xaxis = subplot.xaxis;\n var yaxis = subplot.yaxis;\n var i, j;\n\n // we may have more subplots than initialized data due to Axes.getSubplots method\n if(!scene) return;\n\n var success = prepareRegl(gd, ['ANGLE_instanced_arrays', 'OES_element_index_uint']);\n if(!success) {\n scene.init();\n return;\n }\n\n var count = scene.count;\n var regl = fullLayout._glcanvas.data()[0].regl;\n\n // that is needed for fills\n linkTraces(gd, subplot, cdata);\n\n if(scene.dirty) {\n // make sure scenes are created\n if(scene.error2d === true) {\n scene.error2d = createError(regl);\n }\n if(scene.line2d === true) {\n scene.line2d = createLine(regl);\n }\n if(scene.scatter2d === true) {\n scene.scatter2d = createScatter(regl);\n }\n if(scene.fill2d === true) {\n scene.fill2d = createLine(regl);\n }\n if(scene.glText === true) {\n scene.glText = new Array(count);\n for(i = 0; i < count; i++) {\n scene.glText[i] = new Text(regl);\n }\n }\n\n // update main marker options\n if(scene.glText) {\n if(count > scene.glText.length) {\n // add gl text marker\n var textsToAdd = count - scene.glText.length;\n for(i = 0; i < textsToAdd; i++) {\n scene.glText.push(new Text(regl));\n }\n } else if(count < scene.glText.length) {\n // remove gl text marker\n var textsToRemove = scene.glText.length - count;\n var removedTexts = scene.glText.splice(count, textsToRemove);\n removedTexts.forEach(function(text) { text.destroy(); });\n }\n\n for(i = 0; i < count; i++) {\n scene.glText[i].update(scene.textOptions[i]);\n }\n }\n if(scene.line2d) {\n scene.line2d.update(scene.lineOptions);\n scene.lineOptions = scene.lineOptions.map(function(lineOptions) {\n if(lineOptions && lineOptions.positions) {\n var srcPos = lineOptions.positions;\n\n var firstptdef = 0;\n while(firstptdef < srcPos.length && (isNaN(srcPos[firstptdef]) || isNaN(srcPos[firstptdef + 1]))) {\n firstptdef += 2;\n }\n var lastptdef = srcPos.length - 2;\n while(lastptdef > firstptdef && (isNaN(srcPos[lastptdef]) || isNaN(srcPos[lastptdef + 1]))) {\n lastptdef -= 2;\n }\n lineOptions.positions = srcPos.slice(firstptdef, lastptdef + 2);\n }\n return lineOptions;\n });\n scene.line2d.update(scene.lineOptions);\n }\n if(scene.error2d) {\n var errorBatch = (scene.errorXOptions || []).concat(scene.errorYOptions || []);\n scene.error2d.update(errorBatch);\n }\n if(scene.scatter2d) {\n scene.scatter2d.update(scene.markerOptions);\n }\n\n // fill requires linked traces, so we generate it's positions here\n scene.fillOrder = Lib.repeat(null, count);\n if(scene.fill2d) {\n scene.fillOptions = scene.fillOptions.map(function(fillOptions, i) {\n var cdscatter = cdata[i];\n if(!fillOptions || !cdscatter || !cdscatter[0] || !cdscatter[0].trace) return;\n var cd = cdscatter[0];\n var trace = cd.trace;\n var stash = cd.t;\n var lineOptions = scene.lineOptions[i];\n var last, j;\n\n var fillData = [];\n if(trace._ownfill) fillData.push(i);\n if(trace._nexttrace) fillData.push(i + 1);\n if(fillData.length) scene.fillOrder[i] = fillData;\n\n var pos = [];\n var srcPos = (lineOptions && lineOptions.positions) || stash.positions;\n var firstptdef, lastptdef;\n\n if(trace.fill === 'tozeroy') {\n firstptdef = 0;\n while(firstptdef < srcPos.length && isNaN(srcPos[firstptdef + 1])) {\n firstptdef += 2;\n }\n lastptdef = srcPos.length - 2;\n while(lastptdef > firstptdef && isNaN(srcPos[lastptdef + 1])) {\n lastptdef -= 2;\n }\n if(srcPos[firstptdef + 1] !== 0) {\n pos = [srcPos[firstptdef], 0];\n }\n pos = pos.concat(srcPos.slice(firstptdef, lastptdef + 2));\n if(srcPos[lastptdef + 1] !== 0) {\n pos = pos.concat([srcPos[lastptdef], 0]);\n }\n } else if(trace.fill === 'tozerox') {\n firstptdef = 0;\n while(firstptdef < srcPos.length && isNaN(srcPos[firstptdef])) {\n firstptdef += 2;\n }\n lastptdef = srcPos.length - 2;\n while(lastptdef > firstptdef && isNaN(srcPos[lastptdef])) {\n lastptdef -= 2;\n }\n if(srcPos[firstptdef] !== 0) {\n pos = [0, srcPos[firstptdef + 1]];\n }\n pos = pos.concat(srcPos.slice(firstptdef, lastptdef + 2));\n if(srcPos[lastptdef] !== 0) {\n pos = pos.concat([ 0, srcPos[lastptdef + 1]]);\n }\n } else if(trace.fill === 'toself' || trace.fill === 'tonext') {\n pos = [];\n last = 0;\n for(j = 0; j < srcPos.length; j += 2) {\n if(isNaN(srcPos[j]) || isNaN(srcPos[j + 1])) {\n pos = pos.concat(srcPos.slice(last, j));\n pos.push(srcPos[last], srcPos[last + 1]);\n last = j + 2;\n }\n }\n pos = pos.concat(srcPos.slice(last));\n if(last) {\n pos.push(srcPos[last], srcPos[last + 1]);\n }\n } else {\n var nextTrace = trace._nexttrace;\n\n if(nextTrace) {\n var nextOptions = scene.lineOptions[i + 1];\n\n if(nextOptions) {\n var nextPos = nextOptions.positions;\n if(trace.fill === 'tonexty') {\n pos = srcPos.slice();\n\n for(i = Math.floor(nextPos.length / 2); i--;) {\n var xx = nextPos[i * 2];\n var yy = nextPos[i * 2 + 1];\n if(isNaN(xx) || isNaN(yy)) continue;\n pos.push(xx, yy);\n }\n fillOptions.fill = nextTrace.fillcolor;\n }\n }\n }\n }\n\n // detect prev trace positions to exclude from current fill\n if(trace._prevtrace && trace._prevtrace.fill === 'tonext') {\n var prevLinePos = scene.lineOptions[i - 1].positions;\n\n // FIXME: likely this logic should be tested better\n var offset = pos.length / 2;\n last = offset;\n var hole = [last];\n for(j = 0; j < prevLinePos.length; j += 2) {\n if(isNaN(prevLinePos[j]) || isNaN(prevLinePos[j + 1])) {\n hole.push(j / 2 + offset + 1);\n last = j + 2;\n }\n }\n\n pos = pos.concat(prevLinePos);\n fillOptions.hole = hole;\n }\n fillOptions.fillmode = trace.fill;\n fillOptions.opacity = trace.opacity;\n fillOptions.positions = pos;\n\n return fillOptions;\n });\n\n scene.fill2d.update(scene.fillOptions);\n }\n }\n\n // form batch arrays, and check for selected points\n var dragmode = fullLayout.dragmode;\n var selectMode = dragmode === 'lasso' || dragmode === 'select';\n var clickSelectEnabled = fullLayout.clickmode.indexOf('select') > -1;\n\n for(i = 0; i < count; i++) {\n var cd0 = cdata[i][0];\n var trace = cd0.trace;\n var stash = cd0.t;\n var index = stash.index;\n var len = trace._length;\n var x = stash.x;\n var y = stash.y;\n\n if(trace.selectedpoints || selectMode || clickSelectEnabled) {\n if(!selectMode) selectMode = true;\n\n // regenerate scene batch, if traces number changed during selection\n if(trace.selectedpoints) {\n var selPts = scene.selectBatch[index] = Lib.selIndices2selPoints(trace);\n\n var selDict = {};\n for(j = 0; j < selPts.length; j++) {\n selDict[selPts[j]] = 1;\n }\n var unselPts = [];\n for(j = 0; j < len; j++) {\n if(!selDict[j]) unselPts.push(j);\n }\n scene.unselectBatch[index] = unselPts;\n }\n\n // precalculate px coords since we are not going to pan during select\n // TODO, could do better here e.g.\n // - spin that in a webworker\n // - compute selection from polygons in data coordinates\n // (maybe just for linear axes)\n var xpx = stash.xpx = new Array(len);\n var ypx = stash.ypx = new Array(len);\n for(j = 0; j < len; j++) {\n xpx[j] = xaxis.c2p(x[j]);\n ypx[j] = yaxis.c2p(y[j]);\n }\n } else {\n stash.xpx = stash.ypx = null;\n }\n }\n\n if(selectMode) {\n // create scatter instance by cloning scatter2d\n if(!scene.select2d) {\n scene.select2d = createScatter(fullLayout._glcanvas.data()[1].regl);\n }\n\n // use unselected styles on 'context' canvas\n if(scene.scatter2d) {\n var unselOpts = new Array(count);\n for(i = 0; i < count; i++) {\n unselOpts[i] = scene.selectBatch[i].length || scene.unselectBatch[i].length ?\n scene.markerUnselectedOptions[i] :\n {};\n }\n scene.scatter2d.update(unselOpts);\n }\n\n // use selected style on 'focus' canvas\n if(scene.select2d) {\n scene.select2d.update(scene.markerOptions);\n scene.select2d.update(scene.markerSelectedOptions);\n }\n\n if(scene.glText) {\n cdata.forEach(function(cdscatter) {\n var trace = ((cdscatter || [])[0] || {}).trace || {};\n if(subTypes.hasText(trace)) {\n styleTextSelection(cdscatter);\n }\n });\n }\n } else {\n // reset 'context' scatter2d opts to base opts,\n // thus unsetting markerUnselectedOptions from selection\n if(scene.scatter2d) {\n scene.scatter2d.update(scene.markerOptions);\n }\n }\n\n // provide viewport and range\n var vpRange0 = {\n viewport: getViewport(fullLayout, xaxis, yaxis),\n // TODO do we need those fallbacks?\n range: [\n (xaxis._rl || xaxis.range)[0],\n (yaxis._rl || yaxis.range)[0],\n (xaxis._rl || xaxis.range)[1],\n (yaxis._rl || yaxis.range)[1]\n ]\n };\n var vpRange = Lib.repeat(vpRange0, scene.count);\n\n // upload viewport/range data to GPU\n if(scene.fill2d) {\n scene.fill2d.update(vpRange);\n }\n if(scene.line2d) {\n scene.line2d.update(vpRange);\n }\n if(scene.error2d) {\n scene.error2d.update(vpRange.concat(vpRange));\n }\n if(scene.scatter2d) {\n scene.scatter2d.update(vpRange);\n }\n if(scene.select2d) {\n scene.select2d.update(vpRange);\n }\n if(scene.glText) {\n scene.glText.forEach(function(text) { text.update(vpRange0); });\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergl/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergl/scene_update.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergl/scene_update.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\n// make sure scene exists on subplot, return it\nmodule.exports = function sceneUpdate(gd, subplot) {\n var scene = subplot._scene;\n\n var resetOpts = {\n // number of traces in subplot, since scene:subplot -> 1:1\n count: 0,\n // whether scene requires init hook in plot call (dirty plot call)\n dirty: true,\n // last used options\n lineOptions: [],\n fillOptions: [],\n markerOptions: [],\n markerSelectedOptions: [],\n markerUnselectedOptions: [],\n errorXOptions: [],\n errorYOptions: [],\n textOptions: [],\n textSelectedOptions: [],\n textUnselectedOptions: [],\n // selection batches\n selectBatch: [],\n unselectBatch: []\n };\n\n // regl- component stubs, initialized in dirty plot call\n var initOpts = {\n fill2d: false,\n scatter2d: false,\n error2d: false,\n line2d: false,\n glText: false,\n select2d: false\n };\n\n if(!subplot._scene) {\n scene = subplot._scene = {};\n\n scene.init = function init() {\n Lib.extendFlat(scene, initOpts, resetOpts);\n };\n\n scene.init();\n\n // apply new option to all regl components (used on drag)\n scene.update = function update(opt) {\n var opts = Lib.repeat(opt, scene.count);\n\n if(scene.fill2d) scene.fill2d.update(opts);\n if(scene.scatter2d) scene.scatter2d.update(opts);\n if(scene.line2d) scene.line2d.update(opts);\n if(scene.error2d) scene.error2d.update(opts.concat(opts));\n if(scene.select2d) scene.select2d.update(opts);\n if(scene.glText) {\n for(var i = 0; i < scene.count; i++) {\n scene.glText[i].update(opt);\n }\n }\n };\n\n // draw traces in proper order\n scene.draw = function draw() {\n var count = scene.count;\n var fill2d = scene.fill2d;\n var error2d = scene.error2d;\n var line2d = scene.line2d;\n var scatter2d = scene.scatter2d;\n var glText = scene.glText;\n var select2d = scene.select2d;\n var selectBatch = scene.selectBatch;\n var unselectBatch = scene.unselectBatch;\n\n for(var i = 0; i < count; i++) {\n if(fill2d && scene.fillOrder[i]) {\n fill2d.draw(scene.fillOrder[i]);\n }\n if(line2d && scene.lineOptions[i]) {\n line2d.draw(i);\n }\n if(error2d) {\n if(scene.errorXOptions[i]) error2d.draw(i);\n if(scene.errorYOptions[i]) error2d.draw(i + count);\n }\n if(scatter2d && scene.markerOptions[i]) {\n if(unselectBatch[i].length) {\n var arg = Lib.repeat([], scene.count);\n arg[i] = unselectBatch[i];\n scatter2d.draw(arg);\n } else if(!selectBatch[i].length) {\n scatter2d.draw(i);\n }\n }\n if(glText[i] && scene.textOptions[i]) {\n glText[i].render();\n }\n }\n\n if(select2d) {\n select2d.draw(selectBatch);\n }\n\n scene.dirty = false;\n };\n\n // remove scene resources\n scene.destroy = function destroy() {\n if(scene.fill2d && scene.fill2d.destroy) scene.fill2d.destroy();\n if(scene.scatter2d && scene.scatter2d.destroy) scene.scatter2d.destroy();\n if(scene.error2d && scene.error2d.destroy) scene.error2d.destroy();\n if(scene.line2d && scene.line2d.destroy) scene.line2d.destroy();\n if(scene.select2d && scene.select2d.destroy) scene.select2d.destroy();\n if(scene.glText) {\n scene.glText.forEach(function(text) {\n if(text.destroy) text.destroy();\n });\n }\n\n scene.lineOptions = null;\n scene.fillOptions = null;\n scene.markerOptions = null;\n scene.markerSelectedOptions = null;\n scene.markerUnselectedOptions = null;\n scene.errorXOptions = null;\n scene.errorYOptions = null;\n scene.textOptions = null;\n scene.textSelectedOptions = null;\n scene.textUnselectedOptions = null;\n\n scene.selectBatch = null;\n scene.unselectBatch = null;\n\n // we can't just delete _scene, because `destroy` is called in the\n // middle of supplyDefaults, before relinkPrivateKeys which will put it back.\n subplot._scene = null;\n };\n }\n\n // in case if we have scene from the last calc - reset data\n if(!scene.dirty) {\n Lib.extendFlat(scene, resetOpts);\n }\n\n return scene;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergl/scene_update.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattergl/select.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattergl/select.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar subTypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar styleTextSelection = __webpack_require__(/*! ./edit_style */ \"./node_modules/plotly.js/src/traces/scattergl/edit_style.js\").styleTextSelection;\n\nmodule.exports = function select(searchInfo, selectionTester) {\n var cd = searchInfo.cd;\n var selection = [];\n var trace = cd[0].trace;\n var stash = cd[0].t;\n var len = trace._length;\n var x = stash.x;\n var y = stash.y;\n var scene = stash._scene;\n var index = stash.index;\n\n if(!scene) return selection;\n\n var hasText = subTypes.hasText(trace);\n var hasMarkers = subTypes.hasMarkers(trace);\n var hasOnlyLines = !hasMarkers && !hasText;\n\n if(trace.visible !== true || hasOnlyLines) return selection;\n\n var els = [];\n var unels = [];\n\n // degenerate polygon does not enable selection\n // filter out points by visible scatter ones\n if(selectionTester !== false && !selectionTester.degenerate) {\n for(var i = 0; i < len; i++) {\n if(selectionTester.contains([stash.xpx[i], stash.ypx[i]], false, i, searchInfo)) {\n els.push(i);\n selection.push({\n pointNumber: i,\n x: x[i],\n y: y[i]\n });\n } else {\n unels.push(i);\n }\n }\n }\n\n if(hasMarkers) {\n var scatter2d = scene.scatter2d;\n\n if(!els.length && !unels.length) {\n // reset to base styles when clearing\n var baseOpts = new Array(scene.count);\n baseOpts[index] = scene.markerOptions[index];\n scatter2d.update.apply(scatter2d, baseOpts);\n } else if(!scene.selectBatch[index].length && !scene.unselectBatch[index].length) {\n // set unselected styles on 'context' canvas (if not done already)\n var unselOpts = new Array(scene.count);\n unselOpts[index] = scene.markerUnselectedOptions[index];\n scatter2d.update.apply(scatter2d, unselOpts);\n }\n }\n\n scene.selectBatch[index] = els;\n scene.unselectBatch[index] = unels;\n\n if(hasText) {\n styleTextSelection(cd);\n }\n\n return selection;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattergl/select.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattermapbox/attributes.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattermapbox/attributes.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar texttemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").texttemplateAttrs;\nvar scatterGeoAttrs = __webpack_require__(/*! ../scattergeo/attributes */ \"./node_modules/plotly.js/src/traces/scattergeo/attributes.js\");\nvar scatterAttrs = __webpack_require__(/*! ../scatter/attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\");\nvar mapboxAttrs = __webpack_require__(/*! ../../plots/mapbox/layout_attributes */ \"./node_modules/plotly.js/src/plots/mapbox/layout_attributes.js\");\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar overrideAll = __webpack_require__(/*! ../../plot_api/edit_types */ \"./node_modules/plotly.js/src/plot_api/edit_types.js\").overrideAll;\n\nvar lineAttrs = scatterGeoAttrs.line;\nvar markerAttrs = scatterGeoAttrs.marker;\n\nmodule.exports = overrideAll({\n lon: scatterGeoAttrs.lon,\n lat: scatterGeoAttrs.lat,\n\n // locations\n // locationmode\n\n mode: extendFlat({}, scatterAttrs.mode, {\n dflt: 'markers',\n \n }),\n\n text: extendFlat({}, scatterAttrs.text, {\n \n }),\n texttemplate: texttemplateAttrs({editType: 'plot'}, {\n keys: ['lat', 'lon', 'text']\n }),\n hovertext: extendFlat({}, scatterAttrs.hovertext, {\n \n }),\n\n line: {\n color: lineAttrs.color,\n width: lineAttrs.width\n\n // TODO\n // dash: dash\n },\n\n connectgaps: scatterAttrs.connectgaps,\n\n marker: extendFlat({\n symbol: {\n valType: 'string',\n dflt: 'circle',\n \n arrayOk: true,\n \n },\n opacity: markerAttrs.opacity,\n size: markerAttrs.size,\n sizeref: markerAttrs.sizeref,\n sizemin: markerAttrs.sizemin,\n sizemode: markerAttrs.sizemode\n },\n colorScaleAttrs('marker')\n // line\n ),\n\n fill: scatterGeoAttrs.fill,\n fillcolor: scatterAttrs.fillcolor,\n\n textfont: mapboxAttrs.layers.symbol.textfont,\n textposition: mapboxAttrs.layers.symbol.textposition,\n\n below: {\n valType: 'string',\n \n \n },\n\n selected: {\n marker: scatterAttrs.selected.marker\n },\n unselected: {\n marker: scatterAttrs.unselected.marker\n },\n\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {\n flags: ['lon', 'lat', 'text', 'name']\n }),\n hovertemplate: hovertemplateAttrs(),\n}, 'calc', 'nested');\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattermapbox/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattermapbox/convert.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattermapbox/convert.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\nvar geoJsonUtils = __webpack_require__(/*! ../../lib/geojson_utils */ \"./node_modules/plotly.js/src/lib/geojson_utils.js\");\n\nvar Colorscale = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar makeBubbleSizeFn = __webpack_require__(/*! ../scatter/make_bubble_size_func */ \"./node_modules/plotly.js/src/traces/scatter/make_bubble_size_func.js\");\nvar subTypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar convertTextOpts = __webpack_require__(/*! ../../plots/mapbox/convert_text_opts */ \"./node_modules/plotly.js/src/plots/mapbox/convert_text_opts.js\");\nvar appendArrayPointValue = __webpack_require__(/*! ../../components/fx/helpers */ \"./node_modules/plotly.js/src/components/fx/helpers.js\").appendArrayPointValue;\n\nvar NEWLINES = __webpack_require__(/*! ../../lib/svg_text_utils */ \"./node_modules/plotly.js/src/lib/svg_text_utils.js\").NEWLINES;\nvar BR_TAG_ALL = __webpack_require__(/*! ../../lib/svg_text_utils */ \"./node_modules/plotly.js/src/lib/svg_text_utils.js\").BR_TAG_ALL;\n\nmodule.exports = function convert(gd, calcTrace) {\n var trace = calcTrace[0].trace;\n\n var isVisible = (trace.visible === true && trace._length !== 0);\n var hasFill = (trace.fill !== 'none');\n var hasLines = subTypes.hasLines(trace);\n var hasMarkers = subTypes.hasMarkers(trace);\n var hasText = subTypes.hasText(trace);\n var hasCircles = (hasMarkers && trace.marker.symbol === 'circle');\n var hasSymbols = (hasMarkers && trace.marker.symbol !== 'circle');\n\n var fill = initContainer();\n var line = initContainer();\n var circle = initContainer();\n var symbol = initContainer();\n\n var opts = {\n fill: fill,\n line: line,\n circle: circle,\n symbol: symbol\n };\n\n // early return if not visible or placeholder\n if(!isVisible) return opts;\n\n // fill layer and line layer use the same coords\n var lineCoords;\n if(hasFill || hasLines) {\n lineCoords = geoJsonUtils.calcTraceToLineCoords(calcTrace);\n }\n\n if(hasFill) {\n fill.geojson = geoJsonUtils.makePolygon(lineCoords);\n fill.layout.visibility = 'visible';\n\n Lib.extendFlat(fill.paint, {\n 'fill-color': trace.fillcolor\n });\n }\n\n if(hasLines) {\n line.geojson = geoJsonUtils.makeLine(lineCoords);\n line.layout.visibility = 'visible';\n\n Lib.extendFlat(line.paint, {\n 'line-width': trace.line.width,\n 'line-color': trace.line.color,\n 'line-opacity': trace.opacity\n });\n\n // TODO convert line.dash into line-dasharray\n }\n\n if(hasCircles) {\n var circleOpts = makeCircleOpts(calcTrace);\n circle.geojson = circleOpts.geojson;\n circle.layout.visibility = 'visible';\n\n Lib.extendFlat(circle.paint, {\n 'circle-color': circleOpts.mcc,\n 'circle-radius': circleOpts.mrc,\n 'circle-opacity': circleOpts.mo\n });\n }\n\n if(hasSymbols || hasText) {\n symbol.geojson = makeSymbolGeoJSON(calcTrace, gd);\n\n Lib.extendFlat(symbol.layout, {\n visibility: 'visible',\n 'icon-image': '{symbol}-15',\n 'text-field': '{text}'\n });\n\n if(hasSymbols) {\n Lib.extendFlat(symbol.layout, {\n 'icon-size': trace.marker.size / 10\n });\n\n Lib.extendFlat(symbol.paint, {\n 'icon-opacity': trace.opacity * trace.marker.opacity,\n\n // TODO does not work ??\n 'icon-color': trace.marker.color\n });\n }\n\n if(hasText) {\n var iconSize = (trace.marker || {}).size;\n var textOpts = convertTextOpts(trace.textposition, iconSize);\n\n // all data-driven below !!\n\n Lib.extendFlat(symbol.layout, {\n 'text-size': trace.textfont.size,\n 'text-anchor': textOpts.anchor,\n 'text-offset': textOpts.offset\n\n // TODO font family\n // 'text-font': symbol.textfont.family.split(', '),\n });\n\n Lib.extendFlat(symbol.paint, {\n 'text-color': trace.textfont.color,\n 'text-opacity': trace.opacity\n });\n }\n }\n\n return opts;\n};\n\nfunction initContainer() {\n return {\n geojson: geoJsonUtils.makeBlank(),\n layout: { visibility: 'none' },\n paint: {}\n };\n}\n\nfunction makeCircleOpts(calcTrace) {\n var trace = calcTrace[0].trace;\n var marker = trace.marker;\n var selectedpoints = trace.selectedpoints;\n var arrayColor = Lib.isArrayOrTypedArray(marker.color);\n var arraySize = Lib.isArrayOrTypedArray(marker.size);\n var arrayOpacity = Lib.isArrayOrTypedArray(marker.opacity);\n var i;\n\n function addTraceOpacity(o) { return trace.opacity * o; }\n\n function size2radius(s) { return s / 2; }\n\n var colorFn;\n if(arrayColor) {\n if(Colorscale.hasColorscale(trace, 'marker')) {\n colorFn = Colorscale.makeColorScaleFuncFromTrace(marker);\n } else {\n colorFn = Lib.identity;\n }\n }\n\n var sizeFn;\n if(arraySize) {\n sizeFn = makeBubbleSizeFn(trace);\n }\n\n var opacityFn;\n if(arrayOpacity) {\n opacityFn = function(mo) {\n var mo2 = isNumeric(mo) ? +Lib.constrain(mo, 0, 1) : 0;\n return addTraceOpacity(mo2);\n };\n }\n\n var features = [];\n for(i = 0; i < calcTrace.length; i++) {\n var calcPt = calcTrace[i];\n var lonlat = calcPt.lonlat;\n\n if(isBADNUM(lonlat)) continue;\n\n var props = {};\n if(colorFn) props.mcc = calcPt.mcc = colorFn(calcPt.mc);\n if(sizeFn) props.mrc = calcPt.mrc = sizeFn(calcPt.ms);\n if(opacityFn) props.mo = opacityFn(calcPt.mo);\n if(selectedpoints) props.selected = calcPt.selected || 0;\n\n features.push({\n type: 'Feature',\n geometry: {type: 'Point', coordinates: lonlat},\n properties: props\n });\n }\n\n var fns;\n if(selectedpoints) {\n fns = Drawing.makeSelectedPointStyleFns(trace);\n\n for(i = 0; i < features.length; i++) {\n var d = features[i].properties;\n\n if(fns.selectedOpacityFn) {\n d.mo = addTraceOpacity(fns.selectedOpacityFn(d));\n }\n if(fns.selectedColorFn) {\n d.mcc = fns.selectedColorFn(d);\n }\n if(fns.selectedSizeFn) {\n d.mrc = fns.selectedSizeFn(d);\n }\n }\n }\n\n return {\n geojson: {type: 'FeatureCollection', features: features},\n mcc: arrayColor || (fns && fns.selectedColorFn) ?\n {type: 'identity', property: 'mcc'} :\n marker.color,\n mrc: arraySize || (fns && fns.selectedSizeFn) ?\n {type: 'identity', property: 'mrc'} :\n size2radius(marker.size),\n mo: arrayOpacity || (fns && fns.selectedOpacityFn) ?\n {type: 'identity', property: 'mo'} :\n addTraceOpacity(marker.opacity)\n };\n}\n\nfunction makeSymbolGeoJSON(calcTrace, gd) {\n var fullLayout = gd._fullLayout;\n var trace = calcTrace[0].trace;\n\n var marker = trace.marker || {};\n var symbol = marker.symbol;\n\n var fillSymbol = (symbol !== 'circle') ?\n getFillFunc(symbol) :\n blankFillFunc;\n\n var fillText = subTypes.hasText(trace) ?\n getFillFunc(trace.text) :\n blankFillFunc;\n\n var features = [];\n\n for(var i = 0; i < calcTrace.length; i++) {\n var calcPt = calcTrace[i];\n\n if(isBADNUM(calcPt.lonlat)) continue;\n\n var texttemplate = trace.texttemplate;\n var text;\n\n if(texttemplate) {\n var tt = Array.isArray(texttemplate) ? (texttemplate[i] || '') : texttemplate;\n var labels = trace._module.formatLabels(calcPt, trace, fullLayout);\n var pointValues = {};\n appendArrayPointValue(pointValues, trace, calcPt.i);\n var meta = trace._meta || {};\n text = Lib.texttemplateString(tt, labels, fullLayout._d3locale, pointValues, calcPt, meta);\n } else {\n text = fillText(calcPt.tx);\n }\n\n if(text) {\n text = text.replace(NEWLINES, '').replace(BR_TAG_ALL, '\\n');\n }\n\n features.push({\n type: 'Feature',\n geometry: {\n type: 'Point',\n coordinates: calcPt.lonlat\n },\n properties: {\n symbol: fillSymbol(calcPt.mx),\n text: text\n }\n });\n }\n\n return {\n type: 'FeatureCollection',\n features: features\n };\n}\n\nfunction getFillFunc(attr) {\n if(Lib.isArrayOrTypedArray(attr)) {\n return function(v) { return v; };\n } else if(attr) {\n return function() { return attr; };\n } else {\n return blankFillFunc;\n }\n}\n\nfunction blankFillFunc() { return ''; }\n\n// only need to check lon (OR lat)\nfunction isBADNUM(lonlat) {\n return lonlat[0] === BADNUM;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattermapbox/convert.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattermapbox/defaults.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattermapbox/defaults.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar subTypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar handleMarkerDefaults = __webpack_require__(/*! ../scatter/marker_defaults */ \"./node_modules/plotly.js/src/traces/scatter/marker_defaults.js\");\nvar handleLineDefaults = __webpack_require__(/*! ../scatter/line_defaults */ \"./node_modules/plotly.js/src/traces/scatter/line_defaults.js\");\nvar handleTextDefaults = __webpack_require__(/*! ../scatter/text_defaults */ \"./node_modules/plotly.js/src/traces/scatter/text_defaults.js\");\nvar handleFillColorDefaults = __webpack_require__(/*! ../scatter/fillcolor_defaults */ \"./node_modules/plotly.js/src/traces/scatter/fillcolor_defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scattermapbox/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var len = handleLonLatDefaults(traceIn, traceOut, coerce);\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n coerce('text');\n coerce('texttemplate');\n coerce('hovertext');\n coerce('hovertemplate');\n coerce('mode');\n coerce('below');\n\n if(subTypes.hasLines(traceOut)) {\n handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce, {noDash: true});\n coerce('connectgaps');\n }\n\n if(subTypes.hasMarkers(traceOut)) {\n handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {noLine: true});\n\n // array marker.size and marker.color are only supported with circles\n var marker = traceOut.marker;\n if(marker.symbol !== 'circle') {\n if(Lib.isArrayOrTypedArray(marker.size)) marker.size = marker.size[0];\n if(Lib.isArrayOrTypedArray(marker.color)) marker.color = marker.color[0];\n }\n }\n\n if(subTypes.hasText(traceOut)) {\n handleTextDefaults(traceIn, traceOut, layout, coerce, {noSelect: true});\n }\n\n coerce('fill');\n if(traceOut.fill !== 'none') {\n handleFillColorDefaults(traceIn, traceOut, defaultColor, coerce);\n }\n\n Lib.coerceSelectionMarkerOpacity(traceOut, coerce);\n};\n\nfunction handleLonLatDefaults(traceIn, traceOut, coerce) {\n var lon = coerce('lon') || [];\n var lat = coerce('lat') || [];\n var len = Math.min(lon.length, lat.length);\n traceOut._length = len;\n\n return len;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattermapbox/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattermapbox/event_data.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattermapbox/event_data.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\n\nmodule.exports = function eventData(out, pt) {\n out.lon = pt.lon;\n out.lat = pt.lat;\n\n return out;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattermapbox/event_data.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattermapbox/format_labels.js":
-/*!**************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattermapbox/format_labels.js ***!
- \**************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\n\nmodule.exports = function formatLabels(cdi, trace, fullLayout) {\n var labels = {};\n\n var subplot = fullLayout[trace.subplot]._subplot;\n var ax = subplot.mockAxis;\n\n var lonlat = cdi.lonlat;\n labels.lonLabel = Axes.tickText(ax, ax.c2l(lonlat[0]), true).text;\n labels.latLabel = Axes.tickText(ax, ax.c2l(lonlat[1]), true).text;\n\n return labels;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattermapbox/format_labels.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattermapbox/hover.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattermapbox/hover.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Fx = __webpack_require__(/*! ../../components/fx */ \"./node_modules/plotly.js/src/components/fx/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar getTraceColor = __webpack_require__(/*! ../scatter/get_trace_color */ \"./node_modules/plotly.js/src/traces/scatter/get_trace_color.js\");\nvar fillText = Lib.fillText;\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nmodule.exports = function hoverPoints(pointData, xval, yval) {\n var cd = pointData.cd;\n var trace = cd[0].trace;\n var xa = pointData.xa;\n var ya = pointData.ya;\n var subplot = pointData.subplot;\n\n // compute winding number about [-180, 180] globe\n var winding = (xval >= 0) ?\n Math.floor((xval + 180) / 360) :\n Math.ceil((xval - 180) / 360);\n\n // shift longitude to [-180, 180] to determine closest point\n var lonShift = winding * 360;\n var xval2 = xval - lonShift;\n\n function distFn(d) {\n var lonlat = d.lonlat;\n if(lonlat[0] === BADNUM) return Infinity;\n\n var lon = Lib.modHalf(lonlat[0], 360);\n var lat = lonlat[1];\n var pt = subplot.project([lon, lat]);\n var dx = pt.x - xa.c2p([xval2, lat]);\n var dy = pt.y - ya.c2p([lon, yval]);\n var rad = Math.max(3, d.mrc || 0);\n\n return Math.max(Math.sqrt(dx * dx + dy * dy) - rad, 1 - 3 / rad);\n }\n\n Fx.getClosest(cd, distFn, pointData);\n\n // skip the rest (for this trace) if we didn't find a close point\n if(pointData.index === false) return;\n\n var di = cd[pointData.index];\n var lonlat = di.lonlat;\n var lonlatShifted = [Lib.modHalf(lonlat[0], 360) + lonShift, lonlat[1]];\n\n // shift labels back to original winded globe\n var xc = xa.c2p(lonlatShifted);\n var yc = ya.c2p(lonlatShifted);\n var rad = di.mrc || 1;\n\n pointData.x0 = xc - rad;\n pointData.x1 = xc + rad;\n pointData.y0 = yc - rad;\n pointData.y1 = yc + rad;\n\n var fullLayout = {};\n fullLayout[trace.subplot] = {_subplot: subplot};\n var labels = trace._module.formatLabels(di, trace, fullLayout);\n pointData.lonLabel = labels.lonLabel;\n pointData.latLabel = labels.latLabel;\n\n pointData.color = getTraceColor(trace, di);\n pointData.extraText = getExtraText(trace, di, cd[0].t.labels);\n pointData.hovertemplate = trace.hovertemplate;\n\n return [pointData];\n};\n\nfunction getExtraText(trace, di, labels) {\n if(trace.hovertemplate) return;\n\n var hoverinfo = di.hi || trace.hoverinfo;\n var parts = hoverinfo.split('+');\n var isAll = parts.indexOf('all') !== -1;\n var hasLon = parts.indexOf('lon') !== -1;\n var hasLat = parts.indexOf('lat') !== -1;\n var lonlat = di.lonlat;\n var text = [];\n\n // TODO should we use a mock axis to format hover?\n // If so, we'll need to make precision be zoom-level dependent\n function format(v) {\n return v + '\\u00B0';\n }\n\n if(isAll || (hasLon && hasLat)) {\n text.push('(' + format(lonlat[0]) + ', ' + format(lonlat[1]) + ')');\n } else if(hasLon) {\n text.push(labels.lon + format(lonlat[0]));\n } else if(hasLat) {\n text.push(labels.lat + format(lonlat[1]));\n }\n\n if(isAll || parts.indexOf('text') !== -1) {\n fillText(di, trace, text);\n }\n\n return text.join('
');\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattermapbox/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattermapbox/index.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattermapbox/index.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scattermapbox/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/scattermapbox/defaults.js\"),\n colorbar: __webpack_require__(/*! ../scatter/marker_colorbar */ \"./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js\"),\n formatLabels: __webpack_require__(/*! ./format_labels */ \"./node_modules/plotly.js/src/traces/scattermapbox/format_labels.js\"),\n calc: __webpack_require__(/*! ../scattergeo/calc */ \"./node_modules/plotly.js/src/traces/scattergeo/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/scattermapbox/plot.js\"),\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/scattermapbox/hover.js\"),\n eventData: __webpack_require__(/*! ./event_data */ \"./node_modules/plotly.js/src/traces/scattermapbox/event_data.js\"),\n selectPoints: __webpack_require__(/*! ./select */ \"./node_modules/plotly.js/src/traces/scattermapbox/select.js\"),\n\n styleOnSelect: function(_, cd) {\n if(cd) {\n var trace = cd[0].trace;\n trace._glTrace.update(cd);\n }\n },\n\n moduleType: 'trace',\n name: 'scattermapbox',\n basePlotModule: __webpack_require__(/*! ../../plots/mapbox */ \"./node_modules/plotly.js/src/plots/mapbox/index.js\"),\n categories: ['mapbox', 'gl', 'symbols', 'showLegend', 'scatter-like'],\n meta: {\n \n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattermapbox/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattermapbox/plot.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattermapbox/plot.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar convert = __webpack_require__(/*! ./convert */ \"./node_modules/plotly.js/src/traces/scattermapbox/convert.js\");\nvar LAYER_PREFIX = __webpack_require__(/*! ../../plots/mapbox/constants */ \"./node_modules/plotly.js/src/plots/mapbox/constants.js\").traceLayerPrefix;\nvar ORDER = ['fill', 'line', 'circle', 'symbol'];\n\nfunction ScatterMapbox(subplot, uid) {\n this.type = 'scattermapbox';\n this.subplot = subplot;\n this.uid = uid;\n\n this.sourceIds = {\n fill: 'source-' + uid + '-fill',\n line: 'source-' + uid + '-line',\n circle: 'source-' + uid + '-circle',\n symbol: 'source-' + uid + '-symbol'\n };\n\n this.layerIds = {\n fill: LAYER_PREFIX + uid + '-fill',\n line: LAYER_PREFIX + uid + '-line',\n circle: LAYER_PREFIX + uid + '-circle',\n symbol: LAYER_PREFIX + uid + '-symbol'\n };\n\n // We could merge the 'fill' source with the 'line' source and\n // the 'circle' source with the 'symbol' source if ever having\n // for up-to 4 sources per 'scattermapbox' traces becomes a problem.\n\n // previous 'below' value,\n // need this to update it properly\n this.below = null;\n}\n\nvar proto = ScatterMapbox.prototype;\n\nproto.addSource = function(k, opts) {\n this.subplot.map.addSource(this.sourceIds[k], {\n type: 'geojson',\n data: opts.geojson\n });\n};\n\nproto.setSourceData = function(k, opts) {\n this.subplot.map\n .getSource(this.sourceIds[k])\n .setData(opts.geojson);\n};\n\nproto.addLayer = function(k, opts, below) {\n this.subplot.addLayer({\n type: k,\n id: this.layerIds[k],\n source: this.sourceIds[k],\n layout: opts.layout,\n paint: opts.paint\n }, below);\n};\n\nproto.update = function update(calcTrace) {\n var subplot = this.subplot;\n var map = subplot.map;\n var optsAll = convert(subplot.gd, calcTrace);\n var below = subplot.belowLookup['trace-' + this.uid];\n var i, k, opts;\n\n if(below !== this.below) {\n for(i = ORDER.length - 1; i >= 0; i--) {\n k = ORDER[i];\n map.removeLayer(this.layerIds[k]);\n }\n for(i = 0; i < ORDER.length; i++) {\n k = ORDER[i];\n opts = optsAll[k];\n this.addLayer(k, opts, below);\n }\n this.below = below;\n }\n\n for(i = 0; i < ORDER.length; i++) {\n k = ORDER[i];\n opts = optsAll[k];\n\n subplot.setOptions(this.layerIds[k], 'setLayoutProperty', opts.layout);\n\n if(opts.layout.visibility === 'visible') {\n this.setSourceData(k, opts);\n subplot.setOptions(this.layerIds[k], 'setPaintProperty', opts.paint);\n }\n }\n\n // link ref for quick update during selections\n calcTrace[0].trace._glTrace = this;\n};\n\nproto.dispose = function dispose() {\n var map = this.subplot.map;\n\n for(var i = ORDER.length - 1; i >= 0; i--) {\n var k = ORDER[i];\n map.removeLayer(this.layerIds[k]);\n map.removeSource(this.sourceIds[k]);\n }\n};\n\nmodule.exports = function createScatterMapbox(subplot, calcTrace) {\n var trace = calcTrace[0].trace;\n var scatterMapbox = new ScatterMapbox(subplot, trace.uid);\n var optsAll = convert(subplot.gd, calcTrace);\n var below = scatterMapbox.below = subplot.belowLookup['trace-' + trace.uid];\n\n for(var i = 0; i < ORDER.length; i++) {\n var k = ORDER[i];\n var opts = optsAll[k];\n scatterMapbox.addSource(k, opts);\n scatterMapbox.addLayer(k, opts, below);\n }\n\n // link ref for quick update during selections\n calcTrace[0].trace._glTrace = scatterMapbox;\n\n return scatterMapbox;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattermapbox/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scattermapbox/select.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scattermapbox/select.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar subtypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nmodule.exports = function selectPoints(searchInfo, selectionTester) {\n var cd = searchInfo.cd;\n var xa = searchInfo.xaxis;\n var ya = searchInfo.yaxis;\n var selection = [];\n var trace = cd[0].trace;\n var i;\n\n if(!subtypes.hasMarkers(trace)) return [];\n\n if(selectionTester === false) {\n for(i = 0; i < cd.length; i++) {\n cd[i].selected = 0;\n }\n } else {\n for(i = 0; i < cd.length; i++) {\n var di = cd[i];\n var lonlat = di.lonlat;\n\n if(lonlat[0] !== BADNUM) {\n var lonlat2 = [Lib.modHalf(lonlat[0], 360), lonlat[1]];\n var xy = [xa.c2p(lonlat2), ya.c2p(lonlat2)];\n\n if(selectionTester.contains(xy, null, i, searchInfo)) {\n selection.push({\n pointNumber: i,\n lon: lonlat[0],\n lat: lonlat[1]\n });\n di.selected = 1;\n } else {\n di.selected = 0;\n }\n }\n }\n }\n\n return selection;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scattermapbox/select.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterpolar/attributes.js":
-/*!**********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterpolar/attributes.js ***!
- \**********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar texttemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").texttemplateAttrs;\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar scatterAttrs = __webpack_require__(/*! ../scatter/attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\");\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar lineAttrs = scatterAttrs.line;\n\nmodule.exports = {\n mode: scatterAttrs.mode,\n\n r: {\n valType: 'data_array',\n editType: 'calc+clearAxisTypes',\n \n },\n\n theta: {\n valType: 'data_array',\n editType: 'calc+clearAxisTypes',\n \n },\n\n r0: {\n valType: 'any',\n dflt: 0,\n \n editType: 'calc+clearAxisTypes',\n \n },\n dr: {\n valType: 'number',\n dflt: 1,\n \n editType: 'calc',\n \n },\n\n theta0: {\n valType: 'any',\n dflt: 0,\n \n editType: 'calc+clearAxisTypes',\n \n },\n dtheta: {\n valType: 'number',\n \n editType: 'calc',\n \n },\n\n thetaunit: {\n valType: 'enumerated',\n values: ['radians', 'degrees', 'gradians'],\n dflt: 'degrees',\n \n editType: 'calc+clearAxisTypes',\n \n },\n\n text: scatterAttrs.text,\n texttemplate: texttemplateAttrs({editType: 'plot'}, {\n keys: ['r', 'theta', 'text']\n }),\n hovertext: scatterAttrs.hovertext,\n\n line: {\n color: lineAttrs.color,\n width: lineAttrs.width,\n dash: lineAttrs.dash,\n shape: extendFlat({}, lineAttrs.shape, {\n values: ['linear', 'spline']\n }),\n smoothing: lineAttrs.smoothing,\n editType: 'calc'\n },\n connectgaps: scatterAttrs.connectgaps,\n\n marker: scatterAttrs.marker,\n cliponaxis: extendFlat({}, scatterAttrs.cliponaxis, {dflt: false}),\n\n textposition: scatterAttrs.textposition,\n textfont: scatterAttrs.textfont,\n\n fill: extendFlat({}, scatterAttrs.fill, {\n values: ['none', 'toself', 'tonext'],\n dflt: 'none',\n \n }),\n fillcolor: scatterAttrs.fillcolor,\n\n // TODO error bars\n // https://stackoverflow.com/a/26597487/4068492\n // error_x (error_r, error_theta)\n // error_y\n\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {\n flags: ['r', 'theta', 'text', 'name']\n }),\n hoveron: scatterAttrs.hoveron,\n hovertemplate: hovertemplateAttrs(),\n\n selected: scatterAttrs.selected,\n unselected: scatterAttrs.unselected\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterpolar/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterpolar/calc.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterpolar/calc.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\n\nvar calcColorscale = __webpack_require__(/*! ../scatter/colorscale_calc */ \"./node_modules/plotly.js/src/traces/scatter/colorscale_calc.js\");\nvar arraysToCalcdata = __webpack_require__(/*! ../scatter/arrays_to_calcdata */ \"./node_modules/plotly.js/src/traces/scatter/arrays_to_calcdata.js\");\nvar calcSelection = __webpack_require__(/*! ../scatter/calc_selection */ \"./node_modules/plotly.js/src/traces/scatter/calc_selection.js\");\nvar calcMarkerSize = __webpack_require__(/*! ../scatter/calc */ \"./node_modules/plotly.js/src/traces/scatter/calc.js\").calcMarkerSize;\n\nmodule.exports = function calc(gd, trace) {\n var fullLayout = gd._fullLayout;\n var subplotId = trace.subplot;\n var radialAxis = fullLayout[subplotId].radialaxis;\n var angularAxis = fullLayout[subplotId].angularaxis;\n var rArray = radialAxis.makeCalcdata(trace, 'r');\n var thetaArray = angularAxis.makeCalcdata(trace, 'theta');\n var len = trace._length;\n var cd = new Array(len);\n\n for(var i = 0; i < len; i++) {\n var r = rArray[i];\n var theta = thetaArray[i];\n var cdi = cd[i] = {};\n\n if(isNumeric(r) && isNumeric(theta)) {\n cdi.r = r;\n cdi.theta = theta;\n } else {\n cdi.r = BADNUM;\n }\n }\n\n var ppad = calcMarkerSize(trace, len);\n trace._extremes.x = Axes.findExtremes(radialAxis, rArray, {ppad: ppad});\n\n calcColorscale(gd, trace);\n arraysToCalcdata(cd, trace);\n calcSelection(cd, trace);\n\n return cd;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterpolar/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterpolar/defaults.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterpolar/defaults.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar subTypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar handleMarkerDefaults = __webpack_require__(/*! ../scatter/marker_defaults */ \"./node_modules/plotly.js/src/traces/scatter/marker_defaults.js\");\nvar handleLineDefaults = __webpack_require__(/*! ../scatter/line_defaults */ \"./node_modules/plotly.js/src/traces/scatter/line_defaults.js\");\nvar handleLineShapeDefaults = __webpack_require__(/*! ../scatter/line_shape_defaults */ \"./node_modules/plotly.js/src/traces/scatter/line_shape_defaults.js\");\nvar handleTextDefaults = __webpack_require__(/*! ../scatter/text_defaults */ \"./node_modules/plotly.js/src/traces/scatter/text_defaults.js\");\nvar handleFillColorDefaults = __webpack_require__(/*! ../scatter/fillcolor_defaults */ \"./node_modules/plotly.js/src/traces/scatter/fillcolor_defaults.js\");\nvar PTS_LINESONLY = __webpack_require__(/*! ../scatter/constants */ \"./node_modules/plotly.js/src/traces/scatter/constants.js\").PTS_LINESONLY;\n\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scatterpolar/attributes.js\");\n\nfunction supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var len = handleRThetaDefaults(traceIn, traceOut, layout, coerce);\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n coerce('thetaunit');\n coerce('mode', len < PTS_LINESONLY ? 'lines+markers' : 'lines');\n coerce('text');\n coerce('hovertext');\n if(traceOut.hoveron !== 'fills') coerce('hovertemplate');\n\n if(subTypes.hasLines(traceOut)) {\n handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);\n handleLineShapeDefaults(traceIn, traceOut, coerce);\n coerce('connectgaps');\n }\n\n if(subTypes.hasMarkers(traceOut)) {\n handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});\n }\n\n if(subTypes.hasText(traceOut)) {\n coerce('texttemplate');\n handleTextDefaults(traceIn, traceOut, layout, coerce);\n }\n\n var dfltHoverOn = [];\n\n if(subTypes.hasMarkers(traceOut) || subTypes.hasText(traceOut)) {\n coerce('cliponaxis');\n coerce('marker.maxdisplayed');\n dfltHoverOn.push('points');\n }\n\n coerce('fill');\n\n if(traceOut.fill !== 'none') {\n handleFillColorDefaults(traceIn, traceOut, defaultColor, coerce);\n if(!subTypes.hasLines(traceOut)) handleLineShapeDefaults(traceIn, traceOut, coerce);\n }\n\n if(traceOut.fill === 'tonext' || traceOut.fill === 'toself') {\n dfltHoverOn.push('fills');\n }\n coerce('hoveron', dfltHoverOn.join('+') || 'points');\n\n Lib.coerceSelectionMarkerOpacity(traceOut, coerce);\n}\n\nfunction handleRThetaDefaults(traceIn, traceOut, layout, coerce) {\n var r = coerce('r');\n var theta = coerce('theta');\n var len;\n\n if(r) {\n if(theta) {\n len = Math.min(r.length, theta.length);\n } else {\n len = r.length;\n coerce('theta0');\n coerce('dtheta');\n }\n } else {\n if(!theta) return 0;\n len = traceOut.theta.length;\n coerce('r0');\n coerce('dr');\n }\n\n traceOut._length = len;\n return len;\n}\n\nmodule.exports = {\n handleRThetaDefaults: handleRThetaDefaults,\n supplyDefaults: supplyDefaults\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterpolar/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterpolar/format_labels.js":
-/*!*************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterpolar/format_labels.js ***!
- \*************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\n\nmodule.exports = function formatLabels(cdi, trace, fullLayout) {\n var labels = {};\n\n var subplot = fullLayout[trace.subplot]._subplot;\n var radialAxis;\n var angularAxis;\n\n // for scatterpolargl texttemplate, _subplot is NOT defined, this takes part during the convert step\n // TODO we should consider moving the texttemplate formatting logic to the plot step\n if(!subplot) {\n subplot = fullLayout[trace.subplot];\n radialAxis = subplot.radialaxis;\n angularAxis = subplot.angularaxis;\n } else {\n radialAxis = subplot.radialAxis;\n angularAxis = subplot.angularAxis;\n }\n\n var rVal = radialAxis.c2l(cdi.r);\n labels.rLabel = Axes.tickText(radialAxis, rVal, true).text;\n\n // N.B here the ° sign is part of the formatted value for thetaunit:'degrees'\n var thetaVal = angularAxis.thetaunit === 'degrees' ? Lib.rad2deg(cdi.theta) : cdi.theta;\n labels.thetaLabel = Axes.tickText(angularAxis, thetaVal, true).text;\n\n return labels;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterpolar/format_labels.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterpolar/hover.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterpolar/hover.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar scatterHover = __webpack_require__(/*! ../scatter/hover */ \"./node_modules/plotly.js/src/traces/scatter/hover.js\");\n\nfunction hoverPoints(pointData, xval, yval, hovermode) {\n var scatterPointData = scatterHover(pointData, xval, yval, hovermode);\n if(!scatterPointData || scatterPointData[0].index === false) return;\n\n var newPointData = scatterPointData[0];\n\n // hovering on fill case\n if(newPointData.index === undefined) {\n return scatterPointData;\n }\n\n var subplot = pointData.subplot;\n var cdi = newPointData.cd[newPointData.index];\n var trace = newPointData.trace;\n\n if(!subplot.isPtInside(cdi)) return;\n\n newPointData.xLabelVal = undefined;\n newPointData.yLabelVal = undefined;\n makeHoverPointText(cdi, trace, subplot, newPointData);\n newPointData.hovertemplate = trace.hovertemplate;\n return scatterPointData;\n}\n\nfunction makeHoverPointText(cdi, trace, subplot, pointData) {\n var radialAxis = subplot.radialAxis;\n var angularAxis = subplot.angularAxis;\n radialAxis._hovertitle = 'r';\n angularAxis._hovertitle = 'θ';\n\n var fullLayout = {};\n fullLayout[trace.subplot] = {_subplot: subplot};\n var labels = trace._module.formatLabels(cdi, trace, fullLayout);\n pointData.rLabel = labels.rLabel;\n pointData.thetaLabel = labels.thetaLabel;\n\n var hoverinfo = cdi.hi || trace.hoverinfo;\n var text = [];\n function textPart(ax, val) {\n text.push(ax._hovertitle + ': ' + val);\n }\n\n if(!trace.hovertemplate) {\n var parts = hoverinfo.split('+');\n\n if(parts.indexOf('all') !== -1) parts = ['r', 'theta', 'text'];\n if(parts.indexOf('r') !== -1) textPart(radialAxis, pointData.rLabel);\n if(parts.indexOf('theta') !== -1) textPart(angularAxis, pointData.thetaLabel);\n\n if(parts.indexOf('text') !== -1 && pointData.text) {\n text.push(pointData.text);\n delete pointData.text;\n }\n\n pointData.extraText = text.join('
');\n }\n}\n\nmodule.exports = {\n hoverPoints: hoverPoints,\n makeHoverPointText: makeHoverPointText\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterpolar/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterpolar/index.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterpolar/index.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n moduleType: 'trace',\n name: 'scatterpolar',\n basePlotModule: __webpack_require__(/*! ../../plots/polar */ \"./node_modules/plotly.js/src/plots/polar/index.js\"),\n categories: ['polar', 'symbols', 'showLegend', 'scatter-like'],\n\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scatterpolar/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/scatterpolar/defaults.js\").supplyDefaults,\n colorbar: __webpack_require__(/*! ../scatter/marker_colorbar */ \"./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js\"),\n formatLabels: __webpack_require__(/*! ./format_labels */ \"./node_modules/plotly.js/src/traces/scatterpolar/format_labels.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/scatterpolar/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/scatterpolar/plot.js\"),\n style: __webpack_require__(/*! ../scatter/style */ \"./node_modules/plotly.js/src/traces/scatter/style.js\").style,\n styleOnSelect: __webpack_require__(/*! ../scatter/style */ \"./node_modules/plotly.js/src/traces/scatter/style.js\").styleOnSelect,\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/scatterpolar/hover.js\").hoverPoints,\n selectPoints: __webpack_require__(/*! ../scatter/select */ \"./node_modules/plotly.js/src/traces/scatter/select.js\"),\n\n meta: {\n \n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterpolar/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterpolar/plot.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterpolar/plot.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar scatterPlot = __webpack_require__(/*! ../scatter/plot */ \"./node_modules/plotly.js/src/traces/scatter/plot.js\");\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nmodule.exports = function plot(gd, subplot, moduleCalcData) {\n var mlayer = subplot.layers.frontplot.select('g.scatterlayer');\n\n var plotinfo = {\n xaxis: subplot.xaxis,\n yaxis: subplot.yaxis,\n plot: subplot.framework,\n layerClipId: subplot._hasClipOnAxisFalse ? subplot.clipIds.forTraces : null\n };\n\n var radialAxis = subplot.radialAxis;\n var angularAxis = subplot.angularAxis;\n\n // convert:\n // 'c' (r,theta) -> 'geometric' (r,theta) -> (x,y)\n for(var i = 0; i < moduleCalcData.length; i++) {\n var cdi = moduleCalcData[i];\n\n for(var j = 0; j < cdi.length; j++) {\n var cd = cdi[j];\n var r = cd.r;\n\n if(r === BADNUM) {\n cd.x = cd.y = BADNUM;\n } else {\n var rg = radialAxis.c2g(r);\n var thetag = angularAxis.c2g(cd.theta);\n cd.x = rg * Math.cos(thetag);\n cd.y = rg * Math.sin(thetag);\n }\n }\n }\n\n scatterPlot(gd, plotinfo, moduleCalcData, mlayer);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterpolar/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterpolargl/attributes.js":
-/*!************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterpolargl/attributes.js ***!
- \************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar scatterPolarAttrs = __webpack_require__(/*! ../scatterpolar/attributes */ \"./node_modules/plotly.js/src/traces/scatterpolar/attributes.js\");\nvar scatterGlAttrs = __webpack_require__(/*! ../scattergl/attributes */ \"./node_modules/plotly.js/src/traces/scattergl/attributes.js\");\nvar texttemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").texttemplateAttrs;\n\nmodule.exports = {\n mode: scatterPolarAttrs.mode,\n r: scatterPolarAttrs.r,\n theta: scatterPolarAttrs.theta,\n r0: scatterPolarAttrs.r0,\n dr: scatterPolarAttrs.dr,\n theta0: scatterPolarAttrs.theta0,\n dtheta: scatterPolarAttrs.dtheta,\n thetaunit: scatterPolarAttrs.thetaunit,\n\n text: scatterPolarAttrs.text,\n texttemplate: texttemplateAttrs({editType: 'plot'}, {\n keys: ['r', 'theta', 'text']\n }),\n hovertext: scatterPolarAttrs.hovertext,\n hovertemplate: scatterPolarAttrs.hovertemplate,\n\n line: scatterGlAttrs.line,\n connectgaps: scatterGlAttrs.connectgaps,\n\n marker: scatterGlAttrs.marker,\n // no cliponaxis\n\n fill: scatterGlAttrs.fill,\n fillcolor: scatterGlAttrs.fillcolor,\n\n textposition: scatterGlAttrs.textposition,\n textfont: scatterGlAttrs.textfont,\n\n hoverinfo: scatterPolarAttrs.hoverinfo,\n // no hoveron\n\n selected: scatterPolarAttrs.selected,\n unselected: scatterPolarAttrs.unselected\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterpolargl/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterpolargl/calc.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterpolargl/calc.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar calcColorscale = __webpack_require__(/*! ../scatter/colorscale_calc */ \"./node_modules/plotly.js/src/traces/scatter/colorscale_calc.js\");\nvar calcMarkerSize = __webpack_require__(/*! ../scatter/calc */ \"./node_modules/plotly.js/src/traces/scatter/calc.js\").calcMarkerSize;\nvar convert = __webpack_require__(/*! ../scattergl/convert */ \"./node_modules/plotly.js/src/traces/scattergl/convert.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar TOO_MANY_POINTS = __webpack_require__(/*! ../scattergl/constants */ \"./node_modules/plotly.js/src/traces/scattergl/constants.js\").TOO_MANY_POINTS;\n\nmodule.exports = function calc(gd, trace) {\n var fullLayout = gd._fullLayout;\n var subplotId = trace.subplot;\n var radialAxis = fullLayout[subplotId].radialaxis;\n var angularAxis = fullLayout[subplotId].angularaxis;\n var rArray = trace._r = radialAxis.makeCalcdata(trace, 'r');\n var thetaArray = trace._theta = angularAxis.makeCalcdata(trace, 'theta');\n var len = trace._length;\n var stash = {};\n\n if(len < rArray.length) rArray = rArray.slice(0, len);\n if(len < thetaArray.length) thetaArray = thetaArray.slice(0, len);\n\n stash.r = rArray;\n stash.theta = thetaArray;\n\n calcColorscale(gd, trace);\n\n // only compute 'style' options in calc, as position options\n // depend on the radial range and must be set in plot\n var opts = stash.opts = convert.style(gd, trace);\n\n // For graphs with very large number of points and array marker.size,\n // use average marker size instead to speed things up.\n var ppad;\n if(len < TOO_MANY_POINTS) {\n ppad = calcMarkerSize(trace, len);\n } else if(opts.marker) {\n ppad = 2 * (opts.marker.sizeAvg || Math.max(opts.marker.size, 3));\n }\n trace._extremes.x = Axes.findExtremes(radialAxis, rArray, {ppad: ppad});\n\n return [{x: false, y: false, t: stash, trace: trace}];\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterpolargl/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterpolargl/defaults.js":
-/*!**********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterpolargl/defaults.js ***!
- \**********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar subTypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar handleRThetaDefaults = __webpack_require__(/*! ../scatterpolar/defaults */ \"./node_modules/plotly.js/src/traces/scatterpolar/defaults.js\").handleRThetaDefaults;\nvar handleMarkerDefaults = __webpack_require__(/*! ../scatter/marker_defaults */ \"./node_modules/plotly.js/src/traces/scatter/marker_defaults.js\");\nvar handleLineDefaults = __webpack_require__(/*! ../scatter/line_defaults */ \"./node_modules/plotly.js/src/traces/scatter/line_defaults.js\");\nvar handleTextDefaults = __webpack_require__(/*! ../scatter/text_defaults */ \"./node_modules/plotly.js/src/traces/scatter/text_defaults.js\");\nvar handleFillColorDefaults = __webpack_require__(/*! ../scatter/fillcolor_defaults */ \"./node_modules/plotly.js/src/traces/scatter/fillcolor_defaults.js\");\nvar PTS_LINESONLY = __webpack_require__(/*! ../scatter/constants */ \"./node_modules/plotly.js/src/traces/scatter/constants.js\").PTS_LINESONLY;\n\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scatterpolargl/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var len = handleRThetaDefaults(traceIn, traceOut, layout, coerce);\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n coerce('thetaunit');\n coerce('mode', len < PTS_LINESONLY ? 'lines+markers' : 'lines');\n coerce('text');\n coerce('hovertext');\n if(traceOut.hoveron !== 'fills') coerce('hovertemplate');\n\n if(subTypes.hasLines(traceOut)) {\n handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);\n coerce('connectgaps');\n }\n\n if(subTypes.hasMarkers(traceOut)) {\n handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce);\n }\n\n if(subTypes.hasText(traceOut)) {\n coerce('texttemplate');\n handleTextDefaults(traceIn, traceOut, layout, coerce);\n }\n\n coerce('fill');\n if(traceOut.fill !== 'none') {\n handleFillColorDefaults(traceIn, traceOut, defaultColor, coerce);\n }\n\n Lib.coerceSelectionMarkerOpacity(traceOut, coerce);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterpolargl/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterpolargl/format_labels.js":
-/*!***************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterpolargl/format_labels.js ***!
- \***************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar scatterPolarFormatLabels = __webpack_require__(/*! ../scatterpolar/format_labels */ \"./node_modules/plotly.js/src/traces/scatterpolar/format_labels.js\");\n\nmodule.exports = function formatLabels(cdi, trace, fullLayout) {\n var i = cdi.i;\n if(!('r' in cdi)) cdi.r = trace._r[i];\n if(!('theta' in cdi)) cdi.theta = trace._theta[i];\n return scatterPolarFormatLabels(cdi, trace, fullLayout);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterpolargl/format_labels.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterpolargl/hover.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterpolargl/hover.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar hover = __webpack_require__(/*! ../scattergl/hover */ \"./node_modules/plotly.js/src/traces/scattergl/hover.js\");\nvar makeHoverPointText = __webpack_require__(/*! ../scatterpolar/hover */ \"./node_modules/plotly.js/src/traces/scatterpolar/hover.js\").makeHoverPointText;\n\nfunction hoverPoints(pointData, xval, yval, hovermode) {\n var cd = pointData.cd;\n var stash = cd[0].t;\n var rArray = stash.r;\n var thetaArray = stash.theta;\n\n var scatterPointData = hover.hoverPoints(pointData, xval, yval, hovermode);\n if(!scatterPointData || scatterPointData[0].index === false) return;\n\n var newPointData = scatterPointData[0];\n\n if(newPointData.index === undefined) {\n return scatterPointData;\n }\n\n var subplot = pointData.subplot;\n var cdi = newPointData.cd[newPointData.index];\n var trace = newPointData.trace;\n\n // augment pointData with r/theta param\n cdi.r = rArray[newPointData.index];\n cdi.theta = thetaArray[newPointData.index];\n\n if(!subplot.isPtInside(cdi)) return;\n\n newPointData.xLabelVal = undefined;\n newPointData.yLabelVal = undefined;\n makeHoverPointText(cdi, trace, subplot, newPointData);\n\n return scatterPointData;\n}\n\nmodule.exports = {\n hoverPoints: hoverPoints\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterpolargl/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterpolargl/index.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterpolargl/index.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n moduleType: 'trace',\n name: 'scatterpolargl',\n basePlotModule: __webpack_require__(/*! ../../plots/polar */ \"./node_modules/plotly.js/src/plots/polar/index.js\"),\n categories: ['gl', 'regl', 'polar', 'symbols', 'showLegend', 'scatter-like'],\n\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scatterpolargl/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/scatterpolargl/defaults.js\"),\n colorbar: __webpack_require__(/*! ../scatter/marker_colorbar */ \"./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js\"),\n formatLabels: __webpack_require__(/*! ./format_labels */ \"./node_modules/plotly.js/src/traces/scatterpolargl/format_labels.js\"),\n\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/scatterpolargl/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/scatterpolargl/plot.js\"),\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/scatterpolargl/hover.js\").hoverPoints,\n selectPoints: __webpack_require__(/*! ../scattergl/select */ \"./node_modules/plotly.js/src/traces/scattergl/select.js\"),\n\n meta: {\n \n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterpolargl/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterpolargl/plot.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterpolargl/plot.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar cluster = __webpack_require__(/*! point-cluster */ \"./node_modules/point-cluster/index.js\");\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\nvar scatterglPlot = __webpack_require__(/*! ../scattergl/plot */ \"./node_modules/plotly.js/src/traces/scattergl/plot.js\");\nvar sceneUpdate = __webpack_require__(/*! ../scattergl/scene_update */ \"./node_modules/plotly.js/src/traces/scattergl/scene_update.js\");\nvar convert = __webpack_require__(/*! ../scattergl/convert */ \"./node_modules/plotly.js/src/traces/scattergl/convert.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar TOO_MANY_POINTS = __webpack_require__(/*! ../scattergl/constants */ \"./node_modules/plotly.js/src/traces/scattergl/constants.js\").TOO_MANY_POINTS;\n\nmodule.exports = function plot(gd, subplot, cdata) {\n if(!cdata.length) return;\n\n var radialAxis = subplot.radialAxis;\n var angularAxis = subplot.angularAxis;\n var scene = sceneUpdate(gd, subplot);\n\n cdata.forEach(function(cdscatter) {\n if(!cdscatter || !cdscatter[0] || !cdscatter[0].trace) return;\n var cd = cdscatter[0];\n var trace = cd.trace;\n var stash = cd.t;\n var len = trace._length;\n var rArray = stash.r;\n var thetaArray = stash.theta;\n var opts = stash.opts;\n var i;\n\n var subRArray = rArray.slice();\n var subThetaArray = thetaArray.slice();\n\n // filter out by range\n for(i = 0; i < rArray.length; i++) {\n if(!subplot.isPtInside({r: rArray[i], theta: thetaArray[i]})) {\n subRArray[i] = NaN;\n subThetaArray[i] = NaN;\n }\n }\n\n var positions = new Array(len * 2);\n var x = Array(len);\n var y = Array(len);\n\n for(i = 0; i < len; i++) {\n var r = subRArray[i];\n var xx, yy;\n\n if(isNumeric(r)) {\n var rg = radialAxis.c2g(r);\n var thetag = angularAxis.c2g(subThetaArray[i], trace.thetaunit);\n xx = rg * Math.cos(thetag);\n yy = rg * Math.sin(thetag);\n } else {\n xx = yy = NaN;\n }\n x[i] = positions[i * 2] = xx;\n y[i] = positions[i * 2 + 1] = yy;\n }\n\n stash.tree = cluster(positions);\n\n // FIXME: see scattergl.js#109\n if(opts.marker && len >= TOO_MANY_POINTS) {\n opts.marker.cluster = stash.tree;\n }\n\n if(opts.marker) {\n opts.markerSel.positions = opts.markerUnsel.positions = opts.marker.positions = positions;\n }\n\n if(opts.line && positions.length > 1) {\n Lib.extendFlat(\n opts.line,\n convert.linePositions(gd, trace, positions)\n );\n }\n\n if(opts.text) {\n Lib.extendFlat(\n opts.text,\n {positions: positions},\n convert.textPosition(gd, trace, opts.text, opts.marker)\n );\n Lib.extendFlat(\n opts.textSel,\n {positions: positions},\n convert.textPosition(gd, trace, opts.text, opts.markerSel)\n );\n Lib.extendFlat(\n opts.textUnsel,\n {positions: positions},\n convert.textPosition(gd, trace, opts.text, opts.markerUnsel)\n );\n }\n\n if(opts.fill && !scene.fill2d) scene.fill2d = true;\n if(opts.marker && !scene.scatter2d) scene.scatter2d = true;\n if(opts.line && !scene.line2d) scene.line2d = true;\n if(opts.text && !scene.glText) scene.glText = true;\n\n scene.lineOptions.push(opts.line);\n scene.fillOptions.push(opts.fill);\n scene.markerOptions.push(opts.marker);\n scene.markerSelectedOptions.push(opts.markerSel);\n scene.markerUnselectedOptions.push(opts.markerUnsel);\n scene.textOptions.push(opts.text);\n scene.textSelectedOptions.push(opts.textSel);\n scene.textUnselectedOptions.push(opts.textUnsel);\n scene.selectBatch.push([]);\n scene.unselectBatch.push([]);\n\n stash.x = x;\n stash.y = y;\n stash.rawx = x;\n stash.rawy = y;\n stash.r = rArray;\n stash.theta = thetaArray;\n stash.positions = positions;\n stash._scene = scene;\n stash.index = scene.count;\n scene.count++;\n });\n\n return scatterglPlot(gd, subplot, cdata);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterpolargl/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterternary/attributes.js":
-/*!************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterternary/attributes.js ***!
- \************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar texttemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").texttemplateAttrs;\nvar scatterAttrs = __webpack_require__(/*! ../scatter/attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\");\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar dash = __webpack_require__(/*! ../../components/drawing/attributes */ \"./node_modules/plotly.js/src/components/drawing/attributes.js\").dash;\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nvar scatterMarkerAttrs = scatterAttrs.marker;\nvar scatterLineAttrs = scatterAttrs.line;\nvar scatterMarkerLineAttrs = scatterMarkerAttrs.line;\n\nmodule.exports = {\n a: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n b: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n c: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n sum: {\n valType: 'number',\n \n dflt: 0,\n min: 0,\n editType: 'calc',\n \n },\n mode: extendFlat({}, scatterAttrs.mode, {dflt: 'markers'}),\n text: extendFlat({}, scatterAttrs.text, {\n \n }),\n texttemplate: texttemplateAttrs({editType: 'plot'}, {\n keys: ['a', 'b', 'c', 'text']\n }),\n hovertext: extendFlat({}, scatterAttrs.hovertext, {\n \n }),\n line: {\n color: scatterLineAttrs.color,\n width: scatterLineAttrs.width,\n dash: dash,\n shape: extendFlat({}, scatterLineAttrs.shape,\n {values: ['linear', 'spline']}),\n smoothing: scatterLineAttrs.smoothing,\n editType: 'calc'\n },\n connectgaps: scatterAttrs.connectgaps,\n cliponaxis: scatterAttrs.cliponaxis,\n fill: extendFlat({}, scatterAttrs.fill, {\n values: ['none', 'toself', 'tonext'],\n dflt: 'none',\n \n }),\n fillcolor: scatterAttrs.fillcolor,\n marker: extendFlat({\n symbol: scatterMarkerAttrs.symbol,\n opacity: scatterMarkerAttrs.opacity,\n maxdisplayed: scatterMarkerAttrs.maxdisplayed,\n size: scatterMarkerAttrs.size,\n sizeref: scatterMarkerAttrs.sizeref,\n sizemin: scatterMarkerAttrs.sizemin,\n sizemode: scatterMarkerAttrs.sizemode,\n line: extendFlat({\n width: scatterMarkerLineAttrs.width,\n editType: 'calc'\n },\n colorScaleAttrs('marker.line')\n ),\n gradient: scatterMarkerAttrs.gradient,\n editType: 'calc'\n },\n colorScaleAttrs('marker')\n ),\n\n textfont: scatterAttrs.textfont,\n textposition: scatterAttrs.textposition,\n\n selected: scatterAttrs.selected,\n unselected: scatterAttrs.unselected,\n\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {\n flags: ['a', 'b', 'c', 'text', 'name']\n }),\n hoveron: scatterAttrs.hoveron,\n hovertemplate: hovertemplateAttrs(),\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterternary/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterternary/calc.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterternary/calc.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\nvar calcColorscale = __webpack_require__(/*! ../scatter/colorscale_calc */ \"./node_modules/plotly.js/src/traces/scatter/colorscale_calc.js\");\nvar arraysToCalcdata = __webpack_require__(/*! ../scatter/arrays_to_calcdata */ \"./node_modules/plotly.js/src/traces/scatter/arrays_to_calcdata.js\");\nvar calcSelection = __webpack_require__(/*! ../scatter/calc_selection */ \"./node_modules/plotly.js/src/traces/scatter/calc_selection.js\");\nvar calcMarkerSize = __webpack_require__(/*! ../scatter/calc */ \"./node_modules/plotly.js/src/traces/scatter/calc.js\").calcMarkerSize;\n\nvar dataArrays = ['a', 'b', 'c'];\nvar arraysToFill = {a: ['b', 'c'], b: ['a', 'c'], c: ['a', 'b']};\n\nmodule.exports = function calc(gd, trace) {\n var ternary = gd._fullLayout[trace.subplot];\n var displaySum = ternary.sum;\n var normSum = trace.sum || displaySum;\n var arrays = {a: trace.a, b: trace.b, c: trace.c};\n\n var i, j, dataArray, newArray, fillArray1, fillArray2;\n\n // fill in one missing component\n for(i = 0; i < dataArrays.length; i++) {\n dataArray = dataArrays[i];\n if(arrays[dataArray]) continue;\n\n fillArray1 = arrays[arraysToFill[dataArray][0]];\n fillArray2 = arrays[arraysToFill[dataArray][1]];\n newArray = new Array(fillArray1.length);\n for(j = 0; j < fillArray1.length; j++) {\n newArray[j] = normSum - fillArray1[j] - fillArray2[j];\n }\n arrays[dataArray] = newArray;\n }\n\n // make the calcdata array\n var serieslen = trace._length;\n var cd = new Array(serieslen);\n var a, b, c, norm, x, y;\n for(i = 0; i < serieslen; i++) {\n a = arrays.a[i];\n b = arrays.b[i];\n c = arrays.c[i];\n if(isNumeric(a) && isNumeric(b) && isNumeric(c)) {\n a = +a;\n b = +b;\n c = +c;\n norm = displaySum / (a + b + c);\n if(norm !== 1) {\n a *= norm;\n b *= norm;\n c *= norm;\n }\n // map a, b, c onto x and y where the full scale of y\n // is [0, sum], and x is [-sum, sum]\n // TODO: this makes `a` always the top, `b` the bottom left,\n // and `c` the bottom right. Do we want options to rearrange\n // these?\n y = a;\n x = c - b;\n cd[i] = {x: x, y: y, a: a, b: b, c: c};\n } else cd[i] = {x: false, y: false};\n }\n\n calcMarkerSize(trace, serieslen);\n calcColorscale(gd, trace);\n arraysToCalcdata(cd, trace);\n calcSelection(cd, trace);\n\n return cd;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterternary/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterternary/defaults.js":
-/*!**********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterternary/defaults.js ***!
- \**********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar constants = __webpack_require__(/*! ../scatter/constants */ \"./node_modules/plotly.js/src/traces/scatter/constants.js\");\nvar subTypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar handleMarkerDefaults = __webpack_require__(/*! ../scatter/marker_defaults */ \"./node_modules/plotly.js/src/traces/scatter/marker_defaults.js\");\nvar handleLineDefaults = __webpack_require__(/*! ../scatter/line_defaults */ \"./node_modules/plotly.js/src/traces/scatter/line_defaults.js\");\nvar handleLineShapeDefaults = __webpack_require__(/*! ../scatter/line_shape_defaults */ \"./node_modules/plotly.js/src/traces/scatter/line_shape_defaults.js\");\nvar handleTextDefaults = __webpack_require__(/*! ../scatter/text_defaults */ \"./node_modules/plotly.js/src/traces/scatter/text_defaults.js\");\nvar handleFillColorDefaults = __webpack_require__(/*! ../scatter/fillcolor_defaults */ \"./node_modules/plotly.js/src/traces/scatter/fillcolor_defaults.js\");\n\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scatterternary/attributes.js\");\n\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var a = coerce('a');\n var b = coerce('b');\n var c = coerce('c');\n var len;\n\n // allow any one array to be missing, len is the minimum length of those\n // present. Note that after coerce data_array's are either Arrays (which\n // are truthy even if empty) or undefined. As in scatter, an empty array\n // is different from undefined, because it can signify that this data is\n // not known yet but expected in the future\n if(a) {\n len = a.length;\n if(b) {\n len = Math.min(len, b.length);\n if(c) len = Math.min(len, c.length);\n } else if(c) len = Math.min(len, c.length);\n else len = 0;\n } else if(b && c) {\n len = Math.min(b.length, c.length);\n }\n\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n traceOut._length = len;\n\n coerce('sum');\n\n coerce('text');\n coerce('hovertext');\n if(traceOut.hoveron !== 'fills') coerce('hovertemplate');\n\n var defaultMode = len < constants.PTS_LINESONLY ? 'lines+markers' : 'lines';\n coerce('mode', defaultMode);\n\n if(subTypes.hasLines(traceOut)) {\n handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);\n handleLineShapeDefaults(traceIn, traceOut, coerce);\n coerce('connectgaps');\n }\n\n if(subTypes.hasMarkers(traceOut)) {\n handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});\n }\n\n if(subTypes.hasText(traceOut)) {\n coerce('texttemplate');\n handleTextDefaults(traceIn, traceOut, layout, coerce);\n }\n\n var dfltHoverOn = [];\n\n if(subTypes.hasMarkers(traceOut) || subTypes.hasText(traceOut)) {\n coerce('cliponaxis');\n coerce('marker.maxdisplayed');\n dfltHoverOn.push('points');\n }\n\n coerce('fill');\n if(traceOut.fill !== 'none') {\n handleFillColorDefaults(traceIn, traceOut, defaultColor, coerce);\n if(!subTypes.hasLines(traceOut)) handleLineShapeDefaults(traceIn, traceOut, coerce);\n }\n\n if(traceOut.fill === 'tonext' || traceOut.fill === 'toself') {\n dfltHoverOn.push('fills');\n }\n coerce('hoveron', dfltHoverOn.join('+') || 'points');\n\n Lib.coerceSelectionMarkerOpacity(traceOut, coerce);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterternary/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterternary/event_data.js":
-/*!************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterternary/event_data.js ***!
- \************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function eventData(out, pt, trace, cd, pointNumber) {\n if(pt.xa) out.xaxis = pt.xa;\n if(pt.ya) out.yaxis = pt.ya;\n\n if(cd[pointNumber]) {\n var cdi = cd[pointNumber];\n\n // N.B. These are the normalized coordinates.\n out.a = cdi.a;\n out.b = cdi.b;\n out.c = cdi.c;\n } else {\n // for fill-hover only\n out.a = pt.a;\n out.b = pt.b;\n out.c = pt.c;\n }\n\n return out;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterternary/event_data.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterternary/format_labels.js":
-/*!***************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterternary/format_labels.js ***!
- \***************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\n\nmodule.exports = function formatLabels(cdi, trace, fullLayout) {\n var labels = {};\n\n var subplot = fullLayout[trace.subplot]._subplot;\n labels.aLabel = Axes.tickText(subplot.aaxis, cdi.a, true).text;\n labels.bLabel = Axes.tickText(subplot.baxis, cdi.b, true).text;\n labels.cLabel = Axes.tickText(subplot.caxis, cdi.c, true).text;\n\n return labels;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterternary/format_labels.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterternary/hover.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterternary/hover.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar scatterHover = __webpack_require__(/*! ../scatter/hover */ \"./node_modules/plotly.js/src/traces/scatter/hover.js\");\n\nmodule.exports = function hoverPoints(pointData, xval, yval, hovermode) {\n var scatterPointData = scatterHover(pointData, xval, yval, hovermode);\n if(!scatterPointData || scatterPointData[0].index === false) return;\n\n var newPointData = scatterPointData[0];\n\n // if hovering on a fill, we don't show any point data so the label is\n // unchanged from what scatter gives us - except that it needs to\n // be constrained to the trianglular plot area, not just the rectangular\n // area defined by the synthetic x and y axes\n // TODO: in some cases the vertical middle of the shape is not within\n // the triangular viewport at all, so the label can become disconnected\n // from the shape entirely. But calculating what portion of the shape\n // is actually visible, as constrained by the diagonal axis lines, is not\n // so easy and anyway we lost the information we would have needed to do\n // this inside scatterHover.\n if(newPointData.index === undefined) {\n var yFracUp = 1 - (newPointData.y0 / pointData.ya._length);\n var xLen = pointData.xa._length;\n var xMin = xLen * yFracUp / 2;\n var xMax = xLen - xMin;\n newPointData.x0 = Math.max(Math.min(newPointData.x0, xMax), xMin);\n newPointData.x1 = Math.max(Math.min(newPointData.x1, xMax), xMin);\n return scatterPointData;\n }\n\n var cdi = newPointData.cd[newPointData.index];\n var trace = newPointData.trace;\n var subplot = newPointData.subplot;\n\n newPointData.a = cdi.a;\n newPointData.b = cdi.b;\n newPointData.c = cdi.c;\n\n newPointData.xLabelVal = undefined;\n newPointData.yLabelVal = undefined;\n\n var fullLayout = {};\n fullLayout[trace.subplot] = {_subplot: subplot};\n var labels = trace._module.formatLabels(cdi, trace, fullLayout);\n newPointData.aLabel = labels.aLabel;\n newPointData.bLabel = labels.bLabel;\n newPointData.cLabel = labels.cLabel;\n\n var hoverinfo = cdi.hi || trace.hoverinfo;\n var text = [];\n function textPart(ax, val) {\n text.push(ax._hovertitle + ': ' + val);\n }\n if(!trace.hovertemplate) {\n var parts = hoverinfo.split('+');\n if(parts.indexOf('all') !== -1) parts = ['a', 'b', 'c'];\n if(parts.indexOf('a') !== -1) textPart(subplot.aaxis, newPointData.aLabel);\n if(parts.indexOf('b') !== -1) textPart(subplot.baxis, newPointData.bLabel);\n if(parts.indexOf('c') !== -1) textPart(subplot.caxis, newPointData.cLabel);\n }\n newPointData.extraText = text.join('
');\n newPointData.hovertemplate = trace.hovertemplate;\n return scatterPointData;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterternary/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterternary/index.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterternary/index.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/scatterternary/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/scatterternary/defaults.js\"),\n colorbar: __webpack_require__(/*! ../scatter/marker_colorbar */ \"./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js\"),\n formatLabels: __webpack_require__(/*! ./format_labels */ \"./node_modules/plotly.js/src/traces/scatterternary/format_labels.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/scatterternary/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/scatterternary/plot.js\"),\n style: __webpack_require__(/*! ../scatter/style */ \"./node_modules/plotly.js/src/traces/scatter/style.js\").style,\n styleOnSelect: __webpack_require__(/*! ../scatter/style */ \"./node_modules/plotly.js/src/traces/scatter/style.js\").styleOnSelect,\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/scatterternary/hover.js\"),\n selectPoints: __webpack_require__(/*! ../scatter/select */ \"./node_modules/plotly.js/src/traces/scatter/select.js\"),\n eventData: __webpack_require__(/*! ./event_data */ \"./node_modules/plotly.js/src/traces/scatterternary/event_data.js\"),\n\n moduleType: 'trace',\n name: 'scatterternary',\n basePlotModule: __webpack_require__(/*! ../../plots/ternary */ \"./node_modules/plotly.js/src/plots/ternary/index.js\"),\n categories: ['ternary', 'symbols', 'showLegend', 'scatter-like'],\n meta: {\n \n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterternary/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/scatterternary/plot.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/scatterternary/plot.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar scatterPlot = __webpack_require__(/*! ../scatter/plot */ \"./node_modules/plotly.js/src/traces/scatter/plot.js\");\n\nmodule.exports = function plot(gd, ternary, moduleCalcData) {\n var plotContainer = ternary.plotContainer;\n\n // remove all nodes inside the scatter layer\n plotContainer.select('.scatterlayer').selectAll('*').remove();\n\n // mimic cartesian plotinfo\n var plotinfo = {\n xaxis: ternary.xaxis,\n yaxis: ternary.yaxis,\n plot: plotContainer,\n layerClipId: ternary._hasClipOnAxisFalse ? ternary.clipIdRelative : null\n };\n\n var scatterLayer = ternary.layers.frontplot.select('g.scatterlayer');\n\n scatterPlot(gd, plotinfo, moduleCalcData, scatterLayer);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/scatterternary/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/splom/attributes.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/splom/attributes.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar scatterAttrs = __webpack_require__(/*! ../scatter/attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\");\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar scatterGlAttrs = __webpack_require__(/*! ../scattergl/attributes */ \"./node_modules/plotly.js/src/traces/scattergl/attributes.js\");\nvar cartesianIdRegex = __webpack_require__(/*! ../../plots/cartesian/constants */ \"./node_modules/plotly.js/src/plots/cartesian/constants.js\").idRegex;\nvar templatedArray = __webpack_require__(/*! ../../plot_api/plot_template */ \"./node_modules/plotly.js/src/plot_api/plot_template.js\").templatedArray;\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nvar scatterMarkerAttrs = scatterAttrs.marker;\nvar scatterMarkerLineAttrs = scatterMarkerAttrs.line;\n\nvar markerLineAttrs = extendFlat(colorScaleAttrs('marker.line', {editTypeOverride: 'calc'}), {\n width: extendFlat({}, scatterMarkerLineAttrs.width, {editType: 'calc'}),\n editType: 'calc'\n});\n\nvar markerAttrs = extendFlat(colorScaleAttrs('marker'), {\n symbol: scatterMarkerAttrs.symbol,\n size: extendFlat({}, scatterMarkerAttrs.size, {editType: 'markerSize'}),\n sizeref: scatterMarkerAttrs.sizeref,\n sizemin: scatterMarkerAttrs.sizemin,\n sizemode: scatterMarkerAttrs.sizemode,\n opacity: scatterMarkerAttrs.opacity,\n colorbar: scatterMarkerAttrs.colorbar,\n line: markerLineAttrs,\n editType: 'calc'\n});\n\nmarkerAttrs.color.editType = markerAttrs.cmin.editType = markerAttrs.cmax.editType = 'style';\n\nfunction makeAxesValObject(axLetter) {\n return {\n valType: 'info_array',\n freeLength: true,\n \n editType: 'calc',\n items: {\n valType: 'subplotid',\n regex: cartesianIdRegex[axLetter],\n editType: 'plot'\n },\n \n };\n}\n\nmodule.exports = {\n dimensions: templatedArray('dimension', {\n visible: {\n valType: 'boolean',\n \n dflt: true,\n editType: 'calc',\n \n },\n label: {\n valType: 'string',\n \n editType: 'calc',\n \n },\n values: {\n valType: 'data_array',\n \n editType: 'calc+clearAxisTypes',\n \n },\n\n axis: {\n type: {\n valType: 'enumerated',\n values: ['linear', 'log', 'date', 'category'],\n \n editType: 'calc+clearAxisTypes',\n \n },\n\n // TODO make 'true' the default in v2?\n matches: {\n valType: 'boolean',\n dflt: false,\n \n editType: 'calc',\n \n },\n\n editType: 'calc+clearAxisTypes'\n },\n\n // TODO should add an attribute to pin down x only vars and y only vars\n // like https://seaborn.pydata.org/generated/seaborn.pairplot.html\n // x_vars and y_vars\n\n // maybe more axis defaulting option e.g. `showgrid: false`\n\n editType: 'calc+clearAxisTypes'\n }),\n\n // mode: {}, (only 'markers' for now)\n\n text: extendFlat({}, scatterGlAttrs.text, {\n \n }),\n hovertext: extendFlat({}, scatterGlAttrs.hovertext, {\n \n }),\n\n hovertemplate: hovertemplateAttrs(),\n\n marker: markerAttrs,\n\n xaxes: makeAxesValObject('x'),\n yaxes: makeAxesValObject('y'),\n\n diagonal: {\n visible: {\n valType: 'boolean',\n \n dflt: true,\n editType: 'calc',\n \n },\n\n // type: 'scattergl' | 'histogram' | 'box' | 'violin'\n // ...\n // more options\n\n editType: 'calc'\n },\n\n showupperhalf: {\n valType: 'boolean',\n \n dflt: true,\n editType: 'calc',\n \n },\n showlowerhalf: {\n valType: 'boolean',\n \n dflt: true,\n editType: 'calc',\n \n },\n\n selected: {\n marker: scatterGlAttrs.selected.marker,\n editType: 'calc'\n },\n unselected: {\n marker: scatterGlAttrs.unselected.marker,\n editType: 'calc'\n },\n\n opacity: scatterGlAttrs.opacity\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/splom/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/splom/base_plot.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/splom/base_plot.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar createLine = __webpack_require__(/*! regl-line2d */ \"./node_modules/regl-line2d/index.js\");\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar prepareRegl = __webpack_require__(/*! ../../lib/prepare_regl */ \"./node_modules/plotly.js/src/lib/prepare_regl.js\");\nvar getModuleCalcData = __webpack_require__(/*! ../../plots/get_data */ \"./node_modules/plotly.js/src/plots/get_data.js\").getModuleCalcData;\nvar Cartesian = __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\");\nvar getFromId = __webpack_require__(/*! ../../plots/cartesian/axis_ids */ \"./node_modules/plotly.js/src/plots/cartesian/axis_ids.js\").getFromId;\nvar shouldShowZeroLine = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\").shouldShowZeroLine;\n\nvar SPLOM = 'splom';\n\nfunction plot(gd) {\n var fullLayout = gd._fullLayout;\n var _module = Registry.getModule(SPLOM);\n var splomCalcData = getModuleCalcData(gd.calcdata, _module)[0];\n\n var success = prepareRegl(gd, ['ANGLE_instanced_arrays', 'OES_element_index_uint']);\n if(!success) return;\n\n if(fullLayout._hasOnlyLargeSploms) {\n updateGrid(gd);\n }\n\n _module.plot(gd, {}, splomCalcData);\n}\n\nfunction drag(gd) {\n var cd = gd.calcdata;\n var fullLayout = gd._fullLayout;\n\n if(fullLayout._hasOnlyLargeSploms) {\n updateGrid(gd);\n }\n\n for(var i = 0; i < cd.length; i++) {\n var cd0 = cd[i][0];\n var trace = cd0.trace;\n var scene = fullLayout._splomScenes[trace.uid];\n\n if(trace.type === 'splom' && scene && scene.matrix) {\n dragOne(gd, trace, scene);\n }\n }\n}\n\nfunction dragOne(gd, trace, scene) {\n var visibleLength = scene.matrixOptions.data.length;\n var visibleDims = trace._visibleDims;\n var ranges = scene.viewOpts.ranges = new Array(visibleLength);\n\n for(var k = 0; k < visibleDims.length; k++) {\n var i = visibleDims[k];\n var rng = ranges[k] = new Array(4);\n\n var xa = getFromId(gd, trace._diag[i][0]);\n if(xa) {\n rng[0] = xa.r2l(xa.range[0]);\n rng[2] = xa.r2l(xa.range[1]);\n }\n\n var ya = getFromId(gd, trace._diag[i][1]);\n if(ya) {\n rng[1] = ya.r2l(ya.range[0]);\n rng[3] = ya.r2l(ya.range[1]);\n }\n }\n\n if(scene.selectBatch.length || scene.unselectBatch.length) {\n scene.matrix.update({ranges: ranges}, {ranges: ranges});\n } else {\n scene.matrix.update({ranges: ranges});\n }\n}\n\nfunction updateGrid(gd) {\n var fullLayout = gd._fullLayout;\n var regl = fullLayout._glcanvas.data()[0].regl;\n var splomGrid = fullLayout._splomGrid;\n\n if(!splomGrid) {\n splomGrid = fullLayout._splomGrid = createLine(regl);\n }\n splomGrid.update(makeGridData(gd));\n}\n\nfunction makeGridData(gd) {\n var fullLayout = gd._fullLayout;\n var gs = fullLayout._size;\n var fullView = [0, 0, fullLayout.width, fullLayout.height];\n var lookup = {};\n var k;\n\n function push(prefix, ax, x0, x1, y0, y1) {\n var lcolor = ax[prefix + 'color'];\n var lwidth = ax[prefix + 'width'];\n var key = String(lcolor + lwidth);\n\n if(key in lookup) {\n lookup[key].data.push(NaN, NaN, x0, x1, y0, y1);\n } else {\n lookup[key] = {\n data: [x0, x1, y0, y1],\n join: 'rect',\n thickness: lwidth,\n color: lcolor,\n viewport: fullView,\n range: fullView,\n overlay: false\n };\n }\n }\n\n for(k in fullLayout._splomSubplots) {\n var sp = fullLayout._plots[k];\n var xa = sp.xaxis;\n var ya = sp.yaxis;\n var xVals = xa._gridVals;\n var yVals = ya._gridVals;\n // ya.l2p assumes top-to-bottom coordinate system (a la SVG),\n // we need to compute bottom-to-top offsets and slopes:\n var yOffset = gs.b + ya.domain[0] * gs.h;\n var ym = -ya._m;\n var yb = -ym * ya.r2l(ya.range[0], ya.calendar);\n var x, y;\n\n if(xa.showgrid) {\n for(k = 0; k < xVals.length; k++) {\n x = xa._offset + xa.l2p(xVals[k].x);\n push('grid', xa, x, yOffset, x, yOffset + ya._length);\n }\n }\n if(ya.showgrid) {\n for(k = 0; k < yVals.length; k++) {\n y = yOffset + yb + ym * yVals[k].x;\n push('grid', ya, xa._offset, y, xa._offset + xa._length, y);\n }\n }\n if(shouldShowZeroLine(gd, xa, ya)) {\n x = xa._offset + xa.l2p(0);\n push('zeroline', xa, x, yOffset, x, yOffset + ya._length);\n }\n if(shouldShowZeroLine(gd, ya, xa)) {\n y = yOffset + yb + 0;\n push('zeroline', ya, xa._offset, y, xa._offset + xa._length, y);\n }\n }\n\n var gridBatches = [];\n for(k in lookup) {\n gridBatches.push(lookup[k]);\n }\n\n return gridBatches;\n}\n\nfunction clean(newFullData, newFullLayout, oldFullData, oldFullLayout) {\n var lookup = {};\n var i;\n\n if(oldFullLayout._splomScenes) {\n for(i = 0; i < newFullData.length; i++) {\n var newTrace = newFullData[i];\n if(newTrace.type === 'splom') {\n lookup[newTrace.uid] = 1;\n }\n }\n for(i = 0; i < oldFullData.length; i++) {\n var oldTrace = oldFullData[i];\n if(!lookup[oldTrace.uid]) {\n var scene = oldFullLayout._splomScenes[oldTrace.uid];\n if(scene && scene.destroy) scene.destroy();\n // must first set scene to null in order to get garbage collected\n oldFullLayout._splomScenes[oldTrace.uid] = null;\n delete oldFullLayout._splomScenes[oldTrace.uid];\n }\n }\n }\n\n if(Object.keys(oldFullLayout._splomScenes || {}).length === 0) {\n delete oldFullLayout._splomScenes;\n }\n\n if(oldFullLayout._splomGrid &&\n (!newFullLayout._hasOnlyLargeSploms && oldFullLayout._hasOnlyLargeSploms)) {\n // must first set scene to null in order to get garbage collected\n oldFullLayout._splomGrid.destroy();\n oldFullLayout._splomGrid = null;\n delete oldFullLayout._splomGrid;\n }\n\n Cartesian.clean(newFullData, newFullLayout, oldFullData, oldFullLayout);\n}\n\nmodule.exports = {\n name: SPLOM,\n attr: Cartesian.attr,\n attrRegex: Cartesian.attrRegex,\n layoutAttributes: Cartesian.layoutAttributes,\n supplyLayoutDefaults: Cartesian.supplyLayoutDefaults,\n drawFramework: Cartesian.drawFramework,\n plot: plot,\n drag: drag,\n updateGrid: updateGrid,\n clean: clean,\n updateFx: Cartesian.updateFx,\n toSVG: Cartesian.toSVG\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/splom/base_plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/splom/calc.js":
-/*!*********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/splom/calc.js ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar AxisIDs = __webpack_require__(/*! ../../plots/cartesian/axis_ids */ \"./node_modules/plotly.js/src/plots/cartesian/axis_ids.js\");\n\nvar calcMarkerSize = __webpack_require__(/*! ../scatter/calc */ \"./node_modules/plotly.js/src/traces/scatter/calc.js\").calcMarkerSize;\nvar calcAxisExpansion = __webpack_require__(/*! ../scatter/calc */ \"./node_modules/plotly.js/src/traces/scatter/calc.js\").calcAxisExpansion;\nvar calcColorscale = __webpack_require__(/*! ../scatter/colorscale_calc */ \"./node_modules/plotly.js/src/traces/scatter/colorscale_calc.js\");\nvar convertMarkerSelection = __webpack_require__(/*! ../scattergl/convert */ \"./node_modules/plotly.js/src/traces/scattergl/convert.js\").markerSelection;\nvar convertMarkerStyle = __webpack_require__(/*! ../scattergl/convert */ \"./node_modules/plotly.js/src/traces/scattergl/convert.js\").markerStyle;\nvar sceneUpdate = __webpack_require__(/*! ./scene_update */ \"./node_modules/plotly.js/src/traces/splom/scene_update.js\");\n\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\nvar TOO_MANY_POINTS = __webpack_require__(/*! ../scattergl/constants */ \"./node_modules/plotly.js/src/traces/scattergl/constants.js\").TOO_MANY_POINTS;\n\nmodule.exports = function calc(gd, trace) {\n var dimensions = trace.dimensions;\n var commonLength = trace._length;\n var opts = {};\n // 'c' for calculated, 'l' for linear,\n // only differ here for log axes, pass ldata to createMatrix as 'data'\n var cdata = opts.cdata = [];\n var ldata = opts.data = [];\n // keep track of visible dimensions\n var visibleDims = trace._visibleDims = [];\n var i, k, dim, xa, ya;\n\n function makeCalcdata(ax, dim) {\n // call makeCalcdata with fake input\n var ccol = ax.makeCalcdata({\n v: dim.values,\n vcalendar: trace.calendar\n }, 'v');\n\n for(var j = 0; j < ccol.length; j++) {\n ccol[j] = ccol[j] === BADNUM ? NaN : ccol[j];\n }\n cdata.push(ccol);\n ldata.push(ax.type === 'log' ? Lib.simpleMap(ccol, ax.c2l) : ccol);\n }\n\n for(i = 0; i < dimensions.length; i++) {\n dim = dimensions[i];\n\n if(dim.visible) {\n xa = AxisIDs.getFromId(gd, trace._diag[i][0]);\n ya = AxisIDs.getFromId(gd, trace._diag[i][1]);\n\n // if corresponding x & y axes don't have matching types, skip dim\n if(xa && ya && xa.type !== ya.type) {\n Lib.log('Skipping splom dimension ' + i + ' with conflicting axis types');\n continue;\n }\n\n if(xa) {\n makeCalcdata(xa, dim);\n if(ya && ya.type === 'category') {\n ya._categories = xa._categories.slice();\n }\n } else {\n // should not make it here, if both xa and ya undefined\n makeCalcdata(ya, dim);\n }\n\n visibleDims.push(i);\n }\n }\n\n calcColorscale(gd, trace);\n Lib.extendFlat(opts, convertMarkerStyle(trace));\n\n var visibleLength = cdata.length;\n var hasTooManyPoints = (visibleLength * commonLength) > TOO_MANY_POINTS;\n\n // Reuse SVG scatter axis expansion routine.\n // For graphs with very large number of points and array marker.size,\n // use average marker size instead to speed things up.\n var ppad;\n if(hasTooManyPoints) {\n ppad = 2 * (opts.sizeAvg || Math.max(opts.size, 3));\n } else {\n ppad = calcMarkerSize(trace, commonLength);\n }\n\n for(k = 0; k < visibleDims.length; k++) {\n i = visibleDims[k];\n dim = dimensions[i];\n xa = AxisIDs.getFromId(gd, trace._diag[i][0]) || {};\n ya = AxisIDs.getFromId(gd, trace._diag[i][1]) || {};\n calcAxisExpansion(gd, trace, xa, ya, cdata[k], cdata[k], ppad);\n }\n\n var scene = sceneUpdate(gd, trace);\n if(!scene.matrix) scene.matrix = true;\n scene.matrixOptions = opts;\n\n scene.selectedOptions = convertMarkerSelection(trace, trace.selected);\n scene.unselectedOptions = convertMarkerSelection(trace, trace.unselected);\n\n return [{x: false, y: false, t: {}, trace: trace}];\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/splom/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/splom/defaults.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/splom/defaults.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar handleArrayContainerDefaults = __webpack_require__(/*! ../../plots/array_container_defaults */ \"./node_modules/plotly.js/src/plots/array_container_defaults.js\");\n\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/splom/attributes.js\");\nvar subTypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar handleMarkerDefaults = __webpack_require__(/*! ../scatter/marker_defaults */ \"./node_modules/plotly.js/src/traces/scatter/marker_defaults.js\");\nvar mergeLength = __webpack_require__(/*! ../parcoords/merge_length */ \"./node_modules/plotly.js/src/traces/parcoords/merge_length.js\");\nvar isOpenSymbol = __webpack_require__(/*! ../scattergl/helpers */ \"./node_modules/plotly.js/src/traces/scattergl/helpers.js\").isOpenSymbol;\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var dimensions = handleArrayContainerDefaults(traceIn, traceOut, {\n name: 'dimensions',\n handleItemDefaults: dimensionDefaults\n });\n\n var showDiag = coerce('diagonal.visible');\n var showUpper = coerce('showupperhalf');\n var showLower = coerce('showlowerhalf');\n\n var dimLength = mergeLength(traceOut, dimensions, 'values');\n\n if(!dimLength || (!showDiag && !showUpper && !showLower)) {\n traceOut.visible = false;\n return;\n }\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n\n handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce);\n\n var isOpen = isOpenSymbol(traceOut.marker.symbol);\n var isBubble = subTypes.isBubble(traceOut);\n coerce('marker.line.width', isOpen || isBubble ? 1 : 0);\n\n handleAxisDefaults(traceIn, traceOut, layout, coerce);\n\n Lib.coerceSelectionMarkerOpacity(traceOut, coerce);\n};\n\nfunction dimensionDefaults(dimIn, dimOut) {\n function coerce(attr, dflt) {\n return Lib.coerce(dimIn, dimOut, attributes.dimensions, attr, dflt);\n }\n\n coerce('label');\n var values = coerce('values');\n\n if(!(values && values.length)) dimOut.visible = false;\n else coerce('visible');\n\n coerce('axis.type');\n coerce('axis.matches');\n}\n\nfunction handleAxisDefaults(traceIn, traceOut, layout, coerce) {\n var dimensions = traceOut.dimensions;\n var dimLength = dimensions.length;\n var showUpper = traceOut.showupperhalf;\n var showLower = traceOut.showlowerhalf;\n var showDiag = traceOut.diagonal.visible;\n var i, j;\n\n var xAxesDflt = new Array(dimLength);\n var yAxesDflt = new Array(dimLength);\n\n for(i = 0; i < dimLength; i++) {\n var suffix = i ? i + 1 : '';\n xAxesDflt[i] = 'x' + suffix;\n yAxesDflt[i] = 'y' + suffix;\n }\n\n var xaxes = coerce('xaxes', xAxesDflt);\n var yaxes = coerce('yaxes', yAxesDflt);\n\n // build list of [x,y] axis corresponding to each dimensions[i],\n // very useful for passing options to regl-splom\n var diag = traceOut._diag = new Array(dimLength);\n\n // lookup for 'drawn' x|y axes, to avoid costly indexOf downstream\n traceOut._xaxes = {};\n traceOut._yaxes = {};\n\n // list of 'drawn' x|y axes, use to generate list of subplots\n var xList = [];\n var yList = [];\n\n function fillAxisStashes(axId, counterAxId, dim, list) {\n if(!axId) return;\n\n var axLetter = axId.charAt(0);\n var stash = layout._splomAxes[axLetter];\n\n traceOut['_' + axLetter + 'axes'][axId] = 1;\n list.push(axId);\n\n if(!(axId in stash)) {\n var s = stash[axId] = {};\n if(dim) {\n s.label = dim.label || '';\n if(dim.visible && dim.axis) {\n if(dim.axis.type) s.type = dim.axis.type;\n if(dim.axis.matches) s.matches = counterAxId;\n }\n }\n }\n }\n\n // cases where showDiag and showLower or showUpper are false\n // no special treatment as the 'drawn' x-axes and y-axes no longer match\n // the dimensions items and xaxes|yaxes 1-to-1\n var mustShiftX = !showDiag && !showLower;\n var mustShiftY = !showDiag && !showUpper;\n\n traceOut._axesDim = {};\n for(i = 0; i < dimLength; i++) {\n var dim = dimensions[i];\n var i0 = i === 0;\n var iN = i === dimLength - 1;\n\n var xaId = (i0 && mustShiftX) || (iN && mustShiftY) ?\n undefined :\n xaxes[i];\n\n var yaId = (i0 && mustShiftY) || (iN && mustShiftX) ?\n undefined :\n yaxes[i];\n\n fillAxisStashes(xaId, yaId, dim, xList);\n fillAxisStashes(yaId, xaId, dim, yList);\n diag[i] = [xaId, yaId];\n traceOut._axesDim[xaId] = i;\n traceOut._axesDim[yaId] = i;\n }\n\n // fill in splom subplot keys\n for(i = 0; i < xList.length; i++) {\n for(j = 0; j < yList.length; j++) {\n var id = xList[i] + yList[j];\n\n if(i > j && showUpper) {\n layout._splomSubplots[id] = 1;\n } else if(i < j && showLower) {\n layout._splomSubplots[id] = 1;\n } else if(i === j && (showDiag || !showLower || !showUpper)) {\n // need to include diagonal subplots when\n // hiding one half and the diagonal\n layout._splomSubplots[id] = 1;\n }\n }\n }\n\n // when lower half is omitted, or when just the diagonal is gone,\n // override grid default to make sure axes remain on\n // the left/bottom of the plot area\n if(!showLower || (!showDiag && showUpper && showLower)) {\n layout._splomGridDflt.xside = 'bottom';\n layout._splomGridDflt.yside = 'left';\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/splom/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/splom/edit_style.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/splom/edit_style.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar calcColorscale = __webpack_require__(/*! ../scatter/colorscale_calc */ \"./node_modules/plotly.js/src/traces/scatter/colorscale_calc.js\");\nvar convertMarkerStyle = __webpack_require__(/*! ../scattergl/convert */ \"./node_modules/plotly.js/src/traces/scattergl/convert.js\").markerStyle;\n\nmodule.exports = function editStyle(gd, cd0) {\n var trace = cd0.trace;\n var scene = gd._fullLayout._splomScenes[trace.uid];\n\n if(scene) {\n calcColorscale(gd, trace);\n\n Lib.extendFlat(scene.matrixOptions, convertMarkerStyle(trace));\n // TODO [un]selected styles?\n\n var opts = Lib.extendFlat({}, scene.matrixOptions, scene.viewOpts);\n\n // TODO this is too long for arrayOk attributes!\n scene.matrix.update(opts, null);\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/splom/edit_style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/splom/helpers.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/splom/helpers.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nexports.getDimIndex = function getDimIndex(trace, ax) {\n var axId = ax._id;\n var axLetter = axId.charAt(0);\n var ind = {x: 0, y: 1}[axLetter];\n var visibleDims = trace._visibleDims;\n\n for(var k = 0; k < visibleDims.length; k++) {\n var i = visibleDims[k];\n if(trace._diag[i][ind] === axId) return k;\n }\n return false;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/splom/helpers.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/splom/hover.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/splom/hover.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/traces/splom/helpers.js\");\nvar calcHover = __webpack_require__(/*! ../scattergl/hover */ \"./node_modules/plotly.js/src/traces/scattergl/hover.js\").calcHover;\n\nfunction hoverPoints(pointData, xval, yval) {\n var cd = pointData.cd;\n var trace = cd[0].trace;\n var scene = pointData.scene;\n var cdata = scene.matrixOptions.cdata;\n var xa = pointData.xa;\n var ya = pointData.ya;\n var xpx = xa.c2p(xval);\n var ypx = ya.c2p(yval);\n var maxDistance = pointData.distance;\n\n var xi = helpers.getDimIndex(trace, xa);\n var yi = helpers.getDimIndex(trace, ya);\n if(xi === false || yi === false) return [pointData];\n\n var x = cdata[xi];\n var y = cdata[yi];\n\n var id, dxy;\n var minDist = maxDistance;\n\n for(var i = 0; i < x.length; i++) {\n var ptx = x[i];\n var pty = y[i];\n var dx = xa.c2p(ptx) - xpx;\n var dy = ya.c2p(pty) - ypx;\n var dist = Math.sqrt(dx * dx + dy * dy);\n\n if(dist < minDist) {\n minDist = dxy = dist;\n id = i;\n }\n }\n\n pointData.index = id;\n pointData.distance = minDist;\n pointData.dxy = dxy;\n\n if(id === undefined) return [pointData];\n\n return [calcHover(pointData, x, y, trace)];\n}\n\nmodule.exports = {\n hoverPoints: hoverPoints\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/splom/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/splom/index.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/splom/index.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Grid = __webpack_require__(/*! ../../components/grid */ \"./node_modules/plotly.js/src/components/grid/index.js\");\n\nmodule.exports = {\n moduleType: 'trace',\n name: 'splom',\n\n basePlotModule: __webpack_require__(/*! ./base_plot */ \"./node_modules/plotly.js/src/traces/splom/base_plot.js\"),\n categories: ['gl', 'regl', 'cartesian', 'symbols', 'showLegend', 'scatter-like'],\n\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/splom/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/splom/defaults.js\"),\n colorbar: __webpack_require__(/*! ../scatter/marker_colorbar */ \"./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js\"),\n\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/splom/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/splom/plot.js\"),\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/splom/hover.js\").hoverPoints,\n selectPoints: __webpack_require__(/*! ./select */ \"./node_modules/plotly.js/src/traces/splom/select.js\"),\n editStyle: __webpack_require__(/*! ./edit_style */ \"./node_modules/plotly.js/src/traces/splom/edit_style.js\"),\n\n meta: {\n \n }\n};\n\n// splom traces use the 'grid' component to generate their axes,\n// register it here\nRegistry.register(Grid);\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/splom/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/splom/plot.js":
-/*!*********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/splom/plot.js ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar createMatrix = __webpack_require__(/*! regl-splom */ \"./node_modules/regl-splom/index.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar AxisIDs = __webpack_require__(/*! ../../plots/cartesian/axis_ids */ \"./node_modules/plotly.js/src/plots/cartesian/axis_ids.js\");\n\nmodule.exports = function plot(gd, _, splomCalcData) {\n if(!splomCalcData.length) return;\n\n for(var i = 0; i < splomCalcData.length; i++) {\n plotOne(gd, splomCalcData[i][0]);\n }\n};\n\nfunction plotOne(gd, cd0) {\n var fullLayout = gd._fullLayout;\n var gs = fullLayout._size;\n var trace = cd0.trace;\n var stash = cd0.t;\n var scene = fullLayout._splomScenes[trace.uid];\n var matrixOpts = scene.matrixOptions;\n var cdata = matrixOpts.cdata;\n var regl = fullLayout._glcanvas.data()[0].regl;\n var dragmode = fullLayout.dragmode;\n var xa, ya;\n var i, j, k;\n\n if(cdata.length === 0) return;\n\n // augment options with proper upper/lower halves\n // regl-splom's default grid starts from bottom-left\n matrixOpts.lower = trace.showupperhalf;\n matrixOpts.upper = trace.showlowerhalf;\n matrixOpts.diagonal = trace.diagonal.visible;\n\n var visibleDims = trace._visibleDims;\n var visibleLength = cdata.length;\n var viewOpts = scene.viewOpts = {};\n viewOpts.ranges = new Array(visibleLength);\n viewOpts.domains = new Array(visibleLength);\n\n for(k = 0; k < visibleDims.length; k++) {\n i = visibleDims[k];\n\n var rng = viewOpts.ranges[k] = new Array(4);\n var dmn = viewOpts.domains[k] = new Array(4);\n\n xa = AxisIDs.getFromId(gd, trace._diag[i][0]);\n if(xa) {\n rng[0] = xa._rl[0];\n rng[2] = xa._rl[1];\n dmn[0] = xa.domain[0];\n dmn[2] = xa.domain[1];\n }\n\n ya = AxisIDs.getFromId(gd, trace._diag[i][1]);\n if(ya) {\n rng[1] = ya._rl[0];\n rng[3] = ya._rl[1];\n dmn[1] = ya.domain[0];\n dmn[3] = ya.domain[1];\n }\n }\n\n viewOpts.viewport = [gs.l, gs.b, gs.w + gs.l, gs.h + gs.b];\n\n if(scene.matrix === true) {\n scene.matrix = createMatrix(regl);\n }\n\n var clickSelectEnabled = fullLayout.clickmode.indexOf('select') > -1;\n var selectMode = dragmode === 'lasso' || dragmode === 'select' ||\n !!trace.selectedpoints || clickSelectEnabled;\n var needsBaseUpdate = true;\n\n if(selectMode) {\n var commonLength = trace._length;\n\n // regenerate scene batch, if traces number changed during selection\n if(trace.selectedpoints) {\n scene.selectBatch = trace.selectedpoints;\n\n var selPts = trace.selectedpoints;\n var selDict = {};\n for(i = 0; i < selPts.length; i++) {\n selDict[selPts[i]] = true;\n }\n var unselPts = [];\n for(i = 0; i < commonLength; i++) {\n if(!selDict[i]) unselPts.push(i);\n }\n scene.unselectBatch = unselPts;\n }\n\n // precalculate px coords since we are not going to pan during select\n var xpx = stash.xpx = new Array(visibleLength);\n var ypx = stash.ypx = new Array(visibleLength);\n\n for(k = 0; k < visibleDims.length; k++) {\n i = visibleDims[k];\n\n xa = AxisIDs.getFromId(gd, trace._diag[i][0]);\n if(xa) {\n xpx[k] = new Array(commonLength);\n for(j = 0; j < commonLength; j++) {\n xpx[k][j] = xa.c2p(cdata[k][j]);\n }\n }\n\n ya = AxisIDs.getFromId(gd, trace._diag[i][1]);\n if(ya) {\n ypx[k] = new Array(commonLength);\n for(j = 0; j < commonLength; j++) {\n ypx[k][j] = ya.c2p(cdata[k][j]);\n }\n }\n }\n\n if(scene.selectBatch.length || scene.unselectBatch.length) {\n var unselOpts = Lib.extendFlat({}, matrixOpts, scene.unselectedOptions, viewOpts);\n var selOpts = Lib.extendFlat({}, matrixOpts, scene.selectedOptions, viewOpts);\n scene.matrix.update(unselOpts, selOpts);\n needsBaseUpdate = false;\n }\n } else {\n stash.xpx = stash.ypx = null;\n }\n\n if(needsBaseUpdate) {\n var opts = Lib.extendFlat({}, matrixOpts, viewOpts);\n scene.matrix.update(opts, null);\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/splom/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/splom/scene_update.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/splom/scene_update.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nmodule.exports = function sceneUpdate(gd, trace) {\n var fullLayout = gd._fullLayout;\n var uid = trace.uid;\n\n // must place ref to 'scene' in fullLayout, so that:\n // - it can be relinked properly on updates\n // - it can be destroyed properly when needed\n var splomScenes = fullLayout._splomScenes;\n if(!splomScenes) splomScenes = fullLayout._splomScenes = {};\n\n var reset = {dirty: true};\n\n var first = {\n matrix: false,\n selectBatch: [],\n unselectBatch: []\n };\n\n var scene = splomScenes[trace.uid];\n\n if(!scene) {\n scene = splomScenes[uid] = Lib.extendFlat({}, reset, first);\n\n scene.draw = function draw() {\n if(scene.matrix && scene.matrix.draw) {\n if(scene.selectBatch.length || scene.unselectBatch.length) {\n scene.matrix.draw(scene.unselectBatch, scene.selectBatch);\n } else {\n scene.matrix.draw();\n }\n }\n\n scene.dirty = false;\n };\n\n // remove scene resources\n scene.destroy = function destroy() {\n if(scene.matrix && scene.matrix.destroy) {\n scene.matrix.destroy();\n }\n scene.matrixOptions = null;\n scene.selectBatch = null;\n scene.unselectBatch = null;\n scene = null;\n };\n }\n\n // In case if we have scene from the last calc - reset data\n if(!scene.dirty) {\n Lib.extendFlat(scene, reset);\n }\n\n return scene;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/splom/scene_update.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/splom/select.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/splom/select.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar subTypes = __webpack_require__(/*! ../scatter/subtypes */ \"./node_modules/plotly.js/src/traces/scatter/subtypes.js\");\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/traces/splom/helpers.js\");\n\nmodule.exports = function select(searchInfo, selectionTester) {\n var cd = searchInfo.cd;\n var trace = cd[0].trace;\n var stash = cd[0].t;\n var scene = searchInfo.scene;\n var cdata = scene.matrixOptions.cdata;\n var xa = searchInfo.xaxis;\n var ya = searchInfo.yaxis;\n var selection = [];\n\n if(!scene) return selection;\n\n var hasOnlyLines = (!subTypes.hasMarkers(trace) && !subTypes.hasText(trace));\n if(trace.visible !== true || hasOnlyLines) return selection;\n\n var xi = helpers.getDimIndex(trace, xa);\n var yi = helpers.getDimIndex(trace, ya);\n if(xi === false || yi === false) return selection;\n\n var xpx = stash.xpx[xi];\n var ypx = stash.ypx[yi];\n var x = cdata[xi];\n var y = cdata[yi];\n var els = [];\n var unels = [];\n\n // degenerate polygon does not enable selection\n // filter out points by visible scatter ones\n if(selectionTester !== false && !selectionTester.degenerate) {\n for(var i = 0; i < x.length; i++) {\n if(selectionTester.contains([xpx[i], ypx[i]], null, i, searchInfo)) {\n els.push(i);\n selection.push({\n pointNumber: i,\n x: x[i],\n y: y[i]\n });\n } else {\n unels.push(i);\n }\n }\n }\n\n var matrixOpts = scene.matrixOptions;\n\n if(!els.length && !unels.length) {\n scene.matrix.update(matrixOpts, null);\n } else if(!scene.selectBatch.length && !scene.unselectBatch.length) {\n scene.matrix.update(\n scene.unselectedOptions,\n Lib.extendFlat({}, matrixOpts, scene.selectedOptions, scene.viewOpts)\n );\n }\n\n scene.selectBatch = els;\n scene.unselectBatch = unels;\n\n return selection;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/splom/select.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/streamtube/attributes.js":
-/*!********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/streamtube/attributes.js ***!
- \********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar mesh3dAttrs = __webpack_require__(/*! ../mesh3d/attributes */ \"./node_modules/plotly.js/src/traces/mesh3d/attributes.js\");\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nvar attrs = {\n x: {\n valType: 'data_array',\n \n editType: 'calc+clearAxisTypes',\n \n },\n y: {\n valType: 'data_array',\n \n editType: 'calc+clearAxisTypes',\n \n },\n z: {\n valType: 'data_array',\n \n editType: 'calc+clearAxisTypes',\n \n },\n\n u: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n v: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n w: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n\n starts: {\n x: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n y: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n z: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n editType: 'calc'\n },\n\n maxdisplayed: {\n valType: 'integer',\n min: 0,\n dflt: 1000,\n \n editType: 'calc',\n \n },\n\n // TODO\n //\n // Should add 'absolute' (like cone traces have), but currently gl-streamtube3d's\n // `absoluteTubeSize` doesn't behave well enough for our needs.\n //\n // 'fixed' would be a nice addition to plot stream 'lines', see\n // https://github.com/plotly/plotly.js/commit/812be20750e21e0a1831975001c248d365850f73#r29129877\n //\n // sizemode: {\n // valType: 'enumerated',\n // values: ['scaled', 'absolute', 'fixed'],\n // dflt: 'scaled',\n // \n // editType: 'calc',\n // \n // },\n\n sizeref: {\n valType: 'number',\n \n editType: 'calc',\n min: 0,\n dflt: 1,\n \n },\n\n text: {\n valType: 'string',\n \n dflt: '',\n editType: 'calc',\n \n },\n hovertext: {\n valType: 'string',\n \n dflt: '',\n editType: 'calc',\n \n },\n hovertemplate: hovertemplateAttrs({editType: 'calc'}, {\n keys: [\n 'tubex', 'tubey', 'tubez',\n 'tubeu', 'tubev', 'tubew',\n 'norm', 'divergence'\n ]\n }),\n showlegend: extendFlat({}, baseAttrs.showlegend, {dflt: false})\n};\n\nextendFlat(attrs, colorScaleAttrs('', {\n colorAttr: 'u/v/w norm',\n showScaleDflt: true,\n editTypeOverride: 'calc'\n}));\n\nvar fromMesh3d = ['opacity', 'lightposition', 'lighting'];\nfromMesh3d.forEach(function(k) {\n attrs[k] = mesh3dAttrs[k];\n});\n\nattrs.hoverinfo = extendFlat({}, baseAttrs.hoverinfo, {\n editType: 'calc',\n flags: ['x', 'y', 'z', 'u', 'v', 'w', 'norm', 'divergence', 'text', 'name'],\n dflt: 'x+y+z+norm+text+name'\n});\n\nattrs.transforms = undefined;\n\nmodule.exports = attrs;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/streamtube/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/streamtube/calc.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/streamtube/calc.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar colorscaleCalc = __webpack_require__(/*! ../../components/colorscale/calc */ \"./node_modules/plotly.js/src/components/colorscale/calc.js\");\n\nfunction calc(gd, trace) {\n trace._len = Math.min(\n trace.u.length,\n trace.v.length,\n trace.w.length,\n trace.x.length,\n trace.y.length,\n trace.z.length\n );\n\n trace._u = filter(trace.u, trace._len);\n trace._v = filter(trace.v, trace._len);\n trace._w = filter(trace.w, trace._len);\n trace._x = filter(trace.x, trace._len);\n trace._y = filter(trace.y, trace._len);\n trace._z = filter(trace.z, trace._len);\n\n var grid = processGrid(trace);\n trace._gridFill = grid.fill;\n trace._Xs = grid.Xs;\n trace._Ys = grid.Ys;\n trace._Zs = grid.Zs;\n trace._len = grid.len;\n\n var slen = 0;\n var startx, starty, startz;\n if(trace.starts) {\n startx = filter(trace.starts.x || []);\n starty = filter(trace.starts.y || []);\n startz = filter(trace.starts.z || []);\n slen = Math.min(startx.length, starty.length, startz.length);\n }\n trace._startsX = startx || [];\n trace._startsY = starty || [];\n trace._startsZ = startz || [];\n\n var normMax = 0;\n var normMin = Infinity;\n var i;\n for(i = 0; i < trace._len; i++) {\n var u = trace._u[i];\n var v = trace._v[i];\n var w = trace._w[i];\n var norm = Math.sqrt(u * u + v * v + w * w);\n\n normMax = Math.max(normMax, norm);\n normMin = Math.min(normMin, norm);\n }\n\n colorscaleCalc(gd, trace, {\n vals: [normMin, normMax],\n containerStr: '',\n cLetter: 'c'\n });\n\n for(i = 0; i < slen; i++) {\n var sx = startx[i];\n grid.xMax = Math.max(grid.xMax, sx);\n grid.xMin = Math.min(grid.xMin, sx);\n\n var sy = starty[i];\n grid.yMax = Math.max(grid.yMax, sy);\n grid.yMin = Math.min(grid.yMin, sy);\n\n var sz = startz[i];\n grid.zMax = Math.max(grid.zMax, sz);\n grid.zMin = Math.min(grid.zMin, sz);\n }\n\n trace._slen = slen;\n trace._normMax = normMax;\n trace._xbnds = [grid.xMin, grid.xMax];\n trace._ybnds = [grid.yMin, grid.yMax];\n trace._zbnds = [grid.zMin, grid.zMax];\n}\n\nfunction processGrid(trace) {\n var x = trace._x;\n var y = trace._y;\n var z = trace._z;\n var len = trace._len;\n\n var i, j, k;\n\n var xMax = -Infinity;\n var xMin = Infinity;\n var yMax = -Infinity;\n var yMin = Infinity;\n var zMax = -Infinity;\n var zMin = Infinity;\n\n var gridFill = '';\n var filledX;\n var filledY;\n var filledZ;\n var firstX, lastX;\n var firstY, lastY;\n var firstZ, lastZ;\n if(len) {\n firstX = x[0];\n firstY = y[0];\n firstZ = z[0];\n }\n if(len > 1) {\n lastX = x[len - 1];\n lastY = y[len - 1];\n lastZ = z[len - 1];\n }\n\n for(i = 0; i < len; i++) {\n xMax = Math.max(xMax, x[i]);\n xMin = Math.min(xMin, x[i]);\n\n yMax = Math.max(yMax, y[i]);\n yMin = Math.min(yMin, y[i]);\n\n zMax = Math.max(zMax, z[i]);\n zMin = Math.min(zMin, z[i]);\n\n if(!filledX && x[i] !== firstX) {\n filledX = true;\n gridFill += 'x';\n }\n if(!filledY && y[i] !== firstY) {\n filledY = true;\n gridFill += 'y';\n }\n if(!filledZ && z[i] !== firstZ) {\n filledZ = true;\n gridFill += 'z';\n }\n }\n // fill if not filled - case of having dimension(s) with one item\n if(!filledX) gridFill += 'x';\n if(!filledY) gridFill += 'y';\n if(!filledZ) gridFill += 'z';\n\n var Xs = distinctVals(trace._x);\n var Ys = distinctVals(trace._y);\n var Zs = distinctVals(trace._z);\n\n gridFill = gridFill.replace('x', (firstX > lastX ? '-' : '+') + 'x');\n gridFill = gridFill.replace('y', (firstY > lastY ? '-' : '+') + 'y');\n gridFill = gridFill.replace('z', (firstZ > lastZ ? '-' : '+') + 'z');\n\n var empty = function() {\n len = 0;\n Xs = [];\n Ys = [];\n Zs = [];\n };\n\n // Over-specified mesh case, this would error in tube2mesh\n if(!len || len < Xs.length * Ys.length * Zs.length) empty();\n\n var getArray = function(c) { return c === 'x' ? x : c === 'y' ? y : z; };\n var getVals = function(c) { return c === 'x' ? Xs : c === 'y' ? Ys : Zs; };\n var getDir = function(c) { return c[len - 1] < c[0] ? -1 : 1; };\n\n var arrK = getArray(gridFill[1]);\n var arrJ = getArray(gridFill[3]);\n var arrI = getArray(gridFill[5]);\n var nk = getVals(gridFill[1]).length;\n var nj = getVals(gridFill[3]).length;\n var ni = getVals(gridFill[5]).length;\n\n var arbitrary = false;\n\n var getIndex = function(_i, _j, _k) {\n return nk * (nj * _i + _j) + _k;\n };\n\n var dirK = getDir(getArray(gridFill[1]));\n var dirJ = getDir(getArray(gridFill[3]));\n var dirI = getDir(getArray(gridFill[5]));\n\n for(i = 0; i < ni - 1; i++) {\n for(j = 0; j < nj - 1; j++) {\n for(k = 0; k < nk - 1; k++) {\n var q000 = getIndex(i, j, k);\n var q001 = getIndex(i, j, k + 1);\n var q010 = getIndex(i, j + 1, k);\n var q100 = getIndex(i + 1, j, k);\n\n if(\n !(arrK[q000] * dirK < arrK[q001] * dirK) ||\n !(arrJ[q000] * dirJ < arrJ[q010] * dirJ) ||\n !(arrI[q000] * dirI < arrI[q100] * dirI)\n ) {\n arbitrary = true;\n }\n\n if(arbitrary) break;\n }\n if(arbitrary) break;\n }\n if(arbitrary) break;\n }\n\n if(arbitrary) {\n Lib.warn('Encountered arbitrary coordinates! Unable to input data grid.');\n empty();\n }\n\n return {\n xMin: xMin,\n yMin: yMin,\n zMin: zMin,\n xMax: xMax,\n yMax: yMax,\n zMax: zMax,\n Xs: Xs,\n Ys: Ys,\n Zs: Zs,\n len: len,\n fill: gridFill\n };\n}\n\nfunction distinctVals(col) {\n return Lib.distinctVals(col).vals;\n}\n\nfunction filter(arr, len) {\n if(len === undefined) len = arr.length;\n\n // no need for casting typed arrays to numbers\n if(Lib.isTypedArray(arr)) return arr.subarray(0, len);\n\n var values = [];\n for(var i = 0; i < len; i++) {\n values[i] = +arr[i];\n }\n return values;\n}\n\nmodule.exports = {\n calc: calc,\n filter: filter,\n processGrid: processGrid\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/streamtube/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/streamtube/convert.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/streamtube/convert.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar tube2mesh = __webpack_require__(/*! gl-streamtube3d */ \"./node_modules/gl-streamtube3d/streamtube.js\");\nvar createTubeMesh = tube2mesh.createTubeMesh;\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar parseColorScale = __webpack_require__(/*! ../../lib/gl_format_color */ \"./node_modules/plotly.js/src/lib/gl_format_color.js\").parseColorScale;\nvar extractOpts = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\").extractOpts;\nvar zip3 = __webpack_require__(/*! ../../plots/gl3d/zip3 */ \"./node_modules/plotly.js/src/plots/gl3d/zip3.js\");\n\nvar axisName2scaleIndex = {xaxis: 0, yaxis: 1, zaxis: 2};\n\nfunction Streamtube(scene, uid) {\n this.scene = scene;\n this.uid = uid;\n this.mesh = null;\n this.data = null;\n}\n\nvar proto = Streamtube.prototype;\n\nproto.handlePick = function(selection) {\n var sceneLayout = this.scene.fullSceneLayout;\n var dataScale = this.scene.dataScale;\n\n function fromDataScale(v, axisName) {\n var ax = sceneLayout[axisName];\n var scale = dataScale[axisName2scaleIndex[axisName]];\n return ax.l2c(v) / scale;\n }\n\n if(selection.object === this.mesh) {\n var pos = selection.data.position;\n var uvx = selection.data.velocity;\n\n selection.traceCoordinate = [\n fromDataScale(pos[0], 'xaxis'),\n fromDataScale(pos[1], 'yaxis'),\n fromDataScale(pos[2], 'zaxis'),\n\n fromDataScale(uvx[0], 'xaxis'),\n fromDataScale(uvx[1], 'yaxis'),\n fromDataScale(uvx[2], 'zaxis'),\n\n // u/v/w norm\n selection.data.intensity * this.data._normMax,\n // divergence\n selection.data.divergence\n ];\n\n selection.textLabel = this.data.hovertext || this.data.text;\n\n return true;\n }\n};\n\nfunction getDfltStartingPositions(vec) {\n var len = vec.length;\n var s;\n\n if(len > 2) {\n s = vec.slice(1, len - 1);\n } else if(len === 2) {\n s = [(vec[0] + vec[1]) / 2];\n } else {\n s = vec;\n }\n return s;\n}\n\nfunction getBoundPads(vec) {\n var len = vec.length;\n if(len === 1) {\n return [0.5, 0.5];\n } else {\n return [vec[1] - vec[0], vec[len - 1] - vec[len - 2]];\n }\n}\n\nfunction convert(scene, trace) {\n var sceneLayout = scene.fullSceneLayout;\n var dataScale = scene.dataScale;\n var len = trace._len;\n var tubeOpts = {};\n\n function toDataCoords(arr, axisName) {\n var ax = sceneLayout[axisName];\n var scale = dataScale[axisName2scaleIndex[axisName]];\n return Lib.simpleMap(arr, function(v) { return ax.d2l(v) * scale; });\n }\n\n tubeOpts.vectors = zip3(\n toDataCoords(trace._u, 'xaxis'),\n toDataCoords(trace._v, 'yaxis'),\n toDataCoords(trace._w, 'zaxis'),\n len\n );\n\n // Over-specified mesh case, this would error in tube2mesh\n if(!len) {\n return {\n positions: [],\n cells: []\n };\n }\n\n var meshx = toDataCoords(trace._Xs, 'xaxis');\n var meshy = toDataCoords(trace._Ys, 'yaxis');\n var meshz = toDataCoords(trace._Zs, 'zaxis');\n\n tubeOpts.meshgrid = [meshx, meshy, meshz];\n tubeOpts.gridFill = trace._gridFill;\n\n var slen = trace._slen;\n if(slen) {\n tubeOpts.startingPositions = zip3(\n toDataCoords(trace._startsX, 'xaxis'),\n toDataCoords(trace._startsY, 'yaxis'),\n toDataCoords(trace._startsZ, 'zaxis')\n );\n } else {\n // Default starting positions:\n //\n // if len>2, cut xz plane at min-y,\n // takes all x/y/z pts on that plane except those on the edges\n // to generate \"well-defined\" tubes,\n //\n // if len=2, take position halfway between two the pts,\n //\n // if len=1, take that pt\n var sy0 = meshy[0];\n var sx = getDfltStartingPositions(meshx);\n var sz = getDfltStartingPositions(meshz);\n var startingPositions = new Array(sx.length * sz.length);\n var m = 0;\n\n for(var i = 0; i < sx.length; i++) {\n for(var k = 0; k < sz.length; k++) {\n startingPositions[m++] = [sx[i], sy0, sz[k]];\n }\n }\n tubeOpts.startingPositions = startingPositions;\n }\n\n tubeOpts.colormap = parseColorScale(trace);\n tubeOpts.tubeSize = trace.sizeref;\n tubeOpts.maxLength = trace.maxdisplayed;\n\n // add some padding around the bounds\n // to e.g. allow tubes starting from a slice of the x/y/z mesh\n // to go beyond bounds a little bit w/o getting clipped\n var xbnds = toDataCoords(trace._xbnds, 'xaxis');\n var ybnds = toDataCoords(trace._ybnds, 'yaxis');\n var zbnds = toDataCoords(trace._zbnds, 'zaxis');\n var xpads = getBoundPads(meshx);\n var ypads = getBoundPads(meshy);\n var zpads = getBoundPads(meshz);\n\n var bounds = [\n [xbnds[0] - xpads[0], ybnds[0] - ypads[0], zbnds[0] - zpads[0]],\n [xbnds[1] + xpads[1], ybnds[1] + ypads[1], zbnds[1] + zpads[1]]\n ];\n\n var meshData = tube2mesh(tubeOpts, bounds);\n\n // N.B. cmin/cmax correspond to the min/max vector norm\n // in the u/v/w arrays, which in general is NOT equal to max\n // intensity that colors the tubes.\n var cOpts = extractOpts(trace);\n meshData.vertexIntensityBounds = [cOpts.min / trace._normMax, cOpts.max / trace._normMax];\n\n // pass gl-mesh3d lighting attributes\n var lp = trace.lightposition;\n meshData.lightPosition = [lp.x, lp.y, lp.z];\n meshData.ambient = trace.lighting.ambient;\n meshData.diffuse = trace.lighting.diffuse;\n meshData.specular = trace.lighting.specular;\n meshData.roughness = trace.lighting.roughness;\n meshData.fresnel = trace.lighting.fresnel;\n meshData.opacity = trace.opacity;\n\n // stash autorange pad value\n trace._pad = meshData.tubeScale * trace.sizeref * 2;\n\n return meshData;\n}\n\nproto.update = function(data) {\n this.data = data;\n\n var meshData = convert(this.scene, data);\n this.mesh.update(meshData);\n};\n\nproto.dispose = function() {\n this.scene.glplot.remove(this.mesh);\n this.mesh.dispose();\n};\n\nfunction createStreamtubeTrace(scene, data) {\n var gl = scene.glplot.gl;\n\n var meshData = convert(scene, data);\n var mesh = createTubeMesh(gl, meshData);\n\n var streamtube = new Streamtube(scene, data.uid);\n streamtube.mesh = mesh;\n streamtube.data = data;\n mesh._trace = streamtube;\n\n scene.glplot.add(mesh);\n\n return streamtube;\n}\n\nmodule.exports = createStreamtubeTrace;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/streamtube/convert.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/streamtube/defaults.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/streamtube/defaults.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar colorscaleDefaults = __webpack_require__(/*! ../../components/colorscale/defaults */ \"./node_modules/plotly.js/src/components/colorscale/defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/streamtube/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var u = coerce('u');\n var v = coerce('v');\n var w = coerce('w');\n\n var x = coerce('x');\n var y = coerce('y');\n var z = coerce('z');\n\n if(\n !u || !u.length || !v || !v.length || !w || !w.length ||\n !x || !x.length || !y || !y.length || !z || !z.length\n ) {\n traceOut.visible = false;\n return;\n }\n\n coerce('starts.x');\n coerce('starts.y');\n coerce('starts.z');\n\n coerce('maxdisplayed');\n coerce('sizeref');\n\n coerce('lighting.ambient');\n coerce('lighting.diffuse');\n coerce('lighting.specular');\n coerce('lighting.roughness');\n coerce('lighting.fresnel');\n coerce('lightposition.x');\n coerce('lightposition.y');\n coerce('lightposition.z');\n\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'c'});\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n\n // disable 1D transforms (for now)\n // x/y/z and u/v/w have matching lengths,\n // but they don't have to match with starts.(x|y|z)\n traceOut._length = null;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/streamtube/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/streamtube/index.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/streamtube/index.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n moduleType: 'trace',\n name: 'streamtube',\n basePlotModule: __webpack_require__(/*! ../../plots/gl3d */ \"./node_modules/plotly.js/src/plots/gl3d/index.js\"),\n categories: ['gl3d', 'showLegend'],\n\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/streamtube/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/streamtube/defaults.js\"),\n colorbar: {\n min: 'cmin',\n max: 'cmax'\n },\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/streamtube/calc.js\").calc,\n plot: __webpack_require__(/*! ./convert */ \"./node_modules/plotly.js/src/traces/streamtube/convert.js\"),\n eventData: function(out, pt) {\n out.tubex = out.x;\n out.tubey = out.y;\n out.tubez = out.z;\n\n out.tubeu = pt.traceCoordinate[3];\n out.tubev = pt.traceCoordinate[4];\n out.tubew = pt.traceCoordinate[5];\n\n out.norm = pt.traceCoordinate[6];\n out.divergence = pt.traceCoordinate[7];\n\n // Does not correspond to input x/y/z, so delete them\n delete out.x;\n delete out.y;\n delete out.z;\n\n return out;\n },\n\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/streamtube/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sunburst/attributes.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sunburst/attributes.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar texttemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").texttemplateAttrs;\n\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar domainAttrs = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").attributes;\nvar pieAttrs = __webpack_require__(/*! ../pie/attributes */ \"./node_modules/plotly.js/src/traces/pie/attributes.js\");\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/sunburst/constants.js\");\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nmodule.exports = {\n labels: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n parents: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n\n values: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n branchvalues: {\n valType: 'enumerated',\n values: ['remainder', 'total'],\n dflt: 'remainder',\n editType: 'calc',\n \n \n },\n count: {\n valType: 'flaglist',\n flags: [\n 'branches',\n 'leaves'\n ],\n dflt: 'leaves',\n editType: 'calc',\n \n \n },\n\n level: {\n valType: 'any',\n editType: 'plot',\n anim: true,\n \n \n },\n maxdepth: {\n valType: 'integer',\n editType: 'plot',\n \n dflt: -1,\n \n },\n\n marker: extendFlat({\n colors: {\n valType: 'data_array',\n editType: 'calc',\n \n },\n\n // colorinheritance: {\n // valType: 'enumerated',\n // values: ['per-branch', 'per-label', false]\n // },\n\n line: {\n color: extendFlat({}, pieAttrs.marker.line.color, {\n dflt: null,\n \n }),\n width: extendFlat({}, pieAttrs.marker.line.width, {dflt: 1}),\n editType: 'calc'\n },\n editType: 'calc'\n },\n colorScaleAttrs('marker', {\n colorAttr: 'colors',\n anim: false // TODO: set to anim: true?\n })\n ),\n\n leaf: {\n opacity: {\n valType: 'number',\n editType: 'style',\n \n min: 0,\n max: 1,\n \n },\n editType: 'plot'\n },\n\n text: pieAttrs.text,\n textinfo: {\n valType: 'flaglist',\n \n flags: [\n 'label',\n 'text',\n 'value',\n 'current path',\n 'percent root',\n 'percent entry',\n 'percent parent'\n ],\n extras: ['none'],\n editType: 'plot',\n \n },\n\n // TODO: incorporate `label` and `value` in the eventData\n texttemplate: texttemplateAttrs({editType: 'plot'}, {\n keys: constants.eventDataKeys.concat(['label', 'value'])\n }),\n\n hovertext: pieAttrs.hovertext,\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {\n flags: [\n 'label',\n 'text',\n 'value',\n 'name',\n 'current path',\n 'percent root',\n 'percent entry',\n 'percent parent'\n ],\n dflt: 'label+text+value+name'\n }),\n hovertemplate: hovertemplateAttrs({}, {\n keys: constants.eventDataKeys\n }),\n\n textfont: pieAttrs.textfont,\n insidetextorientation: pieAttrs.insidetextorientation,\n insidetextfont: pieAttrs.insidetextfont,\n outsidetextfont: extendFlat({}, pieAttrs.outsidetextfont, {\n \n }),\n\n domain: domainAttrs({name: 'sunburst', trace: true, editType: 'calc'})\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sunburst/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sunburst/base_plot.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sunburst/base_plot.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar plots = __webpack_require__(/*! ../../plots/plots */ \"./node_modules/plotly.js/src/plots/plots.js\");\n\nexports.name = 'sunburst';\n\nexports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) {\n plots.plotBasePlot(exports.name, gd, traces, transitionOpts, makeOnCompleteCallback);\n};\n\nexports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {\n plots.cleanBasePlot(exports.name, newFullData, newFullLayout, oldFullData, oldFullLayout);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sunburst/base_plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sunburst/calc.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sunburst/calc.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3Hierarchy = __webpack_require__(/*! d3-hierarchy */ \"./node_modules/d3-hierarchy/src/index.js\");\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar makeColorScaleFn = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\").makeColorScaleFuncFromTrace;\nvar makePullColorFn = __webpack_require__(/*! ../pie/calc */ \"./node_modules/plotly.js/src/traces/pie/calc.js\").makePullColorFn;\nvar generateExtendedColors = __webpack_require__(/*! ../pie/calc */ \"./node_modules/plotly.js/src/traces/pie/calc.js\").generateExtendedColors;\nvar colorscaleCalc = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\").calc;\n\nvar ALMOST_EQUAL = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").ALMOST_EQUAL;\n\nvar sunburstExtendedColorWays = {};\nvar treemapExtendedColorWays = {};\n\nexports.calc = function(gd, trace) {\n var fullLayout = gd._fullLayout;\n var ids = trace.ids;\n var hasIds = Lib.isArrayOrTypedArray(ids);\n var labels = trace.labels;\n var parents = trace.parents;\n var values = trace.values;\n var hasValues = Lib.isArrayOrTypedArray(values);\n var cd = [];\n\n var parent2children = {};\n var refs = {};\n var addToLookup = function(parent, v) {\n if(parent2children[parent]) parent2children[parent].push(v);\n else parent2children[parent] = [v];\n refs[v] = 1;\n };\n\n // treat number `0` as valid\n var isValidKey = function(k) {\n return k || typeof k === 'number';\n };\n\n var isValidVal = function(i) {\n return !hasValues || (isNumeric(values[i]) && values[i] >= 0);\n };\n\n var len;\n var isValid;\n var getId;\n\n if(hasIds) {\n len = Math.min(ids.length, parents.length);\n isValid = function(i) { return isValidKey(ids[i]) && isValidVal(i); };\n getId = function(i) { return String(ids[i]); };\n } else {\n len = Math.min(labels.length, parents.length);\n isValid = function(i) { return isValidKey(labels[i]) && isValidVal(i); };\n // TODO We could allow some label / parent duplication\n //\n // From AJ:\n // It would work OK for one level\n // (multiple rows with the same name and different parents -\n // or even the same parent) but if that name is then used as a parent\n // which one is it?\n getId = function(i) { return String(labels[i]); };\n }\n\n if(hasValues) len = Math.min(len, values.length);\n\n for(var i = 0; i < len; i++) {\n if(isValid(i)) {\n var id = getId(i);\n var pid = isValidKey(parents[i]) ? String(parents[i]) : '';\n\n var cdi = {\n i: i,\n id: id,\n pid: pid,\n label: isValidKey(labels[i]) ? String(labels[i]) : ''\n };\n\n if(hasValues) cdi.v = +values[i];\n cd.push(cdi);\n addToLookup(pid, id);\n }\n }\n\n if(!parent2children['']) {\n var impliedRoots = [];\n var k;\n for(k in parent2children) {\n if(!refs[k]) {\n impliedRoots.push(k);\n }\n }\n\n // if an `id` has no ref in the `parents` array,\n // take it as being the root node\n\n if(impliedRoots.length === 1) {\n k = impliedRoots[0];\n cd.unshift({\n hasImpliedRoot: true,\n id: k,\n pid: '',\n label: k\n });\n } else {\n return Lib.warn('Multiple implied roots, cannot build ' + trace.type + ' hierarchy.');\n }\n } else if(parent2children[''].length > 1) {\n var dummyId = Lib.randstr();\n\n // if multiple rows linked to the root node,\n // add dummy \"root of roots\" node to make d3 build the hierarchy successfully\n\n for(var j = 0; j < cd.length; j++) {\n if(cd[j].pid === '') {\n cd[j].pid = dummyId;\n }\n }\n\n cd.unshift({\n hasMultipleRoots: true,\n id: dummyId,\n pid: '',\n label: ''\n });\n }\n\n // TODO might be better to replace stratify() with our own algorithm\n var root;\n try {\n root = d3Hierarchy.stratify()\n .id(function(d) { return d.id; })\n .parentId(function(d) { return d.pid; })(cd);\n } catch(e) {\n return Lib.warn('Failed to build ' + trace.type + ' hierarchy. Error: ' + e.message);\n }\n\n var hierarchy = d3Hierarchy.hierarchy(root);\n var failed = false;\n\n if(hasValues) {\n switch(trace.branchvalues) {\n case 'remainder':\n hierarchy.sum(function(d) { return d.data.v; });\n break;\n case 'total':\n hierarchy.each(function(d) {\n var cdi = d.data.data;\n var v = cdi.v;\n\n if(d.children) {\n var partialSum = d.children.reduce(function(a, c) {\n return a + c.data.data.v;\n }, 0);\n\n // N.B. we must fill in `value` for generated sectors\n // with the partialSum to compute the correct partition\n if(cdi.hasImpliedRoot || cdi.hasMultipleRoots) {\n v = partialSum;\n }\n\n if(v < partialSum * ALMOST_EQUAL) {\n failed = true;\n return Lib.warn([\n 'Total value for node', d.data.data.id,\n 'is smaller than the sum of its children.',\n '\\nparent value =', v,\n '\\nchildren sum =', partialSum\n ].join(' '));\n }\n }\n\n d.value = v;\n });\n break;\n }\n } else {\n countDescendants(hierarchy, trace, {\n branches: trace.count.indexOf('branches') !== -1,\n leaves: trace.count.indexOf('leaves') !== -1\n });\n }\n\n if(failed) return;\n\n // TODO add way to sort by height also?\n hierarchy.sort(function(a, b) { return b.value - a.value; });\n\n var pullColor;\n var scaleColor;\n var colors = trace.marker.colors || [];\n var hasColors = !!colors.length;\n\n if(trace._hasColorscale) {\n if(!hasColors) {\n colors = hasValues ? trace.values : trace._values;\n }\n\n colorscaleCalc(gd, trace, {\n vals: colors,\n containerStr: 'marker',\n cLetter: 'c'\n });\n\n scaleColor = makeColorScaleFn(trace.marker);\n } else {\n pullColor = makePullColorFn(fullLayout['_' + trace.type + 'colormap']);\n }\n\n // TODO keep track of 'root-children' (i.e. branch) for hover info etc.\n\n hierarchy.each(function(d) {\n var cdi = d.data.data;\n // N.B. this mutates items in `cd`\n cdi.color = trace._hasColorscale ?\n scaleColor(colors[cdi.i]) :\n pullColor(colors[cdi.i], cdi.id);\n });\n\n cd[0].hierarchy = hierarchy;\n\n return cd;\n};\n\n/*\n * `calc` filled in (and collated) explicit colors.\n * Now we need to propagate these explicit colors to other traces,\n * and fill in default colors.\n * This is done after sorting, so we pick defaults\n * in the order slices will be displayed\n */\nexports._runCrossTraceCalc = function(desiredType, gd) {\n var fullLayout = gd._fullLayout;\n var calcdata = gd.calcdata;\n var colorWay = fullLayout[desiredType + 'colorway'];\n var colorMap = fullLayout['_' + desiredType + 'colormap'];\n\n if(fullLayout['extend' + desiredType + 'colors']) {\n colorWay = generateExtendedColors(colorWay,\n desiredType === 'treemap' ? treemapExtendedColorWays : sunburstExtendedColorWays\n );\n }\n var dfltColorCount = 0;\n\n function pickColor(d) {\n var cdi = d.data.data;\n var id = cdi.id;\n\n if(cdi.color === false) {\n if(colorMap[id]) {\n // have we seen this label and assigned a color to it in a previous trace?\n cdi.color = colorMap[id];\n } else if(d.parent) {\n if(d.parent.parent) {\n // from third-level on, inherit from parent\n cdi.color = d.parent.data.data.color;\n } else {\n // pick new color for second level\n colorMap[id] = cdi.color = colorWay[dfltColorCount % colorWay.length];\n dfltColorCount++;\n }\n } else {\n // root gets no coloring by default\n cdi.color = 'rgba(0,0,0,0)';\n }\n }\n }\n\n for(var i = 0; i < calcdata.length; i++) {\n var cd = calcdata[i];\n var cd0 = cd[0];\n if(cd0.trace.type === desiredType && cd0.hierarchy) {\n cd0.hierarchy.each(pickColor);\n }\n }\n};\n\nexports.crossTraceCalc = function(gd) {\n return exports._runCrossTraceCalc('sunburst', gd);\n};\n\nfunction countDescendants(node, trace, opts) {\n var nChild = 0;\n\n var children = node.children;\n if(children) {\n var len = children.length;\n\n for(var i = 0; i < len; i++) {\n nChild += countDescendants(children[i], trace, opts);\n }\n\n if(opts.branches) nChild++; // count this branch\n } else {\n if(opts.leaves) nChild++; // count this leaf\n }\n\n // save to the node\n node.value = node.data.data.value = nChild;\n\n // save to the trace\n if(!trace._values) trace._values = [];\n trace._values[node.data.data.i] = nChild;\n\n return nChild;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sunburst/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sunburst/constants.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sunburst/constants.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n CLICK_TRANSITION_TIME: 750,\n CLICK_TRANSITION_EASING: 'linear',\n eventDataKeys: [\n // string\n 'currentPath',\n 'root',\n 'entry',\n // no need to add 'parent' here\n\n // percentages i.e. ratios\n 'percentRoot',\n 'percentEntry',\n 'percentParent'\n ]\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sunburst/constants.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sunburst/defaults.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sunburst/defaults.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/sunburst/attributes.js\");\nvar handleDomainDefaults = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").defaults;\nvar handleText = __webpack_require__(/*! ../bar/defaults */ \"./node_modules/plotly.js/src/traces/bar/defaults.js\").handleText;\n\nvar Colorscale = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\");\nvar hasColorscale = Colorscale.hasColorscale;\nvar colorscaleDefaults = Colorscale.handleDefaults;\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var labels = coerce('labels');\n var parents = coerce('parents');\n\n if(!labels || !labels.length || !parents || !parents.length) {\n traceOut.visible = false;\n return;\n }\n\n var vals = coerce('values');\n if(vals && vals.length) {\n coerce('branchvalues');\n } else {\n coerce('count');\n }\n\n coerce('level');\n coerce('maxdepth');\n\n var lineWidth = coerce('marker.line.width');\n if(lineWidth) coerce('marker.line.color', layout.paper_bgcolor);\n\n coerce('marker.colors');\n var withColorscale = traceOut._hasColorscale = (\n hasColorscale(traceIn, 'marker', 'colors') ||\n (traceIn.marker || {}).coloraxis // N.B. special logic to consider \"values\" colorscales\n );\n if(withColorscale) {\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: 'marker.', cLetter: 'c'});\n }\n\n coerce('leaf.opacity', withColorscale ? 1 : 0.7);\n\n var text = coerce('text');\n coerce('texttemplate');\n if(!traceOut.texttemplate) coerce('textinfo', Array.isArray(text) ? 'text+label' : 'label');\n\n coerce('hovertext');\n coerce('hovertemplate');\n\n var textposition = 'auto';\n handleText(traceIn, traceOut, layout, coerce, textposition, {\n moduleHasSelected: false,\n moduleHasUnselected: false,\n moduleHasConstrain: false,\n moduleHasCliponaxis: false,\n moduleHasTextangle: false,\n moduleHasInsideanchor: false\n });\n\n coerce('insidetextorientation');\n\n handleDomainDefaults(traceOut, layout, coerce);\n\n // do not support transforms for now\n traceOut._length = null;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sunburst/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sunburst/fx.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sunburst/fx.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar appendArrayPointValue = __webpack_require__(/*! ../../components/fx/helpers */ \"./node_modules/plotly.js/src/components/fx/helpers.js\").appendArrayPointValue;\nvar Fx = __webpack_require__(/*! ../../components/fx */ \"./node_modules/plotly.js/src/components/fx/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Events = __webpack_require__(/*! ../../lib/events */ \"./node_modules/plotly.js/src/lib/events.js\");\n\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/traces/sunburst/helpers.js\");\nvar pieHelpers = __webpack_require__(/*! ../pie/helpers */ \"./node_modules/plotly.js/src/traces/pie/helpers.js\");\n\nvar formatValue = pieHelpers.formatPieValue;\n\nmodule.exports = function attachFxHandlers(sliceTop, entry, gd, cd, opts) {\n var cd0 = cd[0];\n var trace = cd0.trace;\n var hierarchy = cd0.hierarchy;\n\n var isSunburst = trace.type === 'sunburst';\n var isTreemap = trace.type === 'treemap';\n\n // hover state vars\n // have we drawn a hover label, so it should be cleared later\n if(!('_hasHoverLabel' in trace)) trace._hasHoverLabel = false;\n // have we emitted a hover event, so later an unhover event should be emitted\n // note that click events do not depend on this - you can still get them\n // with hovermode: false or if you were earlier dragging, then clicked\n // in the same slice that you moused up in\n if(!('_hasHoverEvent' in trace)) trace._hasHoverEvent = false;\n\n var onMouseOver = function(pt) {\n var fullLayoutNow = gd._fullLayout;\n\n if(gd._dragging || fullLayoutNow.hovermode === false) return;\n\n var traceNow = gd._fullData[trace.index];\n var cdi = pt.data.data;\n var ptNumber = cdi.i;\n var isRoot = helpers.isHierarchyRoot(pt);\n var parent = helpers.getParent(hierarchy, pt);\n\n var val = helpers.getValue(pt);\n\n var _cast = function(astr) {\n return Lib.castOption(traceNow, ptNumber, astr);\n };\n\n var hovertemplate = _cast('hovertemplate');\n var hoverinfo = Fx.castHoverinfo(traceNow, fullLayoutNow, ptNumber);\n var separators = fullLayoutNow.separators;\n\n if(hovertemplate || (hoverinfo && hoverinfo !== 'none' && hoverinfo !== 'skip')) {\n var hoverCenterX;\n var hoverCenterY;\n if(isSunburst) {\n hoverCenterX = cd0.cx + pt.pxmid[0] * (1 - pt.rInscribed);\n hoverCenterY = cd0.cy + pt.pxmid[1] * (1 - pt.rInscribed);\n }\n if(isTreemap) {\n hoverCenterX = pt._hoverX;\n hoverCenterY = pt._hoverY;\n }\n\n var hoverPt = {};\n var parts = [];\n var thisText = [];\n var hasFlag = function(flag) { return parts.indexOf(flag) !== -1; };\n\n if(hoverinfo) {\n parts = hoverinfo === 'all' ?\n traceNow._module.attributes.hoverinfo.flags :\n hoverinfo.split('+');\n }\n\n hoverPt.label = cdi.label;\n if(hasFlag('label') && hoverPt.label) thisText.push(hoverPt.label);\n\n if(cdi.hasOwnProperty('v')) {\n hoverPt.value = cdi.v;\n hoverPt.valueLabel = formatValue(hoverPt.value, separators);\n if(hasFlag('value')) thisText.push(hoverPt.valueLabel);\n }\n\n hoverPt.currentPath = pt.currentPath = helpers.getPath(pt.data);\n if(hasFlag('current path') && !isRoot) {\n thisText.push(hoverPt.currentPath);\n }\n\n var tx;\n var allPercents = [];\n var insertPercent = function() {\n if(allPercents.indexOf(tx) === -1) { // no need to add redundant info\n thisText.push(tx);\n allPercents.push(tx);\n }\n };\n\n hoverPt.percentParent = pt.percentParent = val / helpers.getValue(parent);\n hoverPt.parent = pt.parentString = helpers.getPtLabel(parent);\n if(hasFlag('percent parent')) {\n tx = helpers.formatPercent(hoverPt.percentParent, separators) + ' of ' + hoverPt.parent;\n insertPercent();\n }\n\n hoverPt.percentEntry = pt.percentEntry = val / helpers.getValue(entry);\n hoverPt.entry = pt.entry = helpers.getPtLabel(entry);\n if(hasFlag('percent entry') && !isRoot && !pt.onPathbar) {\n tx = helpers.formatPercent(hoverPt.percentEntry, separators) + ' of ' + hoverPt.entry;\n insertPercent();\n }\n\n hoverPt.percentRoot = pt.percentRoot = val / helpers.getValue(hierarchy);\n hoverPt.root = pt.root = helpers.getPtLabel(hierarchy);\n if(hasFlag('percent root') && !isRoot) {\n tx = helpers.formatPercent(hoverPt.percentRoot, separators) + ' of ' + hoverPt.root;\n insertPercent();\n }\n\n hoverPt.text = _cast('hovertext') || _cast('text');\n if(hasFlag('text')) {\n tx = hoverPt.text;\n if(Lib.isValidTextValue(tx)) thisText.push(tx);\n }\n\n var hoverItems = {\n trace: traceNow,\n y: hoverCenterY,\n text: thisText.join('
'),\n name: (hovertemplate || hasFlag('name')) ? traceNow.name : undefined,\n color: _cast('hoverlabel.bgcolor') || cdi.color,\n borderColor: _cast('hoverlabel.bordercolor'),\n fontFamily: _cast('hoverlabel.font.family'),\n fontSize: _cast('hoverlabel.font.size'),\n fontColor: _cast('hoverlabel.font.color'),\n nameLength: _cast('hoverlabel.namelength'),\n textAlign: _cast('hoverlabel.align'),\n hovertemplate: hovertemplate,\n hovertemplateLabels: hoverPt,\n eventData: [makeEventData(pt, traceNow, opts.eventDataKeys)]\n };\n\n if(isSunburst) {\n hoverItems.x0 = hoverCenterX - pt.rInscribed * pt.rpx1;\n hoverItems.x1 = hoverCenterX + pt.rInscribed * pt.rpx1;\n hoverItems.idealAlign = pt.pxmid[0] < 0 ? 'left' : 'right';\n }\n if(isTreemap) {\n hoverItems.x = hoverCenterX;\n hoverItems.idealAlign = hoverCenterX < 0 ? 'left' : 'right';\n }\n\n Fx.loneHover(hoverItems, {\n container: fullLayoutNow._hoverlayer.node(),\n outerContainer: fullLayoutNow._paper.node(),\n gd: gd\n });\n\n trace._hasHoverLabel = true;\n }\n\n if(isTreemap) {\n var slice = sliceTop.select('path.surface');\n opts.styleOne(slice, pt, traceNow, {\n hovered: true\n });\n }\n\n trace._hasHoverEvent = true;\n gd.emit('plotly_hover', {\n points: [makeEventData(pt, traceNow, opts.eventDataKeys)],\n event: d3.event\n });\n };\n\n var onMouseOut = function(evt) {\n var fullLayoutNow = gd._fullLayout;\n var traceNow = gd._fullData[trace.index];\n var pt = d3.select(this).datum();\n\n if(trace._hasHoverEvent) {\n evt.originalEvent = d3.event;\n gd.emit('plotly_unhover', {\n points: [makeEventData(pt, traceNow, opts.eventDataKeys)],\n event: d3.event\n });\n trace._hasHoverEvent = false;\n }\n\n if(trace._hasHoverLabel) {\n Fx.loneUnhover(fullLayoutNow._hoverlayer.node());\n trace._hasHoverLabel = false;\n }\n\n if(isTreemap) {\n var slice = sliceTop.select('path.surface');\n opts.styleOne(slice, pt, traceNow, {\n hovered: false\n });\n }\n };\n\n var onClick = function(pt) {\n // TODO: this does not support right-click. If we want to support it, we\n // would likely need to change pie to use dragElement instead of straight\n // mapbox event binding. Or perhaps better, make a simple wrapper with the\n // right mousedown, mousemove, and mouseup handlers just for a left/right click\n // mapbox would use this too.\n var fullLayoutNow = gd._fullLayout;\n var traceNow = gd._fullData[trace.index];\n\n var noTransition = isSunburst && (helpers.isHierarchyRoot(pt) || helpers.isLeaf(pt));\n\n var id = helpers.getPtId(pt);\n var nextEntry = helpers.isEntry(pt) ?\n helpers.findEntryWithChild(hierarchy, id) :\n helpers.findEntryWithLevel(hierarchy, id);\n var nextLevel = helpers.getPtId(nextEntry);\n\n var typeClickEvtData = {\n points: [makeEventData(pt, traceNow, opts.eventDataKeys)],\n event: d3.event\n };\n if(!noTransition) typeClickEvtData.nextLevel = nextLevel;\n\n var clickVal = Events.triggerHandler(gd, 'plotly_' + trace.type + 'click', typeClickEvtData);\n\n if(clickVal !== false && fullLayoutNow.hovermode) {\n gd._hoverdata = [makeEventData(pt, traceNow, opts.eventDataKeys)];\n Fx.click(gd, d3.event);\n }\n\n // if click does not trigger a transition, we're done!\n if(noTransition) return;\n\n // if custom handler returns false, we're done!\n if(clickVal === false) return;\n\n // skip if triggered from dragging a nearby cartesian subplot\n if(gd._dragging) return;\n\n // skip during transitions, to avoid potential bugs\n // we could remove this check later\n if(gd._transitioning) return;\n\n // store 'old' level in guiEdit stash, so that subsequent Plotly.react\n // calls with the same uirevision can start from the same entry\n Registry.call('_storeDirectGUIEdit', traceNow, fullLayoutNow._tracePreGUI[traceNow.uid], {\n level: traceNow.level\n });\n\n var frame = {\n data: [{level: nextLevel}],\n traces: [trace.index]\n };\n\n var animOpts = {\n frame: {\n redraw: false,\n duration: opts.transitionTime\n },\n transition: {\n duration: opts.transitionTime,\n easing: opts.transitionEasing\n },\n mode: 'immediate',\n fromcurrent: true\n };\n\n Fx.loneUnhover(fullLayoutNow._hoverlayer.node());\n Registry.call('animate', gd, frame, animOpts);\n };\n\n sliceTop.on('mouseover', onMouseOver);\n sliceTop.on('mouseout', onMouseOut);\n sliceTop.on('click', onClick);\n};\n\nfunction makeEventData(pt, trace, keys) {\n var cdi = pt.data.data;\n\n var out = {\n curveNumber: trace.index,\n pointNumber: cdi.i,\n data: trace._input,\n fullData: trace,\n\n // TODO more things like 'children', 'siblings', 'hierarchy?\n };\n\n for(var i = 0; i < keys.length; i++) {\n var key = keys[i];\n if(key in pt) out[key] = pt[key];\n }\n // handle special case of parent\n if('parentString' in pt && !helpers.isHierarchyRoot(pt)) out.parent = pt.parentString;\n\n appendArrayPointValue(out, trace, cdi.i);\n\n return out;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sunburst/fx.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sunburst/helpers.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sunburst/helpers.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar setCursor = __webpack_require__(/*! ../../lib/setcursor */ \"./node_modules/plotly.js/src/lib/setcursor.js\");\nvar pieHelpers = __webpack_require__(/*! ../pie/helpers */ \"./node_modules/plotly.js/src/traces/pie/helpers.js\");\n\nexports.findEntryWithLevel = function(hierarchy, level) {\n var out;\n if(level) {\n hierarchy.eachAfter(function(pt) {\n if(exports.getPtId(pt) === level) {\n return out = pt.copy();\n }\n });\n }\n return out || hierarchy;\n};\n\nexports.findEntryWithChild = function(hierarchy, childId) {\n var out;\n hierarchy.eachAfter(function(pt) {\n var children = pt.children || [];\n for(var i = 0; i < children.length; i++) {\n var child = children[i];\n if(exports.getPtId(child) === childId) {\n return out = pt.copy();\n }\n }\n });\n return out || hierarchy;\n};\n\nexports.isEntry = function(pt) {\n return !pt.parent;\n};\n\nexports.isLeaf = function(pt) {\n return !pt.children;\n};\n\nexports.getPtId = function(pt) {\n return pt.data.data.id;\n};\n\nexports.getPtLabel = function(pt) {\n return pt.data.data.label;\n};\n\nexports.getValue = function(d) {\n return d.value;\n};\n\nexports.isHierarchyRoot = function(pt) {\n return getParentId(pt) === '';\n};\n\nexports.setSliceCursor = function(sliceTop, gd, opts) {\n var hide = opts.isTransitioning;\n if(!hide) {\n var pt = sliceTop.datum();\n hide = (\n (opts.hideOnRoot && exports.isHierarchyRoot(pt)) ||\n (opts.hideOnLeaves && exports.isLeaf(pt))\n );\n }\n setCursor(sliceTop, hide ? null : 'pointer');\n};\n\nfunction determineOutsideTextFont(trace, pt, layoutFont) {\n return {\n color: exports.getOutsideTextFontKey('color', trace, pt, layoutFont),\n family: exports.getOutsideTextFontKey('family', trace, pt, layoutFont),\n size: exports.getOutsideTextFontKey('size', trace, pt, layoutFont)\n };\n}\n\nfunction determineInsideTextFont(trace, pt, layoutFont, opts) {\n var onPathbar = (opts || {}).onPathbar;\n\n var cdi = pt.data.data;\n var ptNumber = cdi.i;\n\n var customColor = Lib.castOption(trace, ptNumber,\n (onPathbar ? 'pathbar.textfont' : 'insidetextfont') + '.color'\n );\n\n if(!customColor && trace._input.textfont) {\n // Why not simply using trace.textfont? Because if not set, it\n // defaults to layout.font which has a default color. But if\n // textfont.color and insidetextfont.color don't supply a value,\n // a contrasting color shall be used.\n customColor = Lib.castOption(trace._input, ptNumber, 'textfont.color');\n }\n\n return {\n color: customColor || Color.contrast(cdi.color),\n family: exports.getInsideTextFontKey('family', trace, pt, layoutFont, opts),\n size: exports.getInsideTextFontKey('size', trace, pt, layoutFont, opts)\n };\n}\n\nexports.getInsideTextFontKey = function(keyStr, trace, pt, layoutFont, opts) {\n var onPathbar = (opts || {}).onPathbar;\n var cont = onPathbar ? 'pathbar.textfont' : 'insidetextfont';\n var ptNumber = pt.data.data.i;\n\n return (\n Lib.castOption(trace, ptNumber, cont + '.' + keyStr) ||\n Lib.castOption(trace, ptNumber, 'textfont.' + keyStr) ||\n layoutFont.size\n );\n};\n\nexports.getOutsideTextFontKey = function(keyStr, trace, pt, layoutFont) {\n var ptNumber = pt.data.data.i;\n\n return (\n Lib.castOption(trace, ptNumber, 'outsidetextfont.' + keyStr) ||\n Lib.castOption(trace, ptNumber, 'textfont.' + keyStr) ||\n layoutFont.size\n );\n};\n\nexports.isOutsideText = function(trace, pt) {\n return !trace._hasColorscale && exports.isHierarchyRoot(pt);\n};\n\nexports.determineTextFont = function(trace, pt, layoutFont, opts) {\n return exports.isOutsideText(trace, pt) ?\n determineOutsideTextFont(trace, pt, layoutFont) :\n determineInsideTextFont(trace, pt, layoutFont, opts);\n};\n\nexports.hasTransition = function(transitionOpts) {\n // We could optimize hasTransition per trace,\n // as sunburst & treemap have no cross-trace logic!\n return !!(transitionOpts && transitionOpts.duration > 0);\n};\n\nexports.getMaxDepth = function(trace) {\n return trace.maxdepth >= 0 ? trace.maxdepth : Infinity;\n};\n\nexports.isHeader = function(pt, trace) { // it is only used in treemap.\n return !(exports.isLeaf(pt) || pt.depth === trace._maxDepth - 1);\n};\n\nfunction getParentId(pt) {\n return pt.data.data.pid;\n}\n\nexports.getParent = function(hierarchy, pt) {\n return exports.findEntryWithLevel(hierarchy, getParentId(pt));\n};\n\nexports.listPath = function(d, keyStr) {\n var parent = d.parent;\n if(!parent) return [];\n var list = keyStr ? [parent.data[keyStr]] : [parent];\n return exports.listPath(parent, keyStr).concat(list);\n};\n\nexports.getPath = function(d) {\n return exports.listPath(d, 'label').join('/') + '/';\n};\n\nexports.formatValue = pieHelpers.formatPieValue;\n\n// TODO: should combine the two in a separate PR - Also please note Lib.formatPercent should support separators.\nexports.formatPercent = function(v, separators) {\n var tx = Lib.formatPercent(v, 0); // use funnel(area) version\n if(tx === '0%') tx = pieHelpers.formatPiePercent(v, separators); // use pie version\n return tx;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sunburst/helpers.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sunburst/index.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sunburst/index.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n moduleType: 'trace',\n name: 'sunburst',\n basePlotModule: __webpack_require__(/*! ./base_plot */ \"./node_modules/plotly.js/src/traces/sunburst/base_plot.js\"),\n categories: [],\n animatable: true,\n\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/sunburst/attributes.js\"),\n layoutAttributes: __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/sunburst/layout_attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/sunburst/defaults.js\"),\n supplyLayoutDefaults: __webpack_require__(/*! ./layout_defaults */ \"./node_modules/plotly.js/src/traces/sunburst/layout_defaults.js\"),\n\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/sunburst/calc.js\").calc,\n crossTraceCalc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/sunburst/calc.js\").crossTraceCalc,\n\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/sunburst/plot.js\").plot,\n style: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/sunburst/style.js\").style,\n\n colorbar: __webpack_require__(/*! ../scatter/marker_colorbar */ \"./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js\"),\n\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sunburst/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sunburst/layout_attributes.js":
-/*!*************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sunburst/layout_attributes.js ***!
- \*************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n sunburstcolorway: {\n valType: 'colorlist',\n \n editType: 'calc',\n \n },\n extendsunburstcolors: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'calc',\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sunburst/layout_attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sunburst/layout_defaults.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sunburst/layout_defaults.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar layoutAttributes = __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/sunburst/layout_attributes.js\");\n\nmodule.exports = function supplyLayoutDefaults(layoutIn, layoutOut) {\n function coerce(attr, dflt) {\n return Lib.coerce(layoutIn, layoutOut, layoutAttributes, attr, dflt);\n }\n coerce('sunburstcolorway', layoutOut.colorway);\n coerce('extendsunburstcolors');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sunburst/layout_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sunburst/plot.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sunburst/plot.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar d3Hierarchy = __webpack_require__(/*! d3-hierarchy */ \"./node_modules/d3-hierarchy/src/index.js\");\n\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar svgTextUtils = __webpack_require__(/*! ../../lib/svg_text_utils */ \"./node_modules/plotly.js/src/lib/svg_text_utils.js\");\nvar uniformText = __webpack_require__(/*! ../bar/uniform_text */ \"./node_modules/plotly.js/src/traces/bar/uniform_text.js\");\nvar recordMinTextSize = uniformText.recordMinTextSize;\nvar clearMinTextSize = uniformText.clearMinTextSize;\nvar piePlot = __webpack_require__(/*! ../pie/plot */ \"./node_modules/plotly.js/src/traces/pie/plot.js\");\nvar computeTransform = piePlot.computeTransform;\nvar transformInsideText = piePlot.transformInsideText;\nvar styleOne = __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/sunburst/style.js\").styleOne;\nvar resizeText = __webpack_require__(/*! ../bar/style */ \"./node_modules/plotly.js/src/traces/bar/style.js\").resizeText;\nvar attachFxHandlers = __webpack_require__(/*! ./fx */ \"./node_modules/plotly.js/src/traces/sunburst/fx.js\");\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/sunburst/constants.js\");\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/traces/sunburst/helpers.js\");\n\nexports.plot = function(gd, cdmodule, transitionOpts, makeOnCompleteCallback) {\n var fullLayout = gd._fullLayout;\n var layer = fullLayout._sunburstlayer;\n var join, onComplete;\n\n // If transition config is provided, then it is only a partial replot and traces not\n // updated are removed.\n var isFullReplot = !transitionOpts;\n var hasTransition = !fullLayout.uniformtext.mode && helpers.hasTransition(transitionOpts);\n\n clearMinTextSize('sunburst', fullLayout);\n\n join = layer.selectAll('g.trace.sunburst')\n .data(cdmodule, function(cd) { return cd[0].trace.uid; });\n\n // using same 'stroke-linejoin' as pie traces\n join.enter().append('g')\n .classed('trace', true)\n .classed('sunburst', true)\n .attr('stroke-linejoin', 'round');\n\n join.order();\n\n if(hasTransition) {\n if(makeOnCompleteCallback) {\n // If it was passed a callback to register completion, make a callback. If\n // this is created, then it must be executed on completion, otherwise the\n // pos-transition redraw will not execute:\n onComplete = makeOnCompleteCallback();\n }\n\n var transition = d3.transition()\n .duration(transitionOpts.duration)\n .ease(transitionOpts.easing)\n .each('end', function() { onComplete && onComplete(); })\n .each('interrupt', function() { onComplete && onComplete(); });\n\n transition.each(function() {\n // Must run the selection again since otherwise enters/updates get grouped together\n // and these get executed out of order. Except we need them in order!\n layer.selectAll('g.trace').each(function(cd) {\n plotOne(gd, cd, this, transitionOpts);\n });\n });\n } else {\n join.each(function(cd) {\n plotOne(gd, cd, this, transitionOpts);\n });\n\n if(fullLayout.uniformtext.mode) {\n resizeText(gd, fullLayout._sunburstlayer.selectAll('.trace'), 'sunburst');\n }\n }\n\n if(isFullReplot) {\n join.exit().remove();\n }\n};\n\nfunction plotOne(gd, cd, element, transitionOpts) {\n var fullLayout = gd._fullLayout;\n var hasTransition = !fullLayout.uniformtext.mode && helpers.hasTransition(transitionOpts);\n\n var gTrace = d3.select(element);\n var slices = gTrace.selectAll('g.slice');\n\n var cd0 = cd[0];\n var trace = cd0.trace;\n var hierarchy = cd0.hierarchy;\n var entry = helpers.findEntryWithLevel(hierarchy, trace.level);\n var maxDepth = helpers.getMaxDepth(trace);\n\n var gs = fullLayout._size;\n var domain = trace.domain;\n var vpw = gs.w * (domain.x[1] - domain.x[0]);\n var vph = gs.h * (domain.y[1] - domain.y[0]);\n var rMax = 0.5 * Math.min(vpw, vph);\n var cx = cd0.cx = gs.l + gs.w * (domain.x[1] + domain.x[0]) / 2;\n var cy = cd0.cy = gs.t + gs.h * (1 - domain.y[0]) - vph / 2;\n\n if(!entry) {\n return slices.remove();\n }\n\n // previous root 'pt' (can be empty)\n var prevEntry = null;\n // stash of 'previous' position data used by tweening functions\n var prevLookup = {};\n\n if(hasTransition) {\n // Important: do this before binding new sliceData!\n slices.each(function(pt) {\n prevLookup[helpers.getPtId(pt)] = {\n rpx0: pt.rpx0,\n rpx1: pt.rpx1,\n x0: pt.x0,\n x1: pt.x1,\n transform: pt.transform\n };\n\n if(!prevEntry && helpers.isEntry(pt)) {\n prevEntry = pt;\n }\n });\n }\n\n // N.B. slice data isn't the calcdata,\n // grab corresponding calcdata item in sliceData[i].data.data\n var sliceData = partition(entry).descendants();\n\n var maxHeight = entry.height + 1;\n var yOffset = 0;\n var cutoff = maxDepth;\n // N.B. handle multiple-root special case\n if(cd0.hasMultipleRoots && helpers.isHierarchyRoot(entry)) {\n sliceData = sliceData.slice(1);\n maxHeight -= 1;\n yOffset = 1;\n cutoff += 1;\n }\n\n // filter out slices that won't show up on graph\n sliceData = sliceData.filter(function(pt) { return pt.y1 <= cutoff; });\n\n // partition span ('y') to sector radial px value\n var maxY = Math.min(maxHeight, maxDepth);\n var y2rpx = function(y) { return (y - yOffset) / maxY * rMax; };\n // (radial px value, partition angle ('x')) to px [x,y]\n var rx2px = function(r, x) { return [r * Math.cos(x), -r * Math.sin(x)]; };\n // slice path generation fn\n var pathSlice = function(d) { return Lib.pathAnnulus(d.rpx0, d.rpx1, d.x0, d.x1, cx, cy); };\n // slice text translate x/y\n\n var getTargetX = function(d) { return cx + getTextXY(d)[0] * (d.transform.rCenter || 0) + (d.transform.x || 0); };\n var getTargetY = function(d) { return cy + getTextXY(d)[1] * (d.transform.rCenter || 0) + (d.transform.y || 0); };\n\n slices = slices.data(sliceData, helpers.getPtId);\n\n slices.enter().append('g')\n .classed('slice', true);\n\n if(hasTransition) {\n slices.exit().transition()\n .each(function() {\n var sliceTop = d3.select(this);\n\n var slicePath = sliceTop.select('path.surface');\n slicePath.transition().attrTween('d', function(pt2) {\n var interp = makeExitSliceInterpolator(pt2);\n return function(t) { return pathSlice(interp(t)); };\n });\n\n var sliceTextGroup = sliceTop.select('g.slicetext');\n sliceTextGroup.attr('opacity', 0);\n })\n .remove();\n } else {\n slices.exit().remove();\n }\n\n slices.order();\n\n // next x1 (i.e. sector end angle) of previous entry\n var nextX1ofPrevEntry = null;\n if(hasTransition && prevEntry) {\n var prevEntryId = helpers.getPtId(prevEntry);\n slices.each(function(pt) {\n if(nextX1ofPrevEntry === null && (helpers.getPtId(pt) === prevEntryId)) {\n nextX1ofPrevEntry = pt.x1;\n }\n });\n }\n\n var updateSlices = slices;\n if(hasTransition) {\n updateSlices = updateSlices.transition().each('end', function() {\n // N.B. gd._transitioning is (still) *true* by the time\n // transition updates get here\n var sliceTop = d3.select(this);\n helpers.setSliceCursor(sliceTop, gd, {\n hideOnRoot: true,\n hideOnLeaves: true,\n isTransitioning: false\n });\n });\n }\n\n updateSlices.each(function(pt) {\n var sliceTop = d3.select(this);\n\n var slicePath = Lib.ensureSingle(sliceTop, 'path', 'surface', function(s) {\n s.style('pointer-events', 'all');\n });\n\n pt.rpx0 = y2rpx(pt.y0);\n pt.rpx1 = y2rpx(pt.y1);\n pt.xmid = (pt.x0 + pt.x1) / 2;\n pt.pxmid = rx2px(pt.rpx1, pt.xmid);\n pt.midangle = -(pt.xmid - Math.PI / 2);\n pt.startangle = -(pt.x0 - Math.PI / 2);\n pt.stopangle = -(pt.x1 - Math.PI / 2);\n pt.halfangle = 0.5 * Math.min(Lib.angleDelta(pt.x0, pt.x1) || Math.PI, Math.PI);\n pt.ring = 1 - (pt.rpx0 / pt.rpx1);\n pt.rInscribed = getInscribedRadiusFraction(pt, trace);\n\n if(hasTransition) {\n slicePath.transition().attrTween('d', function(pt2) {\n var interp = makeUpdateSliceInterpolator(pt2);\n return function(t) { return pathSlice(interp(t)); };\n });\n } else {\n slicePath.attr('d', pathSlice);\n }\n\n sliceTop\n .call(attachFxHandlers, entry, gd, cd, {\n eventDataKeys: constants.eventDataKeys,\n transitionTime: constants.CLICK_TRANSITION_TIME,\n transitionEasing: constants.CLICK_TRANSITION_EASING\n })\n .call(helpers.setSliceCursor, gd, {\n hideOnRoot: true,\n hideOnLeaves: true,\n isTransitioning: gd._transitioning\n });\n\n slicePath.call(styleOne, pt, trace);\n\n var sliceTextGroup = Lib.ensureSingle(sliceTop, 'g', 'slicetext');\n var sliceText = Lib.ensureSingle(sliceTextGroup, 'text', '', function(s) {\n // prohibit tex interpretation until we can handle\n // tex and regular text together\n s.attr('data-notex', 1);\n });\n\n var font = Lib.ensureUniformFontSize(gd, helpers.determineTextFont(trace, pt, fullLayout.font));\n\n sliceText.text(exports.formatSliceLabel(pt, entry, trace, cd, fullLayout))\n .classed('slicetext', true)\n .attr('text-anchor', 'middle')\n .call(Drawing.font, font)\n .call(svgTextUtils.convertToTspans, gd);\n\n // position the text relative to the slice\n var textBB = Drawing.bBox(sliceText.node());\n pt.transform = transformInsideText(textBB, pt, cd0);\n pt.transform.targetX = getTargetX(pt);\n pt.transform.targetY = getTargetY(pt);\n\n var strTransform = function(d, textBB) {\n var transform = d.transform;\n computeTransform(transform, textBB);\n\n transform.fontSize = font.size;\n recordMinTextSize(trace.type, transform, fullLayout);\n\n return Lib.getTextTransform(transform);\n };\n\n if(hasTransition) {\n sliceText.transition().attrTween('transform', function(pt2) {\n var interp = makeUpdateTextInterpolator(pt2);\n return function(t) { return strTransform(interp(t), textBB); };\n });\n } else {\n sliceText.attr('transform', strTransform(pt, textBB));\n }\n });\n\n function makeExitSliceInterpolator(pt) {\n var id = helpers.getPtId(pt);\n var prev = prevLookup[id];\n var entryPrev = prevLookup[helpers.getPtId(entry)];\n var next;\n\n if(entryPrev) {\n var a = pt.x1 > entryPrev.x1 ? 2 * Math.PI : 0;\n // if pt to remove:\n // - if 'below' where the root-node used to be: shrink it radially inward\n // - otherwise, collapse it clockwise or counterclockwise which ever is shortest to theta=0\n next = pt.rpx1 < entryPrev.rpx1 ? {rpx0: 0, rpx1: 0} : {x0: a, x1: a};\n } else {\n // this happens when maxdepth is set, when leaves must\n // be removed and the rootPt is new (i.e. does not have a 'prev' object)\n var parent;\n var parentId = helpers.getPtId(pt.parent);\n slices.each(function(pt2) {\n if(helpers.getPtId(pt2) === parentId) {\n return parent = pt2;\n }\n });\n var parentChildren = parent.children;\n var ci;\n parentChildren.forEach(function(pt2, i) {\n if(helpers.getPtId(pt2) === id) {\n return ci = i;\n }\n });\n var n = parentChildren.length;\n var interp = d3.interpolate(parent.x0, parent.x1);\n next = {\n rpx0: rMax, rpx1: rMax,\n x0: interp(ci / n), x1: interp((ci + 1) / n)\n };\n }\n\n return d3.interpolate(prev, next);\n }\n\n function makeUpdateSliceInterpolator(pt) {\n var prev0 = prevLookup[helpers.getPtId(pt)];\n var prev;\n var next = {x0: pt.x0, x1: pt.x1, rpx0: pt.rpx0, rpx1: pt.rpx1};\n\n if(prev0) {\n // if pt already on graph, this is easy\n prev = prev0;\n } else {\n // for new pts:\n if(prevEntry) {\n // if trace was visible before\n if(pt.parent) {\n if(nextX1ofPrevEntry) {\n // if new branch, twist it in clockwise or\n // counterclockwise which ever is shorter to\n // its final angle\n var a = pt.x1 > nextX1ofPrevEntry ? 2 * Math.PI : 0;\n prev = {x0: a, x1: a};\n } else {\n // if new leaf (when maxdepth is set),\n // grow it radially and angularly from\n // its parent node\n prev = {rpx0: rMax, rpx1: rMax};\n Lib.extendFlat(prev, interpX0X1FromParent(pt));\n }\n } else {\n // if new root-node, grow it radially\n prev = {rpx0: 0, rpx1: 0};\n }\n } else {\n // start sector of new traces from theta=0\n prev = {x0: 0, x1: 0};\n }\n }\n\n return d3.interpolate(prev, next);\n }\n\n function makeUpdateTextInterpolator(pt) {\n var prev0 = prevLookup[helpers.getPtId(pt)];\n var prev;\n var transform = pt.transform;\n\n if(prev0) {\n prev = prev0;\n } else {\n prev = {\n rpx1: pt.rpx1,\n transform: {\n textPosAngle: transform.textPosAngle,\n scale: 0,\n rotate: transform.rotate,\n rCenter: transform.rCenter,\n x: transform.x,\n y: transform.y\n }\n };\n\n // for new pts:\n if(prevEntry) {\n // if trace was visible before\n if(pt.parent) {\n if(nextX1ofPrevEntry) {\n // if new branch, twist it in clockwise or\n // counterclockwise which ever is shorter to\n // its final angle\n var a = pt.x1 > nextX1ofPrevEntry ? 2 * Math.PI : 0;\n prev.x0 = prev.x1 = a;\n } else {\n // if leaf\n Lib.extendFlat(prev, interpX0X1FromParent(pt));\n }\n } else {\n // if new root-node\n prev.x0 = prev.x1 = 0;\n }\n } else {\n // on new traces\n prev.x0 = prev.x1 = 0;\n }\n }\n\n var textPosAngleFn = d3.interpolate(prev.transform.textPosAngle, pt.transform.textPosAngle);\n var rpx1Fn = d3.interpolate(prev.rpx1, pt.rpx1);\n var x0Fn = d3.interpolate(prev.x0, pt.x0);\n var x1Fn = d3.interpolate(prev.x1, pt.x1);\n var scaleFn = d3.interpolate(prev.transform.scale, transform.scale);\n var rotateFn = d3.interpolate(prev.transform.rotate, transform.rotate);\n\n // smooth out start/end from entry, to try to keep text inside sector\n // while keeping transition smooth\n var pow = transform.rCenter === 0 ? 3 :\n prev.transform.rCenter === 0 ? 1 / 3 :\n 1;\n var _rCenterFn = d3.interpolate(prev.transform.rCenter, transform.rCenter);\n var rCenterFn = function(t) { return _rCenterFn(Math.pow(t, pow)); };\n\n return function(t) {\n var rpx1 = rpx1Fn(t);\n var x0 = x0Fn(t);\n var x1 = x1Fn(t);\n var rCenter = rCenterFn(t);\n var pxmid = rx2px(rpx1, (x0 + x1) / 2);\n var textPosAngle = textPosAngleFn(t);\n\n var d = {\n pxmid: pxmid,\n rpx1: rpx1,\n transform: {\n textPosAngle: textPosAngle,\n rCenter: rCenter,\n x: transform.x,\n y: transform.y\n }\n };\n\n recordMinTextSize(trace.type, transform, fullLayout);\n return {\n transform: {\n targetX: getTargetX(d),\n targetY: getTargetY(d),\n scale: scaleFn(t),\n rotate: rotateFn(t),\n rCenter: rCenter\n }\n };\n };\n }\n\n function interpX0X1FromParent(pt) {\n var parent = pt.parent;\n var parentPrev = prevLookup[helpers.getPtId(parent)];\n var out = {};\n\n if(parentPrev) {\n // if parent is visible\n var parentChildren = parent.children;\n var ci = parentChildren.indexOf(pt);\n var n = parentChildren.length;\n var interp = d3.interpolate(parentPrev.x0, parentPrev.x1);\n out.x0 = interp(ci / n);\n out.x1 = interp(ci / n);\n } else {\n // w/o visible parent\n // TODO !!! HOW ???\n out.x0 = out.x1 = 0;\n }\n\n return out;\n }\n}\n\n// x[0-1] keys are angles [radians]\n// y[0-1] keys are hierarchy heights [integers]\nfunction partition(entry) {\n return d3Hierarchy.partition()\n .size([2 * Math.PI, entry.height + 1])(entry);\n}\n\nexports.formatSliceLabel = function(pt, entry, trace, cd, fullLayout) {\n var texttemplate = trace.texttemplate;\n var textinfo = trace.textinfo;\n\n if(!texttemplate && (!textinfo || textinfo === 'none')) {\n return '';\n }\n\n var separators = fullLayout.separators;\n var cd0 = cd[0];\n var cdi = pt.data.data;\n var hierarchy = cd0.hierarchy;\n var isRoot = helpers.isHierarchyRoot(pt);\n var parent = helpers.getParent(hierarchy, pt);\n var val = helpers.getValue(pt);\n\n if(!texttemplate) {\n var parts = textinfo.split('+');\n var hasFlag = function(flag) { return parts.indexOf(flag) !== -1; };\n var thisText = [];\n var tx;\n\n if(hasFlag('label') && cdi.label) {\n thisText.push(cdi.label);\n }\n\n if(cdi.hasOwnProperty('v') && hasFlag('value')) {\n thisText.push(helpers.formatValue(cdi.v, separators));\n }\n\n if(!isRoot) {\n if(hasFlag('current path')) {\n thisText.push(helpers.getPath(pt.data));\n }\n\n var nPercent = 0;\n if(hasFlag('percent parent')) nPercent++;\n if(hasFlag('percent entry')) nPercent++;\n if(hasFlag('percent root')) nPercent++;\n var hasMultiplePercents = nPercent > 1;\n\n if(nPercent) {\n var percent;\n var addPercent = function(key) {\n tx = helpers.formatPercent(percent, separators);\n\n if(hasMultiplePercents) tx += ' of ' + key;\n thisText.push(tx);\n };\n\n if(hasFlag('percent parent') && !isRoot) {\n percent = val / helpers.getValue(parent);\n addPercent('parent');\n }\n if(hasFlag('percent entry')) {\n percent = val / helpers.getValue(entry);\n addPercent('entry');\n }\n if(hasFlag('percent root')) {\n percent = val / helpers.getValue(hierarchy);\n addPercent('root');\n }\n }\n }\n\n if(hasFlag('text')) {\n tx = Lib.castOption(trace, cdi.i, 'text');\n if(Lib.isValidTextValue(tx)) thisText.push(tx);\n }\n\n return thisText.join('
');\n }\n\n var txt = Lib.castOption(trace, cdi.i, 'texttemplate');\n if(!txt) return '';\n var obj = {};\n if(cdi.label) obj.label = cdi.label;\n if(cdi.hasOwnProperty('v')) {\n obj.value = cdi.v;\n obj.valueLabel = helpers.formatValue(cdi.v, separators);\n }\n\n obj.currentPath = helpers.getPath(pt.data);\n\n if(!isRoot) {\n obj.percentParent = val / helpers.getValue(parent);\n obj.percentParentLabel = helpers.formatPercent(\n obj.percentParent, separators\n );\n obj.parent = helpers.getPtLabel(parent);\n }\n\n obj.percentEntry = val / helpers.getValue(entry);\n obj.percentEntryLabel = helpers.formatPercent(\n obj.percentEntry, separators\n );\n obj.entry = helpers.getPtLabel(entry);\n\n obj.percentRoot = val / helpers.getValue(hierarchy);\n obj.percentRootLabel = helpers.formatPercent(\n obj.percentRoot, separators\n );\n obj.root = helpers.getPtLabel(hierarchy);\n\n if(cdi.hasOwnProperty('color')) {\n obj.color = cdi.color;\n }\n var ptTx = Lib.castOption(trace, cdi.i, 'text');\n if(Lib.isValidTextValue(ptTx) || ptTx === '') obj.text = ptTx;\n obj.customdata = Lib.castOption(trace, cdi.i, 'customdata');\n return Lib.texttemplateString(txt, obj, fullLayout._d3locale, obj, trace._meta || {});\n};\n\nfunction getInscribedRadiusFraction(pt) {\n if(pt.rpx0 === 0 && Lib.isFullCircle([pt.x0, pt.x1])) {\n // special case of 100% with no hole\n return 1;\n } else {\n return Math.max(0, Math.min(\n 1 / (1 + 1 / Math.sin(pt.halfangle)),\n pt.ring / 2\n ));\n }\n}\n\nfunction getTextXY(d) {\n return getCoords(d.rpx1, d.transform.textPosAngle);\n}\n\nfunction getCoords(r, angle) {\n return [r * Math.sin(angle), -r * Math.cos(angle)];\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sunburst/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/sunburst/style.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/sunburst/style.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar resizeText = __webpack_require__(/*! ../bar/uniform_text */ \"./node_modules/plotly.js/src/traces/bar/uniform_text.js\").resizeText;\n\nfunction style(gd) {\n var s = gd._fullLayout._sunburstlayer.selectAll('.trace');\n resizeText(gd, s, 'sunburst');\n\n s.each(function(cd) {\n var gTrace = d3.select(this);\n var cd0 = cd[0];\n var trace = cd0.trace;\n\n gTrace.style('opacity', trace.opacity);\n\n gTrace.selectAll('path.surface').each(function(pt) {\n d3.select(this).call(styleOne, pt, trace);\n });\n });\n}\n\nfunction styleOne(s, pt, trace) {\n var cdi = pt.data.data;\n var isLeaf = !pt.children;\n var ptNumber = cdi.i;\n var lineColor = Lib.castOption(trace, ptNumber, 'marker.line.color') || Color.defaultLine;\n var lineWidth = Lib.castOption(trace, ptNumber, 'marker.line.width') || 0;\n\n s.style('stroke-width', lineWidth)\n .call(Color.fill, cdi.color)\n .call(Color.stroke, lineColor)\n .style('opacity', isLeaf ? trace.leaf.opacity : null);\n}\n\nmodule.exports = {\n style: style,\n styleOne: styleOne\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/sunburst/style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/surface/attributes.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/surface/attributes.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar overrideAll = __webpack_require__(/*! ../../plot_api/edit_types */ \"./node_modules/plotly.js/src/plot_api/edit_types.js\").overrideAll;\n\nfunction makeContourProjAttr(axLetter) {\n return {\n valType: 'boolean',\n \n dflt: false,\n \n };\n}\n\nfunction makeContourAttr(axLetter) {\n return {\n show: {\n valType: 'boolean',\n \n dflt: false,\n \n },\n start: {\n valType: 'number',\n dflt: null,\n \n editType: 'plot',\n // impliedEdits: {'^autocontour': false},\n \n },\n end: {\n valType: 'number',\n dflt: null,\n \n editType: 'plot',\n // impliedEdits: {'^autocontour': false},\n \n },\n size: {\n valType: 'number',\n dflt: null,\n min: 0,\n \n editType: 'plot',\n // impliedEdits: {'^autocontour': false},\n \n },\n project: {\n x: makeContourProjAttr('x'),\n y: makeContourProjAttr('y'),\n z: makeContourProjAttr('z')\n },\n color: {\n valType: 'color',\n \n dflt: Color.defaultLine,\n \n },\n usecolormap: {\n valType: 'boolean',\n \n dflt: false,\n \n },\n width: {\n valType: 'number',\n \n min: 1,\n max: 16,\n dflt: 2,\n \n },\n highlight: {\n valType: 'boolean',\n \n dflt: true,\n \n },\n highlightcolor: {\n valType: 'color',\n \n dflt: Color.defaultLine,\n \n },\n highlightwidth: {\n valType: 'number',\n \n min: 1,\n max: 16,\n dflt: 2,\n \n }\n };\n}\n\nvar attrs = module.exports = overrideAll(extendFlat({\n z: {\n valType: 'data_array',\n \n },\n x: {\n valType: 'data_array',\n \n },\n y: {\n valType: 'data_array',\n \n },\n\n text: {\n valType: 'string',\n \n dflt: '',\n arrayOk: true,\n \n },\n hovertext: {\n valType: 'string',\n \n dflt: '',\n arrayOk: true,\n \n },\n hovertemplate: hovertemplateAttrs(),\n\n connectgaps: {\n valType: 'boolean',\n dflt: false,\n \n editType: 'calc',\n \n },\n\n surfacecolor: {\n valType: 'data_array',\n \n },\n},\n\ncolorScaleAttrs('', {\n colorAttr: 'z or surfacecolor',\n showScaleDflt: true,\n autoColorDflt: false,\n editTypeOverride: 'calc'\n}), {\n contours: {\n x: makeContourAttr('x'),\n y: makeContourAttr('y'),\n z: makeContourAttr('z')\n },\n hidesurface: {\n valType: 'boolean',\n \n dflt: false,\n \n },\n\n lightposition: {\n x: {\n valType: 'number',\n \n min: -1e5,\n max: 1e5,\n dflt: 10,\n \n },\n y: {\n valType: 'number',\n \n min: -1e5,\n max: 1e5,\n dflt: 1e4,\n \n },\n z: {\n valType: 'number',\n \n min: -1e5,\n max: 1e5,\n dflt: 0,\n \n }\n },\n\n lighting: {\n ambient: {\n valType: 'number',\n \n min: 0.00,\n max: 1.0,\n dflt: 0.8,\n \n },\n diffuse: {\n valType: 'number',\n \n min: 0.00,\n max: 1.00,\n dflt: 0.8,\n \n },\n specular: {\n valType: 'number',\n \n min: 0.00,\n max: 2.00,\n dflt: 0.05,\n \n },\n roughness: {\n valType: 'number',\n \n min: 0.00,\n max: 1.00,\n dflt: 0.5,\n \n },\n fresnel: {\n valType: 'number',\n \n min: 0.00,\n max: 5.00,\n dflt: 0.2,\n \n }\n },\n\n opacity: {\n valType: 'number',\n \n min: 0,\n max: 1,\n dflt: 1,\n \n },\n\n _deprecated: {\n zauto: extendFlat({}, colorScaleAttrs.zauto, {\n \n }),\n zmin: extendFlat({}, colorScaleAttrs.zmin, {\n \n }),\n zmax: extendFlat({}, colorScaleAttrs.zmax, {\n \n })\n },\n\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo),\n showlegend: extendFlat({}, baseAttrs.showlegend, {dflt: false}),\n}), 'calc', 'nested');\n\nattrs.x.editType = attrs.y.editType = attrs.z.editType = 'calc+clearAxisTypes';\nattrs.transforms = undefined;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/surface/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/surface/calc.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/surface/calc.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar colorscaleCalc = __webpack_require__(/*! ../../components/colorscale/calc */ \"./node_modules/plotly.js/src/components/colorscale/calc.js\");\n\n\n// Compute auto-z and autocolorscale if applicable\nmodule.exports = function calc(gd, trace) {\n if(trace.surfacecolor) {\n colorscaleCalc(gd, trace, {\n vals: trace.surfacecolor,\n containerStr: '',\n cLetter: 'c'\n });\n } else {\n colorscaleCalc(gd, trace, {\n vals: trace.z,\n containerStr: '',\n cLetter: 'c'\n });\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/surface/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/surface/convert.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/surface/convert.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\n\nvar createSurface = __webpack_require__(/*! gl-surface3d */ \"./node_modules/gl-surface3d/surface.js\");\n\nvar ndarray = __webpack_require__(/*! ndarray */ \"./node_modules/ndarray/ndarray.js\");\nvar homography = __webpack_require__(/*! ndarray-homography */ \"./node_modules/ndarray-homography/xform.js\");\nvar fill = __webpack_require__(/*! ndarray-fill */ \"./node_modules/ndarray-fill/index.js\");\n\nvar isArrayOrTypedArray = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").isArrayOrTypedArray;\nvar parseColorScale = __webpack_require__(/*! ../../lib/gl_format_color */ \"./node_modules/plotly.js/src/lib/gl_format_color.js\").parseColorScale;\nvar str2RgbaArray = __webpack_require__(/*! ../../lib/str2rgbarray */ \"./node_modules/plotly.js/src/lib/str2rgbarray.js\");\nvar extractOpts = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\").extractOpts;\n\nvar interp2d = __webpack_require__(/*! ../heatmap/interp2d */ \"./node_modules/plotly.js/src/traces/heatmap/interp2d.js\");\nvar findEmpties = __webpack_require__(/*! ../heatmap/find_empties */ \"./node_modules/plotly.js/src/traces/heatmap/find_empties.js\");\n\nfunction SurfaceTrace(scene, surface, uid) {\n this.scene = scene;\n this.uid = uid;\n this.surface = surface;\n this.data = null;\n this.showContour = [false, false, false];\n this.contourStart = [null, null, null];\n this.contourEnd = [null, null, null];\n this.contourSize = [0, 0, 0];\n this.minValues = [Infinity, Infinity, Infinity];\n this.maxValues = [-Infinity, -Infinity, -Infinity];\n this.dataScaleX = 1.0;\n this.dataScaleY = 1.0;\n this.refineData = true;\n this.objectOffset = [0, 0, 0];\n}\n\nvar proto = SurfaceTrace.prototype;\n\nproto.getXat = function(a, b, calendar, axis) {\n var v = (\n (!isArrayOrTypedArray(this.data.x)) ?\n a :\n (isArrayOrTypedArray(this.data.x[0])) ?\n this.data.x[b][a] :\n this.data.x[a]\n );\n\n return (calendar === undefined) ? v : axis.d2l(v, 0, calendar);\n};\n\nproto.getYat = function(a, b, calendar, axis) {\n var v = (\n (!isArrayOrTypedArray(this.data.y)) ?\n b :\n (isArrayOrTypedArray(this.data.y[0])) ?\n this.data.y[b][a] :\n this.data.y[b]\n );\n\n return (calendar === undefined) ? v : axis.d2l(v, 0, calendar);\n};\n\nproto.getZat = function(a, b, calendar, axis) {\n var v = this.data.z[b][a];\n\n if(v === null && this.data.connectgaps && this.data._interpolatedZ) {\n v = this.data._interpolatedZ[b][a];\n }\n\n return (calendar === undefined) ? v : axis.d2l(v, 0, calendar);\n};\n\nproto.handlePick = function(selection) {\n if(selection.object === this.surface) {\n var xRatio = (selection.data.index[0] - 1) / this.dataScaleX - 1;\n var yRatio = (selection.data.index[1] - 1) / this.dataScaleY - 1;\n\n var j = Math.max(Math.min(Math.round(xRatio), this.data.z[0].length - 1), 0);\n var k = Math.max(Math.min(Math.round(yRatio), this.data._ylength - 1), 0);\n\n selection.index = [j, k];\n\n selection.traceCoordinate = [\n this.getXat(j, k),\n this.getYat(j, k),\n this.getZat(j, k)\n ];\n\n selection.dataCoordinate = [\n this.getXat(j, k, this.data.xcalendar, this.scene.fullSceneLayout.xaxis),\n this.getYat(j, k, this.data.ycalendar, this.scene.fullSceneLayout.yaxis),\n this.getZat(j, k, this.data.zcalendar, this.scene.fullSceneLayout.zaxis)\n ];\n\n for(var i = 0; i < 3; i++) {\n var v = selection.dataCoordinate[i];\n if(v !== null && v !== undefined) {\n selection.dataCoordinate[i] *= this.scene.dataScale[i];\n }\n }\n\n var text = this.data.hovertext || this.data.text;\n if(Array.isArray(text) && text[k] && text[k][j] !== undefined) {\n selection.textLabel = text[k][j];\n } else if(text) {\n selection.textLabel = text;\n } else {\n selection.textLabel = '';\n }\n\n selection.data.dataCoordinate = selection.dataCoordinate.slice();\n\n this.surface.highlight(selection.data);\n\n // Snap spikes to data coordinate\n this.scene.glplot.spikes.position = selection.dataCoordinate;\n\n return true;\n }\n};\n\nfunction isColormapCircular(colormap) {\n var first = colormap[0].rgb;\n var last = colormap[colormap.length - 1].rgb;\n\n return (\n first[0] === last[0] &&\n first[1] === last[1] &&\n first[2] === last[2] &&\n first[3] === last[3]\n );\n}\n\nvar shortPrimes = [\n 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,\n 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199,\n 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293,\n 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397,\n 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499,\n 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599,\n 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691,\n 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797,\n 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887,\n 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997,\n 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097,\n 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193,\n 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297,\n 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,\n 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499,\n 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597,\n 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699,\n 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,\n 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889,\n 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999,\n 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099,\n 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179,\n 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,\n 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399,\n 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477,\n 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593,\n 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699,\n 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797,\n 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897,\n 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999\n];\n\nfunction getPow(a, b) {\n if(a < b) return 0;\n var n = 0;\n while(Math.floor(a % b) === 0) {\n a /= b;\n n++;\n }\n return n;\n}\n\nfunction getFactors(a) {\n var powers = [];\n for(var i = 0; i < shortPrimes.length; i++) {\n var b = shortPrimes[i];\n powers.push(\n getPow(a, b)\n );\n }\n return powers;\n}\n\nfunction smallestDivisor(a) {\n var A = getFactors(a);\n var result = a;\n for(var i = 0; i < shortPrimes.length; i++) {\n if(A[i] > 0) {\n result = shortPrimes[i];\n break;\n }\n }\n return result;\n}\n\nfunction leastCommonMultiple(a, b) {\n if(a < 1 || b < 1) return undefined;\n var A = getFactors(a);\n var B = getFactors(b);\n var n = 1;\n for(var i = 0; i < shortPrimes.length; i++) {\n n *= Math.pow(\n shortPrimes[i], Math.max(A[i], B[i])\n );\n }\n return n;\n}\n\nfunction arrayLCM(A) {\n if(A.length === 0) return undefined;\n var n = 1;\n for(var i = 0; i < A.length; i++) {\n n = leastCommonMultiple(n, A[i]);\n }\n return n;\n}\n\nproto.calcXnums = function(xlen) {\n var i;\n var nums = [];\n for(i = 1; i < xlen; i++) {\n var a = this.getXat(i - 1, 0);\n var b = this.getXat(i, 0);\n\n if(b !== a &&\n a !== undefined && a !== null &&\n b !== undefined && b !== null) {\n nums[i - 1] = Math.abs(b - a);\n } else {\n nums[i - 1] = 0;\n }\n }\n\n var totalDist = 0;\n for(i = 1; i < xlen; i++) {\n totalDist += nums[i - 1];\n }\n\n for(i = 1; i < xlen; i++) {\n if(nums[i - 1] === 0) {\n nums[i - 1] = 1;\n } else {\n nums[i - 1] = Math.round(totalDist / nums[i - 1]);\n }\n }\n\n return nums;\n};\n\nproto.calcYnums = function(ylen) {\n var i;\n var nums = [];\n for(i = 1; i < ylen; i++) {\n var a = this.getYat(0, i - 1);\n var b = this.getYat(0, i);\n\n if(b !== a &&\n a !== undefined && a !== null &&\n b !== undefined && b !== null) {\n nums[i - 1] = Math.abs(b - a);\n } else {\n nums[i - 1] = 0;\n }\n }\n\n var totalDist = 0;\n for(i = 1; i < ylen; i++) {\n totalDist += nums[i - 1];\n }\n\n for(i = 1; i < ylen; i++) {\n if(nums[i - 1] === 0) {\n nums[i - 1] = 1;\n } else {\n nums[i - 1] = Math.round(totalDist / nums[i - 1]);\n }\n }\n\n return nums;\n};\n\nvar highlyComposites = [1, 2, 4, 6, 12, 24, 36, 48, 60, 120, 180, 240, 360, 720, 840, 1260];\n\nvar MIN_RESOLUTION = highlyComposites[9];\nvar MAX_RESOLUTION = highlyComposites[13];\n\nproto.estimateScale = function(resSrc, axis) {\n var nums = (axis === 0) ?\n this.calcXnums(resSrc) :\n this.calcYnums(resSrc);\n\n var resDst = 1 + arrayLCM(nums);\n\n while(resDst < MIN_RESOLUTION) {\n resDst *= 2;\n }\n\n while(resDst > MAX_RESOLUTION) {\n resDst--;\n resDst /= smallestDivisor(resDst);\n resDst++;\n\n if(resDst < MIN_RESOLUTION) {\n // resDst = MIN_RESOLUTION; // option 1: use min resolution\n resDst = MAX_RESOLUTION; // option 2: use max resolution\n }\n }\n\n var scale = Math.round(resDst / resSrc);\n return (scale > 1) ? scale : 1;\n};\n\nproto.refineCoords = function(coords) {\n var scaleW = this.dataScaleX;\n var scaleH = this.dataScaleY;\n\n var width = coords[0].shape[0];\n var height = coords[0].shape[1];\n\n var newWidth = Math.floor(coords[0].shape[0] * scaleW + 1) | 0;\n var newHeight = Math.floor(coords[0].shape[1] * scaleH + 1) | 0;\n\n // Pad coords by +1\n var padWidth = 1 + width + 1;\n var padHeight = 1 + height + 1;\n var padImg = ndarray(new Float32Array(padWidth * padHeight), [padWidth, padHeight]);\n\n for(var i = 0; i < coords.length; ++i) {\n this.surface.padField(padImg, coords[i]);\n\n var scaledImg = ndarray(new Float32Array(newWidth * newHeight), [newWidth, newHeight]);\n homography(scaledImg, padImg,\n [\n scaleW, 0, 0,\n 0, scaleH, 0,\n 0, 0, 1\n ]\n );\n coords[i] = scaledImg;\n }\n};\n\nfunction insertIfNewLevel(arr, newValue) {\n var found = false;\n for(var k = 0; k < arr.length; k++) {\n if(newValue === arr[k]) {\n found = true;\n break;\n }\n }\n if(found === false) arr.push(newValue);\n}\n\nproto.setContourLevels = function() {\n var newLevels = [[], [], []];\n var useNewLevels = [false, false, false];\n var needsUpdate = false;\n\n var i, j, value;\n\n for(i = 0; i < 3; ++i) {\n if(this.showContour[i]) {\n needsUpdate = true;\n\n if(\n this.contourSize[i] > 0 &&\n this.contourStart[i] !== null &&\n this.contourEnd[i] !== null &&\n this.contourEnd[i] > this.contourStart[i]\n ) {\n useNewLevels[i] = true;\n\n for(j = this.contourStart[i]; j < this.contourEnd[i]; j += this.contourSize[i]) {\n value = j * this.scene.dataScale[i];\n\n insertIfNewLevel(newLevels[i], value);\n }\n }\n }\n }\n\n if(needsUpdate) {\n var allLevels = [[], [], []];\n for(i = 0; i < 3; ++i) {\n if(this.showContour[i]) {\n allLevels[i] = useNewLevels[i] ? newLevels[i] : this.scene.contourLevels[i];\n }\n }\n this.surface.update({ levels: allLevels });\n }\n};\n\nproto.update = function(data) {\n var scene = this.scene;\n var sceneLayout = scene.fullSceneLayout;\n var surface = this.surface;\n var alpha = data.opacity;\n var colormap = parseColorScale(data, alpha);\n var scaleFactor = scene.dataScale;\n var xlen = data.z[0].length;\n var ylen = data._ylength;\n var contourLevels = scene.contourLevels;\n\n // Save data\n this.data = data;\n\n /*\n * Fill and transpose zdata.\n * Consistent with 'heatmap' and 'contour', plotly 'surface'\n * 'z' are such that sub-arrays correspond to y-coords\n * and that the sub-array entries correspond to a x-coords,\n * which is the transpose of 'gl-surface-plot'.\n */\n\n var i, j, k, v;\n var rawCoords = [];\n for(i = 0; i < 3; i++) {\n rawCoords[i] = [];\n for(j = 0; j < xlen; j++) {\n rawCoords[i][j] = [];\n /*\n for(k = 0; k < ylen; k++) {\n rawCoords[i][j][k] = undefined;\n }\n */\n }\n }\n\n // coords x, y & z\n for(j = 0; j < xlen; j++) {\n for(k = 0; k < ylen; k++) {\n rawCoords[0][j][k] = this.getXat(j, k, data.xcalendar, sceneLayout.xaxis);\n rawCoords[1][j][k] = this.getYat(j, k, data.ycalendar, sceneLayout.yaxis);\n rawCoords[2][j][k] = this.getZat(j, k, data.zcalendar, sceneLayout.zaxis);\n }\n }\n\n if(data.connectgaps) {\n data._emptypoints = findEmpties(rawCoords[2]);\n interp2d(rawCoords[2], data._emptypoints);\n\n data._interpolatedZ = [];\n for(j = 0; j < xlen; j++) {\n data._interpolatedZ[j] = [];\n for(k = 0; k < ylen; k++) {\n data._interpolatedZ[j][k] = rawCoords[2][j][k];\n }\n }\n }\n\n // Note: log axes are not defined in surfaces yet.\n // but they could be defined here...\n\n for(i = 0; i < 3; i++) {\n for(j = 0; j < xlen; j++) {\n for(k = 0; k < ylen; k++) {\n v = rawCoords[i][j][k];\n if(v === null || v === undefined) {\n rawCoords[i][j][k] = NaN;\n } else {\n v = rawCoords[i][j][k] *= scaleFactor[i];\n }\n }\n }\n }\n\n for(i = 0; i < 3; i++) {\n for(j = 0; j < xlen; j++) {\n for(k = 0; k < ylen; k++) {\n v = rawCoords[i][j][k];\n if(v !== null && v !== undefined) {\n if(this.minValues[i] > v) {\n this.minValues[i] = v;\n }\n if(this.maxValues[i] < v) {\n this.maxValues[i] = v;\n }\n }\n }\n }\n }\n\n for(i = 0; i < 3; i++) {\n this.objectOffset[i] = 0.5 * (this.minValues[i] + this.maxValues[i]);\n }\n\n for(i = 0; i < 3; i++) {\n for(j = 0; j < xlen; j++) {\n for(k = 0; k < ylen; k++) {\n v = rawCoords[i][j][k];\n if(v !== null && v !== undefined) {\n rawCoords[i][j][k] -= this.objectOffset[i];\n }\n }\n }\n }\n\n // convert processed raw data to Float32 matrices\n var coords = [\n ndarray(new Float32Array(xlen * ylen), [xlen, ylen]),\n ndarray(new Float32Array(xlen * ylen), [xlen, ylen]),\n ndarray(new Float32Array(xlen * ylen), [xlen, ylen])\n ];\n fill(coords[0], function(row, col) { return rawCoords[0][row][col]; });\n fill(coords[1], function(row, col) { return rawCoords[1][row][col]; });\n fill(coords[2], function(row, col) { return rawCoords[2][row][col]; });\n rawCoords = []; // free memory\n\n var params = {\n colormap: colormap,\n levels: [[], [], []],\n showContour: [true, true, true],\n showSurface: !data.hidesurface,\n contourProject: [\n [false, false, false],\n [false, false, false],\n [false, false, false]\n ],\n contourWidth: [1, 1, 1],\n contourColor: [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]],\n contourTint: [1, 1, 1],\n dynamicColor: [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]],\n dynamicWidth: [1, 1, 1],\n dynamicTint: [1, 1, 1],\n opacity: data.opacity\n };\n\n var cOpts = extractOpts(data);\n params.intensityBounds = [cOpts.min, cOpts.max];\n\n // Refine surface color if necessary\n if(data.surfacecolor) {\n var intensity = ndarray(new Float32Array(xlen * ylen), [xlen, ylen]);\n\n fill(intensity, function(row, col) {\n return data.surfacecolor[col][row];\n });\n\n coords.push(intensity);\n } else {\n // when 'z' is used as 'intensity',\n // we must scale its value\n params.intensityBounds[0] *= scaleFactor[2];\n params.intensityBounds[1] *= scaleFactor[2];\n }\n\n if(MAX_RESOLUTION < coords[0].shape[0] ||\n MAX_RESOLUTION < coords[0].shape[1]) {\n this.refineData = false;\n }\n\n if(this.refineData === true) {\n this.dataScaleX = this.estimateScale(coords[0].shape[0], 0);\n this.dataScaleY = this.estimateScale(coords[0].shape[1], 1);\n if(this.dataScaleX !== 1 || this.dataScaleY !== 1) {\n this.refineCoords(coords);\n }\n }\n\n if(data.surfacecolor) {\n params.intensity = coords.pop();\n }\n\n var highlightEnable = [true, true, true];\n var axis = ['x', 'y', 'z'];\n\n for(i = 0; i < 3; ++i) {\n var contourParams = data.contours[axis[i]];\n highlightEnable[i] = contourParams.highlight;\n\n params.showContour[i] = contourParams.show || contourParams.highlight;\n if(!params.showContour[i]) continue;\n\n params.contourProject[i] = [\n contourParams.project.x,\n contourParams.project.y,\n contourParams.project.z\n ];\n\n if(contourParams.show) {\n this.showContour[i] = true;\n params.levels[i] = contourLevels[i];\n surface.highlightColor[i] = params.contourColor[i] = str2RgbaArray(contourParams.color);\n\n if(contourParams.usecolormap) {\n surface.highlightTint[i] = params.contourTint[i] = 0;\n } else {\n surface.highlightTint[i] = params.contourTint[i] = 1;\n }\n params.contourWidth[i] = contourParams.width;\n\n this.contourStart[i] = contourParams.start;\n this.contourEnd[i] = contourParams.end;\n this.contourSize[i] = contourParams.size;\n } else {\n this.showContour[i] = false;\n\n this.contourStart[i] = null;\n this.contourEnd[i] = null;\n this.contourSize[i] = 0;\n }\n\n if(contourParams.highlight) {\n params.dynamicColor[i] = str2RgbaArray(contourParams.highlightcolor);\n params.dynamicWidth[i] = contourParams.highlightwidth;\n }\n }\n\n // see https://github.com/plotly/plotly.js/issues/940\n if(isColormapCircular(colormap)) {\n params.vertexColor = true;\n }\n\n params.objectOffset = this.objectOffset;\n\n params.coords = coords;\n surface.update(params);\n\n surface.visible = data.visible;\n surface.enableDynamic = highlightEnable;\n surface.enableHighlight = highlightEnable;\n\n surface.snapToData = true;\n\n if('lighting' in data) {\n surface.ambientLight = data.lighting.ambient;\n surface.diffuseLight = data.lighting.diffuse;\n surface.specularLight = data.lighting.specular;\n surface.roughness = data.lighting.roughness;\n surface.fresnel = data.lighting.fresnel;\n }\n\n if('lightposition' in data) {\n surface.lightPosition = [data.lightposition.x, data.lightposition.y, data.lightposition.z];\n }\n\n if(alpha && alpha < 1) {\n surface.supportsTransparency = true;\n }\n};\n\nproto.dispose = function() {\n this.scene.glplot.remove(this.surface);\n this.surface.dispose();\n};\n\nfunction createSurfaceTrace(scene, data) {\n var gl = scene.glplot.gl;\n var surface = createSurface({ gl: gl });\n var result = new SurfaceTrace(scene, surface, data.uid);\n surface._trace = result;\n result.update(data);\n scene.glplot.add(surface);\n return result;\n}\n\nmodule.exports = createSurfaceTrace;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/surface/convert.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/surface/defaults.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/surface/defaults.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Registry = __webpack_require__(/*! ../../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar colorscaleDefaults = __webpack_require__(/*! ../../components/colorscale/defaults */ \"./node_modules/plotly.js/src/components/colorscale/defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/surface/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n var i, j;\n\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var x = coerce('x');\n var y = coerce('y');\n\n var z = coerce('z');\n if(!z || !z.length ||\n (x ? (x.length < 1) : false) ||\n (y ? (y.length < 1) : false)\n ) {\n traceOut.visible = false;\n return;\n }\n\n traceOut._xlength = (Array.isArray(x) && Lib.isArrayOrTypedArray(x[0])) ? z.length : z[0].length;\n traceOut._ylength = z.length;\n\n var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleTraceDefaults');\n handleCalendarDefaults(traceIn, traceOut, ['x', 'y', 'z'], layout);\n\n coerce('text');\n coerce('hovertext');\n coerce('hovertemplate');\n\n // Coerce remaining properties\n [\n 'lighting.ambient',\n 'lighting.diffuse',\n 'lighting.specular',\n 'lighting.roughness',\n 'lighting.fresnel',\n 'lightposition.x',\n 'lightposition.y',\n 'lightposition.z',\n 'hidesurface',\n 'connectgaps',\n 'opacity'\n ].forEach(function(x) { coerce(x); });\n\n var surfaceColor = coerce('surfacecolor');\n\n var dims = ['x', 'y', 'z'];\n for(i = 0; i < 3; ++i) {\n var contourDim = 'contours.' + dims[i];\n var show = coerce(contourDim + '.show');\n var highlight = coerce(contourDim + '.highlight');\n\n if(show || highlight) {\n for(j = 0; j < 3; ++j) {\n coerce(contourDim + '.project.' + dims[j]);\n }\n }\n\n if(show) {\n coerce(contourDim + '.color');\n coerce(contourDim + '.width');\n coerce(contourDim + '.usecolormap');\n }\n\n if(highlight) {\n coerce(contourDim + '.highlightcolor');\n coerce(contourDim + '.highlightwidth');\n }\n\n coerce(contourDim + '.start');\n coerce(contourDim + '.end');\n coerce(contourDim + '.size');\n }\n\n // backward compatibility block\n if(!surfaceColor) {\n mapLegacy(traceIn, 'zmin', 'cmin');\n mapLegacy(traceIn, 'zmax', 'cmax');\n mapLegacy(traceIn, 'zauto', 'cauto');\n }\n\n // TODO if contours.?.usecolormap are false and hidesurface is true\n // the colorbar shouldn't be shown by default\n\n colorscaleDefaults(\n traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'c'}\n );\n\n // disable 1D transforms - currently surface does NOT support column data like heatmap does\n // you can use mesh3d for this use case, but not surface\n traceOut._length = null;\n};\n\nfunction mapLegacy(traceIn, oldAttr, newAttr) {\n if(oldAttr in traceIn && !(newAttr in traceIn)) {\n traceIn[newAttr] = traceIn[oldAttr];\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/surface/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/surface/index.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/surface/index.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/surface/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/surface/defaults.js\"),\n colorbar: {\n min: 'cmin',\n max: 'cmax'\n },\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/surface/calc.js\"),\n plot: __webpack_require__(/*! ./convert */ \"./node_modules/plotly.js/src/traces/surface/convert.js\"),\n\n moduleType: 'trace',\n name: 'surface',\n basePlotModule: __webpack_require__(/*! ../../plots/gl3d */ \"./node_modules/plotly.js/src/plots/gl3d/index.js\"),\n categories: ['gl3d', '2dMap', 'showLegend'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/surface/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/table/attributes.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/table/attributes.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar annAttrs = __webpack_require__(/*! ../../components/annotations/attributes */ \"./node_modules/plotly.js/src/components/annotations/attributes.js\");\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar overrideAll = __webpack_require__(/*! ../../plot_api/edit_types */ \"./node_modules/plotly.js/src/plot_api/edit_types.js\").overrideAll;\nvar fontAttrs = __webpack_require__(/*! ../../plots/font_attributes */ \"./node_modules/plotly.js/src/plots/font_attributes.js\");\nvar domainAttrs = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").attributes;\n\nvar FORMAT_LINK = __webpack_require__(/*! ../../constants/docs */ \"./node_modules/plotly.js/src/constants/docs.js\").FORMAT_LINK;\n\nvar attrs = module.exports = overrideAll({\n domain: domainAttrs({name: 'table', trace: true}),\n\n columnwidth: {\n valType: 'number',\n arrayOk: true,\n dflt: null,\n \n \n },\n\n columnorder: {\n valType: 'data_array',\n \n \n },\n\n header: {\n\n values: {\n valType: 'data_array',\n \n dflt: [],\n \n },\n\n format: {\n valType: 'data_array',\n \n dflt: [],\n \n },\n\n prefix: {\n valType: 'string',\n arrayOk: true,\n dflt: null,\n \n \n },\n\n suffix: {\n valType: 'string',\n arrayOk: true,\n dflt: null,\n \n \n },\n\n height: {\n valType: 'number',\n dflt: 28,\n \n \n },\n\n align: extendFlat({}, annAttrs.align, {arrayOk: true}),\n\n line: {\n width: {\n valType: 'number',\n arrayOk: true,\n dflt: 1,\n \n },\n color: {\n valType: 'color',\n arrayOk: true,\n dflt: 'grey',\n \n }\n },\n\n fill: {\n color: {\n valType: 'color',\n arrayOk: true,\n dflt: 'white',\n \n \n }\n },\n\n font: extendFlat({}, fontAttrs({arrayOk: true}))\n },\n\n cells: {\n\n values: {\n valType: 'data_array',\n \n dflt: [],\n \n },\n\n format: {\n valType: 'data_array',\n \n dflt: [],\n \n },\n\n prefix: {\n valType: 'string',\n arrayOk: true,\n dflt: null,\n \n \n },\n\n suffix: {\n valType: 'string',\n arrayOk: true,\n dflt: null,\n \n \n },\n\n height: {\n valType: 'number',\n dflt: 20,\n \n \n },\n\n align: extendFlat({}, annAttrs.align, {arrayOk: true}),\n\n line: {\n width: {\n valType: 'number',\n arrayOk: true,\n dflt: 1,\n \n },\n color: {\n valType: 'color',\n arrayOk: true,\n dflt: 'grey',\n \n }\n },\n\n fill: {\n color: {\n valType: 'color',\n arrayOk: true,\n \n dflt: 'white',\n \n }\n },\n\n font: extendFlat({}, fontAttrs({arrayOk: true}))\n }\n}, 'calc', 'from-root');\nattrs.transforms = undefined;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/table/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/table/base_plot.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/table/base_plot.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar getModuleCalcData = __webpack_require__(/*! ../../plots/get_data */ \"./node_modules/plotly.js/src/plots/get_data.js\").getModuleCalcData;\nvar tablePlot = __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/table/plot.js\");\n\nvar TABLE = 'table';\n\nexports.name = TABLE;\n\nexports.plot = function(gd) {\n var calcData = getModuleCalcData(gd.calcdata, TABLE)[0];\n if(calcData.length) tablePlot(gd, calcData);\n};\n\nexports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {\n var hadTable = (oldFullLayout._has && oldFullLayout._has(TABLE));\n var hasTable = (newFullLayout._has && newFullLayout._has(TABLE));\n\n if(hadTable && !hasTable) {\n oldFullLayout._paperdiv.selectAll('.table').remove();\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/table/base_plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/table/calc.js":
-/*!*********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/table/calc.js ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar wrap = __webpack_require__(/*! ../../lib/gup */ \"./node_modules/plotly.js/src/lib/gup.js\").wrap;\n\nmodule.exports = function calc() {\n // we don't actually need to include the trace here, since that will be added\n // by Plots.doCalcdata, and that's all we actually need later.\n return wrap({});\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/table/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/table/constants.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/table/constants.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n cellPad: 8,\n columnExtentOffset: 10,\n columnTitleOffset: 28,\n emptyHeaderHeight: 16,\n latexCheck: /^\\$.*\\$$/,\n goldenRatio: 1.618,\n lineBreaker: '
',\n maxDimensionCount: 60,\n overdrag: 45,\n releaseTransitionDuration: 120,\n releaseTransitionEase: 'cubic-out',\n scrollbarCaptureWidth: 18,\n scrollbarHideDelay: 1000,\n scrollbarHideDuration: 1000,\n scrollbarOffset: 5,\n scrollbarWidth: 8,\n transitionDuration: 100,\n transitionEase: 'cubic-out',\n uplift: 5,\n wrapSpacer: ' ',\n wrapSplitCharacter: ' ',\n cn: {\n // general class names\n table: 'table',\n tableControlView: 'table-control-view',\n scrollBackground: 'scroll-background',\n yColumn: 'y-column',\n columnBlock: 'column-block',\n scrollAreaClip: 'scroll-area-clip',\n scrollAreaClipRect: 'scroll-area-clip-rect',\n columnBoundary: 'column-boundary',\n columnBoundaryClippath: 'column-boundary-clippath',\n columnBoundaryRect: 'column-boundary-rect',\n columnCells: 'column-cells',\n columnCell: 'column-cell',\n cellRect: 'cell-rect',\n cellText: 'cell-text',\n cellTextHolder: 'cell-text-holder',\n\n // scroll related class names\n scrollbarKit: 'scrollbar-kit',\n scrollbar: 'scrollbar',\n scrollbarSlider: 'scrollbar-slider',\n scrollbarGlyph: 'scrollbar-glyph',\n scrollbarCaptureZone: 'scrollbar-capture-zone'\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/table/constants.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/table/data_preparation_helper.js":
-/*!****************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/table/data_preparation_helper.js ***!
- \****************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar c = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/table/constants.js\");\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar isNumeric = __webpack_require__(/*! fast-isnumeric */ \"./node_modules/fast-isnumeric/index.js\");\n\n// pure functions, don't alter but passes on `gd` and parts of `trace` without deep copying\nmodule.exports = function calc(gd, trace) {\n var cellsValues = squareStringMatrix(trace.cells.values);\n var slicer = function(a) {\n return a.slice(trace.header.values.length, a.length);\n };\n var headerValuesIn = squareStringMatrix(trace.header.values);\n if(headerValuesIn.length && !headerValuesIn[0].length) {\n headerValuesIn[0] = [''];\n headerValuesIn = squareStringMatrix(headerValuesIn);\n }\n var headerValues = headerValuesIn\n .concat(slicer(cellsValues).map(function() {\n return emptyStrings((headerValuesIn[0] || ['']).length);\n }));\n\n var domain = trace.domain;\n var groupWidth = Math.floor(gd._fullLayout._size.w * (domain.x[1] - domain.x[0]));\n var groupHeight = Math.floor(gd._fullLayout._size.h * (domain.y[1] - domain.y[0]));\n var headerRowHeights = trace.header.values.length ?\n headerValues[0].map(function() { return trace.header.height; }) :\n [c.emptyHeaderHeight];\n var rowHeights = cellsValues.length ? cellsValues[0].map(function() { return trace.cells.height; }) : [];\n var headerHeight = headerRowHeights.reduce(sum, 0);\n var scrollHeight = groupHeight - headerHeight;\n var minimumFillHeight = scrollHeight + c.uplift;\n var anchorToRowBlock = makeAnchorToRowBlock(rowHeights, minimumFillHeight);\n var anchorToHeaderRowBlock = makeAnchorToRowBlock(headerRowHeights, headerHeight);\n var headerRowBlocks = makeRowBlock(anchorToHeaderRowBlock, []);\n var rowBlocks = makeRowBlock(anchorToRowBlock, headerRowBlocks);\n var uniqueKeys = {};\n var columnOrder = trace._fullInput.columnorder.concat(slicer(cellsValues.map(function(d, i) {return i;})));\n var columnWidths = headerValues.map(function(d, i) {\n var value = Array.isArray(trace.columnwidth) ?\n trace.columnwidth[Math.min(i, trace.columnwidth.length - 1)] :\n trace.columnwidth;\n return isNumeric(value) ? Number(value) : 1;\n });\n var totalColumnWidths = columnWidths.reduce(sum, 0);\n\n // fit columns in the available vertical space as there's no vertical scrolling now\n columnWidths = columnWidths.map(function(d) { return d / totalColumnWidths * groupWidth; });\n\n var maxLineWidth = Math.max(arrayMax(trace.header.line.width), arrayMax(trace.cells.line.width));\n\n var calcdata = {\n // include staticPlot in the key so if it changes we delete and redraw\n key: trace.uid + gd._context.staticPlot,\n translateX: domain.x[0] * gd._fullLayout._size.w,\n translateY: gd._fullLayout._size.h * (1 - domain.y[1]),\n size: gd._fullLayout._size,\n width: groupWidth,\n maxLineWidth: maxLineWidth,\n height: groupHeight,\n columnOrder: columnOrder, // will be mutated on column move, todo use in callback\n groupHeight: groupHeight,\n rowBlocks: rowBlocks,\n headerRowBlocks: headerRowBlocks,\n scrollY: 0, // will be mutated on scroll\n cells: extendFlat({}, trace.cells, {values: cellsValues}),\n headerCells: extendFlat({}, trace.header, {values: headerValues}),\n gdColumns: headerValues.map(function(d) {return d[0];}),\n gdColumnsOriginalOrder: headerValues.map(function(d) {return d[0];}),\n prevPages: [0, 0],\n scrollbarState: {scrollbarScrollInProgress: false},\n columns: headerValues.map(function(label, i) {\n var foundKey = uniqueKeys[label];\n uniqueKeys[label] = (foundKey || 0) + 1;\n var key = label + '__' + uniqueKeys[label];\n return {\n key: key,\n label: label,\n specIndex: i,\n xIndex: columnOrder[i],\n xScale: xScale,\n x: undefined, // initialized below\n calcdata: undefined, // initialized below\n columnWidth: columnWidths[i]\n };\n })\n };\n\n calcdata.columns.forEach(function(col) {\n col.calcdata = calcdata;\n col.x = xScale(col);\n });\n\n return calcdata;\n};\n\nfunction arrayMax(maybeArray) {\n if(Array.isArray(maybeArray)) {\n var max = 0;\n for(var i = 0; i < maybeArray.length; i++) {\n max = Math.max(max, arrayMax(maybeArray[i]));\n }\n return max;\n }\n return maybeArray;\n}\n\nfunction sum(a, b) { return a + b; }\n\n// fill matrix in place to equal lengths\n// and ensure it's uniformly 2D\nfunction squareStringMatrix(matrixIn) {\n var matrix = matrixIn.slice();\n var minLen = Infinity;\n var maxLen = 0;\n var i;\n for(i = 0; i < matrix.length; i++) {\n if(!Array.isArray(matrix[i])) matrix[i] = [matrix[i]];\n minLen = Math.min(minLen, matrix[i].length);\n maxLen = Math.max(maxLen, matrix[i].length);\n }\n\n if(minLen !== maxLen) {\n for(i = 0; i < matrix.length; i++) {\n var padLen = maxLen - matrix[i].length;\n if(padLen) matrix[i] = matrix[i].concat(emptyStrings(padLen));\n }\n }\n return matrix;\n}\n\nfunction emptyStrings(len) {\n var padArray = new Array(len);\n for(var j = 0; j < len; j++) padArray[j] = '';\n return padArray;\n}\n\nfunction xScale(d) {\n return d.calcdata.columns.reduce(function(prev, next) {\n return next.xIndex < d.xIndex ? prev + next.columnWidth : prev;\n }, 0);\n}\n\nfunction makeRowBlock(anchorToRowBlock, auxiliary) {\n var blockAnchorKeys = Object.keys(anchorToRowBlock);\n return blockAnchorKeys.map(function(k) {return extendFlat({}, anchorToRowBlock[k], {auxiliaryBlocks: auxiliary});});\n}\n\nfunction makeAnchorToRowBlock(rowHeights, minimumFillHeight) {\n var anchorToRowBlock = {};\n var currentRowHeight;\n var currentAnchor = 0;\n var currentBlockHeight = 0;\n var currentBlock = makeIdentity();\n var currentFirstRowIndex = 0;\n var blockCounter = 0;\n for(var i = 0; i < rowHeights.length; i++) {\n currentRowHeight = rowHeights[i];\n currentBlock.rows.push({\n rowIndex: i,\n rowHeight: currentRowHeight\n });\n currentBlockHeight += currentRowHeight;\n if(currentBlockHeight >= minimumFillHeight || i === rowHeights.length - 1) {\n anchorToRowBlock[currentAnchor] = currentBlock;\n currentBlock.key = blockCounter++;\n currentBlock.firstRowIndex = currentFirstRowIndex;\n currentBlock.lastRowIndex = i;\n currentBlock = makeIdentity();\n currentAnchor += currentBlockHeight;\n currentFirstRowIndex = i + 1;\n currentBlockHeight = 0;\n }\n }\n\n return anchorToRowBlock;\n}\n\nfunction makeIdentity() {\n return {\n firstRowIndex: null,\n lastRowIndex: null,\n rows: []\n };\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/table/data_preparation_helper.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/table/data_split_helpers.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/table/data_split_helpers.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\n// pure functions, don't alter but passes on `gd` and parts of `trace` without deep copying\n\nexports.splitToPanels = function(d) {\n var prevPages = [0, 0];\n var headerPanel = extendFlat({}, d, {\n key: 'header',\n type: 'header',\n page: 0,\n prevPages: prevPages,\n currentRepaint: [null, null],\n dragHandle: true,\n values: d.calcdata.headerCells.values[d.specIndex],\n rowBlocks: d.calcdata.headerRowBlocks,\n calcdata: extendFlat({}, d.calcdata, {cells: d.calcdata.headerCells})\n });\n var revolverPanel1 = extendFlat({}, d, {\n key: 'cells1',\n type: 'cells',\n page: 0,\n prevPages: prevPages,\n currentRepaint: [null, null],\n dragHandle: false,\n values: d.calcdata.cells.values[d.specIndex],\n rowBlocks: d.calcdata.rowBlocks\n });\n var revolverPanel2 = extendFlat({}, d, {\n key: 'cells2',\n type: 'cells',\n page: 1,\n prevPages: prevPages,\n currentRepaint: [null, null],\n dragHandle: false,\n values: d.calcdata.cells.values[d.specIndex],\n rowBlocks: d.calcdata.rowBlocks\n });\n // order due to SVG using painter's algo:\n return [revolverPanel1, revolverPanel2, headerPanel];\n};\n\nexports.splitToCells = function(d) {\n var fromTo = rowFromTo(d);\n return (d.values || []).slice(fromTo[0], fromTo[1]).map(function(v, i) {\n // By keeping identical key, a DOM node removal, creation and addition is spared, important when visible\n // grid has a lot of elements (quadratic with xcol/ycol count).\n // But it has to be busted when `svgUtil.convertToTspans` is used as it reshapes cell subtrees asynchronously,\n // and by that time the user may have scrolled away, resulting in stale overwrites. The real solution will be\n // to turn `svgUtil.convertToTspans` into a cancelable request, in which case no key busting is needed.\n var buster = (typeof v === 'string') && v.match(/[<$&> ]/) ? '_keybuster_' + Math.random() : '';\n return {\n // keyWithinBlock: /*fromTo[0] + */i, // optimized future version - no busting\n // keyWithinBlock: fromTo[0] + i, // initial always-unoptimized version - janky scrolling with 5+ columns\n keyWithinBlock: i + buster, // current compromise: regular content is very fast; async content is possible\n key: fromTo[0] + i,\n column: d,\n calcdata: d.calcdata,\n page: d.page,\n rowBlocks: d.rowBlocks,\n value: v\n };\n });\n};\n\nfunction rowFromTo(d) {\n var rowBlock = d.rowBlocks[d.page];\n // fixme rowBlock truthiness check is due to ugly hack of placing 2nd panel as d.page = -1\n var rowFrom = rowBlock ? rowBlock.rows[0].rowIndex : 0;\n var rowTo = rowBlock ? rowFrom + rowBlock.rows.length : 0;\n return [rowFrom, rowTo];\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/table/data_split_helpers.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/table/defaults.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/table/defaults.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/table/attributes.js\");\nvar handleDomainDefaults = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").defaults;\n\nfunction defaultColumnOrder(traceOut, coerce) {\n var specifiedColumnOrder = traceOut.columnorder || [];\n var commonLength = traceOut.header.values.length;\n var truncated = specifiedColumnOrder.slice(0, commonLength);\n var sorted = truncated.slice().sort(function(a, b) {return a - b;});\n var oneStepped = truncated.map(function(d) {return sorted.indexOf(d);});\n for(var i = oneStepped.length; i < commonLength; i++) {\n oneStepped.push(i);\n }\n coerce('columnorder', oneStepped);\n}\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n handleDomainDefaults(traceOut, layout, coerce);\n\n coerce('columnwidth');\n\n coerce('header.values');\n coerce('header.format');\n coerce('header.align');\n\n coerce('header.prefix');\n coerce('header.suffix');\n coerce('header.height');\n coerce('header.line.width');\n coerce('header.line.color');\n coerce('header.fill.color');\n Lib.coerceFont(coerce, 'header.font', Lib.extendFlat({}, layout.font));\n\n defaultColumnOrder(traceOut, coerce);\n\n coerce('cells.values');\n coerce('cells.format');\n coerce('cells.align');\n coerce('cells.prefix');\n coerce('cells.suffix');\n coerce('cells.height');\n coerce('cells.line.width');\n coerce('cells.line.color');\n coerce('cells.fill.color');\n Lib.coerceFont(coerce, 'cells.font', Lib.extendFlat({}, layout.font));\n\n // disable 1D transforms\n traceOut._length = null;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/table/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/table/index.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/table/index.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/table/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/table/defaults.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/table/calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/table/plot.js\"),\n\n moduleType: 'trace',\n name: 'table',\n basePlotModule: __webpack_require__(/*! ./base_plot */ \"./node_modules/plotly.js/src/traces/table/base_plot.js\"),\n categories: ['noOpacity'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/table/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/table/plot.js":
-/*!*********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/table/plot.js ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar c = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/table/constants.js\");\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar gup = __webpack_require__(/*! ../../lib/gup */ \"./node_modules/plotly.js/src/lib/gup.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar svgUtil = __webpack_require__(/*! ../../lib/svg_text_utils */ \"./node_modules/plotly.js/src/lib/svg_text_utils.js\");\nvar raiseToTop = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").raiseToTop;\nvar cancelEeaseColumn = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").cancelTransition;\nvar prepareData = __webpack_require__(/*! ./data_preparation_helper */ \"./node_modules/plotly.js/src/traces/table/data_preparation_helper.js\");\nvar splitData = __webpack_require__(/*! ./data_split_helpers */ \"./node_modules/plotly.js/src/traces/table/data_split_helpers.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\n\nmodule.exports = function plot(gd, wrappedTraceHolders) {\n var dynamic = !gd._context.staticPlot;\n\n var table = gd._fullLayout._paper.selectAll('.' + c.cn.table)\n .data(wrappedTraceHolders.map(function(wrappedTraceHolder) {\n var traceHolder = gup.unwrap(wrappedTraceHolder);\n var trace = traceHolder.trace;\n return prepareData(gd, trace);\n }), gup.keyFun);\n\n table.exit().remove();\n\n table.enter()\n .append('g')\n .classed(c.cn.table, true)\n .attr('overflow', 'visible')\n .style('box-sizing', 'content-box')\n .style('position', 'absolute')\n .style('left', 0)\n .style('overflow', 'visible')\n .style('shape-rendering', 'crispEdges')\n .style('pointer-events', 'all');\n\n table\n .attr('width', function(d) {return d.width + d.size.l + d.size.r;})\n .attr('height', function(d) {return d.height + d.size.t + d.size.b;})\n .attr('transform', function(d) {\n return 'translate(' + d.translateX + ',' + d.translateY + ')';\n });\n\n var tableControlView = table.selectAll('.' + c.cn.tableControlView)\n .data(gup.repeat, gup.keyFun);\n\n var cvEnter = tableControlView.enter()\n .append('g')\n .classed(c.cn.tableControlView, true)\n .style('box-sizing', 'content-box');\n if(dynamic) {\n cvEnter\n .on('mousemove', function(d) {\n tableControlView\n .filter(function(dd) {return d === dd;})\n .call(renderScrollbarKit, gd);\n })\n .on('mousewheel', function(d) {\n if(d.scrollbarState.wheeling) return;\n d.scrollbarState.wheeling = true;\n var newY = d.scrollY + d3.event.deltaY;\n var noChange = makeDragRow(gd, tableControlView, null, newY)(d);\n if(!noChange) {\n d3.event.stopPropagation();\n d3.event.preventDefault();\n }\n d.scrollbarState.wheeling = false;\n })\n .call(renderScrollbarKit, gd, true);\n }\n\n tableControlView\n .attr('transform', function(d) {return 'translate(' + d.size.l + ' ' + d.size.t + ')';});\n\n // scrollBackground merely ensures that mouse events are captured even on crazy fast scrollwheeling\n // otherwise rendering glitches may occur\n var scrollBackground = tableControlView.selectAll('.' + c.cn.scrollBackground)\n .data(gup.repeat, gup.keyFun);\n\n scrollBackground.enter()\n .append('rect')\n .classed(c.cn.scrollBackground, true)\n .attr('fill', 'none');\n\n scrollBackground\n .attr('width', function(d) {return d.width;})\n .attr('height', function(d) {return d.height;});\n\n tableControlView.each(function(d) {\n Drawing.setClipUrl(d3.select(this), scrollAreaBottomClipKey(gd, d), gd);\n });\n\n var yColumn = tableControlView.selectAll('.' + c.cn.yColumn)\n .data(function(vm) {return vm.columns;}, gup.keyFun);\n\n yColumn.enter()\n .append('g')\n .classed(c.cn.yColumn, true);\n\n yColumn.exit().remove();\n\n yColumn.attr('transform', function(d) {return 'translate(' + d.x + ' 0)';});\n\n if(dynamic) {\n yColumn.call(d3.behavior.drag()\n .origin(function(d) {\n var movedColumn = d3.select(this);\n easeColumn(movedColumn, d, -c.uplift);\n raiseToTop(this);\n d.calcdata.columnDragInProgress = true;\n renderScrollbarKit(tableControlView.filter(function(dd) {return d.calcdata.key === dd.key;}), gd);\n return d;\n })\n .on('drag', function(d) {\n var movedColumn = d3.select(this);\n var getter = function(dd) {return (d === dd ? d3.event.x : dd.x) + dd.columnWidth / 2;};\n d.x = Math.max(-c.overdrag, Math.min(d.calcdata.width + c.overdrag - d.columnWidth, d3.event.x));\n\n var sortableColumns = flatData(yColumn).filter(function(dd) {return dd.calcdata.key === d.calcdata.key;});\n var newOrder = sortableColumns.sort(function(a, b) {return getter(a) - getter(b);});\n newOrder.forEach(function(dd, i) {\n dd.xIndex = i;\n dd.x = d === dd ? dd.x : dd.xScale(dd);\n });\n\n yColumn.filter(function(dd) {return d !== dd;})\n .transition()\n .ease(c.transitionEase)\n .duration(c.transitionDuration)\n .attr('transform', function(d) {return 'translate(' + d.x + ' 0)';});\n movedColumn\n .call(cancelEeaseColumn)\n .attr('transform', 'translate(' + d.x + ' -' + c.uplift + ' )');\n })\n .on('dragend', function(d) {\n var movedColumn = d3.select(this);\n var p = d.calcdata;\n d.x = d.xScale(d);\n d.calcdata.columnDragInProgress = false;\n easeColumn(movedColumn, d, 0);\n columnMoved(gd, p, p.columns.map(function(dd) {return dd.xIndex;}));\n })\n );\n }\n\n yColumn.each(function(d) {\n Drawing.setClipUrl(d3.select(this), columnBoundaryClipKey(gd, d), gd);\n });\n\n var columnBlock = yColumn.selectAll('.' + c.cn.columnBlock)\n .data(splitData.splitToPanels, gup.keyFun);\n\n columnBlock.enter()\n .append('g')\n .classed(c.cn.columnBlock, true)\n .attr('id', function(d) {return d.key;});\n\n columnBlock\n .style('cursor', function(d) {\n return d.dragHandle ? 'ew-resize' : d.calcdata.scrollbarState.barWiggleRoom ? 'ns-resize' : 'default';\n });\n\n var headerColumnBlock = columnBlock.filter(headerBlock);\n var cellsColumnBlock = columnBlock.filter(cellsBlock);\n\n if(dynamic) {\n cellsColumnBlock.call(d3.behavior.drag()\n .origin(function(d) {\n d3.event.stopPropagation();\n return d;\n })\n .on('drag', makeDragRow(gd, tableControlView, -1))\n .on('dragend', function() {\n // fixme emit plotly notification\n })\n );\n }\n\n // initial rendering: header is rendered first, as it may may have async LaTeX (show header first)\n // but blocks are _entered_ the way they are due to painter's algo (header on top)\n renderColumnCellTree(gd, tableControlView, headerColumnBlock, columnBlock);\n renderColumnCellTree(gd, tableControlView, cellsColumnBlock, columnBlock);\n\n var scrollAreaClip = tableControlView.selectAll('.' + c.cn.scrollAreaClip)\n .data(gup.repeat, gup.keyFun);\n\n scrollAreaClip.enter()\n .append('clipPath')\n .classed(c.cn.scrollAreaClip, true)\n .attr('id', function(d) {return scrollAreaBottomClipKey(gd, d);});\n\n var scrollAreaClipRect = scrollAreaClip.selectAll('.' + c.cn.scrollAreaClipRect)\n .data(gup.repeat, gup.keyFun);\n\n scrollAreaClipRect.enter()\n .append('rect')\n .classed(c.cn.scrollAreaClipRect, true)\n .attr('x', -c.overdrag)\n .attr('y', -c.uplift)\n .attr('fill', 'none');\n\n scrollAreaClipRect\n .attr('width', function(d) {return d.width + 2 * c.overdrag;})\n .attr('height', function(d) {return d.height + c.uplift;});\n\n var columnBoundary = yColumn.selectAll('.' + c.cn.columnBoundary)\n .data(gup.repeat, gup.keyFun);\n\n columnBoundary.enter()\n .append('g')\n .classed(c.cn.columnBoundary, true);\n\n var columnBoundaryClippath = yColumn.selectAll('.' + c.cn.columnBoundaryClippath)\n .data(gup.repeat, gup.keyFun);\n\n // SVG spec doesn't mandate wrapping into a and doesn't seem to cause a speed difference\n columnBoundaryClippath.enter()\n .append('clipPath')\n .classed(c.cn.columnBoundaryClippath, true);\n\n columnBoundaryClippath\n .attr('id', function(d) {return columnBoundaryClipKey(gd, d);});\n\n var columnBoundaryRect = columnBoundaryClippath.selectAll('.' + c.cn.columnBoundaryRect)\n .data(gup.repeat, gup.keyFun);\n\n columnBoundaryRect.enter()\n .append('rect')\n .classed(c.cn.columnBoundaryRect, true)\n .attr('fill', 'none');\n\n columnBoundaryRect\n .attr('width', function(d) { return d.columnWidth + 2 * roundHalfWidth(d); })\n .attr('height', function(d) {return d.calcdata.height + 2 * roundHalfWidth(d) + c.uplift;})\n .attr('x', function(d) { return -roundHalfWidth(d); })\n .attr('y', function(d) { return -roundHalfWidth(d); });\n\n updateBlockYPosition(null, cellsColumnBlock, tableControlView);\n};\n\nfunction roundHalfWidth(d) {\n return Math.ceil(d.calcdata.maxLineWidth / 2);\n}\n\nfunction scrollAreaBottomClipKey(gd, d) {\n return 'clip' + gd._fullLayout._uid + '_scrollAreaBottomClip_' + d.key;\n}\n\nfunction columnBoundaryClipKey(gd, d) {\n return 'clip' + gd._fullLayout._uid + '_columnBoundaryClippath_' + d.calcdata.key + '_' + d.specIndex;\n}\n\nfunction flatData(selection) {\n return [].concat.apply([], selection.map(function(g) {return g;}))\n .map(function(g) {return g.__data__;});\n}\n\nfunction renderScrollbarKit(tableControlView, gd, bypassVisibleBar) {\n function calcTotalHeight(d) {\n var blocks = d.rowBlocks;\n return firstRowAnchor(blocks, blocks.length - 1) + (blocks.length ? rowsHeight(blocks[blocks.length - 1], Infinity) : 1);\n }\n\n var scrollbarKit = tableControlView.selectAll('.' + c.cn.scrollbarKit)\n .data(gup.repeat, gup.keyFun);\n\n scrollbarKit.enter()\n .append('g')\n .classed(c.cn.scrollbarKit, true)\n .style('shape-rendering', 'geometricPrecision');\n\n scrollbarKit\n .each(function(d) {\n var s = d.scrollbarState;\n s.totalHeight = calcTotalHeight(d);\n s.scrollableAreaHeight = d.groupHeight - headerHeight(d);\n s.currentlyVisibleHeight = Math.min(s.totalHeight, s.scrollableAreaHeight);\n s.ratio = s.currentlyVisibleHeight / s.totalHeight;\n s.barLength = Math.max(s.ratio * s.currentlyVisibleHeight, c.goldenRatio * c.scrollbarWidth);\n s.barWiggleRoom = s.currentlyVisibleHeight - s.barLength;\n s.wiggleRoom = Math.max(0, s.totalHeight - s.scrollableAreaHeight);\n s.topY = s.barWiggleRoom === 0 ? 0 : (d.scrollY / s.wiggleRoom) * s.barWiggleRoom;\n s.bottomY = s.topY + s.barLength;\n s.dragMultiplier = s.wiggleRoom / s.barWiggleRoom;\n })\n .attr('transform', function(d) {\n var xPosition = d.width + c.scrollbarWidth / 2 + c.scrollbarOffset;\n return 'translate(' + xPosition + ' ' + headerHeight(d) + ')';\n });\n\n var scrollbar = scrollbarKit.selectAll('.' + c.cn.scrollbar)\n .data(gup.repeat, gup.keyFun);\n\n scrollbar.enter()\n .append('g')\n .classed(c.cn.scrollbar, true);\n\n var scrollbarSlider = scrollbar.selectAll('.' + c.cn.scrollbarSlider)\n .data(gup.repeat, gup.keyFun);\n\n scrollbarSlider.enter()\n .append('g')\n .classed(c.cn.scrollbarSlider, true);\n\n scrollbarSlider\n .attr('transform', function(d) {\n return 'translate(0 ' + (d.scrollbarState.topY || 0) + ')';\n });\n\n var scrollbarGlyph = scrollbarSlider.selectAll('.' + c.cn.scrollbarGlyph)\n .data(gup.repeat, gup.keyFun);\n\n scrollbarGlyph.enter()\n .append('line')\n .classed(c.cn.scrollbarGlyph, true)\n .attr('stroke', 'black')\n .attr('stroke-width', c.scrollbarWidth)\n .attr('stroke-linecap', 'round')\n .attr('y1', c.scrollbarWidth / 2);\n\n scrollbarGlyph\n .attr('y2', function(d) {\n return d.scrollbarState.barLength - c.scrollbarWidth / 2;\n })\n .attr('stroke-opacity', function(d) {\n return d.columnDragInProgress || !d.scrollbarState.barWiggleRoom || bypassVisibleBar ? 0 : 0.4;\n });\n\n // cancel transition: possible pending (also, delayed) transition\n scrollbarGlyph\n .transition().delay(0).duration(0);\n\n scrollbarGlyph\n .transition().delay(c.scrollbarHideDelay).duration(c.scrollbarHideDuration)\n .attr('stroke-opacity', 0);\n\n var scrollbarCaptureZone = scrollbar.selectAll('.' + c.cn.scrollbarCaptureZone)\n .data(gup.repeat, gup.keyFun);\n\n scrollbarCaptureZone.enter()\n .append('line')\n .classed(c.cn.scrollbarCaptureZone, true)\n .attr('stroke', 'white')\n .attr('stroke-opacity', 0.01) // some browser might get rid of a 0 opacity element\n .attr('stroke-width', c.scrollbarCaptureWidth)\n .attr('stroke-linecap', 'butt')\n .attr('y1', 0)\n .on('mousedown', function(d) {\n var y = d3.event.y;\n var bbox = this.getBoundingClientRect();\n var s = d.scrollbarState;\n var pixelVal = y - bbox.top;\n var inverseScale = d3.scale.linear().domain([0, s.scrollableAreaHeight]).range([0, s.totalHeight]).clamp(true);\n if(!(s.topY <= pixelVal && pixelVal <= s.bottomY)) {\n makeDragRow(gd, tableControlView, null, inverseScale(pixelVal - s.barLength / 2))(d);\n }\n })\n .call(d3.behavior.drag()\n .origin(function(d) {\n d3.event.stopPropagation();\n d.scrollbarState.scrollbarScrollInProgress = true;\n return d;\n })\n .on('drag', makeDragRow(gd, tableControlView))\n .on('dragend', function() {\n // fixme emit Plotly event\n })\n );\n\n scrollbarCaptureZone\n .attr('y2', function(d) {\n return d.scrollbarState.scrollableAreaHeight;\n });\n\n // Remove scroll glyph and capture zone on static plots\n // as they don't render properly when converted to PDF\n // in the Chrome PDF viewer\n // https://github.com/plotly/streambed/issues/11618\n if(gd._context.staticPlot) {\n scrollbarGlyph.remove();\n scrollbarCaptureZone.remove();\n }\n}\n\nfunction renderColumnCellTree(gd, tableControlView, columnBlock, allColumnBlock) {\n // fixme this perf hotspot\n // this is performance critical code as scrolling calls it on every revolver switch\n // it appears sufficiently fast but there are plenty of low-hanging fruits for performance optimization\n\n var columnCells = renderColumnCells(columnBlock);\n\n var columnCell = renderColumnCell(columnCells);\n\n supplyStylingValues(columnCell);\n\n var cellRect = renderCellRect(columnCell);\n\n sizeAndStyleRect(cellRect);\n\n var cellTextHolder = renderCellTextHolder(columnCell);\n\n var cellText = renderCellText(cellTextHolder);\n\n setFont(cellText);\n populateCellText(cellText, tableControlView, allColumnBlock, gd);\n\n // doing this at the end when text, and text stlying are set\n setCellHeightAndPositionY(columnCell);\n}\n\nfunction renderColumnCells(columnBlock) {\n var columnCells = columnBlock.selectAll('.' + c.cn.columnCells)\n .data(gup.repeat, gup.keyFun);\n\n columnCells.enter()\n .append('g')\n .classed(c.cn.columnCells, true);\n\n columnCells.exit()\n .remove();\n\n return columnCells;\n}\n\nfunction renderColumnCell(columnCells) {\n var columnCell = columnCells.selectAll('.' + c.cn.columnCell)\n .data(splitData.splitToCells, function(d) {return d.keyWithinBlock;});\n\n columnCell.enter()\n .append('g')\n .classed(c.cn.columnCell, true);\n\n columnCell.exit()\n .remove();\n\n return columnCell;\n}\n\nfunction renderCellRect(columnCell) {\n var cellRect = columnCell.selectAll('.' + c.cn.cellRect)\n .data(gup.repeat, function(d) {return d.keyWithinBlock;});\n\n cellRect.enter()\n .append('rect')\n .classed(c.cn.cellRect, true);\n\n return cellRect;\n}\n\nfunction renderCellText(cellTextHolder) {\n var cellText = cellTextHolder.selectAll('.' + c.cn.cellText)\n .data(gup.repeat, function(d) {return d.keyWithinBlock;});\n\n cellText.enter()\n .append('text')\n .classed(c.cn.cellText, true)\n .style('cursor', function() {return 'auto';})\n .on('mousedown', function() {d3.event.stopPropagation();});\n\n return cellText;\n}\n\nfunction renderCellTextHolder(columnCell) {\n var cellTextHolder = columnCell.selectAll('.' + c.cn.cellTextHolder)\n .data(gup.repeat, function(d) {return d.keyWithinBlock;});\n\n cellTextHolder.enter()\n .append('g')\n .classed(c.cn.cellTextHolder, true)\n .style('shape-rendering', 'geometricPrecision');\n\n return cellTextHolder;\n}\n\nfunction supplyStylingValues(columnCell) {\n columnCell\n .each(function(d, i) {\n var spec = d.calcdata.cells.font;\n var col = d.column.specIndex;\n var font = {\n size: gridPick(spec.size, col, i),\n color: gridPick(spec.color, col, i),\n family: gridPick(spec.family, col, i)\n };\n d.rowNumber = d.key;\n d.align = gridPick(d.calcdata.cells.align, col, i);\n d.cellBorderWidth = gridPick(d.calcdata.cells.line.width, col, i);\n d.font = font;\n });\n}\n\nfunction setFont(cellText) {\n cellText\n .each(function(d) {\n Drawing.font(d3.select(this), d.font);\n });\n}\n\nfunction sizeAndStyleRect(cellRect) {\n cellRect\n .attr('width', function(d) {return d.column.columnWidth;})\n .attr('stroke-width', function(d) {return d.cellBorderWidth;})\n .each(function(d) {\n var atomicSelection = d3.select(this);\n Color.stroke(atomicSelection, gridPick(d.calcdata.cells.line.color, d.column.specIndex, d.rowNumber));\n Color.fill(atomicSelection, gridPick(d.calcdata.cells.fill.color, d.column.specIndex, d.rowNumber));\n });\n}\n\nfunction populateCellText(cellText, tableControlView, allColumnBlock, gd) {\n cellText\n .text(function(d) {\n var col = d.column.specIndex;\n var row = d.rowNumber;\n\n var userSuppliedContent = d.value;\n var stringSupplied = (typeof userSuppliedContent === 'string');\n var hasBreaks = stringSupplied && userSuppliedContent.match(/
/i);\n var userBrokenText = !stringSupplied || hasBreaks;\n d.mayHaveMarkup = stringSupplied && userSuppliedContent.match(/[<&>]/);\n\n var latex = isLatex(userSuppliedContent);\n d.latex = latex;\n\n var prefix = latex ? '' : gridPick(d.calcdata.cells.prefix, col, row) || '';\n var suffix = latex ? '' : gridPick(d.calcdata.cells.suffix, col, row) || '';\n var format = latex ? null : gridPick(d.calcdata.cells.format, col, row) || null;\n\n var prefixSuffixedText = prefix + (format ? d3.format(format)(d.value) : d.value) + suffix;\n\n var hasWrapSplitCharacter;\n d.wrappingNeeded = !d.wrapped && !userBrokenText && !latex && (hasWrapSplitCharacter = hasWrapCharacter(prefixSuffixedText));\n d.cellHeightMayIncrease = hasBreaks || latex || d.mayHaveMarkup || (hasWrapSplitCharacter === void(0) ? hasWrapCharacter(prefixSuffixedText) : hasWrapSplitCharacter);\n d.needsConvertToTspans = d.mayHaveMarkup || d.wrappingNeeded || d.latex;\n\n var textToRender;\n if(d.wrappingNeeded) {\n var hrefPreservedText = c.wrapSplitCharacter === ' ' ? prefixSuffixedText.replace(/ pTop) {\n pages.push(blockIndex);\n }\n pTop += rowsHeight;\n\n // consider this nice final optimization; put it in `for` condition - caveat, currently the\n // block.allRowsHeight relies on being invalidated, so enabling this opt may not be safe\n // if(pages.length > 1) break;\n }\n\n return pages;\n}\n\nfunction updateBlockYPosition(gd, cellsColumnBlock, tableControlView) {\n var d = flatData(cellsColumnBlock)[0];\n if(d === undefined) return;\n var blocks = d.rowBlocks;\n var calcdata = d.calcdata;\n\n var bottom = firstRowAnchor(blocks, blocks.length);\n var scrollHeight = d.calcdata.groupHeight - headerHeight(d);\n var scrollY = calcdata.scrollY = Math.max(0, Math.min(bottom - scrollHeight, calcdata.scrollY));\n\n var pages = findPagesAndCacheHeights(blocks, scrollY, scrollHeight);\n if(pages.length === 1) {\n if(pages[0] === blocks.length - 1) {\n pages.unshift(pages[0] - 1);\n } else {\n pages.push(pages[0] + 1);\n }\n }\n\n // make phased out page jump by 2 while leaving stationary page intact\n if(pages[0] % 2) {\n pages.reverse();\n }\n\n cellsColumnBlock\n .each(function(d, i) {\n // these values will also be needed when a block is translated again due to growing cell height\n d.page = pages[i];\n d.scrollY = scrollY;\n });\n\n cellsColumnBlock\n .attr('transform', function(d) {\n var yTranslate = firstRowAnchor(d.rowBlocks, d.page) - d.scrollY;\n return 'translate(0 ' + yTranslate + ')';\n });\n\n // conditionally rerendering panel 0 and 1\n if(gd) {\n conditionalPanelRerender(gd, tableControlView, cellsColumnBlock, pages, d.prevPages, d, 0);\n conditionalPanelRerender(gd, tableControlView, cellsColumnBlock, pages, d.prevPages, d, 1);\n renderScrollbarKit(tableControlView, gd);\n }\n}\n\nfunction makeDragRow(gd, allTableControlView, optionalMultiplier, optionalPosition) {\n return function dragRow(eventD) {\n // may come from whichever DOM event target: drag, wheel, bar... eventD corresponds to event target\n var d = eventD.calcdata ? eventD.calcdata : eventD;\n var tableControlView = allTableControlView.filter(function(dd) {return d.key === dd.key;});\n var multiplier = optionalMultiplier || d.scrollbarState.dragMultiplier;\n\n var initialScrollY = d.scrollY;\n\n d.scrollY = optionalPosition === void(0) ? d.scrollY + multiplier * d3.event.dy : optionalPosition;\n var cellsColumnBlock = tableControlView.selectAll('.' + c.cn.yColumn).selectAll('.' + c.cn.columnBlock).filter(cellsBlock);\n updateBlockYPosition(gd, cellsColumnBlock, tableControlView);\n\n // return false if we've \"used\" the scroll, ie it did something,\n // so the event shouldn't bubble (if appropriate)\n return d.scrollY === initialScrollY;\n };\n}\n\nfunction conditionalPanelRerender(gd, tableControlView, cellsColumnBlock, pages, prevPages, d, revolverIndex) {\n var shouldComponentUpdate = pages[revolverIndex] !== prevPages[revolverIndex];\n if(shouldComponentUpdate) {\n clearTimeout(d.currentRepaint[revolverIndex]);\n d.currentRepaint[revolverIndex] = setTimeout(function() {\n // setTimeout might lag rendering but yields a smoother scroll, because fast scrolling makes\n // some repaints invisible ie. wasteful (DOM work blocks the main thread)\n var toRerender = cellsColumnBlock.filter(function(d, i) {return i === revolverIndex && pages[i] !== prevPages[i];});\n renderColumnCellTree(gd, tableControlView, toRerender, cellsColumnBlock);\n prevPages[revolverIndex] = pages[revolverIndex];\n });\n }\n}\n\nfunction wrapTextMaker(columnBlock, element, tableControlView, gd) {\n return function wrapText() {\n var cellTextHolder = d3.select(element.parentNode);\n cellTextHolder\n .each(function(d) {\n var fragments = d.fragments;\n cellTextHolder.selectAll('tspan.line').each(function(dd, i) {\n fragments[i].width = this.getComputedTextLength();\n });\n // last element is only for measuring the separator character, so it's ignored:\n var separatorLength = fragments[fragments.length - 1].width;\n var rest = fragments.slice(0, -1);\n var currentRow = [];\n var currentAddition, currentAdditionLength;\n var currentRowLength = 0;\n var rowLengthLimit = d.column.columnWidth - 2 * c.cellPad;\n d.value = '';\n while(rest.length) {\n currentAddition = rest.shift();\n currentAdditionLength = currentAddition.width + separatorLength;\n if(currentRowLength + currentAdditionLength > rowLengthLimit) {\n d.value += currentRow.join(c.wrapSpacer) + c.lineBreaker;\n currentRow = [];\n currentRowLength = 0;\n }\n currentRow.push(currentAddition.text);\n currentRowLength += currentAdditionLength;\n }\n if(currentRowLength) {\n d.value += currentRow.join(c.wrapSpacer);\n }\n d.wrapped = true;\n });\n\n // the pre-wrapped text was rendered only for the text measurements\n cellTextHolder.selectAll('tspan.line').remove();\n\n // resupply text, now wrapped\n populateCellText(cellTextHolder.select('.' + c.cn.cellText), tableControlView, columnBlock, gd);\n d3.select(element.parentNode.parentNode).call(setCellHeightAndPositionY);\n };\n}\n\nfunction updateYPositionMaker(columnBlock, element, tableControlView, gd, d) {\n return function updateYPosition() {\n if(d.settledY) return;\n var cellTextHolder = d3.select(element.parentNode);\n var l = getBlock(d);\n var rowIndex = d.key - l.firstRowIndex;\n\n var declaredRowHeight = l.rows[rowIndex].rowHeight;\n\n var requiredHeight = d.cellHeightMayIncrease ? element.parentNode.getBoundingClientRect().height + 2 * c.cellPad : declaredRowHeight;\n\n var finalHeight = Math.max(requiredHeight, declaredRowHeight);\n var increase = finalHeight - l.rows[rowIndex].rowHeight;\n\n if(increase) {\n // current row height increased\n l.rows[rowIndex].rowHeight = finalHeight;\n\n columnBlock\n .selectAll('.' + c.cn.columnCell)\n .call(setCellHeightAndPositionY);\n\n updateBlockYPosition(null, columnBlock.filter(cellsBlock), 0);\n\n // if d.column.type === 'header', then the scrollbar has to be pushed downward to the scrollable area\n // if d.column.type === 'cells', it can still be relevant if total scrolling content height is less than the\n // scrollable window, as increases to row heights may need scrollbar updates\n renderScrollbarKit(tableControlView, gd, true);\n }\n\n cellTextHolder\n .attr('transform', function() {\n // this code block is only invoked for items where d.cellHeightMayIncrease is truthy\n var element = this;\n var columnCellElement = element.parentNode;\n var box = columnCellElement.getBoundingClientRect();\n var rectBox = d3.select(element.parentNode).select('.' + c.cn.cellRect).node().getBoundingClientRect();\n var currentTransform = element.transform.baseVal.consolidate();\n var yPosition = rectBox.top - box.top + (currentTransform ? currentTransform.matrix.f : c.cellPad);\n return 'translate(' + xPosition(d, d3.select(element.parentNode).select('.' + c.cn.cellTextHolder).node().getBoundingClientRect().width) + ' ' + yPosition + ')';\n });\n\n d.settledY = true;\n };\n}\n\nfunction xPosition(d, optionalWidth) {\n switch(d.align) {\n case 'left': return c.cellPad;\n case 'right': return d.column.columnWidth - (optionalWidth || 0) - c.cellPad;\n case 'center': return (d.column.columnWidth - (optionalWidth || 0)) / 2;\n default: return c.cellPad;\n }\n}\n\nfunction setCellHeightAndPositionY(columnCell) {\n columnCell\n .attr('transform', function(d) {\n var headerHeight = d.rowBlocks[0].auxiliaryBlocks.reduce(function(p, n) {return p + rowsHeight(n, Infinity);}, 0);\n var l = getBlock(d);\n var rowAnchor = rowsHeight(l, d.key);\n var yOffset = rowAnchor + headerHeight;\n return 'translate(0 ' + yOffset + ')';\n })\n .selectAll('.' + c.cn.cellRect)\n .attr('height', function(d) {return getRow(getBlock(d), d.key).rowHeight;});\n}\n\nfunction firstRowAnchor(blocks, page) {\n var total = 0;\n for(var i = page - 1; i >= 0; i--) {\n total += allRowsHeight(blocks[i]);\n }\n return total;\n}\n\nfunction rowsHeight(rowBlock, key) {\n var total = 0;\n for(var i = 0; i < rowBlock.rows.length && rowBlock.rows[i].rowIndex < key; i++) {\n total += rowBlock.rows[i].rowHeight;\n }\n return total;\n}\n\nfunction allRowsHeight(rowBlock) {\n var cached = rowBlock.allRowsHeight;\n\n if(cached !== void(0)) {\n return cached;\n }\n\n var total = 0;\n for(var i = 0; i < rowBlock.rows.length; i++) {\n total += rowBlock.rows[i].rowHeight;\n }\n rowBlock.allRowsHeight = total;\n\n return total;\n}\n\nfunction getBlock(d) {return d.rowBlocks[d.page];}\nfunction getRow(l, i) {return l.rows[i - l.firstRowIndex];}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/table/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/treemap/attributes.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/treemap/attributes.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar texttemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").texttemplateAttrs;\n\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar domainAttrs = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").attributes;\nvar pieAttrs = __webpack_require__(/*! ../pie/attributes */ \"./node_modules/plotly.js/src/traces/pie/attributes.js\");\nvar sunburstAttrs = __webpack_require__(/*! ../sunburst/attributes */ \"./node_modules/plotly.js/src/traces/sunburst/attributes.js\");\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/treemap/constants.js\");\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nmodule.exports = {\n labels: sunburstAttrs.labels,\n parents: sunburstAttrs.parents,\n\n values: sunburstAttrs.values,\n branchvalues: sunburstAttrs.branchvalues,\n count: sunburstAttrs.count,\n\n level: sunburstAttrs.level,\n maxdepth: sunburstAttrs.maxdepth,\n\n tiling: {\n packing: {\n valType: 'enumerated',\n values: [\n 'squarify',\n 'binary',\n 'dice',\n 'slice',\n 'slice-dice',\n 'dice-slice'\n ],\n dflt: 'squarify',\n \n editType: 'plot',\n \n },\n\n squarifyratio: {\n valType: 'number',\n \n min: 1,\n dflt: 1,\n editType: 'plot',\n \n },\n\n flip: {\n valType: 'flaglist',\n \n flags: [\n 'x',\n 'y'\n ],\n dflt: '',\n editType: 'plot',\n \n },\n\n pad: {\n valType: 'number',\n \n min: 0,\n dflt: 3,\n editType: 'plot',\n \n },\n\n editType: 'calc',\n },\n\n marker: extendFlat({\n pad: {\n t: {\n valType: 'number',\n \n min: 0,\n editType: 'plot',\n \n },\n l: {\n valType: 'number',\n \n min: 0,\n editType: 'plot',\n \n },\n r: {\n valType: 'number',\n \n min: 0,\n editType: 'plot',\n \n },\n b: {\n valType: 'number',\n \n min: 0,\n editType: 'plot',\n \n },\n\n editType: 'calc'\n },\n\n colors: sunburstAttrs.marker.colors,\n\n depthfade: {\n valType: 'enumerated',\n values: [true, false, 'reversed'],\n editType: 'style',\n \n \n },\n\n line: sunburstAttrs.marker.line,\n\n editType: 'calc'\n },\n colorScaleAttrs('marker', {\n colorAttr: 'colors',\n anim: false // TODO: set to anim: true?\n })\n ),\n\n pathbar: {\n visible: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'plot',\n \n },\n\n side: {\n valType: 'enumerated',\n values: [\n 'top',\n 'bottom'\n ],\n dflt: 'top',\n \n editType: 'plot',\n \n },\n\n edgeshape: {\n valType: 'enumerated',\n values: [\n '>',\n '<',\n '|',\n '/',\n '\\\\'\n ],\n dflt: '>',\n \n editType: 'plot',\n \n },\n\n thickness: {\n valType: 'number',\n min: 12,\n \n editType: 'plot',\n \n },\n\n textfont: extendFlat({}, pieAttrs.textfont, {\n \n }),\n\n editType: 'calc'\n },\n\n text: pieAttrs.text,\n textinfo: sunburstAttrs.textinfo,\n // TODO: incorporate `label` and `value` in the eventData\n texttemplate: texttemplateAttrs({editType: 'plot'}, {\n keys: constants.eventDataKeys.concat(['label', 'value'])\n }),\n\n hovertext: pieAttrs.hovertext,\n hoverinfo: sunburstAttrs.hoverinfo,\n hovertemplate: hovertemplateAttrs({}, {\n keys: constants.eventDataKeys\n }),\n\n textfont: pieAttrs.textfont,\n insidetextfont: pieAttrs.insidetextfont,\n outsidetextfont: extendFlat({}, pieAttrs.outsidetextfont, {\n \n }),\n\n textposition: {\n valType: 'enumerated',\n values: [\n 'top left', 'top center', 'top right',\n 'middle left', 'middle center', 'middle right',\n 'bottom left', 'bottom center', 'bottom right'\n ],\n dflt: 'top left',\n \n editType: 'plot',\n \n },\n\n domain: domainAttrs({name: 'treemap', trace: true, editType: 'calc'}),\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/treemap/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/treemap/base_plot.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/treemap/base_plot.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar plots = __webpack_require__(/*! ../../plots/plots */ \"./node_modules/plotly.js/src/plots/plots.js\");\n\nexports.name = 'treemap';\n\nexports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) {\n plots.plotBasePlot(exports.name, gd, traces, transitionOpts, makeOnCompleteCallback);\n};\n\nexports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {\n plots.cleanBasePlot(exports.name, newFullData, newFullLayout, oldFullData, oldFullLayout);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/treemap/base_plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/treemap/calc.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/treemap/calc.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar calc = __webpack_require__(/*! ../sunburst/calc */ \"./node_modules/plotly.js/src/traces/sunburst/calc.js\");\n\nexports.calc = function(gd, trace) {\n return calc.calc(gd, trace);\n};\n\nexports.crossTraceCalc = function(gd) {\n return calc._runCrossTraceCalc('treemap', gd);\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/treemap/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/treemap/constants.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/treemap/constants.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n CLICK_TRANSITION_TIME: 750,\n CLICK_TRANSITION_EASING: 'poly',\n eventDataKeys: [\n // string\n 'currentPath',\n 'root',\n 'entry',\n // no need to add 'parent' here\n\n // percentages i.e. ratios\n 'percentRoot',\n 'percentEntry',\n 'percentParent'\n ],\n gapWithPathbar: 1 // i.e. one pixel\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/treemap/constants.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/treemap/defaults.js":
-/*!***************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/treemap/defaults.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/treemap/attributes.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar handleDomainDefaults = __webpack_require__(/*! ../../plots/domain */ \"./node_modules/plotly.js/src/plots/domain.js\").defaults;\nvar handleText = __webpack_require__(/*! ../bar/defaults */ \"./node_modules/plotly.js/src/traces/bar/defaults.js\").handleText;\nvar TEXTPAD = __webpack_require__(/*! ../bar/constants */ \"./node_modules/plotly.js/src/traces/bar/constants.js\").TEXTPAD;\n\nvar Colorscale = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\");\nvar hasColorscale = Colorscale.hasColorscale;\nvar colorscaleDefaults = Colorscale.handleDefaults;\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var labels = coerce('labels');\n var parents = coerce('parents');\n\n if(!labels || !labels.length || !parents || !parents.length) {\n traceOut.visible = false;\n return;\n }\n\n var vals = coerce('values');\n if(vals && vals.length) {\n coerce('branchvalues');\n } else {\n coerce('count');\n }\n\n coerce('level');\n coerce('maxdepth');\n\n var packing = coerce('tiling.packing');\n if(packing === 'squarify') {\n coerce('tiling.squarifyratio');\n }\n\n coerce('tiling.flip');\n coerce('tiling.pad');\n\n var text = coerce('text');\n coerce('texttemplate');\n if(!traceOut.texttemplate) coerce('textinfo', Array.isArray(text) ? 'text+label' : 'label');\n\n coerce('hovertext');\n coerce('hovertemplate');\n\n var hasPathbar = coerce('pathbar.visible');\n\n var textposition = 'auto';\n handleText(traceIn, traceOut, layout, coerce, textposition, {\n hasPathbar: hasPathbar,\n moduleHasSelected: false,\n moduleHasUnselected: false,\n moduleHasConstrain: false,\n moduleHasCliponaxis: false,\n moduleHasTextangle: false,\n moduleHasInsideanchor: false\n });\n coerce('textposition');\n var bottomText = traceOut.textposition.indexOf('bottom') !== -1;\n\n var lineWidth = coerce('marker.line.width');\n if(lineWidth) coerce('marker.line.color', layout.paper_bgcolor);\n\n var colors = coerce('marker.colors');\n var withColorscale = traceOut._hasColorscale = (\n hasColorscale(traceIn, 'marker', 'colors') ||\n (traceIn.marker || {}).coloraxis // N.B. special logic to consider \"values\" colorscales\n );\n if(withColorscale) {\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: 'marker.', cLetter: 'c'});\n } else {\n coerce('marker.depthfade', !(colors || []).length);\n }\n\n var headerSize = traceOut.textfont.size * 2;\n\n coerce('marker.pad.t', bottomText ? headerSize / 4 : headerSize);\n coerce('marker.pad.l', headerSize / 4);\n coerce('marker.pad.r', headerSize / 4);\n coerce('marker.pad.b', bottomText ? headerSize : headerSize / 4);\n\n if(withColorscale) {\n colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: 'marker.', cLetter: 'c'});\n }\n\n traceOut._hovered = {\n marker: {\n line: {\n width: 2,\n color: Color.contrast(layout.paper_bgcolor)\n }\n }\n };\n\n if(hasPathbar) {\n // This works even for multi-line labels as treemap pathbar trim out line breaks\n coerce('pathbar.thickness', traceOut.pathbar.textfont.size + 2 * TEXTPAD);\n\n coerce('pathbar.side');\n coerce('pathbar.edgeshape');\n }\n\n handleDomainDefaults(traceOut, layout, coerce);\n\n // do not support transforms for now\n traceOut._length = null;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/treemap/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/treemap/draw_ancestors.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/treemap/draw_ancestors.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar svgTextUtils = __webpack_require__(/*! ../../lib/svg_text_utils */ \"./node_modules/plotly.js/src/lib/svg_text_utils.js\");\n\nvar partition = __webpack_require__(/*! ./partition */ \"./node_modules/plotly.js/src/traces/treemap/partition.js\");\nvar styleOne = __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/treemap/style.js\").styleOne;\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/treemap/constants.js\");\nvar helpers = __webpack_require__(/*! ../sunburst/helpers */ \"./node_modules/plotly.js/src/traces/sunburst/helpers.js\");\nvar attachFxHandlers = __webpack_require__(/*! ../sunburst/fx */ \"./node_modules/plotly.js/src/traces/sunburst/fx.js\");\n\nvar onPathbar = true; // for Ancestors\n\nmodule.exports = function drawAncestors(gd, cd, entry, slices, opts) {\n var barDifY = opts.barDifY;\n var width = opts.width;\n var height = opts.height;\n var viewX = opts.viewX;\n var viewY = opts.viewY;\n var pathSlice = opts.pathSlice;\n var toMoveInsideSlice = opts.toMoveInsideSlice;\n var strTransform = opts.strTransform;\n var hasTransition = opts.hasTransition;\n var handleSlicesExit = opts.handleSlicesExit;\n var makeUpdateSliceInterpolator = opts.makeUpdateSliceInterpolator;\n var makeUpdateTextInterpolator = opts.makeUpdateTextInterpolator;\n var refRect = {};\n\n var fullLayout = gd._fullLayout;\n var cd0 = cd[0];\n var trace = cd0.trace;\n var hierarchy = cd0.hierarchy;\n\n var eachWidth = width / trace._entryDepth;\n\n var pathIds = helpers.listPath(entry.data, 'id');\n\n var sliceData = partition(hierarchy.copy(), [width, height], {\n packing: 'dice',\n pad: {\n inner: 0,\n top: 0,\n left: 0,\n right: 0,\n bottom: 0\n }\n }).descendants();\n\n // edit slices that show up on graph\n sliceData = sliceData.filter(function(pt) {\n var level = pathIds.indexOf(pt.data.id);\n if(level === -1) return false;\n\n pt.x0 = eachWidth * level;\n pt.x1 = eachWidth * (level + 1);\n pt.y0 = barDifY;\n pt.y1 = barDifY + height;\n\n pt.onPathbar = true;\n\n return true;\n });\n\n sliceData.reverse();\n\n slices = slices.data(sliceData, helpers.getPtId);\n\n slices.enter().append('g')\n .classed('pathbar', true);\n\n handleSlicesExit(slices, onPathbar, refRect, [width, height], pathSlice);\n\n slices.order();\n\n var updateSlices = slices;\n if(hasTransition) {\n updateSlices = updateSlices.transition().each('end', function() {\n // N.B. gd._transitioning is (still) *true* by the time\n // transition updates get here\n var sliceTop = d3.select(this);\n helpers.setSliceCursor(sliceTop, gd, {\n hideOnRoot: false,\n hideOnLeaves: false,\n isTransitioning: false\n });\n });\n }\n\n updateSlices.each(function(pt) {\n pt._hoverX = viewX(pt.x1 - Math.min(width, height) / 2);\n pt._hoverY = viewY(pt.y1 - height / 2);\n\n var sliceTop = d3.select(this);\n\n var slicePath = Lib.ensureSingle(sliceTop, 'path', 'surface', function(s) {\n s.style('pointer-events', 'all');\n });\n\n if(hasTransition) {\n slicePath.transition().attrTween('d', function(pt2) {\n var interp = makeUpdateSliceInterpolator(pt2, onPathbar, refRect, [width, height]);\n return function(t) { return pathSlice(interp(t)); };\n });\n } else {\n slicePath.attr('d', pathSlice);\n }\n\n sliceTop\n .call(attachFxHandlers, entry, gd, cd, {\n styleOne: styleOne,\n eventDataKeys: constants.eventDataKeys,\n transitionTime: constants.CLICK_TRANSITION_TIME,\n transitionEasing: constants.CLICK_TRANSITION_EASING\n })\n .call(helpers.setSliceCursor, gd, {\n hideOnRoot: false,\n hideOnLeaves: false,\n isTransitioning: gd._transitioning\n });\n\n slicePath.call(styleOne, pt, trace, {\n hovered: false\n });\n\n pt._text = (helpers.getPtLabel(pt) || '').split('
').join(' ') || '';\n\n var sliceTextGroup = Lib.ensureSingle(sliceTop, 'g', 'slicetext');\n var sliceText = Lib.ensureSingle(sliceTextGroup, 'text', '', function(s) {\n // prohibit tex interpretation until we can handle\n // tex and regular text together\n s.attr('data-notex', 1);\n });\n\n var font = Lib.ensureUniformFontSize(gd, helpers.determineTextFont(trace, pt, fullLayout.font, {\n onPathbar: true\n }));\n\n sliceText.text(pt._text || ' ') // use one space character instead of a blank string to avoid jumps during transition\n .classed('slicetext', true)\n .attr('text-anchor', 'start')\n .call(Drawing.font, font)\n .call(svgTextUtils.convertToTspans, gd);\n\n pt.textBB = Drawing.bBox(sliceText.node());\n pt.transform = toMoveInsideSlice(pt, {\n fontSize: font.size,\n onPathbar: true\n });\n pt.transform.fontSize = font.size;\n\n if(hasTransition) {\n sliceText.transition().attrTween('transform', function(pt2) {\n var interp = makeUpdateTextInterpolator(pt2, onPathbar, refRect, [width, height]);\n return function(t) { return strTransform(interp(t)); };\n });\n } else {\n sliceText.attr('transform', strTransform(pt));\n }\n });\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/treemap/draw_ancestors.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/treemap/draw_descendants.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/treemap/draw_descendants.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar svgTextUtils = __webpack_require__(/*! ../../lib/svg_text_utils */ \"./node_modules/plotly.js/src/lib/svg_text_utils.js\");\n\nvar partition = __webpack_require__(/*! ./partition */ \"./node_modules/plotly.js/src/traces/treemap/partition.js\");\nvar styleOne = __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/treemap/style.js\").styleOne;\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/treemap/constants.js\");\nvar helpers = __webpack_require__(/*! ../sunburst/helpers */ \"./node_modules/plotly.js/src/traces/sunburst/helpers.js\");\nvar attachFxHandlers = __webpack_require__(/*! ../sunburst/fx */ \"./node_modules/plotly.js/src/traces/sunburst/fx.js\");\nvar formatSliceLabel = __webpack_require__(/*! ../sunburst/plot */ \"./node_modules/plotly.js/src/traces/sunburst/plot.js\").formatSliceLabel;\n\nvar onPathbar = false; // for Descendants\n\nmodule.exports = function drawDescendants(gd, cd, entry, slices, opts) {\n var width = opts.width;\n var height = opts.height;\n var viewX = opts.viewX;\n var viewY = opts.viewY;\n var pathSlice = opts.pathSlice;\n var toMoveInsideSlice = opts.toMoveInsideSlice;\n var strTransform = opts.strTransform;\n var hasTransition = opts.hasTransition;\n var handleSlicesExit = opts.handleSlicesExit;\n var makeUpdateSliceInterpolator = opts.makeUpdateSliceInterpolator;\n var makeUpdateTextInterpolator = opts.makeUpdateTextInterpolator;\n var prevEntry = opts.prevEntry;\n var refRect = {};\n\n var fullLayout = gd._fullLayout;\n var cd0 = cd[0];\n var trace = cd0.trace;\n\n var hasLeft = trace.textposition.indexOf('left') !== -1;\n var hasRight = trace.textposition.indexOf('right') !== -1;\n var hasBottom = trace.textposition.indexOf('bottom') !== -1;\n\n var noRoomForHeader = (!hasBottom && !trace.marker.pad.t) || (hasBottom && !trace.marker.pad.b);\n\n // N.B. slice data isn't the calcdata,\n // grab corresponding calcdata item in sliceData[i].data.data\n var allData = partition(entry, [width, height], {\n packing: trace.tiling.packing,\n squarifyratio: trace.tiling.squarifyratio,\n flipX: trace.tiling.flip.indexOf('x') > -1,\n flipY: trace.tiling.flip.indexOf('y') > -1,\n pad: {\n inner: trace.tiling.pad,\n top: trace.marker.pad.t,\n left: trace.marker.pad.l,\n right: trace.marker.pad.r,\n bottom: trace.marker.pad.b,\n }\n });\n\n var sliceData = allData.descendants();\n\n var minVisibleDepth = Infinity;\n var maxVisibleDepth = -Infinity;\n sliceData.forEach(function(pt) {\n var depth = pt.depth;\n if(depth >= trace._maxDepth) {\n // hide slices that won't show up on graph\n pt.x0 = pt.x1 = (pt.x0 + pt.x1) / 2;\n pt.y0 = pt.y1 = (pt.y0 + pt.y1) / 2;\n } else {\n minVisibleDepth = Math.min(minVisibleDepth, depth);\n maxVisibleDepth = Math.max(maxVisibleDepth, depth);\n }\n });\n\n slices = slices.data(sliceData, helpers.getPtId);\n\n trace._maxVisibleLayers = isFinite(maxVisibleDepth) ? maxVisibleDepth - minVisibleDepth + 1 : 0;\n\n slices.enter().append('g')\n .classed('slice', true);\n\n handleSlicesExit(slices, onPathbar, refRect, [width, height], pathSlice);\n\n slices.order();\n\n // next coords of previous entry\n var nextOfPrevEntry = null;\n if(hasTransition && prevEntry) {\n var prevEntryId = helpers.getPtId(prevEntry);\n slices.each(function(pt) {\n if(nextOfPrevEntry === null && (helpers.getPtId(pt) === prevEntryId)) {\n nextOfPrevEntry = {\n x0: pt.x0,\n x1: pt.x1,\n y0: pt.y0,\n y1: pt.y1\n };\n }\n });\n }\n\n var getRefRect = function() {\n return nextOfPrevEntry || {\n x0: 0,\n x1: width,\n y0: 0,\n y1: height\n };\n };\n\n var updateSlices = slices;\n if(hasTransition) {\n updateSlices = updateSlices.transition().each('end', function() {\n // N.B. gd._transitioning is (still) *true* by the time\n // transition updates get here\n var sliceTop = d3.select(this);\n helpers.setSliceCursor(sliceTop, gd, {\n hideOnRoot: true,\n hideOnLeaves: false,\n isTransitioning: false\n });\n });\n }\n\n updateSlices.each(function(pt) {\n var isHeader = helpers.isHeader(pt, trace);\n\n pt._hoverX = viewX(pt.x1 - trace.marker.pad.r),\n pt._hoverY = hasBottom ?\n viewY(pt.y1 - trace.marker.pad.b / 2) :\n viewY(pt.y0 + trace.marker.pad.t / 2);\n\n var sliceTop = d3.select(this);\n\n var slicePath = Lib.ensureSingle(sliceTop, 'path', 'surface', function(s) {\n s.style('pointer-events', 'all');\n });\n\n if(hasTransition) {\n slicePath.transition().attrTween('d', function(pt2) {\n var interp = makeUpdateSliceInterpolator(pt2, onPathbar, getRefRect(), [width, height]);\n return function(t) { return pathSlice(interp(t)); };\n });\n } else {\n slicePath.attr('d', pathSlice);\n }\n\n sliceTop\n .call(attachFxHandlers, entry, gd, cd, {\n styleOne: styleOne,\n eventDataKeys: constants.eventDataKeys,\n transitionTime: constants.CLICK_TRANSITION_TIME,\n transitionEasing: constants.CLICK_TRANSITION_EASING\n })\n .call(helpers.setSliceCursor, gd, { isTransitioning: gd._transitioning });\n\n slicePath.call(styleOne, pt, trace, {\n hovered: false\n });\n\n if(pt.x0 === pt.x1 || pt.y0 === pt.y1) {\n pt._text = '';\n } else {\n if(isHeader) {\n pt._text = noRoomForHeader ? '' : helpers.getPtLabel(pt) || '';\n } else {\n pt._text = formatSliceLabel(pt, entry, trace, cd, fullLayout) || '';\n }\n }\n\n var sliceTextGroup = Lib.ensureSingle(sliceTop, 'g', 'slicetext');\n var sliceText = Lib.ensureSingle(sliceTextGroup, 'text', '', function(s) {\n // prohibit tex interpretation until we can handle\n // tex and regular text together\n s.attr('data-notex', 1);\n });\n\n var font = Lib.ensureUniformFontSize(gd, helpers.determineTextFont(trace, pt, fullLayout.font));\n\n sliceText.text(pt._text || ' ') // use one space character instead of a blank string to avoid jumps during transition\n .classed('slicetext', true)\n .attr('text-anchor', hasRight ? 'end' : (hasLeft || isHeader) ? 'start' : 'middle')\n .call(Drawing.font, font)\n .call(svgTextUtils.convertToTspans, gd);\n\n pt.textBB = Drawing.bBox(sliceText.node());\n pt.transform = toMoveInsideSlice(pt, {\n fontSize: font.size,\n isHeader: isHeader\n });\n pt.transform.fontSize = font.size;\n\n if(hasTransition) {\n sliceText.transition().attrTween('transform', function(pt2) {\n var interp = makeUpdateTextInterpolator(pt2, onPathbar, getRefRect(), [width, height]);\n return function(t) { return strTransform(interp(t)); };\n });\n } else {\n sliceText.attr('transform', strTransform(pt));\n }\n });\n\n return nextOfPrevEntry;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/treemap/draw_descendants.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/treemap/index.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/treemap/index.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n moduleType: 'trace',\n name: 'treemap',\n basePlotModule: __webpack_require__(/*! ./base_plot */ \"./node_modules/plotly.js/src/traces/treemap/base_plot.js\"),\n categories: [],\n animatable: true,\n\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/treemap/attributes.js\"),\n layoutAttributes: __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/treemap/layout_attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/treemap/defaults.js\"),\n supplyLayoutDefaults: __webpack_require__(/*! ./layout_defaults */ \"./node_modules/plotly.js/src/traces/treemap/layout_defaults.js\"),\n\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/treemap/calc.js\").calc,\n crossTraceCalc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/treemap/calc.js\").crossTraceCalc,\n\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/treemap/plot.js\"),\n style: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/treemap/style.js\").style,\n\n colorbar: __webpack_require__(/*! ../scatter/marker_colorbar */ \"./node_modules/plotly.js/src/traces/scatter/marker_colorbar.js\"),\n\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/treemap/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/treemap/layout_attributes.js":
-/*!************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/treemap/layout_attributes.js ***!
- \************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n treemapcolorway: {\n valType: 'colorlist',\n \n editType: 'calc',\n \n },\n extendtreemapcolors: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'calc',\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/treemap/layout_attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/treemap/layout_defaults.js":
-/*!**********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/treemap/layout_defaults.js ***!
- \**********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar layoutAttributes = __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/treemap/layout_attributes.js\");\n\nmodule.exports = function supplyLayoutDefaults(layoutIn, layoutOut) {\n function coerce(attr, dflt) {\n return Lib.coerce(layoutIn, layoutOut, layoutAttributes, attr, dflt);\n }\n coerce('treemapcolorway', layoutOut.colorway);\n coerce('extendtreemapcolors');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/treemap/layout_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/treemap/partition.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/treemap/partition.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3Hierarchy = __webpack_require__(/*! d3-hierarchy */ \"./node_modules/d3-hierarchy/src/index.js\");\n\nmodule.exports = function partition(entry, size, opts) {\n var flipX = opts.flipX;\n var flipY = opts.flipY;\n var swapXY = opts.packing === 'dice-slice';\n\n var top = opts.pad[flipY ? 'bottom' : 'top'];\n var left = opts.pad[flipX ? 'right' : 'left'];\n var right = opts.pad[flipX ? 'left' : 'right'];\n var bottom = opts.pad[flipY ? 'top' : 'bottom'];\n\n var tmp;\n if(swapXY) {\n tmp = left;\n left = top;\n top = tmp;\n\n tmp = right;\n right = bottom;\n bottom = tmp;\n }\n\n var result = d3Hierarchy\n .treemap()\n .tile(getTilingMethod(opts.packing, opts.squarifyratio))\n .paddingInner(opts.pad.inner)\n .paddingLeft(left)\n .paddingRight(right)\n .paddingTop(top)\n .paddingBottom(bottom)\n .size(\n swapXY ? [size[1], size[0]] : size\n )(entry);\n\n if(swapXY || flipX || flipY) {\n flipTree(result, size, {\n swapXY: swapXY,\n flipX: flipX,\n flipY: flipY\n });\n }\n return result;\n};\n\nfunction getTilingMethod(key, squarifyratio) {\n switch(key) {\n case 'squarify':\n return d3Hierarchy.treemapSquarify.ratio(squarifyratio);\n case 'binary':\n return d3Hierarchy.treemapBinary;\n case 'dice':\n return d3Hierarchy.treemapDice;\n case 'slice':\n return d3Hierarchy.treemapSlice;\n default: // i.e. 'slice-dice' | 'dice-slice'\n return d3Hierarchy.treemapSliceDice;\n }\n}\n\nfunction flipTree(node, size, opts) {\n var tmp;\n\n if(opts.swapXY) {\n // swap x0 and y0\n tmp = node.x0;\n node.x0 = node.y0;\n node.y0 = tmp;\n\n // swap x1 and y1\n tmp = node.x1;\n node.x1 = node.y1;\n node.y1 = tmp;\n }\n\n if(opts.flipX) {\n tmp = node.x0;\n node.x0 = size[0] - node.x1;\n node.x1 = size[0] - tmp;\n }\n\n if(opts.flipY) {\n tmp = node.y0;\n node.y0 = size[1] - node.y1;\n node.y1 = size[1] - tmp;\n }\n\n var children = node.children;\n if(children) {\n for(var i = 0; i < children.length; i++) {\n flipTree(children[i], size, opts);\n }\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/treemap/partition.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/treemap/plot.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/treemap/plot.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar helpers = __webpack_require__(/*! ../sunburst/helpers */ \"./node_modules/plotly.js/src/traces/sunburst/helpers.js\");\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar TEXTPAD = __webpack_require__(/*! ../bar/constants */ \"./node_modules/plotly.js/src/traces/bar/constants.js\").TEXTPAD;\nvar barPlot = __webpack_require__(/*! ../bar/plot */ \"./node_modules/plotly.js/src/traces/bar/plot.js\");\nvar toMoveInsideBar = barPlot.toMoveInsideBar;\nvar uniformText = __webpack_require__(/*! ../bar/uniform_text */ \"./node_modules/plotly.js/src/traces/bar/uniform_text.js\");\nvar recordMinTextSize = uniformText.recordMinTextSize;\nvar clearMinTextSize = uniformText.clearMinTextSize;\nvar resizeText = __webpack_require__(/*! ../bar/style */ \"./node_modules/plotly.js/src/traces/bar/style.js\").resizeText;\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/treemap/constants.js\");\nvar drawDescendants = __webpack_require__(/*! ./draw_descendants */ \"./node_modules/plotly.js/src/traces/treemap/draw_descendants.js\");\nvar drawAncestors = __webpack_require__(/*! ./draw_ancestors */ \"./node_modules/plotly.js/src/traces/treemap/draw_ancestors.js\");\n\nmodule.exports = function(gd, cdmodule, transitionOpts, makeOnCompleteCallback) {\n var fullLayout = gd._fullLayout;\n var layer = fullLayout._treemaplayer;\n var join, onComplete;\n\n // If transition config is provided, then it is only a partial replot and traces not\n // updated are removed.\n var isFullReplot = !transitionOpts;\n\n clearMinTextSize('treemap', fullLayout);\n\n join = layer.selectAll('g.trace.treemap')\n .data(cdmodule, function(cd) { return cd[0].trace.uid; });\n\n join.enter().append('g')\n .classed('trace', true)\n .classed('treemap', true);\n\n join.order();\n\n if(!fullLayout.uniformtext.mode && helpers.hasTransition(transitionOpts)) {\n if(makeOnCompleteCallback) {\n // If it was passed a callback to register completion, make a callback. If\n // this is created, then it must be executed on completion, otherwise the\n // pos-transition redraw will not execute:\n onComplete = makeOnCompleteCallback();\n }\n\n var transition = d3.transition()\n .duration(transitionOpts.duration)\n .ease(transitionOpts.easing)\n .each('end', function() { onComplete && onComplete(); })\n .each('interrupt', function() { onComplete && onComplete(); });\n\n transition.each(function() {\n // Must run the selection again since otherwise enters/updates get grouped together\n // and these get executed out of order. Except we need them in order!\n layer.selectAll('g.trace').each(function(cd) {\n plotOne(gd, cd, this, transitionOpts);\n });\n });\n } else {\n join.each(function(cd) {\n plotOne(gd, cd, this, transitionOpts);\n });\n\n if(fullLayout.uniformtext.mode) {\n resizeText(gd, fullLayout._treemaplayer.selectAll('.trace'), 'treemap');\n }\n }\n\n if(isFullReplot) {\n join.exit().remove();\n }\n};\n\nfunction getKey(pt) {\n return helpers.isHierarchyRoot(pt) ?\n '' : // don't use the dummyId\n helpers.getPtId(pt);\n}\n\nfunction plotOne(gd, cd, element, transitionOpts) {\n var fullLayout = gd._fullLayout;\n var cd0 = cd[0];\n var trace = cd0.trace;\n var hierarchy = cd0.hierarchy;\n var entry = helpers.findEntryWithLevel(hierarchy, trace.level);\n\n var gTrace = d3.select(element);\n var selAncestors = gTrace.selectAll('g.pathbar');\n var selDescendants = gTrace.selectAll('g.slice');\n\n if(!entry) {\n selAncestors.remove();\n selDescendants.remove();\n return;\n }\n\n var isRoot = helpers.isHierarchyRoot(entry);\n var hasTransition = !fullLayout.uniformtext.mode && helpers.hasTransition(transitionOpts);\n\n var maxDepth = helpers.getMaxDepth(trace);\n var hasVisibleDepth = function(pt) {\n return pt.data.depth - entry.data.depth < maxDepth;\n };\n\n var gs = fullLayout._size;\n var domain = trace.domain;\n\n var vpw = gs.w * (domain.x[1] - domain.x[0]);\n var vph = gs.h * (domain.y[1] - domain.y[0]);\n var barW = vpw;\n var barH = trace.pathbar.thickness;\n var barPad = trace.marker.line.width + constants.gapWithPathbar;\n var barDifY = !trace.pathbar.visible ? 0 :\n trace.pathbar.side.indexOf('bottom') > -1 ? vph + barPad : -(barH + barPad);\n\n var pathbarOrigin = {\n x0: barW, // slide to the right\n x1: barW,\n y0: barDifY,\n y1: barDifY + barH\n };\n\n var findClosestEdge = function(pt, ref, size) {\n var e = trace.tiling.pad;\n var isLeftOfRect = function(x) { return x - e <= ref.x0; };\n var isRightOfRect = function(x) { return x + e >= ref.x1; };\n var isBottomOfRect = function(y) { return y - e <= ref.y0; };\n var isTopOfRect = function(y) { return y + e >= ref.y1; };\n\n return {\n x0: isLeftOfRect(pt.x0 - e) ? 0 : isRightOfRect(pt.x0 - e) ? size[0] : pt.x0,\n x1: isLeftOfRect(pt.x1 + e) ? 0 : isRightOfRect(pt.x1 + e) ? size[0] : pt.x1,\n y0: isBottomOfRect(pt.y0 - e) ? 0 : isTopOfRect(pt.y0 - e) ? size[1] : pt.y0,\n y1: isBottomOfRect(pt.y1 + e) ? 0 : isTopOfRect(pt.y1 + e) ? size[1] : pt.y1\n };\n };\n\n // stash of 'previous' position data used by tweening functions\n var prevEntry = null;\n var prevLookupPathbar = {};\n var prevLookupSlices = {};\n var nextOfPrevEntry = null;\n var getPrev = function(pt, onPathbar) {\n return onPathbar ?\n prevLookupPathbar[getKey(pt)] :\n prevLookupSlices[getKey(pt)];\n };\n\n var getOrigin = function(pt, onPathbar, refRect, size) {\n if(onPathbar) {\n return prevLookupPathbar[getKey(hierarchy)] || pathbarOrigin;\n } else {\n var ref = prevLookupSlices[trace.level] || refRect;\n\n if(hasVisibleDepth(pt)) { // case of an empty object - happens when maxdepth is set\n return findClosestEdge(pt, ref, size);\n }\n }\n return {};\n };\n\n // N.B. handle multiple-root special case\n if(cd0.hasMultipleRoots && isRoot) {\n maxDepth++;\n }\n\n trace._maxDepth = maxDepth;\n trace._backgroundColor = fullLayout.paper_bgcolor;\n trace._entryDepth = entry.data.depth;\n trace._atRootLevel = isRoot;\n\n var cenX = -vpw / 2 + gs.l + gs.w * (domain.x[1] + domain.x[0]) / 2;\n var cenY = -vph / 2 + gs.t + gs.h * (1 - (domain.y[1] + domain.y[0]) / 2);\n\n var viewMapX = function(x) { return cenX + x; };\n var viewMapY = function(y) { return cenY + y; };\n\n var barY0 = viewMapY(0);\n var barX0 = viewMapX(0);\n\n var viewBarX = function(x) { return barX0 + x; };\n var viewBarY = function(y) { return barY0 + y; };\n\n function pos(x, y) {\n return x + ',' + y;\n }\n\n var xStart = viewBarX(0);\n var limitX0 = function(p) { p.x = Math.max(xStart, p.x); };\n\n var edgeshape = trace.pathbar.edgeshape;\n\n // pathbar(directory) path generation fn\n var pathAncestor = function(d) {\n var _x0 = viewBarX(Math.max(Math.min(d.x0, d.x0), 0));\n var _x1 = viewBarX(Math.min(Math.max(d.x1, d.x1), barW));\n var _y0 = viewBarY(d.y0);\n var _y1 = viewBarY(d.y1);\n\n var halfH = barH / 2;\n\n var pL = {};\n var pR = {};\n\n pL.x = _x0;\n pR.x = _x1;\n\n pL.y = pR.y = (_y0 + _y1) / 2;\n\n var pA = {x: _x0, y: _y0};\n var pB = {x: _x1, y: _y0};\n var pC = {x: _x1, y: _y1};\n var pD = {x: _x0, y: _y1};\n\n if(edgeshape === '>') {\n pA.x -= halfH;\n pB.x -= halfH;\n pC.x -= halfH;\n pD.x -= halfH;\n } else if(edgeshape === '/') {\n pC.x -= halfH;\n pD.x -= halfH;\n pL.x -= halfH / 2;\n pR.x -= halfH / 2;\n } else if(edgeshape === '\\\\') {\n pA.x -= halfH;\n pB.x -= halfH;\n pL.x -= halfH / 2;\n pR.x -= halfH / 2;\n } else if(edgeshape === '<') {\n pL.x -= halfH;\n pR.x -= halfH;\n }\n\n limitX0(pA);\n limitX0(pD);\n limitX0(pL);\n\n limitX0(pB);\n limitX0(pC);\n limitX0(pR);\n\n return (\n 'M' + pos(pA.x, pA.y) +\n 'L' + pos(pB.x, pB.y) +\n 'L' + pos(pR.x, pR.y) +\n 'L' + pos(pC.x, pC.y) +\n 'L' + pos(pD.x, pD.y) +\n 'L' + pos(pL.x, pL.y) +\n 'Z'\n );\n };\n\n // slice path generation fn\n var pathDescendant = function(d) {\n var _x0 = viewMapX(d.x0);\n var _x1 = viewMapX(d.x1);\n var _y0 = viewMapY(d.y0);\n var _y1 = viewMapY(d.y1);\n\n var dx = _x1 - _x0;\n var dy = _y1 - _y0;\n if(!dx || !dy) return '';\n\n var FILLET = 0; // TODO: may expose this constant\n\n var r = (\n dx > 2 * FILLET &&\n dy > 2 * FILLET\n ) ? FILLET : 0;\n\n var arc = function(rx, ry) { return r ? 'a' + pos(r, r) + ' 0 0 1 ' + pos(rx, ry) : ''; };\n\n return (\n 'M' + pos(_x0, _y0 + r) +\n arc(r, -r) +\n 'L' + pos(_x1 - r, _y0) +\n arc(r, r) +\n 'L' + pos(_x1, _y1 - r) +\n arc(-r, r) +\n 'L' + pos(_x0 + r, _y1) +\n arc(-r, -r) + 'Z'\n );\n };\n\n var toMoveInsideSlice = function(pt, opts) {\n var x0 = pt.x0;\n var x1 = pt.x1;\n var y0 = pt.y0;\n var y1 = pt.y1;\n var textBB = pt.textBB;\n\n var hasFlag = function(f) { return trace.textposition.indexOf(f) !== -1; };\n\n var hasBottom = hasFlag('bottom');\n var hasTop = hasFlag('top') || (opts.isHeader && !hasBottom);\n\n var anchor =\n hasTop ? 'start' :\n hasBottom ? 'end' : 'middle';\n\n var hasRight = hasFlag('right');\n var hasLeft = hasFlag('left') || opts.onPathbar;\n\n var leftToRight =\n hasLeft ? -1 :\n hasRight ? 1 : 0;\n\n var pad = trace.marker.pad;\n if(opts.isHeader) {\n x0 += pad.l - TEXTPAD;\n x1 -= pad.r - TEXTPAD;\n if(x0 >= x1) {\n var mid = (x0 + x1) / 2;\n x0 = mid;\n x1 = mid;\n }\n\n // limit the drawing area for headers\n var limY;\n if(hasBottom) {\n limY = y1 - pad.b;\n if(y0 < limY && limY < y1) y0 = limY;\n } else {\n limY = y0 + pad.t;\n if(y0 < limY && limY < y1) y1 = limY;\n }\n }\n\n // position the text relative to the slice\n var transform = toMoveInsideBar(x0, x1, y0, y1, textBB, {\n isHorizontal: false,\n constrained: true,\n angle: 0,\n anchor: anchor,\n leftToRight: leftToRight\n });\n transform.fontSize = opts.fontSize;\n\n transform.targetX = viewMapX(transform.targetX);\n transform.targetY = viewMapY(transform.targetY);\n\n if(isNaN(transform.targetX) || isNaN(transform.targetY)) {\n return {};\n }\n\n if(x0 !== x1 && y0 !== y1) {\n recordMinTextSize(trace.type, transform, fullLayout);\n }\n\n return {\n scale: transform.scale,\n rotate: transform.rotate,\n textX: transform.textX,\n textY: transform.textY,\n anchorX: transform.anchorX,\n anchorY: transform.anchorY,\n targetX: transform.targetX,\n targetY: transform.targetY\n };\n };\n\n var interpFromParent = function(pt, onPathbar) {\n var parentPrev;\n var i = 0;\n var Q = pt;\n while(!parentPrev && i < maxDepth) { // loop to find a parent/grandParent on the previous graph\n i++;\n Q = Q.parent;\n if(Q) {\n parentPrev = getPrev(Q, onPathbar);\n } else i = maxDepth;\n }\n return parentPrev || {};\n };\n\n var makeExitSliceInterpolator = function(pt, onPathbar, refRect, size) {\n var prev = getPrev(pt, onPathbar);\n var next;\n\n if(onPathbar) {\n next = pathbarOrigin;\n } else {\n var entryPrev = getPrev(entry, onPathbar);\n if(entryPrev) {\n // 'entryPrev' is here has the previous coordinates of the entry\n // node, which corresponds to the last \"clicked\" node when zooming in\n next = findClosestEdge(pt, entryPrev, size);\n } else {\n // this happens when maxdepth is set, when leaves must\n // be removed and the entry is new (i.e. does not have a 'prev' object)\n next = {};\n }\n }\n\n return d3.interpolate(prev, next);\n };\n\n var makeUpdateSliceInterpolator = function(pt, onPathbar, refRect, size) {\n var prev0 = getPrev(pt, onPathbar);\n var prev;\n\n if(prev0) {\n // if pt already on graph, this is easy\n prev = prev0;\n } else {\n // for new pts:\n if(onPathbar) {\n prev = pathbarOrigin;\n } else {\n if(prevEntry) {\n // if trace was visible before\n if(pt.parent) {\n var ref = nextOfPrevEntry || refRect;\n\n if(ref && !onPathbar) {\n prev = findClosestEdge(pt, ref, size);\n } else {\n // if new leaf (when maxdepth is set),\n // grow it from its parent node\n prev = {};\n Lib.extendFlat(prev, interpFromParent(pt, onPathbar));\n }\n } else {\n prev = pt;\n }\n } else {\n prev = {};\n }\n }\n }\n\n return d3.interpolate(prev, {\n x0: pt.x0,\n x1: pt.x1,\n y0: pt.y0,\n y1: pt.y1\n });\n };\n\n var makeUpdateTextInterpolator = function(pt, onPathbar, refRect, size) {\n var prev0 = getPrev(pt, onPathbar);\n var prev = {};\n var origin = getOrigin(pt, onPathbar, refRect, size);\n\n Lib.extendFlat(prev, {\n transform: toMoveInsideSlice({\n x0: origin.x0,\n x1: origin.x1,\n y0: origin.y0,\n y1: origin.y1,\n textBB: pt.textBB,\n _text: pt._text\n }, {\n isHeader: helpers.isHeader(pt, trace)\n })\n });\n\n if(prev0) {\n // if pt already on graph, this is easy\n prev = prev0;\n } else {\n // for new pts:\n if(pt.parent) {\n Lib.extendFlat(prev, interpFromParent(pt, onPathbar));\n }\n }\n\n var transform = pt.transform;\n if(pt.x0 !== pt.x1 && pt.y0 !== pt.y1) {\n recordMinTextSize(trace.type, transform, fullLayout);\n }\n\n return d3.interpolate(prev, {\n transform: {\n scale: transform.scale,\n rotate: transform.rotate,\n textX: transform.textX,\n textY: transform.textY,\n anchorX: transform.anchorX,\n anchorY: transform.anchorY,\n targetX: transform.targetX,\n targetY: transform.targetY\n }\n });\n };\n\n var handleSlicesExit = function(slices, onPathbar, refRect, size, pathSlice) {\n var width = size[0];\n var height = size[1];\n\n if(hasTransition) {\n slices.exit().transition()\n .each(function() {\n var sliceTop = d3.select(this);\n\n var slicePath = sliceTop.select('path.surface');\n slicePath.transition().attrTween('d', function(pt2) {\n var interp = makeExitSliceInterpolator(pt2, onPathbar, refRect, [width, height]);\n return function(t) { return pathSlice(interp(t)); };\n });\n\n var sliceTextGroup = sliceTop.select('g.slicetext');\n sliceTextGroup.attr('opacity', 0);\n })\n .remove();\n } else {\n slices.exit().remove();\n }\n };\n\n var strTransform = function(d) {\n var transform = d.transform;\n\n if(d.x0 !== d.x1 && d.y0 !== d.y1) {\n recordMinTextSize(trace.type, transform, fullLayout);\n }\n\n return Lib.getTextTransform({\n textX: transform.textX,\n textY: transform.textY,\n anchorX: transform.anchorX,\n anchorY: transform.anchorY,\n targetX: transform.targetX,\n targetY: transform.targetY,\n scale: transform.scale,\n rotate: transform.rotate\n });\n };\n\n if(hasTransition) {\n // Important: do this before binding new sliceData!\n\n selAncestors.each(function(pt) {\n prevLookupPathbar[getKey(pt)] = {\n x0: pt.x0,\n x1: pt.x1,\n y0: pt.y0,\n y1: pt.y1\n };\n\n if(pt.transform) {\n prevLookupPathbar[getKey(pt)].transform = {\n textX: pt.transform.textX,\n textY: pt.transform.textY,\n anchorX: pt.transform.anchorX,\n anchorY: pt.transform.anchorY,\n targetX: pt.transform.targetX,\n targetY: pt.transform.targetY,\n scale: pt.transform.scale,\n rotate: pt.transform.rotate\n };\n }\n });\n\n selDescendants.each(function(pt) {\n prevLookupSlices[getKey(pt)] = {\n x0: pt.x0,\n x1: pt.x1,\n y0: pt.y0,\n y1: pt.y1\n };\n\n if(pt.transform) {\n prevLookupSlices[getKey(pt)].transform = {\n textX: pt.transform.textX,\n textY: pt.transform.textY,\n anchorX: pt.transform.anchorX,\n anchorY: pt.transform.anchorY,\n targetX: pt.transform.targetX,\n targetY: pt.transform.targetY,\n scale: pt.transform.scale,\n rotate: pt.transform.rotate\n };\n }\n\n if(!prevEntry && helpers.isEntry(pt)) {\n prevEntry = pt;\n }\n });\n }\n\n nextOfPrevEntry = drawDescendants(gd, cd, entry, selDescendants, {\n width: vpw,\n height: vph,\n\n viewX: viewMapX,\n viewY: viewMapY,\n\n pathSlice: pathDescendant,\n toMoveInsideSlice: toMoveInsideSlice,\n\n prevEntry: prevEntry,\n makeUpdateSliceInterpolator: makeUpdateSliceInterpolator,\n makeUpdateTextInterpolator: makeUpdateTextInterpolator,\n\n handleSlicesExit: handleSlicesExit,\n hasTransition: hasTransition,\n strTransform: strTransform\n });\n\n if(trace.pathbar.visible) {\n drawAncestors(gd, cd, entry, selAncestors, {\n barDifY: barDifY,\n width: barW,\n height: barH,\n\n viewX: viewBarX,\n viewY: viewBarY,\n\n pathSlice: pathAncestor,\n toMoveInsideSlice: toMoveInsideSlice,\n\n makeUpdateSliceInterpolator: makeUpdateSliceInterpolator,\n makeUpdateTextInterpolator: makeUpdateTextInterpolator,\n\n handleSlicesExit: handleSlicesExit,\n hasTransition: hasTransition,\n strTransform: strTransform\n });\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/treemap/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/treemap/style.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/treemap/style.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar helpers = __webpack_require__(/*! ../sunburst/helpers */ \"./node_modules/plotly.js/src/traces/sunburst/helpers.js\");\nvar resizeText = __webpack_require__(/*! ../bar/uniform_text */ \"./node_modules/plotly.js/src/traces/bar/uniform_text.js\").resizeText;\n\nfunction style(gd) {\n var s = gd._fullLayout._treemaplayer.selectAll('.trace');\n resizeText(gd, s, 'treemap');\n\n s.each(function(cd) {\n var gTrace = d3.select(this);\n var cd0 = cd[0];\n var trace = cd0.trace;\n\n gTrace.style('opacity', trace.opacity);\n\n gTrace.selectAll('path.surface').each(function(pt) {\n d3.select(this).call(styleOne, pt, trace, {\n hovered: false\n });\n });\n });\n}\n\nfunction styleOne(s, pt, trace, opts) {\n var hovered = (opts || {}).hovered;\n var cdi = pt.data.data;\n var ptNumber = cdi.i;\n var lineColor;\n var lineWidth;\n var fillColor = cdi.color;\n var isRoot = helpers.isHierarchyRoot(pt);\n var opacity = 1;\n\n if(hovered) {\n lineColor = trace._hovered.marker.line.color;\n lineWidth = trace._hovered.marker.line.width;\n } else {\n if(isRoot && fillColor === 'rgba(0,0,0,0)') {\n opacity = 0;\n lineColor = 'rgba(0,0,0,0)';\n lineWidth = 0;\n } else {\n lineColor = Lib.castOption(trace, ptNumber, 'marker.line.color') || Color.defaultLine;\n lineWidth = Lib.castOption(trace, ptNumber, 'marker.line.width') || 0;\n\n if(!trace._hasColorscale && !pt.onPathbar) {\n var depthfade = trace.marker.depthfade;\n if(depthfade) {\n var fadedColor = Color.combine(Color.addOpacity(trace._backgroundColor, 0.75), fillColor);\n var n;\n\n if(depthfade === true) {\n var maxDepth = helpers.getMaxDepth(trace);\n if(isFinite(maxDepth)) {\n if(helpers.isLeaf(pt)) {\n n = 0;\n } else {\n n = (trace._maxVisibleLayers) - (pt.data.depth - trace._entryDepth);\n }\n } else {\n n = pt.data.height + 1;\n }\n } else { // i.e. case of depthfade === 'reversed'\n n = pt.data.depth - trace._entryDepth;\n if(!trace._atRootLevel) n++;\n }\n\n if(n > 0) {\n for(var i = 0; i < n; i++) {\n var ratio = 0.5 * i / n;\n fillColor = Color.combine(Color.addOpacity(fadedColor, ratio), fillColor);\n }\n }\n }\n }\n }\n }\n\n s.style('stroke-width', lineWidth)\n .call(Color.fill, fillColor)\n .call(Color.stroke, lineColor)\n .style('opacity', opacity);\n}\n\nmodule.exports = {\n style: style,\n styleOne: styleOne\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/treemap/style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/violin/attributes.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/violin/attributes.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar boxAttrs = __webpack_require__(/*! ../box/attributes */ \"./node_modules/plotly.js/src/traces/box/attributes.js\");\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\n\nmodule.exports = {\n y: boxAttrs.y,\n x: boxAttrs.x,\n x0: boxAttrs.x0,\n y0: boxAttrs.y0,\n name: extendFlat({}, boxAttrs.name, {\n \n }),\n orientation: extendFlat({}, boxAttrs.orientation, {\n \n }),\n\n bandwidth: {\n valType: 'number',\n min: 0,\n \n editType: 'calc',\n \n },\n\n scalegroup: {\n valType: 'string',\n \n dflt: '',\n editType: 'calc',\n \n },\n scalemode: {\n valType: 'enumerated',\n values: ['width', 'count'],\n dflt: 'width',\n \n editType: 'calc',\n \n },\n\n spanmode: {\n valType: 'enumerated',\n values: ['soft', 'hard', 'manual'],\n dflt: 'soft',\n \n editType: 'calc',\n \n },\n span: {\n valType: 'info_array',\n items: [\n {valType: 'any', editType: 'calc'},\n {valType: 'any', editType: 'calc'}\n ],\n \n editType: 'calc',\n \n },\n\n line: {\n color: {\n valType: 'color',\n \n editType: 'style',\n \n },\n width: {\n valType: 'number',\n \n min: 0,\n dflt: 2,\n editType: 'style',\n \n },\n editType: 'plot'\n },\n fillcolor: boxAttrs.fillcolor,\n\n points: extendFlat({}, boxAttrs.boxpoints, {\n \n }),\n jitter: extendFlat({}, boxAttrs.jitter, {\n \n }),\n pointpos: extendFlat({}, boxAttrs.pointpos, {\n \n }),\n\n width: extendFlat({}, boxAttrs.width, {\n \n }),\n\n marker: boxAttrs.marker,\n text: boxAttrs.text,\n hovertext: boxAttrs.hovertext,\n hovertemplate: boxAttrs.hovertemplate,\n\n box: {\n visible: {\n valType: 'boolean',\n dflt: false,\n \n editType: 'plot',\n \n },\n width: {\n valType: 'number',\n min: 0,\n max: 1,\n dflt: 0.25,\n \n editType: 'plot',\n \n },\n fillcolor: {\n valType: 'color',\n \n editType: 'style',\n \n },\n line: {\n color: {\n valType: 'color',\n \n editType: 'style',\n \n },\n width: {\n valType: 'number',\n min: 0,\n \n editType: 'style',\n \n },\n editType: 'style'\n },\n editType: 'plot'\n },\n\n meanline: {\n visible: {\n valType: 'boolean',\n dflt: false,\n \n editType: 'plot',\n \n },\n color: {\n valType: 'color',\n \n editType: 'style',\n \n },\n width: {\n valType: 'number',\n min: 0,\n \n editType: 'style',\n \n },\n editType: 'plot'\n },\n\n side: {\n valType: 'enumerated',\n values: ['both', 'positive', 'negative'],\n dflt: 'both',\n \n editType: 'calc',\n \n },\n\n offsetgroup: boxAttrs.offsetgroup,\n alignmentgroup: boxAttrs.alignmentgroup,\n\n selected: boxAttrs.selected,\n unselected: boxAttrs.unselected,\n\n hoveron: {\n valType: 'flaglist',\n flags: ['violins', 'points', 'kde'],\n dflt: 'violins+points+kde',\n extras: ['all'],\n \n editType: 'style',\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/violin/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/violin/calc.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/violin/calc.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar boxCalc = __webpack_require__(/*! ../box/calc */ \"./node_modules/plotly.js/src/traces/box/calc.js\");\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/traces/violin/helpers.js\");\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nmodule.exports = function calc(gd, trace) {\n var cd = boxCalc(gd, trace);\n\n if(cd[0].t.empty) return cd;\n\n var fullLayout = gd._fullLayout;\n var valAxis = Axes.getFromId(\n gd,\n trace[trace.orientation === 'h' ? 'xaxis' : 'yaxis']\n );\n\n var spanMin = Infinity;\n var spanMax = -Infinity;\n var maxKDE = 0;\n var maxCount = 0;\n\n for(var i = 0; i < cd.length; i++) {\n var cdi = cd[i];\n var vals = cdi.pts.map(helpers.extractVal);\n\n var bandwidth = cdi.bandwidth = calcBandwidth(trace, cdi, vals);\n var span = cdi.span = calcSpan(trace, cdi, valAxis, bandwidth);\n\n if(cdi.min === cdi.max && bandwidth === 0) {\n // if span is zero and bandwidth is zero, we want a violin with zero width\n span = cdi.span = [cdi.min, cdi.max];\n cdi.density = [{v: 1, t: span[0]}];\n cdi.bandwidth = bandwidth;\n maxKDE = Math.max(maxKDE, 1);\n } else {\n // step that well covers the bandwidth and is multiple of span distance\n var dist = span[1] - span[0];\n var n = Math.ceil(dist / (bandwidth / 3));\n var step = dist / n;\n\n if(!isFinite(step) || !isFinite(n)) {\n Lib.error('Something went wrong with computing the violin span');\n cd[0].t.empty = true;\n return cd;\n }\n\n var kde = helpers.makeKDE(cdi, trace, vals);\n cdi.density = new Array(n);\n\n for(var k = 0, t = span[0]; t < (span[1] + step / 2); k++, t += step) {\n var v = kde(t);\n cdi.density[k] = {v: v, t: t};\n maxKDE = Math.max(maxKDE, v);\n }\n }\n\n maxCount = Math.max(maxCount, vals.length);\n spanMin = Math.min(spanMin, span[0]);\n spanMax = Math.max(spanMax, span[1]);\n }\n\n var extremes = Axes.findExtremes(valAxis, [spanMin, spanMax], {padded: true});\n trace._extremes[valAxis._id] = extremes;\n\n if(trace.width) {\n cd[0].t.maxKDE = maxKDE;\n } else {\n var violinScaleGroupStats = fullLayout._violinScaleGroupStats;\n var scaleGroup = trace.scalegroup;\n var groupStats = violinScaleGroupStats[scaleGroup];\n\n if(groupStats) {\n groupStats.maxKDE = Math.max(groupStats.maxKDE, maxKDE);\n groupStats.maxCount = Math.max(groupStats.maxCount, maxCount);\n } else {\n violinScaleGroupStats[scaleGroup] = {\n maxKDE: maxKDE,\n maxCount: maxCount\n };\n }\n }\n\n cd[0].t.labels.kde = Lib._(gd, 'kde:');\n\n return cd;\n};\n\n// Default to Silveman's rule of thumb\n// - https://stats.stackexchange.com/a/6671\n// - https://en.wikipedia.org/wiki/Kernel_density_estimation#A_rule-of-thumb_bandwidth_estimator\n// - https://github.com/statsmodels/statsmodels/blob/master/statsmodels/nonparametric/bandwidths.py\nfunction silvermanRule(len, ssd, iqr) {\n var a = Math.min(ssd, iqr / 1.349);\n return 1.059 * a * Math.pow(len, -0.2);\n}\n\nfunction calcBandwidth(trace, cdi, vals) {\n var span = cdi.max - cdi.min;\n\n // If span is zero\n if(!span) {\n if(trace.bandwidth) {\n return trace.bandwidth;\n } else {\n // if span is zero and no bandwidth is specified\n // it returns zero bandwidth which is a special case\n return 0;\n }\n }\n\n // Limit how small the bandwidth can be.\n //\n // Silverman's rule of thumb can be \"very\" small\n // when IQR does a poor job at describing the spread\n // of the distribution.\n // We also want to limit custom bandwidths\n // to not blow up kde computations.\n\n if(trace.bandwidth) {\n return Math.max(trace.bandwidth, span / 1e4);\n } else {\n var len = vals.length;\n var ssd = Lib.stdev(vals, len - 1, cdi.mean);\n return Math.max(\n silvermanRule(len, ssd, cdi.q3 - cdi.q1),\n span / 100\n );\n }\n}\n\nfunction calcSpan(trace, cdi, valAxis, bandwidth) {\n var spanmode = trace.spanmode;\n var spanIn = trace.span || [];\n var spanTight = [cdi.min, cdi.max];\n var spanLoose = [cdi.min - 2 * bandwidth, cdi.max + 2 * bandwidth];\n var spanOut;\n\n function calcSpanItem(index) {\n var s = spanIn[index];\n var sc = valAxis.type === 'multicategory' ?\n valAxis.r2c(s) :\n valAxis.d2c(s, 0, trace[cdi.valLetter + 'calendar']);\n return sc === BADNUM ? spanLoose[index] : sc;\n }\n\n if(spanmode === 'soft') {\n spanOut = spanLoose;\n } else if(spanmode === 'hard') {\n spanOut = spanTight;\n } else {\n spanOut = [calcSpanItem(0), calcSpanItem(1)];\n }\n\n // to reuse the equal-range-item block\n var dummyAx = {\n type: 'linear',\n range: spanOut\n };\n Axes.setConvert(dummyAx);\n dummyAx.cleanRange();\n\n return spanOut;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/violin/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/violin/cross_trace_calc.js":
-/*!**********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/violin/cross_trace_calc.js ***!
- \**********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar setPositionOffset = __webpack_require__(/*! ../box/cross_trace_calc */ \"./node_modules/plotly.js/src/traces/box/cross_trace_calc.js\").setPositionOffset;\nvar orientations = ['v', 'h'];\n\nmodule.exports = function crossTraceCalc(gd, plotinfo) {\n var calcdata = gd.calcdata;\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n\n for(var i = 0; i < orientations.length; i++) {\n var orientation = orientations[i];\n var posAxis = orientation === 'h' ? ya : xa;\n var violinList = [];\n\n for(var j = 0; j < calcdata.length; j++) {\n var cd = calcdata[j];\n var t = cd[0].t;\n var trace = cd[0].trace;\n\n if(trace.visible === true && trace.type === 'violin' &&\n !t.empty &&\n trace.orientation === orientation &&\n trace.xaxis === xa._id &&\n trace.yaxis === ya._id\n ) {\n violinList.push(j);\n }\n }\n\n setPositionOffset('violin', gd, violinList, posAxis);\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/violin/cross_trace_calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/violin/defaults.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/violin/defaults.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\n\nvar boxDefaults = __webpack_require__(/*! ../box/defaults */ \"./node_modules/plotly.js/src/traces/box/defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/violin/attributes.js\");\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n function coerce2(attr, dflt) {\n return Lib.coerce2(traceIn, traceOut, attributes, attr, dflt);\n }\n\n boxDefaults.handleSampleDefaults(traceIn, traceOut, coerce, layout);\n if(traceOut.visible === false) return;\n\n coerce('bandwidth');\n coerce('side');\n\n var width = coerce('width');\n if(!width) {\n coerce('scalegroup', traceOut.name);\n coerce('scalemode');\n }\n\n var span = coerce('span');\n var spanmodeDflt;\n if(Array.isArray(span)) spanmodeDflt = 'manual';\n coerce('spanmode', spanmodeDflt);\n\n var lineColor = coerce('line.color', (traceIn.marker || {}).color || defaultColor);\n var lineWidth = coerce('line.width');\n var fillColor = coerce('fillcolor', Color.addOpacity(traceOut.line.color, 0.5));\n\n boxDefaults.handlePointsDefaults(traceIn, traceOut, coerce, {prefix: ''});\n\n var boxWidth = coerce2('box.width');\n var boxFillColor = coerce2('box.fillcolor', fillColor);\n var boxLineColor = coerce2('box.line.color', lineColor);\n var boxLineWidth = coerce2('box.line.width', lineWidth);\n var boxVisible = coerce('box.visible', Boolean(boxWidth || boxFillColor || boxLineColor || boxLineWidth));\n if(!boxVisible) traceOut.box = {visible: false};\n\n var meanLineColor = coerce2('meanline.color', lineColor);\n var meanLineWidth = coerce2('meanline.width', lineWidth);\n var meanLineVisible = coerce('meanline.visible', Boolean(meanLineColor || meanLineWidth));\n if(!meanLineVisible) traceOut.meanline = {visible: false};\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/violin/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/violin/helpers.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/violin/helpers.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\n// Maybe add kernels more down the road,\n// but note that the default `spanmode: 'soft'` bounds might have\n// to become kernel-dependent\nvar kernels = {\n gaussian: function(v) {\n return (1 / Math.sqrt(2 * Math.PI)) * Math.exp(-0.5 * v * v);\n }\n};\n\nexports.makeKDE = function(calcItem, trace, vals) {\n var len = vals.length;\n var kernel = kernels.gaussian;\n var bandwidth = calcItem.bandwidth;\n var factor = 1 / (len * bandwidth);\n\n // don't use Lib.aggNums to skip isNumeric checks\n return function(x) {\n var sum = 0;\n for(var i = 0; i < len; i++) {\n sum += kernel((x - vals[i]) / bandwidth);\n }\n return factor * sum;\n };\n};\n\nexports.getPositionOnKdePath = function(calcItem, trace, valuePx) {\n var posLetter, valLetter;\n\n if(trace.orientation === 'h') {\n posLetter = 'y';\n valLetter = 'x';\n } else {\n posLetter = 'x';\n valLetter = 'y';\n }\n\n var pointOnPath = Lib.findPointOnPath(\n calcItem.path,\n valuePx,\n valLetter,\n {pathLength: calcItem.pathLength}\n );\n\n var posCenterPx = calcItem.posCenterPx;\n var posOnPath0 = pointOnPath[posLetter];\n var posOnPath1 = trace.side === 'both' ?\n 2 * posCenterPx - posOnPath0 :\n posCenterPx;\n\n return [posOnPath0, posOnPath1];\n};\n\nexports.getKdeValue = function(calcItem, trace, valueDist) {\n var vals = calcItem.pts.map(exports.extractVal);\n var kde = exports.makeKDE(calcItem, trace, vals);\n return kde(valueDist) / calcItem.posDensityScale;\n};\n\nexports.extractVal = function(o) { return o.v; };\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/violin/helpers.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/violin/hover.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/violin/hover.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar boxHoverPoints = __webpack_require__(/*! ../box/hover */ \"./node_modules/plotly.js/src/traces/box/hover.js\");\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/traces/violin/helpers.js\");\n\nmodule.exports = function hoverPoints(pointData, xval, yval, hovermode, hoverLayer) {\n var cd = pointData.cd;\n var trace = cd[0].trace;\n var hoveron = trace.hoveron;\n var hasHoveronViolins = hoveron.indexOf('violins') !== -1;\n var hasHoveronKDE = hoveron.indexOf('kde') !== -1;\n var closeData = [];\n var closePtData;\n var violinLineAttrs;\n\n if(hasHoveronViolins || hasHoveronKDE) {\n var closeBoxData = boxHoverPoints.hoverOnBoxes(pointData, xval, yval, hovermode);\n\n if(hasHoveronKDE && closeBoxData.length > 0) {\n var xa = pointData.xa;\n var ya = pointData.ya;\n var pLetter, vLetter, pAxis, vAxis, vVal;\n\n if(trace.orientation === 'h') {\n vVal = xval;\n pLetter = 'y';\n pAxis = ya;\n vLetter = 'x';\n vAxis = xa;\n } else {\n vVal = yval;\n pLetter = 'x';\n pAxis = xa;\n vLetter = 'y';\n vAxis = ya;\n }\n\n var di = cd[pointData.index];\n\n if(vVal >= di.span[0] && vVal <= di.span[1]) {\n var kdePointData = Lib.extendFlat({}, pointData);\n var vValPx = vAxis.c2p(vVal, true);\n var kdeVal = helpers.getKdeValue(di, trace, vVal);\n var pOnPath = helpers.getPositionOnKdePath(di, trace, vValPx);\n var paOffset = pAxis._offset;\n var paLength = pAxis._length;\n\n kdePointData[pLetter + '0'] = pOnPath[0];\n kdePointData[pLetter + '1'] = pOnPath[1];\n kdePointData[vLetter + '0'] = kdePointData[vLetter + '1'] = vValPx;\n kdePointData[vLetter + 'Label'] = vLetter + ': ' + Axes.hoverLabelText(vAxis, vVal) + ', ' + cd[0].t.labels.kde + ' ' + kdeVal.toFixed(3);\n\n // move the spike to the KDE point\n kdePointData.spikeDistance = closeBoxData[0].spikeDistance;\n var spikePosAttr = pLetter + 'Spike';\n kdePointData[spikePosAttr] = closeBoxData[0][spikePosAttr];\n closeBoxData[0].spikeDistance = undefined;\n closeBoxData[0][spikePosAttr] = undefined;\n\n // no hovertemplate support yet\n kdePointData.hovertemplate = false;\n\n closeData.push(kdePointData);\n\n violinLineAttrs = {stroke: pointData.color};\n violinLineAttrs[pLetter + '1'] = Lib.constrain(paOffset + pOnPath[0], paOffset, paOffset + paLength);\n violinLineAttrs[pLetter + '2'] = Lib.constrain(paOffset + pOnPath[1], paOffset, paOffset + paLength);\n violinLineAttrs[vLetter + '1'] = violinLineAttrs[vLetter + '2'] = vAxis._offset + vValPx;\n }\n }\n\n if(hasHoveronViolins) {\n closeData = closeData.concat(closeBoxData);\n }\n }\n\n if(hoveron.indexOf('points') !== -1) {\n closePtData = boxHoverPoints.hoverOnPoints(pointData, xval, yval);\n }\n\n // update violin line (if any)\n var violinLine = hoverLayer.selectAll('.violinline-' + trace.uid)\n .data(violinLineAttrs ? [0] : []);\n violinLine.enter().append('line')\n .classed('violinline-' + trace.uid, true)\n .attr('stroke-width', 1.5);\n violinLine.exit().remove();\n violinLine.attr(violinLineAttrs);\n\n // same combine logic as box hoverPoints\n if(hovermode === 'closest') {\n if(closePtData) return [closePtData];\n return closeData;\n }\n if(closePtData) {\n closeData.push(closePtData);\n return closeData;\n }\n return closeData;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/violin/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/violin/index.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/violin/index.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/violin/attributes.js\"),\n layoutAttributes: __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/violin/layout_attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/violin/defaults.js\"),\n crossTraceDefaults: __webpack_require__(/*! ../box/defaults */ \"./node_modules/plotly.js/src/traces/box/defaults.js\").crossTraceDefaults,\n supplyLayoutDefaults: __webpack_require__(/*! ./layout_defaults */ \"./node_modules/plotly.js/src/traces/violin/layout_defaults.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/violin/calc.js\"),\n crossTraceCalc: __webpack_require__(/*! ./cross_trace_calc */ \"./node_modules/plotly.js/src/traces/violin/cross_trace_calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/violin/plot.js\"),\n style: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/violin/style.js\"),\n styleOnSelect: __webpack_require__(/*! ../scatter/style */ \"./node_modules/plotly.js/src/traces/scatter/style.js\").styleOnSelect,\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/violin/hover.js\"),\n selectPoints: __webpack_require__(/*! ../box/select */ \"./node_modules/plotly.js/src/traces/box/select.js\"),\n\n moduleType: 'trace',\n name: 'violin',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['cartesian', 'svg', 'symbols', 'oriented', 'box-violin', 'showLegend', 'violinLayout', 'zoomScale'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/violin/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/violin/layout_attributes.js":
-/*!***********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/violin/layout_attributes.js ***!
- \***********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar boxLayoutAttrs = __webpack_require__(/*! ../box/layout_attributes */ \"./node_modules/plotly.js/src/traces/box/layout_attributes.js\");\nvar extendFlat = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").extendFlat;\n\nmodule.exports = {\n violinmode: extendFlat({}, boxLayoutAttrs.boxmode, {\n \n }),\n violingap: extendFlat({}, boxLayoutAttrs.boxgap, {\n \n }),\n violingroupgap: extendFlat({}, boxLayoutAttrs.boxgroupgap, {\n \n })\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/violin/layout_attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/violin/layout_defaults.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/violin/layout_defaults.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar layoutAttributes = __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/violin/layout_attributes.js\");\nvar boxLayoutDefaults = __webpack_require__(/*! ../box/layout_defaults */ \"./node_modules/plotly.js/src/traces/box/layout_defaults.js\");\n\nmodule.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {\n function coerce(attr, dflt) {\n return Lib.coerce(layoutIn, layoutOut, layoutAttributes, attr, dflt);\n }\n boxLayoutDefaults._supply(layoutIn, layoutOut, fullData, coerce, 'violin');\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/violin/layout_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/violin/plot.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/violin/plot.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\n\nvar boxPlot = __webpack_require__(/*! ../box/plot */ \"./node_modules/plotly.js/src/traces/box/plot.js\");\nvar linePoints = __webpack_require__(/*! ../scatter/line_points */ \"./node_modules/plotly.js/src/traces/scatter/line_points.js\");\nvar helpers = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/traces/violin/helpers.js\");\n\nmodule.exports = function plot(gd, plotinfo, cdViolins, violinLayer) {\n var fullLayout = gd._fullLayout;\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n\n function makePath(pts) {\n var segments = linePoints(pts, {\n xaxis: xa,\n yaxis: ya,\n connectGaps: true,\n baseTolerance: 0.75,\n shape: 'spline',\n simplify: true,\n linearized: true\n });\n return Drawing.smoothopen(segments[0], 1);\n }\n\n Lib.makeTraceGroups(violinLayer, cdViolins, 'trace violins').each(function(cd) {\n var plotGroup = d3.select(this);\n var cd0 = cd[0];\n var t = cd0.t;\n var trace = cd0.trace;\n\n if(trace.visible !== true || t.empty) {\n plotGroup.remove();\n return;\n }\n\n var bPos = t.bPos;\n var bdPos = t.bdPos;\n var valAxis = plotinfo[t.valLetter + 'axis'];\n var posAxis = plotinfo[t.posLetter + 'axis'];\n var hasBothSides = trace.side === 'both';\n var hasPositiveSide = hasBothSides || trace.side === 'positive';\n var hasNegativeSide = hasBothSides || trace.side === 'negative';\n\n var violins = plotGroup.selectAll('path.violin').data(Lib.identity);\n\n violins.enter().append('path')\n .style('vector-effect', 'non-scaling-stroke')\n .attr('class', 'violin');\n\n violins.exit().remove();\n\n violins.each(function(d) {\n var pathSel = d3.select(this);\n var density = d.density;\n var len = density.length;\n var posCenter = posAxis.c2l(d.pos + bPos, true);\n var posCenterPx = posAxis.l2p(posCenter);\n\n var scale;\n if(trace.width) {\n scale = t.maxKDE / bdPos;\n } else {\n var groupStats = fullLayout._violinScaleGroupStats[trace.scalegroup];\n scale = trace.scalemode === 'count' ?\n (groupStats.maxKDE / bdPos) * (groupStats.maxCount / d.pts.length) :\n groupStats.maxKDE / bdPos;\n }\n\n var pathPos, pathNeg, path;\n var i, k, pts, pt;\n\n if(hasPositiveSide) {\n pts = new Array(len);\n for(i = 0; i < len; i++) {\n pt = pts[i] = {};\n pt[t.posLetter] = posCenter + (density[i].v / scale);\n pt[t.valLetter] = valAxis.c2l(density[i].t, true);\n }\n pathPos = makePath(pts);\n }\n\n if(hasNegativeSide) {\n pts = new Array(len);\n for(k = 0, i = len - 1; k < len; k++, i--) {\n pt = pts[k] = {};\n pt[t.posLetter] = posCenter - (density[i].v / scale);\n pt[t.valLetter] = valAxis.c2l(density[i].t, true);\n }\n pathNeg = makePath(pts);\n }\n\n if(hasBothSides) {\n path = pathPos + 'L' + pathNeg.substr(1) + 'Z';\n } else {\n var startPt = [posCenterPx, valAxis.c2p(density[0].t)];\n var endPt = [posCenterPx, valAxis.c2p(density[len - 1].t)];\n\n if(trace.orientation === 'h') {\n startPt.reverse();\n endPt.reverse();\n }\n\n if(hasPositiveSide) {\n path = 'M' + startPt + 'L' + pathPos.substr(1) + 'L' + endPt;\n } else {\n path = 'M' + endPt + 'L' + pathNeg.substr(1) + 'L' + startPt;\n }\n }\n pathSel.attr('d', path);\n\n // save a few things used in getPositionOnKdePath, getKdeValue\n // on hover and for meanline draw block below\n d.posCenterPx = posCenterPx;\n d.posDensityScale = scale * bdPos;\n d.path = pathSel.node();\n d.pathLength = d.path.getTotalLength() / (hasBothSides ? 2 : 1);\n });\n\n var boxAttrs = trace.box;\n var boxWidth = boxAttrs.width;\n var boxLineWidth = (boxAttrs.line || {}).width;\n var bdPosScaled;\n var bPosPxOffset;\n\n if(hasBothSides) {\n bdPosScaled = bdPos * boxWidth;\n bPosPxOffset = 0;\n } else if(hasPositiveSide) {\n bdPosScaled = [0, bdPos * boxWidth / 2];\n bPosPxOffset = boxLineWidth * {x: 1, y: -1}[t.posLetter];\n } else {\n bdPosScaled = [bdPos * boxWidth / 2, 0];\n bPosPxOffset = boxLineWidth * {x: -1, y: 1}[t.posLetter];\n }\n\n // inner box\n boxPlot.plotBoxAndWhiskers(plotGroup, {pos: posAxis, val: valAxis}, trace, {\n bPos: bPos,\n bdPos: bdPosScaled,\n bPosPxOffset: bPosPxOffset\n });\n\n // meanline insider box\n boxPlot.plotBoxMean(plotGroup, {pos: posAxis, val: valAxis}, trace, {\n bPos: bPos,\n bdPos: bdPosScaled,\n bPosPxOffset: bPosPxOffset\n });\n\n var fn;\n if(!trace.box.visible && trace.meanline.visible) {\n fn = Lib.identity;\n }\n\n // N.B. use different class name than boxPlot.plotBoxMean,\n // to avoid selectAll conflict\n var meanPaths = plotGroup.selectAll('path.meanline').data(fn || []);\n meanPaths.enter().append('path')\n .attr('class', 'meanline')\n .style('fill', 'none')\n .style('vector-effect', 'non-scaling-stroke');\n meanPaths.exit().remove();\n meanPaths.each(function(d) {\n var v = valAxis.c2p(d.mean, true);\n var p = helpers.getPositionOnKdePath(d, trace, v);\n\n d3.select(this).attr('d',\n trace.orientation === 'h' ?\n 'M' + v + ',' + p[0] + 'V' + p[1] :\n 'M' + p[0] + ',' + v + 'H' + p[1]\n );\n });\n\n boxPlot.plotPoints(plotGroup, {x: xa, y: ya}, trace, t);\n });\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/violin/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/violin/style.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/violin/style.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar stylePoints = __webpack_require__(/*! ../scatter/style */ \"./node_modules/plotly.js/src/traces/scatter/style.js\").stylePoints;\n\nmodule.exports = function style(gd) {\n var s = d3.select(gd).selectAll('g.trace.violins');\n\n s.style('opacity', function(d) { return d[0].trace.opacity; });\n\n s.each(function(d) {\n var trace = d[0].trace;\n var sel = d3.select(this);\n var box = trace.box || {};\n var boxLine = box.line || {};\n var meanline = trace.meanline || {};\n var meanLineWidth = meanline.width;\n\n sel.selectAll('path.violin')\n .style('stroke-width', trace.line.width + 'px')\n .call(Color.stroke, trace.line.color)\n .call(Color.fill, trace.fillcolor);\n\n sel.selectAll('path.box')\n .style('stroke-width', boxLine.width + 'px')\n .call(Color.stroke, boxLine.color)\n .call(Color.fill, box.fillcolor);\n\n var meanLineStyle = {\n 'stroke-width': meanLineWidth + 'px',\n 'stroke-dasharray': (2 * meanLineWidth) + 'px,' + meanLineWidth + 'px'\n };\n\n sel.selectAll('path.mean')\n .style(meanLineStyle)\n .call(Color.stroke, meanline.color);\n\n sel.selectAll('path.meanline')\n .style(meanLineStyle)\n .call(Color.stroke, meanline.color);\n\n stylePoints(sel, trace, gd);\n });\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/violin/style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/volume/attributes.js":
-/*!****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/volume/attributes.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar colorScaleAttrs = __webpack_require__(/*! ../../components/colorscale/attributes */ \"./node_modules/plotly.js/src/components/colorscale/attributes.js\");\nvar isosurfaceAttrs = __webpack_require__(/*! ../isosurface/attributes */ \"./node_modules/plotly.js/src/traces/isosurface/attributes.js\");\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\n\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar overrideAll = __webpack_require__(/*! ../../plot_api/edit_types */ \"./node_modules/plotly.js/src/plot_api/edit_types.js\").overrideAll;\n\nvar attrs = module.exports = overrideAll(extendFlat({\n x: isosurfaceAttrs.x,\n y: isosurfaceAttrs.y,\n z: isosurfaceAttrs.z,\n value: isosurfaceAttrs.value,\n isomin: isosurfaceAttrs.isomin,\n isomax: isosurfaceAttrs.isomax,\n surface: isosurfaceAttrs.surface,\n spaceframe: {\n show: {\n valType: 'boolean',\n \n dflt: false,\n \n },\n fill: {\n valType: 'number',\n \n min: 0,\n max: 1,\n dflt: 1,\n \n }\n },\n\n slices: isosurfaceAttrs.slices,\n caps: isosurfaceAttrs.caps,\n text: isosurfaceAttrs.text,\n hovertext: isosurfaceAttrs.hovertext,\n hovertemplate: isosurfaceAttrs.hovertemplate\n},\n\ncolorScaleAttrs('', {\n colorAttr: '`value`',\n showScaleDflt: true,\n editTypeOverride: 'calc'\n}), {\n\n colorbar: isosurfaceAttrs.colorbar,\n opacity: isosurfaceAttrs.opacity,\n opacityscale: {\n valType: 'any',\n \n editType: 'calc',\n \n },\n\n lightposition: isosurfaceAttrs.lightposition,\n lighting: isosurfaceAttrs.lighting,\n flatshading: isosurfaceAttrs.flatshading,\n contour: isosurfaceAttrs.contour,\n\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo),\n showlegend: extendFlat({}, baseAttrs.showlegend, {dflt: false})\n}), 'calc', 'nested');\n\nattrs.x.editType = attrs.y.editType = attrs.z.editType = attrs.value.editType = 'calc+clearAxisTypes';\nattrs.transforms = undefined;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/volume/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/volume/convert.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/volume/convert.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar createMesh = __webpack_require__(/*! gl-mesh3d */ \"./node_modules/gl-mesh3d/mesh.js\");\n\nvar parseColorScale = __webpack_require__(/*! ../../lib/gl_format_color */ \"./node_modules/plotly.js/src/lib/gl_format_color.js\").parseColorScale;\nvar str2RgbaArray = __webpack_require__(/*! ../../lib/str2rgbarray */ \"./node_modules/plotly.js/src/lib/str2rgbarray.js\");\nvar extractOpts = __webpack_require__(/*! ../../components/colorscale */ \"./node_modules/plotly.js/src/components/colorscale/index.js\").extractOpts;\nvar zip3 = __webpack_require__(/*! ../../plots/gl3d/zip3 */ \"./node_modules/plotly.js/src/plots/gl3d/zip3.js\");\n\nvar findNearestOnAxis = __webpack_require__(/*! ../isosurface/convert */ \"./node_modules/plotly.js/src/traces/isosurface/convert.js\").findNearestOnAxis;\nvar generateIsoMeshes = __webpack_require__(/*! ../isosurface/convert */ \"./node_modules/plotly.js/src/traces/isosurface/convert.js\").generateIsoMeshes;\n\nfunction VolumeTrace(scene, mesh, uid) {\n this.scene = scene;\n this.uid = uid;\n this.mesh = mesh;\n this.name = '';\n this.data = null;\n this.showContour = false;\n}\n\nvar proto = VolumeTrace.prototype;\n\nproto.handlePick = function(selection) {\n if(selection.object === this.mesh) {\n var rawId = selection.data.index;\n\n var x = this.data._meshX[rawId];\n var y = this.data._meshY[rawId];\n var z = this.data._meshZ[rawId];\n\n var height = this.data._Ys.length;\n var depth = this.data._Zs.length;\n\n var i = findNearestOnAxis(x, this.data._Xs).id;\n var j = findNearestOnAxis(y, this.data._Ys).id;\n var k = findNearestOnAxis(z, this.data._Zs).id;\n\n var selectIndex = selection.index = k + depth * j + depth * height * i;\n\n selection.traceCoordinate = [\n this.data._meshX[selectIndex],\n this.data._meshY[selectIndex],\n this.data._meshZ[selectIndex],\n this.data._value[selectIndex]\n ];\n\n var text = this.data.hovertext || this.data.text;\n if(Array.isArray(text) && text[selectIndex] !== undefined) {\n selection.textLabel = text[selectIndex];\n } else if(text) {\n selection.textLabel = text;\n }\n\n return true;\n }\n};\n\nproto.update = function(data) {\n var scene = this.scene;\n var layout = scene.fullSceneLayout;\n\n this.data = generateIsoMeshes(data);\n\n // Unpack position data\n function toDataCoords(axis, coord, scale, calendar) {\n return coord.map(function(x) {\n return axis.d2l(x, 0, calendar) * scale;\n });\n }\n\n var positions = zip3(\n toDataCoords(layout.xaxis, data._meshX, scene.dataScale[0], data.xcalendar),\n toDataCoords(layout.yaxis, data._meshY, scene.dataScale[1], data.ycalendar),\n toDataCoords(layout.zaxis, data._meshZ, scene.dataScale[2], data.zcalendar));\n\n var cells = zip3(data._meshI, data._meshJ, data._meshK);\n\n var config = {\n positions: positions,\n cells: cells,\n lightPosition: [data.lightposition.x, data.lightposition.y, data.lightposition.z],\n ambient: data.lighting.ambient,\n diffuse: data.lighting.diffuse,\n specular: data.lighting.specular,\n roughness: data.lighting.roughness,\n fresnel: data.lighting.fresnel,\n vertexNormalsEpsilon: data.lighting.vertexnormalsepsilon,\n faceNormalsEpsilon: data.lighting.facenormalsepsilon,\n opacity: data.opacity,\n opacityscale: data.opacityscale,\n contourEnable: data.contour.show,\n contourColor: str2RgbaArray(data.contour.color).slice(0, 3),\n contourWidth: data.contour.width,\n useFacetNormals: data.flatshading\n };\n\n var cOpts = extractOpts(data);\n config.vertexIntensity = data._meshIntensity;\n config.vertexIntensityBounds = [cOpts.min, cOpts.max];\n config.colormap = parseColorScale(data);\n\n // Update mesh\n this.mesh.update(config);\n};\n\nproto.dispose = function() {\n this.scene.glplot.remove(this.mesh);\n this.mesh.dispose();\n};\n\nfunction createVolumeTrace(scene, data) {\n var gl = scene.glplot.gl;\n var mesh = createMesh({gl: gl});\n var result = new VolumeTrace(scene, mesh, data.uid);\n\n mesh._trace = result;\n result.update(data);\n scene.glplot.add(mesh);\n return result;\n}\n\nmodule.exports = createVolumeTrace;\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/volume/convert.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/volume/defaults.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/volume/defaults.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/volume/attributes.js\");\nvar supplyIsoDefaults = __webpack_require__(/*! ../isosurface/defaults */ \"./node_modules/plotly.js/src/traces/isosurface/defaults.js\").supplyIsoDefaults;\n\nvar MIN = 0.1; // Note: often we don't want the data cube to be disappeared\n\nfunction createWave(n, minOpacity) {\n var arr = [];\n var steps = 32; // Max: 256\n for(var i = 0; i < steps; i++) {\n var u = i / (steps - 1);\n var v = minOpacity + (1 - minOpacity) * (1 - Math.pow(Math.sin(n * u * Math.PI), 2));\n arr.push([\n u,\n Math.max(1, Math.min(0, v))\n ]);\n }\n return arr;\n}\n\nmodule.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n supplyIsoDefaults(traceIn, traceOut, defaultColor, layout, coerce);\n\n var opacityscale = coerce('opacityscale');\n if(opacityscale === 'max') {\n traceOut.opacityscale = [[0, MIN], [1, 1]];\n } else if(opacityscale === 'min') {\n traceOut.opacityscale = [[0, 1], [1, MIN]];\n } else if(opacityscale === 'extremes') {\n traceOut.opacityscale = createWave(1, MIN);\n } else if(!isValidScaleArray(opacityscale)) {\n traceOut.opacityscale = undefined;\n }\n};\n\nfunction isValidScaleArray(scl) {\n var highestVal = 0;\n\n if(!Array.isArray(scl) || scl.length < 2) return false;\n\n if(!scl[0] || !scl[scl.length - 1]) return false;\n\n if(+scl[0][0] !== 0 || +scl[scl.length - 1][0] !== 1) return false;\n\n for(var i = 0; i < scl.length; i++) {\n var si = scl[i];\n\n if(si.length !== 2 || +si[0] < highestVal) {\n return false;\n }\n\n highestVal = +si[0];\n }\n\n return true;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/volume/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/volume/index.js":
-/*!***********************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/volume/index.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/volume/attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/volume/defaults.js\"),\n calc: __webpack_require__(/*! ../isosurface/calc */ \"./node_modules/plotly.js/src/traces/isosurface/calc.js\"),\n colorbar: {\n min: 'cmin',\n max: 'cmax'\n },\n plot: __webpack_require__(/*! ./convert */ \"./node_modules/plotly.js/src/traces/volume/convert.js\"),\n\n moduleType: 'trace',\n name: 'volume',\n basePlotModule: __webpack_require__(/*! ../../plots/gl3d */ \"./node_modules/plotly.js/src/plots/gl3d/index.js\"),\n categories: ['gl3d', 'showLegend'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/volume/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/waterfall/attributes.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/waterfall/attributes.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar barAttrs = __webpack_require__(/*! ../bar/attributes */ \"./node_modules/plotly.js/src/traces/bar/attributes.js\");\nvar lineAttrs = __webpack_require__(/*! ../scatter/attributes */ \"./node_modules/plotly.js/src/traces/scatter/attributes.js\").line;\nvar baseAttrs = __webpack_require__(/*! ../../plots/attributes */ \"./node_modules/plotly.js/src/plots/attributes.js\");\nvar hovertemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").hovertemplateAttrs;\nvar texttemplateAttrs = __webpack_require__(/*! ../../plots/template_attributes */ \"./node_modules/plotly.js/src/plots/template_attributes.js\").texttemplateAttrs;\nvar constants = __webpack_require__(/*! ./constants */ \"./node_modules/plotly.js/src/traces/waterfall/constants.js\");\nvar extendFlat = __webpack_require__(/*! ../../lib/extend */ \"./node_modules/plotly.js/src/lib/extend.js\").extendFlat;\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\n\nfunction directionAttrs(dirTxt) {\n return {\n marker: {\n color: extendFlat({}, barAttrs.marker.color, {\n arrayOk: false,\n editType: 'style',\n \n }),\n line: {\n color: extendFlat({}, barAttrs.marker.line.color, {\n arrayOk: false,\n editType: 'style',\n \n }),\n width: extendFlat({}, barAttrs.marker.line.width, {\n arrayOk: false,\n editType: 'style',\n \n }),\n editType: 'style',\n },\n editType: 'style'\n },\n editType: 'style'\n };\n}\n\nmodule.exports = {\n measure: {\n valType: 'data_array',\n dflt: [],\n \n editType: 'calc',\n \n },\n\n base: {\n valType: 'number',\n dflt: null,\n arrayOk: false,\n \n editType: 'calc',\n \n },\n\n x: barAttrs.x,\n x0: barAttrs.x0,\n dx: barAttrs.dx,\n y: barAttrs.y,\n y0: barAttrs.y0,\n dy: barAttrs.dy,\n\n hovertext: barAttrs.hovertext,\n hovertemplate: hovertemplateAttrs({}, {\n keys: constants.eventDataKeys\n }),\n\n hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {\n flags: ['name', 'x', 'y', 'text', 'initial', 'delta', 'final']\n }),\n\n textinfo: {\n valType: 'flaglist',\n flags: ['label', 'text', 'initial', 'delta', 'final'],\n extras: ['none'],\n \n editType: 'plot',\n arrayOk: false,\n \n },\n // TODO: incorporate `label` and `value` in the eventData\n texttemplate: texttemplateAttrs({editType: 'plot'}, {\n keys: constants.eventDataKeys.concat(['label'])\n }),\n text: barAttrs.text,\n textposition: barAttrs.textposition,\n insidetextanchor: barAttrs.insidetextanchor,\n textangle: barAttrs.textangle,\n textfont: barAttrs.textfont,\n insidetextfont: barAttrs.insidetextfont,\n outsidetextfont: barAttrs.outsidetextfont,\n constraintext: barAttrs.constraintext,\n\n cliponaxis: barAttrs.cliponaxis,\n orientation: barAttrs.orientation,\n\n offset: barAttrs.offset,\n width: barAttrs.width,\n\n increasing: directionAttrs('increasing'),\n decreasing: directionAttrs('decreasing'),\n totals: directionAttrs('intermediate sums and total'),\n\n connector: {\n line: {\n color: extendFlat({}, lineAttrs.color, {dflt: Color.defaultLine}),\n width: extendFlat({}, lineAttrs.width, {\n editType: 'plot', // i.e. to adjust bars is mode: 'between'. See https://github.com/plotly/plotly.js/issues/3787\n }),\n dash: lineAttrs.dash,\n editType: 'plot'\n },\n mode: {\n valType: 'enumerated',\n values: ['spanning', 'between'],\n dflt: 'between',\n \n editType: 'plot',\n \n },\n visible: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'plot',\n \n },\n editType: 'plot'\n },\n\n offsetgroup: barAttrs.offsetgroup,\n alignmentgroup: barAttrs.alignmentgroup\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/waterfall/attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/waterfall/calc.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/waterfall/calc.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Axes = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar mergeArray = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\").mergeArray;\nvar calcSelection = __webpack_require__(/*! ../scatter/calc_selection */ \"./node_modules/plotly.js/src/traces/scatter/calc_selection.js\");\nvar BADNUM = __webpack_require__(/*! ../../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nfunction isAbsolute(a) {\n return (a === 'a' || a === 'absolute');\n}\n\nfunction isTotal(a) {\n return (a === 't' || a === 'total');\n}\n\nmodule.exports = function calc(gd, trace) {\n var xa = Axes.getFromId(gd, trace.xaxis || 'x');\n var ya = Axes.getFromId(gd, trace.yaxis || 'y');\n var size, pos;\n\n if(trace.orientation === 'h') {\n size = xa.makeCalcdata(trace, 'x');\n pos = ya.makeCalcdata(trace, 'y');\n } else {\n size = ya.makeCalcdata(trace, 'y');\n pos = xa.makeCalcdata(trace, 'x');\n }\n\n // create the \"calculated data\" to plot\n var serieslen = Math.min(pos.length, size.length);\n var cd = new Array(serieslen);\n\n // set position and size (as well as for waterfall total size)\n var previousSum = 0;\n var newSize;\n // trace-wide flags\n var hasTotals = false;\n\n for(var i = 0; i < serieslen; i++) {\n var amount = size[i] || 0;\n\n var connectToNext = false;\n if(size[i] !== BADNUM || isTotal(trace.measure[i]) || isAbsolute(trace.measure[i])) {\n if(i + 1 < serieslen && (size[i + 1] !== BADNUM || isTotal(trace.measure[i + 1]) || isAbsolute(trace.measure[i + 1]))) {\n connectToNext = true;\n }\n }\n\n var cdi = cd[i] = {\n i: i,\n p: pos[i],\n s: amount,\n rawS: amount,\n cNext: connectToNext\n };\n\n if(isAbsolute(trace.measure[i])) {\n previousSum = cdi.s;\n\n cdi.isSum = true;\n cdi.dir = 'totals';\n cdi.s = previousSum;\n } else if(isTotal(trace.measure[i])) {\n cdi.isSum = true;\n cdi.dir = 'totals';\n cdi.s = previousSum;\n } else {\n // default: relative\n cdi.isSum = false;\n cdi.dir = cdi.rawS < 0 ? 'decreasing' : 'increasing';\n newSize = cdi.s;\n cdi.s = previousSum + newSize;\n previousSum += newSize;\n }\n\n if(cdi.dir === 'totals') {\n hasTotals = true;\n }\n\n if(trace.ids) {\n cdi.id = String(trace.ids[i]);\n }\n\n cdi.v = (trace.base || 0) + previousSum;\n }\n\n if(cd.length) cd[0].hasTotals = hasTotals;\n\n mergeArray(trace.text, cd, 'tx');\n mergeArray(trace.hovertext, cd, 'htx');\n calcSelection(cd, trace);\n\n return cd;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/waterfall/calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/waterfall/constants.js":
-/*!******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/waterfall/constants.js ***!
- \******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n eventDataKeys: [\n 'initial',\n 'delta',\n 'final'\n ]\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/waterfall/constants.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/waterfall/cross_trace_calc.js":
-/*!*************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/waterfall/cross_trace_calc.js ***!
- \*************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar setGroupPositions = __webpack_require__(/*! ../bar/cross_trace_calc */ \"./node_modules/plotly.js/src/traces/bar/cross_trace_calc.js\").setGroupPositions;\n\nmodule.exports = function crossTraceCalc(gd, plotinfo) {\n var fullLayout = gd._fullLayout;\n var fullData = gd._fullData;\n var calcdata = gd.calcdata;\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n var waterfalls = [];\n var waterfallsVert = [];\n var waterfallsHorz = [];\n var cd, i;\n\n for(i = 0; i < fullData.length; i++) {\n var fullTrace = fullData[i];\n\n if(\n fullTrace.visible === true &&\n fullTrace.xaxis === xa._id &&\n fullTrace.yaxis === ya._id &&\n fullTrace.type === 'waterfall'\n ) {\n cd = calcdata[i];\n\n if(fullTrace.orientation === 'h') {\n waterfallsHorz.push(cd);\n } else {\n waterfallsVert.push(cd);\n }\n\n waterfalls.push(cd);\n }\n }\n\n var opts = {\n mode: fullLayout.waterfallmode,\n norm: fullLayout.waterfallnorm,\n gap: fullLayout.waterfallgap,\n groupgap: fullLayout.waterfallgroupgap\n };\n\n setGroupPositions(gd, xa, ya, waterfallsVert, opts);\n setGroupPositions(gd, ya, xa, waterfallsHorz, opts);\n\n for(i = 0; i < waterfalls.length; i++) {\n cd = waterfalls[i];\n\n for(var j = 0; j < cd.length; j++) {\n var di = cd[j];\n\n if(di.isSum === false) {\n di.s0 += (j === 0) ? 0 : cd[j - 1].s;\n }\n\n if(j + 1 < cd.length) {\n cd[j].nextP0 = cd[j + 1].p0;\n cd[j].nextS0 = cd[j + 1].s0;\n }\n }\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/waterfall/cross_trace_calc.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/waterfall/defaults.js":
-/*!*****************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/waterfall/defaults.js ***!
- \*****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\n\nvar handleGroupingDefaults = __webpack_require__(/*! ../bar/defaults */ \"./node_modules/plotly.js/src/traces/bar/defaults.js\").handleGroupingDefaults;\nvar handleText = __webpack_require__(/*! ../bar/defaults */ \"./node_modules/plotly.js/src/traces/bar/defaults.js\").handleText;\nvar handleXYDefaults = __webpack_require__(/*! ../scatter/xy_defaults */ \"./node_modules/plotly.js/src/traces/scatter/xy_defaults.js\");\nvar attributes = __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/waterfall/attributes.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar delta = __webpack_require__(/*! ../../constants/delta.js */ \"./node_modules/plotly.js/src/constants/delta.js\");\n\nvar INCREASING_COLOR = delta.INCREASING.COLOR;\nvar DECREASING_COLOR = delta.DECREASING.COLOR;\nvar TOTALS_COLOR = '#4499FF';\n\nfunction handleDirection(coerce, direction, defaultColor) {\n coerce(direction + '.marker.color', defaultColor);\n coerce(direction + '.marker.line.color', Color.defaultLine);\n coerce(direction + '.marker.line.width');\n}\n\nfunction supplyDefaults(traceIn, traceOut, defaultColor, layout) {\n function coerce(attr, dflt) {\n return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);\n }\n\n var len = handleXYDefaults(traceIn, traceOut, layout, coerce);\n if(!len) {\n traceOut.visible = false;\n return;\n }\n\n coerce('measure');\n\n coerce('orientation', (traceOut.x && !traceOut.y) ? 'h' : 'v');\n coerce('base');\n coerce('offset');\n coerce('width');\n\n coerce('text');\n\n coerce('hovertext');\n coerce('hovertemplate');\n\n var textposition = coerce('textposition');\n handleText(traceIn, traceOut, layout, coerce, textposition, {\n moduleHasSelected: false,\n moduleHasUnselected: false,\n moduleHasConstrain: true,\n moduleHasCliponaxis: true,\n moduleHasTextangle: true,\n moduleHasInsideanchor: true\n });\n\n\n if(traceOut.textposition !== 'none') {\n coerce('texttemplate');\n if(!traceOut.texttemplate) coerce('textinfo');\n }\n\n handleDirection(coerce, 'increasing', INCREASING_COLOR);\n handleDirection(coerce, 'decreasing', DECREASING_COLOR);\n handleDirection(coerce, 'totals', TOTALS_COLOR);\n\n var connectorVisible = coerce('connector.visible');\n if(connectorVisible) {\n coerce('connector.mode');\n var connectorLineWidth = coerce('connector.line.width');\n if(connectorLineWidth) {\n coerce('connector.line.color');\n coerce('connector.line.dash');\n }\n }\n}\n\nfunction crossTraceDefaults(fullData, fullLayout) {\n var traceIn, traceOut;\n\n function coerce(attr) {\n return Lib.coerce(traceOut._input, traceOut, attributes, attr);\n }\n\n if(fullLayout.waterfallmode === 'group') {\n for(var i = 0; i < fullData.length; i++) {\n traceOut = fullData[i];\n traceIn = traceOut._input;\n\n handleGroupingDefaults(traceIn, traceOut, fullLayout, coerce);\n }\n }\n}\n\nmodule.exports = {\n supplyDefaults: supplyDefaults,\n crossTraceDefaults: crossTraceDefaults\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/waterfall/defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/waterfall/event_data.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/waterfall/event_data.js ***!
- \*******************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = function eventData(out, pt /* , trace, cd, pointNumber */) {\n // standard cartesian event data\n out.x = 'xVal' in pt ? pt.xVal : pt.x;\n out.y = 'yVal' in pt ? pt.yVal : pt.y;\n\n // for funnel\n if('initial' in pt) out.initial = pt.initial;\n if('delta' in pt) out.delta = pt.delta;\n if('final' in pt) out.final = pt.final;\n\n if(pt.xa) out.xaxis = pt.xa;\n if(pt.ya) out.yaxis = pt.ya;\n\n return out;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/waterfall/event_data.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/waterfall/hover.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/waterfall/hover.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar hoverLabelText = __webpack_require__(/*! ../../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\").hoverLabelText;\nvar opacity = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\").opacity;\nvar hoverOnBars = __webpack_require__(/*! ../bar/hover */ \"./node_modules/plotly.js/src/traces/bar/hover.js\").hoverOnBars;\nvar delta = __webpack_require__(/*! ../../constants/delta.js */ \"./node_modules/plotly.js/src/constants/delta.js\");\n\nvar DIRSYMBOL = {\n increasing: delta.INCREASING.SYMBOL,\n decreasing: delta.DECREASING.SYMBOL\n};\n\nmodule.exports = function hoverPoints(pointData, xval, yval, hovermode) {\n var point = hoverOnBars(pointData, xval, yval, hovermode);\n if(!point) return;\n\n var cd = point.cd;\n var trace = cd[0].trace;\n var isHorizontal = (trace.orientation === 'h');\n\n var vAxis = isHorizontal ? pointData.xa : pointData.ya;\n\n function formatNumber(a) {\n return hoverLabelText(vAxis, a);\n }\n\n // the closest data point\n var index = point.index;\n var di = cd[index];\n\n var size = (di.isSum) ? di.b + di.s : di.rawS;\n\n if(!di.isSum) {\n point.initial = di.b + di.s - size;\n point.delta = size;\n point.final = point.initial + point.delta;\n\n var v = formatNumber(Math.abs(point.delta));\n point.deltaLabel = size < 0 ? '(' + v + ')' : v;\n point.finalLabel = formatNumber(point.final);\n point.initialLabel = formatNumber(point.initial);\n }\n\n var hoverinfo = di.hi || trace.hoverinfo;\n var text = [];\n if(hoverinfo && hoverinfo !== 'none' && hoverinfo !== 'skip') {\n var isAll = (hoverinfo === 'all');\n var parts = hoverinfo.split('+');\n\n var hasFlag = function(flag) { return isAll || parts.indexOf(flag) !== -1; };\n\n if(!di.isSum) {\n if(hasFlag('final') &&\n (isHorizontal ? !hasFlag('x') : !hasFlag('y')) // don't display redundant info.\n ) {\n text.push(point.finalLabel);\n }\n if(hasFlag('delta')) {\n if(size < 0) {\n text.push(point.deltaLabel + ' ' + DIRSYMBOL.decreasing);\n } else {\n text.push(point.deltaLabel + ' ' + DIRSYMBOL.increasing);\n }\n }\n if(hasFlag('initial')) {\n text.push('Initial: ' + point.initialLabel);\n }\n }\n }\n\n if(text.length) point.extraText = text.join('
');\n\n point.color = getTraceColor(trace, di);\n\n return [point];\n};\n\nfunction getTraceColor(trace, di) {\n var cont = trace[di.dir].marker;\n var mc = cont.color;\n var mlc = cont.line.color;\n var mlw = cont.line.width;\n if(opacity(mc)) return mc;\n else if(opacity(mlc) && mlw) return mlc;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/waterfall/hover.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/waterfall/index.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/waterfall/index.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n attributes: __webpack_require__(/*! ./attributes */ \"./node_modules/plotly.js/src/traces/waterfall/attributes.js\"),\n layoutAttributes: __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/waterfall/layout_attributes.js\"),\n supplyDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/waterfall/defaults.js\").supplyDefaults,\n crossTraceDefaults: __webpack_require__(/*! ./defaults */ \"./node_modules/plotly.js/src/traces/waterfall/defaults.js\").crossTraceDefaults,\n supplyLayoutDefaults: __webpack_require__(/*! ./layout_defaults */ \"./node_modules/plotly.js/src/traces/waterfall/layout_defaults.js\"),\n calc: __webpack_require__(/*! ./calc */ \"./node_modules/plotly.js/src/traces/waterfall/calc.js\"),\n crossTraceCalc: __webpack_require__(/*! ./cross_trace_calc */ \"./node_modules/plotly.js/src/traces/waterfall/cross_trace_calc.js\"),\n plot: __webpack_require__(/*! ./plot */ \"./node_modules/plotly.js/src/traces/waterfall/plot.js\"),\n style: __webpack_require__(/*! ./style */ \"./node_modules/plotly.js/src/traces/waterfall/style.js\").style,\n hoverPoints: __webpack_require__(/*! ./hover */ \"./node_modules/plotly.js/src/traces/waterfall/hover.js\"),\n eventData: __webpack_require__(/*! ./event_data */ \"./node_modules/plotly.js/src/traces/waterfall/event_data.js\"),\n\n selectPoints: __webpack_require__(/*! ../bar/select */ \"./node_modules/plotly.js/src/traces/bar/select.js\"),\n\n moduleType: 'trace',\n name: 'waterfall',\n basePlotModule: __webpack_require__(/*! ../../plots/cartesian */ \"./node_modules/plotly.js/src/plots/cartesian/index.js\"),\n categories: ['bar-like', 'cartesian', 'svg', 'oriented', 'showLegend', 'zoomScale'],\n meta: {\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/waterfall/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/waterfall/layout_attributes.js":
-/*!**************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/waterfall/layout_attributes.js ***!
- \**************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nmodule.exports = {\n waterfallmode: {\n valType: 'enumerated',\n values: ['group', 'overlay'],\n dflt: 'group',\n \n editType: 'calc',\n \n },\n waterfallgap: {\n valType: 'number',\n min: 0,\n max: 1,\n \n editType: 'calc',\n \n },\n waterfallgroupgap: {\n valType: 'number',\n min: 0,\n max: 1,\n dflt: 0,\n \n editType: 'calc',\n \n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/waterfall/layout_attributes.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/waterfall/layout_defaults.js":
-/*!************************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/waterfall/layout_defaults.js ***!
- \************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar layoutAttributes = __webpack_require__(/*! ./layout_attributes */ \"./node_modules/plotly.js/src/traces/waterfall/layout_attributes.js\");\n\nmodule.exports = function(layoutIn, layoutOut, fullData) {\n var hasTraceType = false;\n\n function coerce(attr, dflt) {\n return Lib.coerce(layoutIn, layoutOut, layoutAttributes, attr, dflt);\n }\n\n for(var i = 0; i < fullData.length; i++) {\n var trace = fullData[i];\n\n if(trace.visible && trace.type === 'waterfall') {\n hasTraceType = true;\n break;\n }\n }\n\n if(hasTraceType) {\n coerce('waterfallmode');\n coerce('waterfallgap', 0.2);\n coerce('waterfallgroupgap');\n }\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/waterfall/layout_defaults.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/waterfall/plot.js":
-/*!*************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/waterfall/plot.js ***!
- \*************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\nvar Lib = __webpack_require__(/*! ../../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar barPlot = __webpack_require__(/*! ../bar/plot */ \"./node_modules/plotly.js/src/traces/bar/plot.js\");\nvar clearMinTextSize = __webpack_require__(/*! ../bar/uniform_text */ \"./node_modules/plotly.js/src/traces/bar/uniform_text.js\").clearMinTextSize;\n\nmodule.exports = function plot(gd, plotinfo, cdModule, traceLayer) {\n var fullLayout = gd._fullLayout;\n\n clearMinTextSize('waterfall', fullLayout);\n\n barPlot.plot(gd, plotinfo, cdModule, traceLayer, {\n mode: fullLayout.waterfallmode,\n norm: fullLayout.waterfallmode,\n gap: fullLayout.waterfallgap,\n groupgap: fullLayout.waterfallgroupgap\n });\n\n plotConnectors(gd, plotinfo, cdModule, traceLayer);\n};\n\nfunction plotConnectors(gd, plotinfo, cdModule, traceLayer) {\n var xa = plotinfo.xaxis;\n var ya = plotinfo.yaxis;\n\n Lib.makeTraceGroups(traceLayer, cdModule, 'trace bars').each(function(cd) {\n var plotGroup = d3.select(this);\n var trace = cd[0].trace;\n\n var group = Lib.ensureSingle(plotGroup, 'g', 'lines');\n\n if(!trace.connector || !trace.connector.visible) {\n group.remove();\n return;\n }\n\n var isHorizontal = (trace.orientation === 'h');\n var mode = trace.connector.mode;\n\n var connectors = group.selectAll('g.line').data(Lib.identity);\n\n connectors.enter().append('g')\n .classed('line', true);\n\n connectors.exit().remove();\n\n var len = connectors.size();\n\n connectors.each(function(di, i) {\n // don't draw lines between nulls\n if(i !== len - 1 && !di.cNext) return;\n\n var xy = getXY(di, xa, ya, isHorizontal);\n var x = xy[0];\n var y = xy[1];\n\n var shape = '';\n\n if(mode === 'spanning') {\n if(!di.isSum && i > 0) {\n if(isHorizontal) {\n shape += 'M' + x[0] + ',' + y[1] + 'V' + y[0];\n } else {\n shape += 'M' + x[1] + ',' + y[0] + 'H' + x[0];\n }\n }\n }\n\n if(mode !== 'between') {\n if(di.isSum || i < len - 1) {\n if(isHorizontal) {\n shape += 'M' + x[1] + ',' + y[0] + 'V' + y[1];\n } else {\n shape += 'M' + x[0] + ',' + y[1] + 'H' + x[1];\n }\n }\n }\n\n if(x[2] !== undefined && y[2] !== undefined) {\n if(isHorizontal) {\n shape += 'M' + x[1] + ',' + y[1] + 'V' + y[2];\n } else {\n shape += 'M' + x[1] + ',' + y[1] + 'H' + x[2];\n }\n }\n\n if(shape === '') shape = 'M0,0Z';\n\n Lib.ensureSingle(d3.select(this), 'path')\n .attr('d', shape)\n .call(Drawing.setClipUrl, plotinfo.layerClipId, gd);\n });\n });\n}\n\nfunction getXY(di, xa, ya, isHorizontal) {\n var s = [];\n var p = [];\n\n var sAxis = isHorizontal ? xa : ya;\n var pAxis = isHorizontal ? ya : xa;\n\n s[0] = sAxis.c2p(di.s0, true);\n p[0] = pAxis.c2p(di.p0, true);\n\n s[1] = sAxis.c2p(di.s1, true);\n p[1] = pAxis.c2p(di.p1, true);\n\n s[2] = sAxis.c2p(di.nextS0, true);\n p[2] = pAxis.c2p(di.nextP0, true);\n\n return isHorizontal ? [s, p] : [p, s];\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/waterfall/plot.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/traces/waterfall/style.js":
-/*!**************************************************************!*\
- !*** ./node_modules/plotly.js/src/traces/waterfall/style.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar d3 = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n\nvar Drawing = __webpack_require__(/*! ../../components/drawing */ \"./node_modules/plotly.js/src/components/drawing/index.js\");\nvar Color = __webpack_require__(/*! ../../components/color */ \"./node_modules/plotly.js/src/components/color/index.js\");\nvar DESELECTDIM = __webpack_require__(/*! ../../constants/interactions */ \"./node_modules/plotly.js/src/constants/interactions.js\").DESELECTDIM;\nvar barStyle = __webpack_require__(/*! ../bar/style */ \"./node_modules/plotly.js/src/traces/bar/style.js\");\nvar resizeText = __webpack_require__(/*! ../bar/uniform_text */ \"./node_modules/plotly.js/src/traces/bar/uniform_text.js\").resizeText;\nvar styleTextPoints = barStyle.styleTextPoints;\n\nfunction style(gd, cd, sel) {\n var s = sel ? sel : d3.select(gd).selectAll('g.waterfalllayer').selectAll('g.trace');\n resizeText(gd, s, 'waterfall');\n\n s.style('opacity', function(d) { return d[0].trace.opacity; });\n\n s.each(function(d) {\n var gTrace = d3.select(this);\n var trace = d[0].trace;\n\n gTrace.selectAll('.point > path').each(function(di) {\n if(!di.isBlank) {\n var cont = trace[di.dir].marker;\n\n d3.select(this)\n .call(Color.fill, cont.color)\n .call(Color.stroke, cont.line.color)\n .call(Drawing.dashLine, cont.line.dash, cont.line.width)\n .style('opacity', trace.selectedpoints && !di.selected ? DESELECTDIM : 1);\n }\n });\n\n styleTextPoints(gTrace, trace, gd);\n\n gTrace.selectAll('.lines').each(function() {\n var cont = trace.connector.line;\n\n Drawing.lineGroupStyle(\n d3.select(this).selectAll('path'),\n cont.width,\n cont.color,\n cont.dash\n );\n });\n });\n}\n\nmodule.exports = {\n style: style\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/traces/waterfall/style.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/transforms/aggregate.js":
-/*!************************************************************!*\
- !*** ./node_modules/plotly.js/src/transforms/aggregate.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Axes = __webpack_require__(/*! ../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar Lib = __webpack_require__(/*! ../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar PlotSchema = __webpack_require__(/*! ../plot_api/plot_schema */ \"./node_modules/plotly.js/src/plot_api/plot_schema.js\");\nvar pointsAccessorFunction = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/transforms/helpers.js\").pointsAccessorFunction;\nvar BADNUM = __webpack_require__(/*! ../constants/numerical */ \"./node_modules/plotly.js/src/constants/numerical.js\").BADNUM;\n\nexports.moduleType = 'transform';\n\nexports.name = 'aggregate';\n\nvar attrs = exports.attributes = {\n enabled: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'calc',\n \n },\n groups: {\n // TODO: groupby should support string or array grouping this way too\n // currently groupby only allows a grouping array\n valType: 'string',\n strict: true,\n noBlank: true,\n arrayOk: true,\n dflt: 'x',\n \n editType: 'calc',\n \n },\n aggregations: {\n _isLinkedToArray: 'aggregation',\n target: {\n valType: 'string',\n \n editType: 'calc',\n \n },\n func: {\n valType: 'enumerated',\n values: ['count', 'sum', 'avg', 'median', 'mode', 'rms', 'stddev', 'min', 'max', 'first', 'last', 'change', 'range'],\n dflt: 'first',\n \n editType: 'calc',\n \n },\n funcmode: {\n valType: 'enumerated',\n values: ['sample', 'population'],\n dflt: 'sample',\n \n editType: 'calc',\n \n },\n enabled: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'calc',\n \n },\n editType: 'calc'\n },\n editType: 'calc'\n};\n\nvar aggAttrs = attrs.aggregations;\n\n/**\n * Supply transform attributes defaults\n *\n * @param {object} transformIn\n * object linked to trace.transforms[i] with 'func' set to exports.name\n * @param {object} traceOut\n * the _fullData trace this transform applies to\n * @param {object} layout\n * the plot's (not-so-full) layout\n * @param {object} traceIn\n * the input data trace this transform applies to\n *\n * @return {object} transformOut\n * copy of transformIn that contains attribute defaults\n */\nexports.supplyDefaults = function(transformIn, traceOut) {\n var transformOut = {};\n var i;\n\n function coerce(attr, dflt) {\n return Lib.coerce(transformIn, transformOut, attrs, attr, dflt);\n }\n\n var enabled = coerce('enabled');\n\n if(!enabled) return transformOut;\n\n /*\n * Normally _arrayAttrs is calculated during doCalc, but that comes later.\n * Anyway this can change due to *count* aggregations (see below) so it's not\n * necessarily the same set.\n *\n * For performance we turn it into an object of truthy values\n * we'll use 1 for arrays we haven't aggregated yet, 0 for finished arrays,\n * as distinct from undefined which means this array isn't present in the input\n * missing arrays can still be aggregate outputs for *count* aggregations.\n */\n var arrayAttrArray = PlotSchema.findArrayAttributes(traceOut);\n var arrayAttrs = {};\n for(i = 0; i < arrayAttrArray.length; i++) arrayAttrs[arrayAttrArray[i]] = 1;\n\n var groups = coerce('groups');\n\n if(!Array.isArray(groups)) {\n if(!arrayAttrs[groups]) {\n transformOut.enabled = false;\n return transformOut;\n }\n arrayAttrs[groups] = 0;\n }\n\n var aggregationsIn = transformIn.aggregations || [];\n var aggregationsOut = transformOut.aggregations = new Array(aggregationsIn.length);\n var aggregationOut;\n\n function coercei(attr, dflt) {\n return Lib.coerce(aggregationsIn[i], aggregationOut, aggAttrs, attr, dflt);\n }\n\n for(i = 0; i < aggregationsIn.length; i++) {\n aggregationOut = {_index: i};\n var target = coercei('target');\n var func = coercei('func');\n var enabledi = coercei('enabled');\n\n // add this aggregation to the output only if it's the first instance\n // of a valid target attribute - or an unused target attribute with \"count\"\n if(enabledi && target && (arrayAttrs[target] || (func === 'count' && arrayAttrs[target] === undefined))) {\n if(func === 'stddev') coercei('funcmode');\n\n arrayAttrs[target] = 0;\n aggregationsOut[i] = aggregationOut;\n } else aggregationsOut[i] = {enabled: false, _index: i};\n }\n\n // any array attributes we haven't yet covered, fill them with the default aggregation\n for(i = 0; i < arrayAttrArray.length; i++) {\n if(arrayAttrs[arrayAttrArray[i]]) {\n aggregationsOut.push({\n target: arrayAttrArray[i],\n func: aggAttrs.func.dflt,\n enabled: true,\n _index: -1\n });\n }\n }\n\n return transformOut;\n};\n\n\nexports.calcTransform = function(gd, trace, opts) {\n if(!opts.enabled) return;\n\n var groups = opts.groups;\n\n var groupArray = Lib.getTargetArray(trace, {target: groups});\n if(!groupArray) return;\n\n var i, vi, groupIndex, newGrouping;\n\n var groupIndices = {};\n var indexToPoints = {};\n var groupings = [];\n\n var originalPointsAccessor = pointsAccessorFunction(trace.transforms, opts);\n\n var len = groupArray.length;\n if(trace._length) len = Math.min(len, trace._length);\n\n for(i = 0; i < len; i++) {\n vi = groupArray[i];\n groupIndex = groupIndices[vi];\n if(groupIndex === undefined) {\n groupIndices[vi] = groupings.length;\n newGrouping = [i];\n groupings.push(newGrouping);\n indexToPoints[groupIndices[vi]] = originalPointsAccessor(i);\n } else {\n groupings[groupIndex].push(i);\n indexToPoints[groupIndices[vi]] = (indexToPoints[groupIndices[vi]] || []).concat(originalPointsAccessor(i));\n }\n }\n\n opts._indexToPoints = indexToPoints;\n\n var aggregations = opts.aggregations;\n\n for(i = 0; i < aggregations.length; i++) {\n aggregateOneArray(gd, trace, groupings, aggregations[i]);\n }\n\n if(typeof groups === 'string') {\n aggregateOneArray(gd, trace, groupings, {\n target: groups,\n func: 'first',\n enabled: true\n });\n }\n\n trace._length = groupings.length;\n};\n\nfunction aggregateOneArray(gd, trace, groupings, aggregation) {\n if(!aggregation.enabled) return;\n\n var attr = aggregation.target;\n var targetNP = Lib.nestedProperty(trace, attr);\n var arrayIn = targetNP.get();\n var conversions = Axes.getDataConversions(gd, trace, attr, arrayIn);\n var func = getAggregateFunction(aggregation, conversions);\n\n var arrayOut = new Array(groupings.length);\n for(var i = 0; i < groupings.length; i++) {\n arrayOut[i] = func(arrayIn, groupings[i]);\n }\n targetNP.set(arrayOut);\n\n if(aggregation.func === 'count') {\n // count does not depend on an input array, so it's likely not part of _arrayAttrs yet\n // but after this transform it most definitely *is* an array attribute.\n Lib.pushUnique(trace._arrayAttrs, attr);\n }\n}\n\nfunction getAggregateFunction(opts, conversions) {\n var func = opts.func;\n var d2c = conversions.d2c;\n var c2d = conversions.c2d;\n\n switch(func) {\n // count, first, and last don't depend on anything about the data\n // point back to pure functions for performance\n case 'count':\n return count;\n case 'first':\n return first;\n case 'last':\n return last;\n\n case 'sum':\n // This will produce output in all cases even though it's nonsensical\n // for date or category data.\n return function(array, indices) {\n var total = 0;\n for(var i = 0; i < indices.length; i++) {\n var vi = d2c(array[indices[i]]);\n if(vi !== BADNUM) total += vi;\n }\n return c2d(total);\n };\n\n case 'avg':\n // Generally meaningless for category data but it still does something.\n return function(array, indices) {\n var total = 0;\n var cnt = 0;\n for(var i = 0; i < indices.length; i++) {\n var vi = d2c(array[indices[i]]);\n if(vi !== BADNUM) {\n total += vi;\n cnt++;\n }\n }\n return cnt ? c2d(total / cnt) : BADNUM;\n };\n\n case 'min':\n return function(array, indices) {\n var out = Infinity;\n for(var i = 0; i < indices.length; i++) {\n var vi = d2c(array[indices[i]]);\n if(vi !== BADNUM) out = Math.min(out, vi);\n }\n return (out === Infinity) ? BADNUM : c2d(out);\n };\n\n case 'max':\n return function(array, indices) {\n var out = -Infinity;\n for(var i = 0; i < indices.length; i++) {\n var vi = d2c(array[indices[i]]);\n if(vi !== BADNUM) out = Math.max(out, vi);\n }\n return (out === -Infinity) ? BADNUM : c2d(out);\n };\n\n case 'range':\n return function(array, indices) {\n var min = Infinity;\n var max = -Infinity;\n for(var i = 0; i < indices.length; i++) {\n var vi = d2c(array[indices[i]]);\n if(vi !== BADNUM) {\n min = Math.min(min, vi);\n max = Math.max(max, vi);\n }\n }\n return (max === -Infinity || min === Infinity) ? BADNUM : c2d(max - min);\n };\n\n case 'change':\n return function(array, indices) {\n var first = d2c(array[indices[0]]);\n var last = d2c(array[indices[indices.length - 1]]);\n return (first === BADNUM || last === BADNUM) ? BADNUM : c2d(last - first);\n };\n\n case 'median':\n return function(array, indices) {\n var sortCalc = [];\n for(var i = 0; i < indices.length; i++) {\n var vi = d2c(array[indices[i]]);\n if(vi !== BADNUM) sortCalc.push(vi);\n }\n if(!sortCalc.length) return BADNUM;\n sortCalc.sort();\n var mid = (sortCalc.length - 1) / 2;\n return c2d((sortCalc[Math.floor(mid)] + sortCalc[Math.ceil(mid)]) / 2);\n };\n\n case 'mode':\n return function(array, indices) {\n var counts = {};\n var maxCnt = 0;\n var out = BADNUM;\n for(var i = 0; i < indices.length; i++) {\n var vi = d2c(array[indices[i]]);\n if(vi !== BADNUM) {\n var counti = counts[vi] = (counts[vi] || 0) + 1;\n if(counti > maxCnt) {\n maxCnt = counti;\n out = vi;\n }\n }\n }\n return maxCnt ? c2d(out) : BADNUM;\n };\n\n case 'rms':\n return function(array, indices) {\n var total = 0;\n var cnt = 0;\n for(var i = 0; i < indices.length; i++) {\n var vi = d2c(array[indices[i]]);\n if(vi !== BADNUM) {\n total += vi * vi;\n cnt++;\n }\n }\n return cnt ? c2d(Math.sqrt(total / cnt)) : BADNUM;\n };\n\n case 'stddev':\n return function(array, indices) {\n // balance numerical stability with performance:\n // so that we call d2c once per element but don't need to\n // store them, reference all to the first element\n var total = 0;\n var total2 = 0;\n var cnt = 1;\n var v0 = BADNUM;\n var i;\n for(i = 0; i < indices.length && v0 === BADNUM; i++) {\n v0 = d2c(array[indices[i]]);\n }\n if(v0 === BADNUM) return BADNUM;\n\n for(; i < indices.length; i++) {\n var vi = d2c(array[indices[i]]);\n if(vi !== BADNUM) {\n var dv = vi - v0;\n total += dv;\n total2 += dv * dv;\n cnt++;\n }\n }\n\n // This is population std dev, if we want sample std dev\n // we would need (...) / (cnt - 1)\n // Also note there's no c2d here - that means for dates the result\n // is a number of milliseconds, and for categories it's a number\n // of category differences, which is not generically meaningful but\n // as in other cases we don't forbid it.\n var norm = (opts.funcmode === 'sample') ? (cnt - 1) : cnt;\n // this is debatable: should a count of 1 return sample stddev of\n // 0 or undefined?\n if(!norm) return 0;\n return Math.sqrt((total2 - (total * total / cnt)) / norm);\n };\n }\n}\n\nfunction count(array, indices) {\n return indices.length;\n}\n\nfunction first(array, indices) {\n return array[indices[0]];\n}\n\nfunction last(array, indices) {\n return array[indices[indices.length - 1]];\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/transforms/aggregate.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/transforms/filter.js":
-/*!*********************************************************!*\
- !*** ./node_modules/plotly.js/src/transforms/filter.js ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Registry = __webpack_require__(/*! ../registry */ \"./node_modules/plotly.js/src/registry.js\");\nvar Axes = __webpack_require__(/*! ../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar pointsAccessorFunction = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/transforms/helpers.js\").pointsAccessorFunction;\n\nvar filterOps = __webpack_require__(/*! ../constants/filter_ops */ \"./node_modules/plotly.js/src/constants/filter_ops.js\");\nvar COMPARISON_OPS = filterOps.COMPARISON_OPS;\nvar INTERVAL_OPS = filterOps.INTERVAL_OPS;\nvar SET_OPS = filterOps.SET_OPS;\n\nexports.moduleType = 'transform';\n\nexports.name = 'filter';\n\nexports.attributes = {\n enabled: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'calc',\n \n },\n target: {\n valType: 'string',\n strict: true,\n noBlank: true,\n arrayOk: true,\n dflt: 'x',\n \n editType: 'calc',\n \n },\n operation: {\n valType: 'enumerated',\n values: []\n .concat(COMPARISON_OPS)\n .concat(INTERVAL_OPS)\n .concat(SET_OPS),\n dflt: '=',\n \n editType: 'calc',\n \n },\n value: {\n valType: 'any',\n dflt: 0,\n \n editType: 'calc',\n \n },\n preservegaps: {\n valType: 'boolean',\n dflt: false,\n \n editType: 'calc',\n \n },\n editType: 'calc'\n};\n\nexports.supplyDefaults = function(transformIn) {\n var transformOut = {};\n\n function coerce(attr, dflt) {\n return Lib.coerce(transformIn, transformOut, exports.attributes, attr, dflt);\n }\n\n var enabled = coerce('enabled');\n\n if(enabled) {\n var target = coerce('target');\n\n if(Lib.isArrayOrTypedArray(target) && target.length === 0) {\n transformOut.enabled = false;\n return transformOut;\n }\n\n coerce('preservegaps');\n coerce('operation');\n coerce('value');\n\n var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleDefaults');\n handleCalendarDefaults(transformIn, transformOut, 'valuecalendar', null);\n handleCalendarDefaults(transformIn, transformOut, 'targetcalendar', null);\n }\n\n return transformOut;\n};\n\nexports.calcTransform = function(gd, trace, opts) {\n if(!opts.enabled) return;\n\n var targetArray = Lib.getTargetArray(trace, opts);\n if(!targetArray) return;\n\n var target = opts.target;\n\n var len = targetArray.length;\n if(trace._length) len = Math.min(len, trace._length);\n\n var targetCalendar = opts.targetcalendar;\n var arrayAttrs = trace._arrayAttrs;\n var preservegaps = opts.preservegaps;\n\n // even if you provide targetcalendar, if target is a string and there\n // is a calendar attribute matching target it will get used instead.\n if(typeof target === 'string') {\n var attrTargetCalendar = Lib.nestedProperty(trace, target + 'calendar').get();\n if(attrTargetCalendar) targetCalendar = attrTargetCalendar;\n }\n\n var d2c = Axes.getDataToCoordFunc(gd, trace, target, targetArray);\n var filterFunc = getFilterFunc(opts, d2c, targetCalendar);\n var originalArrays = {};\n var indexToPoints = {};\n var index = 0;\n\n function forAllAttrs(fn, index) {\n for(var j = 0; j < arrayAttrs.length; j++) {\n var np = Lib.nestedProperty(trace, arrayAttrs[j]);\n fn(np, index);\n }\n }\n\n var initFn;\n var fillFn;\n if(preservegaps) {\n initFn = function(np) {\n originalArrays[np.astr] = Lib.extendDeep([], np.get());\n np.set(new Array(len));\n };\n fillFn = function(np, index) {\n var val = originalArrays[np.astr][index];\n np.get()[index] = val;\n };\n } else {\n initFn = function(np) {\n originalArrays[np.astr] = Lib.extendDeep([], np.get());\n np.set([]);\n };\n fillFn = function(np, index) {\n var val = originalArrays[np.astr][index];\n np.get().push(val);\n };\n }\n\n // copy all original array attribute values, and clear arrays in trace\n forAllAttrs(initFn);\n\n var originalPointsAccessor = pointsAccessorFunction(trace.transforms, opts);\n\n // loop through filter array, fill trace arrays if passed\n for(var i = 0; i < len; i++) {\n var passed = filterFunc(targetArray[i]);\n if(passed) {\n forAllAttrs(fillFn, i);\n indexToPoints[index++] = originalPointsAccessor(i);\n } else if(preservegaps) index++;\n }\n\n opts._indexToPoints = indexToPoints;\n trace._length = index;\n};\n\nfunction getFilterFunc(opts, d2c, targetCalendar) {\n var operation = opts.operation;\n var value = opts.value;\n var hasArrayValue = Array.isArray(value);\n\n function isOperationIn(array) {\n return array.indexOf(operation) !== -1;\n }\n\n var d2cValue = function(v) { return d2c(v, 0, opts.valuecalendar); };\n var d2cTarget = function(v) { return d2c(v, 0, targetCalendar); };\n\n var coercedValue;\n\n if(isOperationIn(COMPARISON_OPS)) {\n coercedValue = hasArrayValue ? d2cValue(value[0]) : d2cValue(value);\n } else if(isOperationIn(INTERVAL_OPS)) {\n coercedValue = hasArrayValue ?\n [d2cValue(value[0]), d2cValue(value[1])] :\n [d2cValue(value), d2cValue(value)];\n } else if(isOperationIn(SET_OPS)) {\n coercedValue = hasArrayValue ? value.map(d2cValue) : [d2cValue(value)];\n }\n\n switch(operation) {\n case '=':\n return function(v) { return d2cTarget(v) === coercedValue; };\n\n case '!=':\n return function(v) { return d2cTarget(v) !== coercedValue; };\n\n case '<':\n return function(v) { return d2cTarget(v) < coercedValue; };\n\n case '<=':\n return function(v) { return d2cTarget(v) <= coercedValue; };\n\n case '>':\n return function(v) { return d2cTarget(v) > coercedValue; };\n\n case '>=':\n return function(v) { return d2cTarget(v) >= coercedValue; };\n\n case '[]':\n return function(v) {\n var cv = d2cTarget(v);\n return cv >= coercedValue[0] && cv <= coercedValue[1];\n };\n\n case '()':\n return function(v) {\n var cv = d2cTarget(v);\n return cv > coercedValue[0] && cv < coercedValue[1];\n };\n\n case '[)':\n return function(v) {\n var cv = d2cTarget(v);\n return cv >= coercedValue[0] && cv < coercedValue[1];\n };\n\n case '(]':\n return function(v) {\n var cv = d2cTarget(v);\n return cv > coercedValue[0] && cv <= coercedValue[1];\n };\n\n case '][':\n return function(v) {\n var cv = d2cTarget(v);\n return cv <= coercedValue[0] || cv >= coercedValue[1];\n };\n\n case ')(':\n return function(v) {\n var cv = d2cTarget(v);\n return cv < coercedValue[0] || cv > coercedValue[1];\n };\n\n case '](':\n return function(v) {\n var cv = d2cTarget(v);\n return cv <= coercedValue[0] || cv > coercedValue[1];\n };\n\n case ')[':\n return function(v) {\n var cv = d2cTarget(v);\n return cv < coercedValue[0] || cv >= coercedValue[1];\n };\n\n case '{}':\n return function(v) {\n return coercedValue.indexOf(d2cTarget(v)) !== -1;\n };\n\n case '}{':\n return function(v) {\n return coercedValue.indexOf(d2cTarget(v)) === -1;\n };\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/transforms/filter.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/transforms/groupby.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/transforms/groupby.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar PlotSchema = __webpack_require__(/*! ../plot_api/plot_schema */ \"./node_modules/plotly.js/src/plot_api/plot_schema.js\");\nvar Plots = __webpack_require__(/*! ../plots/plots */ \"./node_modules/plotly.js/src/plots/plots.js\");\nvar pointsAccessorFunction = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/transforms/helpers.js\").pointsAccessorFunction;\n\nexports.moduleType = 'transform';\n\nexports.name = 'groupby';\n\nexports.attributes = {\n enabled: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'calc',\n \n },\n groups: {\n valType: 'data_array',\n dflt: [],\n \n editType: 'calc',\n \n },\n nameformat: {\n valType: 'string',\n \n editType: 'calc',\n \n },\n styles: {\n _isLinkedToArray: 'style',\n target: {\n valType: 'string',\n \n editType: 'calc',\n \n },\n value: {\n valType: 'any',\n \n dflt: {},\n editType: 'calc',\n \n _compareAsJSON: true\n },\n editType: 'calc'\n },\n editType: 'calc'\n};\n\n/**\n * Supply transform attributes defaults\n *\n * @param {object} transformIn\n * object linked to trace.transforms[i] with 'type' set to exports.name\n * @param {object} traceOut\n * the _fullData trace this transform applies to\n * @param {object} layout\n * the plot's (not-so-full) layout\n * @param {object} traceIn\n * the input data trace this transform applies to\n *\n * @return {object} transformOut\n * copy of transformIn that contains attribute defaults\n */\nexports.supplyDefaults = function(transformIn, traceOut, layout) {\n var i;\n var transformOut = {};\n\n function coerce(attr, dflt) {\n return Lib.coerce(transformIn, transformOut, exports.attributes, attr, dflt);\n }\n\n var enabled = coerce('enabled');\n\n if(!enabled) return transformOut;\n\n coerce('groups');\n coerce('nameformat', layout._dataLength > 1 ? '%{group} (%{trace})' : '%{group}');\n\n var styleIn = transformIn.styles;\n var styleOut = transformOut.styles = [];\n\n if(styleIn) {\n for(i = 0; i < styleIn.length; i++) {\n var thisStyle = styleOut[i] = {};\n Lib.coerce(styleIn[i], styleOut[i], exports.attributes.styles, 'target');\n var value = Lib.coerce(styleIn[i], styleOut[i], exports.attributes.styles, 'value');\n\n // so that you can edit value in place and have Plotly.react notice it, or\n // rebuild it every time and have Plotly.react NOT think it changed:\n // use _compareAsJSON to say we should diff the _JSON_value\n if(Lib.isPlainObject(value)) thisStyle.value = Lib.extendDeep({}, value);\n else if(value) delete thisStyle.value;\n }\n }\n\n return transformOut;\n};\n\n\n/**\n * Apply transform !!!\n *\n * @param {array} data\n * array of transformed traces (is [fullTrace] upon first transform)\n *\n * @param {object} state\n * state object which includes:\n * - transform {object} full transform attributes\n * - fullTrace {object} full trace object which is being transformed\n * - fullData {array} full pre-transform(s) data array\n * - layout {object} the plot's (not-so-full) layout\n *\n * @return {object} newData\n * array of transformed traces\n */\nexports.transform = function(data, state) {\n var newTraces, i, j;\n var newData = [];\n\n for(i = 0; i < data.length; i++) {\n newTraces = transformOne(data[i], state);\n\n for(j = 0; j < newTraces.length; j++) {\n newData.push(newTraces[j]);\n }\n }\n\n return newData;\n};\n\nfunction transformOne(trace, state) {\n var i, j, k, attr, srcArray, groupName, newTrace, transforms, arrayLookup;\n var groupNameObj;\n\n var opts = state.transform;\n var transformIndex = state.transformIndex;\n var groups = trace.transforms[transformIndex].groups;\n var originalPointsAccessor = pointsAccessorFunction(trace.transforms, opts);\n\n if(!(Lib.isArrayOrTypedArray(groups)) || groups.length === 0) {\n return [trace];\n }\n\n var groupNames = Lib.filterUnique(groups);\n var newData = new Array(groupNames.length);\n var len = groups.length;\n\n var arrayAttrs = PlotSchema.findArrayAttributes(trace);\n\n var styles = opts.styles || [];\n var styleLookup = {};\n for(i = 0; i < styles.length; i++) {\n styleLookup[styles[i].target] = styles[i].value;\n }\n\n if(opts.styles) {\n groupNameObj = Lib.keyedContainer(opts, 'styles', 'target', 'value.name');\n }\n\n // An index to map group name --> expanded trace index\n var indexLookup = {};\n var indexCnts = {};\n\n for(i = 0; i < groupNames.length; i++) {\n groupName = groupNames[i];\n indexLookup[groupName] = i;\n indexCnts[groupName] = 0;\n\n // Start with a deep extend that just copies array references.\n newTrace = newData[i] = Lib.extendDeepNoArrays({}, trace);\n newTrace._group = groupName;\n newTrace.transforms[transformIndex]._indexToPoints = {};\n\n var suppliedName = null;\n if(groupNameObj) {\n suppliedName = groupNameObj.get(groupName);\n }\n\n if(suppliedName || suppliedName === '') {\n newTrace.name = suppliedName;\n } else {\n newTrace.name = Lib.templateString(opts.nameformat, {\n trace: trace.name,\n group: groupName\n });\n }\n\n // In order for groups to apply correctly to other transform data (e.g.\n // a filter transform), we have to break the connection and clone the\n // transforms so that each group writes grouped values into a different\n // destination. This function does not break the array reference\n // connection between the split transforms it creates. That's handled in\n // initialize, which creates a new empty array for each arrayAttr.\n transforms = newTrace.transforms;\n newTrace.transforms = [];\n for(j = 0; j < transforms.length; j++) {\n newTrace.transforms[j] = Lib.extendDeepNoArrays({}, transforms[j]);\n }\n\n // Initialize empty arrays for the arrayAttrs, to be split in the next step\n for(j = 0; j < arrayAttrs.length; j++) {\n Lib.nestedProperty(newTrace, arrayAttrs[j]).set([]);\n }\n }\n\n // For each array attribute including those nested inside this and other\n // transforms (small note that we technically only need to do this for\n // transforms that have not yet been applied):\n for(k = 0; k < arrayAttrs.length; k++) {\n attr = arrayAttrs[k];\n\n // Cache all the arrays to which we'll push:\n for(j = 0, arrayLookup = []; j < groupNames.length; j++) {\n arrayLookup[j] = Lib.nestedProperty(newData[j], attr).get();\n }\n\n // Get the input data:\n srcArray = Lib.nestedProperty(trace, attr).get();\n\n // Send each data point to the appropriate expanded trace:\n for(j = 0; j < len; j++) {\n // Map group data --> trace index --> array and push data onto it\n arrayLookup[indexLookup[groups[j]]].push(srcArray[j]);\n }\n }\n\n for(j = 0; j < len; j++) {\n newTrace = newData[indexLookup[groups[j]]];\n\n var indexToPoints = newTrace.transforms[transformIndex]._indexToPoints;\n indexToPoints[indexCnts[groups[j]]] = originalPointsAccessor(j);\n indexCnts[groups[j]]++;\n }\n\n for(i = 0; i < groupNames.length; i++) {\n groupName = groupNames[i];\n newTrace = newData[i];\n\n Plots.clearExpandedTraceDefaultColors(newTrace);\n\n // there's no need to coerce styleLookup[groupName] here\n // as another round of supplyDefaults is done on the transformed traces\n newTrace = Lib.extendDeepNoArrays(newTrace, styleLookup[groupName] || {});\n }\n\n return newData;\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/transforms/groupby.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/transforms/helpers.js":
-/*!**********************************************************!*\
- !*** ./node_modules/plotly.js/src/transforms/helpers.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nexports.pointsAccessorFunction = function(transforms, opts) {\n var tr;\n var prevIndexToPoints;\n for(var i = 0; i < transforms.length; i++) {\n tr = transforms[i];\n if(tr === opts) break;\n if(!tr._indexToPoints || tr.enabled === false) continue;\n prevIndexToPoints = tr._indexToPoints;\n }\n var originalPointsAccessor = prevIndexToPoints ?\n function(i) {return prevIndexToPoints[i];} :\n function(i) {return [i];};\n return originalPointsAccessor;\n};\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/transforms/helpers.js?");
-
-/***/ }),
-
-/***/ "./node_modules/plotly.js/src/transforms/sort.js":
-/*!*******************************************************!*\
- !*** ./node_modules/plotly.js/src/transforms/sort.js ***!
- \*******************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n* Copyright 2012-2020, Plotly, Inc.\n* All rights reserved.\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\n\n\nvar Lib = __webpack_require__(/*! ../lib */ \"./node_modules/plotly.js/src/lib/index.js\");\nvar Axes = __webpack_require__(/*! ../plots/cartesian/axes */ \"./node_modules/plotly.js/src/plots/cartesian/axes.js\");\nvar pointsAccessorFunction = __webpack_require__(/*! ./helpers */ \"./node_modules/plotly.js/src/transforms/helpers.js\").pointsAccessorFunction;\n\nexports.moduleType = 'transform';\n\nexports.name = 'sort';\n\nexports.attributes = {\n enabled: {\n valType: 'boolean',\n dflt: true,\n \n editType: 'calc',\n \n },\n target: {\n valType: 'string',\n strict: true,\n noBlank: true,\n arrayOk: true,\n dflt: 'x',\n \n editType: 'calc',\n \n },\n order: {\n valType: 'enumerated',\n values: ['ascending', 'descending'],\n dflt: 'ascending',\n \n editType: 'calc',\n \n },\n editType: 'calc'\n};\n\nexports.supplyDefaults = function(transformIn) {\n var transformOut = {};\n\n function coerce(attr, dflt) {\n return Lib.coerce(transformIn, transformOut, exports.attributes, attr, dflt);\n }\n\n var enabled = coerce('enabled');\n\n if(enabled) {\n coerce('target');\n coerce('order');\n }\n\n return transformOut;\n};\n\nexports.calcTransform = function(gd, trace, opts) {\n if(!opts.enabled) return;\n\n var targetArray = Lib.getTargetArray(trace, opts);\n if(!targetArray) return;\n\n var target = opts.target;\n\n var len = targetArray.length;\n if(trace._length) len = Math.min(len, trace._length);\n\n var arrayAttrs = trace._arrayAttrs;\n var d2c = Axes.getDataToCoordFunc(gd, trace, target, targetArray);\n var indices = getIndices(opts, targetArray, d2c, len);\n var originalPointsAccessor = pointsAccessorFunction(trace.transforms, opts);\n var indexToPoints = {};\n var i, j;\n\n for(i = 0; i < arrayAttrs.length; i++) {\n var np = Lib.nestedProperty(trace, arrayAttrs[i]);\n var arrayOld = np.get();\n var arrayNew = new Array(len);\n\n for(j = 0; j < len; j++) {\n arrayNew[j] = arrayOld[indices[j]];\n }\n\n np.set(arrayNew);\n }\n\n for(j = 0; j < len; j++) {\n indexToPoints[j] = originalPointsAccessor(indices[j]);\n }\n\n opts._indexToPoints = indexToPoints;\n trace._length = len;\n};\n\nfunction getIndices(opts, targetArray, d2c, len) {\n var sortedArray = new Array(len);\n var indices = new Array(len);\n var i;\n\n for(i = 0; i < len; i++) {\n sortedArray[i] = {v: targetArray[i], i: i};\n }\n\n sortedArray.sort(getSortFunc(opts, d2c));\n\n for(i = 0; i < len; i++) {\n indices[i] = sortedArray[i].i;\n }\n\n return indices;\n}\n\nfunction getSortFunc(opts, d2c) {\n switch(opts.order) {\n case 'ascending':\n return function(a, b) { return d2c(a.v) - d2c(b.v); };\n case 'descending':\n return function(a, b) { return d2c(b.v) - d2c(a.v); };\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/plotly.js/src/transforms/sort.js?");
-
-/***/ }),
-
-/***/ "./node_modules/point-cluster/index.js":
-/*!*********************************************!*\
- !*** ./node_modules/point-cluster/index.js ***!
- \*********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nmodule.exports = __webpack_require__(/*! ./quad */ \"./node_modules/point-cluster/quad.js\")\n\r\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbIkY6L3NvdXJjZS92dWUtcGxvdGx5LmpzL25vZGVfbW9kdWxlcy9wb2ludC1jbHVzdGVyL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0J1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vcXVhZCcpXG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUNaO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDOyJ9\n\n//# sourceURL=webpack:///./node_modules/point-cluster/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/point-cluster/quad.js":
-/*!********************************************!*\
- !*** ./node_modules/point-cluster/quad.js ***!
- \********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/**\n * @module point-cluster/quad\n *\n * Bucket based quad tree clustering\n */\n\n\n\nvar search = __webpack_require__(/*! binary-search-bounds */ \"./node_modules/binary-search-bounds/search-bounds.js\")\nvar clamp = __webpack_require__(/*! clamp */ \"./node_modules/clamp/index.js\")\nvar rect = __webpack_require__(/*! parse-rect */ \"./node_modules/parse-rect/index.js\")\nvar getBounds = __webpack_require__(/*! array-bounds */ \"./node_modules/array-bounds/index.js\")\nvar pick = __webpack_require__(/*! pick-by-alias */ \"./node_modules/pick-by-alias/index.js\")\nvar defined = __webpack_require__(/*! defined */ \"./node_modules/defined/index.js\")\nvar flatten = __webpack_require__(/*! flatten-vertex-data */ \"./node_modules/flatten-vertex-data/index.js\")\nvar isObj = __webpack_require__(/*! is-obj */ \"./node_modules/is-obj/index.js\")\nvar dtype = __webpack_require__(/*! dtype */ \"./node_modules/dtype/index.js\")\nvar log2 = __webpack_require__(/*! math-log2 */ \"./node_modules/math-log2/index.js\")\n\nvar MAX_GROUP_ID = 1073741824\n\nmodule.exports = function cluster (srcPoints, options) {\n\tif (!options) { options = {} }\n\n\tsrcPoints = flatten(srcPoints, 'float64')\n\n\toptions = pick(options, {\n\t\tbounds: 'range bounds dataBox databox',\n\t\tmaxDepth: 'depth maxDepth maxdepth level maxLevel maxlevel levels',\n\t\tdtype: 'type dtype format out dst output destination'\n\t\t// sort: 'sortBy sortby sort',\n\t\t// pick: 'pick levelPoint',\n\t\t// nodeSize: 'node nodeSize minNodeSize minSize size'\n\t})\n\n\t// let nodeSize = defined(options.nodeSize, 1)\n\tvar maxDepth = defined(options.maxDepth, 255)\n\tvar bounds = defined(options.bounds, getBounds(srcPoints, 2))\n\tif (bounds[0] === bounds[2]) { bounds[2]++ }\n\tif (bounds[1] === bounds[3]) { bounds[3]++ }\n\n\tvar points = normalize(srcPoints, bounds)\n\n\t// init variables\n\tvar n = srcPoints.length >>> 1\n\tvar ids\n\tif (!options.dtype) { options.dtype = 'array' }\n\n\tif (typeof options.dtype === 'string') {\n\t\tids = new (dtype(options.dtype))(n)\n\t}\n\telse if (options.dtype) {\n\t\tids = options.dtype\n\t\tif (Array.isArray(ids)) { ids.length = n }\n\t}\n\tfor (var i = 0; i < n; ++i) {\n\t\tids[i] = i\n\t}\n\n\t// representative point indexes for levels\n\tvar levels = []\n\n\t// starting indexes of subranges in sub levels, levels.length * 4\n\tvar sublevels = []\n\n\t// unique group ids, sorted in z-curve fashion within levels by shifting bits\n\tvar groups = []\n\n\t// level offsets in `ids`\n\tvar offsets = []\n\n\n\t// sort points\n\tsort(0, 0, 1, ids, 0, 1)\n\n\n\t// return reordered ids with provided methods\n\t// save level offsets in output buffer\n\tvar offset = 0\n\tfor (var level = 0; level < levels.length; level++) {\n\t\tvar levelItems = levels[level]\n\t\tif (ids.set) { ids.set(levelItems, offset) }\n\t\telse {\n\t\t\tfor (var i$1 = 0, l = levelItems.length; i$1 < l; i$1++) {\n\t\t\t\tids[i$1 + offset] = levelItems[i$1]\n\t\t\t}\n\t\t}\n\t\tvar nextOffset = offset + levels[level].length\n\t\toffsets[level] = [offset, nextOffset]\n\t\toffset = nextOffset\n\t}\n\n\tids.range = range\n\n\treturn ids\n\n\n\n\t// FIXME: it is possible to create one typed array heap and reuse that to avoid memory blow\n\tfunction sort (x, y, diam, ids, level, group) {\n\t\tif (!ids.length) { return null }\n\n\t\t// save first point as level representative\n\t\tvar levelItems = levels[level] || (levels[level] = [])\n\t\tvar levelGroups = groups[level] || (groups[level] = [])\n\t\tvar sublevel = sublevels[level] || (sublevels[level] = [])\n\t\tvar offset = levelItems.length\n\n\t\tlevel++\n\n\t\t// max depth reached - put all items into a first group\n\t\t// alternatively - if group id overflow - avoid proceeding\n\t\tif (level > maxDepth || group > MAX_GROUP_ID) {\n\t\t\tfor (var i = 0; i < ids.length; i++) {\n\t\t\t\tlevelItems.push(ids[i])\n\t\t\t\tlevelGroups.push(group)\n\t\t\t\tsublevel.push(null, null, null, null)\n\t\t\t}\n\n\t\t\treturn offset\n\t\t}\n\n\t\tlevelItems.push(ids[0])\n\t\tlevelGroups.push(group)\n\n\t\tif (ids.length <= 1) {\n\t\t\tsublevel.push(null, null, null, null)\n\t\t\treturn offset\n\t\t}\n\n\n\t\tvar d2 = diam * .5\n\t\tvar cx = x + d2, cy = y + d2\n\n\t\t// distribute points by 4 buckets\n\t\tvar lolo = [], lohi = [], hilo = [], hihi = []\n\n\t\tfor (var i$1 = 1, l = ids.length; i$1 < l; i$1++) {\n\t\t\tvar idx = ids[i$1],\n\t\t\t\tx$1 = points[idx * 2],\n\t\t\t\ty$1 = points[idx * 2 + 1]\n\t\t\tx$1 < cx ? (y$1 < cy ? lolo.push(idx) : lohi.push(idx)) : (y$1 < cy ? hilo.push(idx) : hihi.push(idx))\n\t\t}\n\n\t\tgroup <<= 2\n\n\t\tsublevel.push(\n\t\t\tsort(x, y, d2, lolo, level, group),\n\t\t\tsort(x, cy, d2, lohi, level, group + 1),\n\t\t\tsort(cx, y, d2, hilo, level, group + 2),\n\t\t\tsort(cx, cy, d2, hihi, level, group + 3)\n\t\t)\n\n\t\treturn offset\n\t}\n\n\t// get all points within the passed range\n\tfunction range () {\n\t\tvar args = [], len = arguments.length;\n\t\twhile ( len-- ) args[ len ] = arguments[ len ];\n\n\t\tvar options\n\n\t\tif (isObj(args[args.length - 1])) {\n\t\t\tvar arg = args.pop()\n\n\t\t\t// detect if that was a rect object\n\t\t\tif (!args.length && (arg.x != null || arg.l != null || arg.left != null)) {\n\t\t\t\targs = [arg]\n\t\t\t\toptions = {}\n\t\t\t}\n\n\t\t\toptions = pick(arg, {\n\t\t\t\tlevel: 'level maxLevel',\n\t\t\t\td: 'd diam diameter r radius px pxSize pixel pixelSize maxD size minSize',\n\t\t\t\tlod: 'lod details ranges offsets'\n\t\t\t})\n\t\t}\n\t\telse {\n\t\t\toptions = {}\n\t\t}\n\n\t\tif (!args.length) { args = bounds }\n\n\t\tvar box = rect.apply( void 0, args )\n\n\t\tvar ref = [\n\t\t\tMath.min(box.x, box.x + box.width),\n\t\t\tMath.min(box.y, box.y + box.height),\n\t\t\tMath.max(box.x, box.x + box.width),\n\t\t\tMath.max(box.y, box.y + box.height)\n\t\t];\n\t\tvar minX = ref[0];\n\t\tvar minY = ref[1];\n\t\tvar maxX = ref[2];\n\t\tvar maxY = ref[3];\n\n\t\tvar ref$1 = normalize([minX, minY, maxX, maxY], bounds );\n\t\tvar nminX = ref$1[0];\n\t\tvar nminY = ref$1[1];\n\t\tvar nmaxX = ref$1[2];\n\t\tvar nmaxY = ref$1[3];\n\n\t\tvar maxLevel = defined(options.level, levels.length)\n\n\t\t// limit maxLevel by px size\n\t\tif (options.d != null) {\n\t\t\tvar d\n\t\t\tif (typeof options.d === 'number') { d = [options.d, options.d] }\n\t\t\telse if (options.d.length) { d = options.d }\n\n\t\t\tmaxLevel = Math.min(\n\t\t\t\tMath.max(\n\t\t\t\t\tMath.ceil(-log2(Math.abs(d[0]) / (bounds[2] - bounds[0]))),\n\t\t\t\t\tMath.ceil(-log2(Math.abs(d[1]) / (bounds[3] - bounds[1])))\n\t\t\t\t),\n\t\t\t\tmaxLevel\n\t\t\t)\n\t\t}\n\t\tmaxLevel = Math.min(maxLevel, levels.length)\n\n\t\t// return levels of details\n\t\tif (options.lod) {\n\t\t\treturn lod(nminX, nminY, nmaxX, nmaxY, maxLevel)\n\t\t}\n\n\n\n\t\t// do selection ids\n\t\tvar selection = []\n\n\t\t// FIXME: probably we can do LOD here beforehead\n\t\tselect( 0, 0, 1, 0, 0, 1)\n\n\t\tfunction select ( lox, loy, d, level, from, to ) {\n\t\t\tif (from === null || to === null) { return }\n\n\t\t\tvar hix = lox + d\n\t\t\tvar hiy = loy + d\n\n\t\t\t// if box does not intersect level - ignore\n\t\t\tif ( nminX > hix || nminY > hiy || nmaxX < lox || nmaxY < loy ) { return }\n\t\t\tif ( level >= maxLevel ) { return }\n\t\t\tif ( from === to ) { return }\n\n\t\t\t// if points fall into box range - take it\n\t\t\tvar levelItems = levels[level]\n\n\t\t\tif (to === undefined) { to = levelItems.length }\n\n\t\t\tfor (var i = from; i < to; i++) {\n\t\t\t\tvar id = levelItems[i]\n\n\t\t\t\tvar px = srcPoints[ id * 2 ]\n\t\t\t\tvar py = srcPoints[ id * 2 + 1 ]\n\n\t\t\t\tif ( px >= minX && px <= maxX && py >= minY && py <= maxY ) {selection.push(id)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// for every subsection do select\n\t\t\tvar offsets = sublevels[ level ]\n\t\t\tvar off0 = offsets[ from * 4 + 0 ]\n\t\t\tvar off1 = offsets[ from * 4 + 1 ]\n\t\t\tvar off2 = offsets[ from * 4 + 2 ]\n\t\t\tvar off3 = offsets[ from * 4 + 3 ]\n\t\t\tvar end = nextOffset(offsets, from + 1)\n\n\t\t\tvar d2 = d * .5\n\t\t\tvar nextLevel = level + 1\n\t\t\tselect( lox, loy, d2, nextLevel, off0, off1 || off2 || off3 || end)\n\t\t\tselect( lox, loy + d2, d2, nextLevel, off1, off2 || off3 || end)\n\t\t\tselect( lox + d2, loy, d2, nextLevel, off2, off3 || end)\n\t\t\tselect( lox + d2, loy + d2, d2, nextLevel, off3, end)\n\t\t}\n\n\t\tfunction nextOffset(offsets, from) {\n\t\t\tvar offset = null, i = 0\n\t\t\twhile(offset === null) {\n\t\t\t\toffset = offsets[ from * 4 + i ]\n\t\t\t\ti++\n\t\t\t\tif (i > offsets.length) { return null }\n\t\t\t}\n\t\t\treturn offset\n\t\t}\n\n\t\treturn selection\n\t}\n\n\t// get range offsets within levels to render lods appropriate for zoom level\n\t// TODO: it is possible to store minSize of a point to optimize neede level calc\n\tfunction lod (lox, loy, hix, hiy, maxLevel) {\n\t\tvar ranges = []\n\n\t\tfor (var level = 0; level < maxLevel; level++) {\n\t\t\tvar levelGroups = groups[level]\n\t\t\tvar from = offsets[level][0]\n\n\t\t\tvar levelGroupStart = group(lox, loy, level)\n\t\t\tvar levelGroupEnd = group(hix, hiy, level)\n\n\t\t\t// FIXME: utilize sublevels to speed up search range here\n\t\t\tvar startOffset = search.ge(levelGroups, levelGroupStart)\n\t\t\tvar endOffset = search.gt(levelGroups, levelGroupEnd, startOffset, levelGroups.length - 1)\n\n\t\t\tranges[level] = [startOffset + from, endOffset + from]\n\t\t}\n\n\t\treturn ranges\n\t}\n\n\t// get group id closest to the x,y coordinate, corresponding to a level\n\tfunction group (x, y, level) {\n\t\tvar group = 1\n\n\t\tvar cx = .5, cy = .5\n\t\tvar diam = .5\n\n\t\tfor (var i = 0; i < level; i++) {\n\t\t\tgroup <<= 2\n\n\t\t\tgroup += x < cx ? (y < cy ? 0 : 1) : (y < cy ? 2 : 3)\n\n\t\t\tdiam *= .5\n\n\t\t\tcx += x < cx ? -diam : diam\n\t\t\tcy += y < cy ? -diam : diam\n\t\t}\n\n\t\treturn group\n\t}\n}\n\n\n// normalize points by bounds\nfunction normalize (pts, bounds) {\n\tvar lox = bounds[0];\n\tvar loy = bounds[1];\n\tvar hix = bounds[2];\n\tvar hiy = bounds[3];\n\tvar scaleX = 1.0 / (hix - lox)\n\tvar scaleY = 1.0 / (hiy - loy)\n\tvar result = new Array(pts.length)\n\n\tfor (var i = 0, n = pts.length / 2; i < n; i++) {\n\t\tresult[2*i] = clamp((pts[2*i] - lox) * scaleX, 0, 1)\n\t\tresult[2*i+1] = clamp((pts[2*i+1] - loy) * scaleY, 0, 1)\n\t}\n\n\treturn result\n}\n\r\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbIkY6L3NvdXJjZS92dWUtcGxvdGx5LmpzL25vZGVfbW9kdWxlcy9wb2ludC1jbHVzdGVyL3F1YWQuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbW9kdWxlICBwb2ludC1jbHVzdGVyL3F1YWRcbiAqXG4gKiBCdWNrZXQgYmFzZWQgcXVhZCB0cmVlIGNsdXN0ZXJpbmdcbiAqL1xuXG4ndXNlIHN0cmljdCdcblxuY29uc3Qgc2VhcmNoID0gcmVxdWlyZSgnYmluYXJ5LXNlYXJjaC1ib3VuZHMnKVxuY29uc3QgY2xhbXAgPSByZXF1aXJlKCdjbGFtcCcpXG5jb25zdCByZWN0ID0gcmVxdWlyZSgncGFyc2UtcmVjdCcpXG5jb25zdCBnZXRCb3VuZHMgPSByZXF1aXJlKCdhcnJheS1ib3VuZHMnKVxuY29uc3QgcGljayA9IHJlcXVpcmUoJ3BpY2stYnktYWxpYXMnKVxuY29uc3QgZGVmaW5lZCA9IHJlcXVpcmUoJ2RlZmluZWQnKVxuY29uc3QgZmxhdHRlbiA9IHJlcXVpcmUoJ2ZsYXR0ZW4tdmVydGV4LWRhdGEnKVxuY29uc3QgaXNPYmogPSByZXF1aXJlKCdpcy1vYmonKVxuY29uc3QgZHR5cGUgPSByZXF1aXJlKCdkdHlwZScpXG5jb25zdCBsb2cyID0gcmVxdWlyZSgnbWF0aC1sb2cyJylcblxuY29uc3QgTUFYX0dST1VQX0lEID0gMTA3Mzc0MTgyNFxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNsdXN0ZXIgKHNyY1BvaW50cywgb3B0aW9ucykge1xuXHRpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fVxuXG5cdHNyY1BvaW50cyA9IGZsYXR0ZW4oc3JjUG9pbnRzLCAnZmxvYXQ2NCcpXG5cblx0b3B0aW9ucyA9IHBpY2sob3B0aW9ucywge1xuXHRcdGJvdW5kczogJ3JhbmdlIGJvdW5kcyBkYXRhQm94IGRhdGFib3gnLFxuXHRcdG1heERlcHRoOiAnZGVwdGggbWF4RGVwdGggbWF4ZGVwdGggbGV2ZWwgbWF4TGV2ZWwgbWF4bGV2ZWwgbGV2ZWxzJyxcblx0XHRkdHlwZTogJ3R5cGUgZHR5cGUgZm9ybWF0IG91dCBkc3Qgb3V0cHV0IGRlc3RpbmF0aW9uJ1xuXHRcdC8vIHNvcnQ6ICdzb3J0Qnkgc29ydGJ5IHNvcnQnLFxuXHRcdC8vIHBpY2s6ICdwaWNrIGxldmVsUG9pbnQnLFxuXHRcdC8vIG5vZGVTaXplOiAnbm9kZSBub2RlU2l6ZSBtaW5Ob2RlU2l6ZSBtaW5TaXplIHNpemUnXG5cdH0pXG5cblx0Ly8gbGV0IG5vZGVTaXplID0gZGVmaW5lZChvcHRpb25zLm5vZGVTaXplLCAxKVxuXHRsZXQgbWF4RGVwdGggPSBkZWZpbmVkKG9wdGlvbnMubWF4RGVwdGgsIDI1NSlcblx0bGV0IGJvdW5kcyA9IGRlZmluZWQob3B0aW9ucy5ib3VuZHMsIGdldEJvdW5kcyhzcmNQb2ludHMsIDIpKVxuXHRpZiAoYm91bmRzWzBdID09PSBib3VuZHNbMl0pIGJvdW5kc1syXSsrXG5cdGlmIChib3VuZHNbMV0gPT09IGJvdW5kc1szXSkgYm91bmRzWzNdKytcblxuXHRsZXQgcG9pbnRzID0gbm9ybWFsaXplKHNyY1BvaW50cywgYm91bmRzKVxuXG5cdC8vIGluaXQgdmFyaWFibGVzXG5cdGxldCBuID0gc3JjUG9pbnRzLmxlbmd0aCA+Pj4gMVxuXHRsZXQgaWRzXG5cdGlmICghb3B0aW9ucy5kdHlwZSkgb3B0aW9ucy5kdHlwZSA9ICdhcnJheSdcblxuXHRpZiAodHlwZW9mIG9wdGlvbnMuZHR5cGUgPT09ICdzdHJpbmcnKSB7XG5cdFx0aWRzID0gbmV3IChkdHlwZShvcHRpb25zLmR0eXBlKSkobilcblx0fVxuXHRlbHNlIGlmIChvcHRpb25zLmR0eXBlKSB7XG5cdFx0aWRzID0gb3B0aW9ucy5kdHlwZVxuXHRcdGlmIChBcnJheS5pc0FycmF5KGlkcykpIGlkcy5sZW5ndGggPSBuXG5cdH1cblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBuOyArK2kpIHtcblx0XHRpZHNbaV0gPSBpXG5cdH1cblxuXHQvLyByZXByZXNlbnRhdGl2ZSBwb2ludCBpbmRleGVzIGZvciBsZXZlbHNcblx0bGV0IGxldmVscyA9IFtdXG5cblx0Ly8gc3RhcnRpbmcgaW5kZXhlcyBvZiBzdWJyYW5nZXMgaW4gc3ViIGxldmVscywgbGV2ZWxzLmxlbmd0aCAqIDRcblx0bGV0IHN1YmxldmVscyA9IFtdXG5cblx0Ly8gdW5pcXVlIGdyb3VwIGlkcywgc29ydGVkIGluIHotY3VydmUgZmFzaGlvbiB3aXRoaW4gbGV2ZWxzIGJ5IHNoaWZ0aW5nIGJpdHNcblx0bGV0IGdyb3VwcyA9IFtdXG5cblx0Ly8gbGV2ZWwgb2Zmc2V0cyBpbiBgaWRzYFxuXHRsZXQgb2Zmc2V0cyA9IFtdXG5cblxuXHQvLyBzb3J0IHBvaW50c1xuXHRzb3J0KDAsIDAsIDEsIGlkcywgMCwgMSlcblxuXG5cdC8vIHJldHVybiByZW9yZGVyZWQgaWRzIHdpdGggcHJvdmlkZWQgbWV0aG9kc1xuXHQvLyBzYXZlIGxldmVsIG9mZnNldHMgaW4gb3V0cHV0IGJ1ZmZlclxuXHRsZXQgb2Zmc2V0ID0gMFxuXHRmb3IgKGxldCBsZXZlbCA9IDA7IGxldmVsIDwgbGV2ZWxzLmxlbmd0aDsgbGV2ZWwrKykge1xuXHRcdGxldCBsZXZlbEl0ZW1zID0gbGV2ZWxzW2xldmVsXVxuXHRcdGlmIChpZHMuc2V0KSBpZHMuc2V0KGxldmVsSXRlbXMsIG9mZnNldClcblx0XHRlbHNlIHtcblx0XHRcdGZvciAobGV0IGkgPSAwLCBsID0gbGV2ZWxJdGVtcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcblx0XHRcdFx0aWRzW2kgKyBvZmZzZXRdID0gbGV2ZWxJdGVtc1tpXVxuXHRcdFx0fVxuXHRcdH1cblx0XHRsZXQgbmV4dE9mZnNldCA9IG9mZnNldCArIGxldmVsc1tsZXZlbF0ubGVuZ3RoXG5cdFx0b2Zmc2V0c1tsZXZlbF0gPSBbb2Zmc2V0LCBuZXh0T2Zmc2V0XVxuXHRcdG9mZnNldCA9IG5leHRPZmZzZXRcblx0fVxuXG5cdGlkcy5yYW5nZSA9IHJhbmdlXG5cblx0cmV0dXJuIGlkc1xuXG5cblxuXHQvLyBGSVhNRTogaXQgaXMgcG9zc2libGUgdG8gY3JlYXRlIG9uZSB0eXBlZCBhcnJheSBoZWFwIGFuZCByZXVzZSB0aGF0IHRvIGF2b2lkIG1lbW9yeSBibG93XG5cdGZ1bmN0aW9uIHNvcnQgKHgsIHksIGRpYW0sIGlkcywgbGV2ZWwsIGdyb3VwKSB7XG5cdFx0aWYgKCFpZHMubGVuZ3RoKSByZXR1cm4gbnVsbFxuXG5cdFx0Ly8gc2F2ZSBmaXJzdCBwb2ludCBhcyBsZXZlbCByZXByZXNlbnRhdGl2ZVxuXHRcdGxldCBsZXZlbEl0ZW1zID0gbGV2ZWxzW2xldmVsXSB8fCAobGV2ZWxzW2xldmVsXSA9IFtdKVxuXHRcdGxldCBsZXZlbEdyb3VwcyA9IGdyb3Vwc1tsZXZlbF0gfHwgKGdyb3Vwc1tsZXZlbF0gPSBbXSlcblx0XHRsZXQgc3VibGV2ZWwgPSBzdWJsZXZlbHNbbGV2ZWxdIHx8IChzdWJsZXZlbHNbbGV2ZWxdID0gW10pXG5cdFx0bGV0IG9mZnNldCA9IGxldmVsSXRlbXMubGVuZ3RoXG5cblx0XHRsZXZlbCsrXG5cblx0XHQvLyBtYXggZGVwdGggcmVhY2hlZCAtIHB1dCBhbGwgaXRlbXMgaW50byBhIGZpcnN0IGdyb3VwXG5cdFx0Ly8gYWx0ZXJuYXRpdmVseSAtIGlmIGdyb3VwIGlkIG92ZXJmbG93IC0gYXZvaWQgcHJvY2VlZGluZ1xuXHRcdGlmIChsZXZlbCA+IG1heERlcHRoIHx8IGdyb3VwID4gTUFYX0dST1VQX0lEKSB7XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGlkcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRsZXZlbEl0ZW1zLnB1c2goaWRzW2ldKVxuXHRcdFx0XHRsZXZlbEdyb3Vwcy5wdXNoKGdyb3VwKVxuXHRcdFx0XHRzdWJsZXZlbC5wdXNoKG51bGwsIG51bGwsIG51bGwsIG51bGwpXG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBvZmZzZXRcblx0XHR9XG5cblx0XHRsZXZlbEl0ZW1zLnB1c2goaWRzWzBdKVxuXHRcdGxldmVsR3JvdXBzLnB1c2goZ3JvdXApXG5cblx0XHRpZiAoaWRzLmxlbmd0aCA8PSAxKSB7XG5cdFx0XHRzdWJsZXZlbC5wdXNoKG51bGwsIG51bGwsIG51bGwsIG51bGwpXG5cdFx0XHRyZXR1cm4gb2Zmc2V0XG5cdFx0fVxuXG5cblx0XHRsZXQgZDIgPSBkaWFtICogLjVcblx0XHRsZXQgY3ggPSB4ICsgZDIsIGN5ID0geSArIGQyXG5cblx0XHQvLyBkaXN0cmlidXRlIHBvaW50cyBieSA0IGJ1Y2tldHNcblx0XHRsZXQgbG9sbyA9IFtdLCBsb2hpID0gW10sIGhpbG8gPSBbXSwgaGloaSA9IFtdXG5cblx0XHRmb3IgKGxldCBpID0gMSwgbCA9IGlkcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcblx0XHRcdGxldCBpZHggPSBpZHNbaV0sXG5cdFx0XHRcdHggPSBwb2ludHNbaWR4ICogMl0sXG5cdFx0XHRcdHkgPSBwb2ludHNbaWR4ICogMiArIDFdXG5cdFx0XHR4IDwgY3ggPyAoeSA8IGN5ID8gbG9sby5wdXNoKGlkeCkgOiBsb2hpLnB1c2goaWR4KSkgOiAoeSA8IGN5ID8gaGlsby5wdXNoKGlkeCkgOiBoaWhpLnB1c2goaWR4KSlcblx0XHR9XG5cblx0XHRncm91cCA8PD0gMlxuXG5cdFx0c3VibGV2ZWwucHVzaChcblx0XHRcdHNvcnQoeCwgeSwgZDIsIGxvbG8sIGxldmVsLCBncm91cCksXG5cdFx0XHRzb3J0KHgsIGN5LCBkMiwgbG9oaSwgbGV2ZWwsIGdyb3VwICsgMSksXG5cdFx0XHRzb3J0KGN4LCB5LCBkMiwgaGlsbywgbGV2ZWwsIGdyb3VwICsgMiksXG5cdFx0XHRzb3J0KGN4LCBjeSwgZDIsIGhpaGksIGxldmVsLCBncm91cCArIDMpXG5cdFx0KVxuXG5cdFx0cmV0dXJuIG9mZnNldFxuXHR9XG5cblx0Ly8gZ2V0IGFsbCBwb2ludHMgd2l0aGluIHRoZSBwYXNzZWQgcmFuZ2Vcblx0ZnVuY3Rpb24gcmFuZ2UgKCAuLi5hcmdzICkge1xuXHRcdGxldCBvcHRpb25zXG5cblx0XHRpZiAoaXNPYmooYXJnc1thcmdzLmxlbmd0aCAtIDFdKSkge1xuXHRcdFx0bGV0IGFyZyA9IGFyZ3MucG9wKClcblxuXHRcdFx0Ly8gZGV0ZWN0IGlmIHRoYXQgd2FzIGEgcmVjdCBvYmplY3Rcblx0XHRcdGlmICghYXJncy5sZW5ndGggJiYgKGFyZy54ICE9IG51bGwgfHwgYXJnLmwgIT0gbnVsbCB8fCBhcmcubGVmdCAhPSBudWxsKSkge1xuXHRcdFx0XHRhcmdzID0gW2FyZ11cblx0XHRcdFx0b3B0aW9ucyA9IHt9XG5cdFx0XHR9XG5cblx0XHRcdG9wdGlvbnMgPSBwaWNrKGFyZywge1xuXHRcdFx0XHRsZXZlbDogJ2xldmVsIG1heExldmVsJyxcblx0XHRcdFx0ZDogJ2QgZGlhbSBkaWFtZXRlciByIHJhZGl1cyBweCBweFNpemUgcGl4ZWwgcGl4ZWxTaXplIG1heEQgc2l6ZSBtaW5TaXplJyxcblx0XHRcdFx0bG9kOiAnbG9kIGRldGFpbHMgcmFuZ2VzIG9mZnNldHMnXG5cdFx0XHR9KVxuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdG9wdGlvbnMgPSB7fVxuXHRcdH1cblxuXHRcdGlmICghYXJncy5sZW5ndGgpIGFyZ3MgPSBib3VuZHNcblxuXHRcdGxldCBib3ggPSByZWN0KCAuLi5hcmdzIClcblxuXHRcdGxldCBbbWluWCwgbWluWSwgbWF4WCwgbWF4WV0gPSBbXG5cdFx0XHRNYXRoLm1pbihib3gueCwgYm94LnggKyBib3gud2lkdGgpLFxuXHRcdFx0TWF0aC5taW4oYm94LnksIGJveC55ICsgYm94LmhlaWdodCksXG5cdFx0XHRNYXRoLm1heChib3gueCwgYm94LnggKyBib3gud2lkdGgpLFxuXHRcdFx0TWF0aC5tYXgoYm94LnksIGJveC55ICsgYm94LmhlaWdodClcblx0XHRdXG5cblx0XHRsZXQgW25taW5YLCBubWluWSwgbm1heFgsIG5tYXhZXSA9IG5vcm1hbGl6ZShbbWluWCwgbWluWSwgbWF4WCwgbWF4WV0sIGJvdW5kcyApXG5cblx0XHRsZXQgbWF4TGV2ZWwgPSBkZWZpbmVkKG9wdGlvbnMubGV2ZWwsIGxldmVscy5sZW5ndGgpXG5cblx0XHQvLyBsaW1pdCBtYXhMZXZlbCBieSBweCBzaXplXG5cdFx0aWYgKG9wdGlvbnMuZCAhPSBudWxsKSB7XG5cdFx0XHRsZXQgZFxuXHRcdFx0aWYgKHR5cGVvZiBvcHRpb25zLmQgPT09ICdudW1iZXInKSBkID0gW29wdGlvbnMuZCwgb3B0aW9ucy5kXVxuXHRcdFx0ZWxzZSBpZiAob3B0aW9ucy5kLmxlbmd0aCkgZCA9IG9wdGlvbnMuZFxuXG5cdFx0XHRtYXhMZXZlbCA9IE1hdGgubWluKFxuXHRcdFx0XHRNYXRoLm1heChcblx0XHRcdFx0XHRNYXRoLmNlaWwoLWxvZzIoTWF0aC5hYnMoZFswXSkgLyAoYm91bmRzWzJdIC0gYm91bmRzWzBdKSkpLFxuXHRcdFx0XHRcdE1hdGguY2VpbCgtbG9nMihNYXRoLmFicyhkWzFdKSAvIChib3VuZHNbM10gLSBib3VuZHNbMV0pKSlcblx0XHRcdFx0KSxcblx0XHRcdFx0bWF4TGV2ZWxcblx0XHRcdClcblx0XHR9XG5cdFx0bWF4TGV2ZWwgPSBNYXRoLm1pbihtYXhMZXZlbCwgbGV2ZWxzLmxlbmd0aClcblxuXHRcdC8vIHJldHVybiBsZXZlbHMgb2YgZGV0YWlsc1xuXHRcdGlmIChvcHRpb25zLmxvZCkge1xuXHRcdFx0cmV0dXJuIGxvZChubWluWCwgbm1pblksIG5tYXhYLCBubWF4WSwgbWF4TGV2ZWwpXG5cdFx0fVxuXG5cblxuXHRcdC8vIGRvIHNlbGVjdGlvbiBpZHNcblx0XHRsZXQgc2VsZWN0aW9uID0gW11cblxuXHRcdC8vIEZJWE1FOiBwcm9iYWJseSB3ZSBjYW4gZG8gTE9EIGhlcmUgYmVmb3JlaGVhZFxuXHRcdHNlbGVjdCggMCwgMCwgMSwgMCwgMCwgMSlcblxuXHRcdGZ1bmN0aW9uIHNlbGVjdCAoIGxveCwgbG95LCBkLCBsZXZlbCwgZnJvbSwgdG8gKSB7XG5cdFx0XHRpZiAoZnJvbSA9PT0gbnVsbCB8fCB0byA9PT0gbnVsbCkgcmV0dXJuXG5cblx0XHRcdGxldCBoaXggPSBsb3ggKyBkXG5cdFx0XHRsZXQgaGl5ID0gbG95ICsgZFxuXG5cdFx0XHQvLyBpZiBib3ggZG9lcyBub3QgaW50ZXJzZWN0IGxldmVsIC0gaWdub3JlXG5cdFx0XHRpZiAoIG5taW5YID4gaGl4IHx8IG5taW5ZID4gaGl5IHx8IG5tYXhYIDwgbG94IHx8IG5tYXhZIDwgbG95ICkgcmV0dXJuXG5cdFx0XHRpZiAoIGxldmVsID49IG1heExldmVsICkgcmV0dXJuXG5cdFx0XHRpZiAoIGZyb20gPT09IHRvICkgcmV0dXJuXG5cblx0XHRcdC8vIGlmIHBvaW50cyBmYWxsIGludG8gYm94IHJhbmdlIC0gdGFrZSBpdFxuXHRcdFx0bGV0IGxldmVsSXRlbXMgPSBsZXZlbHNbbGV2ZWxdXG5cblx0XHRcdGlmICh0byA9PT0gdW5kZWZpbmVkKSB0byA9IGxldmVsSXRlbXMubGVuZ3RoXG5cblx0XHRcdGZvciAobGV0IGkgPSBmcm9tOyBpIDwgdG87IGkrKykge1xuXHRcdFx0XHRsZXQgaWQgPSBsZXZlbEl0ZW1zW2ldXG5cblx0XHRcdFx0bGV0IHB4ID0gc3JjUG9pbnRzWyBpZCAqIDIgXVxuXHRcdFx0XHRsZXQgcHkgPSBzcmNQb2ludHNbIGlkICogMiArIDEgXVxuXG5cdFx0XHRcdGlmICggcHggPj0gbWluWCAmJiBweCA8PSBtYXhYICYmIHB5ID49IG1pblkgJiYgcHkgPD0gbWF4WSApIHtzZWxlY3Rpb24ucHVzaChpZClcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBmb3IgZXZlcnkgc3Vic2VjdGlvbiBkbyBzZWxlY3Rcblx0XHRcdGxldCBvZmZzZXRzID0gc3VibGV2ZWxzWyBsZXZlbCBdXG5cdFx0XHRsZXQgb2ZmMCA9IG9mZnNldHNbIGZyb20gKiA0ICsgMCBdXG5cdFx0XHRsZXQgb2ZmMSA9IG9mZnNldHNbIGZyb20gKiA0ICsgMSBdXG5cdFx0XHRsZXQgb2ZmMiA9IG9mZnNldHNbIGZyb20gKiA0ICsgMiBdXG5cdFx0XHRsZXQgb2ZmMyA9IG9mZnNldHNbIGZyb20gKiA0ICsgMyBdXG5cdFx0XHRsZXQgZW5kID0gbmV4dE9mZnNldChvZmZzZXRzLCBmcm9tICsgMSlcblxuXHRcdFx0bGV0IGQyID0gZCAqIC41XG5cdFx0XHRsZXQgbmV4dExldmVsID0gbGV2ZWwgKyAxXG5cdFx0XHRzZWxlY3QoIGxveCwgbG95LCBkMiwgbmV4dExldmVsLCBvZmYwLCBvZmYxIHx8IG9mZjIgfHwgb2ZmMyB8fCBlbmQpXG5cdFx0XHRzZWxlY3QoIGxveCwgbG95ICsgZDIsIGQyLCBuZXh0TGV2ZWwsIG9mZjEsIG9mZjIgfHwgb2ZmMyB8fCBlbmQpXG5cdFx0XHRzZWxlY3QoIGxveCArIGQyLCBsb3ksIGQyLCBuZXh0TGV2ZWwsIG9mZjIsIG9mZjMgfHwgZW5kKVxuXHRcdFx0c2VsZWN0KCBsb3ggKyBkMiwgbG95ICsgZDIsIGQyLCBuZXh0TGV2ZWwsIG9mZjMsIGVuZClcblx0XHR9XG5cblx0XHRmdW5jdGlvbiBuZXh0T2Zmc2V0KG9mZnNldHMsIGZyb20pIHtcblx0XHRcdGxldCBvZmZzZXQgPSBudWxsLCBpID0gMFxuXHRcdFx0d2hpbGUob2Zmc2V0ID09PSBudWxsKSB7XG5cdFx0XHRcdG9mZnNldCA9IG9mZnNldHNbIGZyb20gKiA0ICsgaSBdXG5cdFx0XHRcdGkrK1xuXHRcdFx0XHRpZiAoaSA+IG9mZnNldHMubGVuZ3RoKSByZXR1cm4gbnVsbFxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG9mZnNldFxuXHRcdH1cblxuXHRcdHJldHVybiBzZWxlY3Rpb25cblx0fVxuXG5cdC8vIGdldCByYW5nZSBvZmZzZXRzIHdpdGhpbiBsZXZlbHMgdG8gcmVuZGVyIGxvZHMgYXBwcm9wcmlhdGUgZm9yIHpvb20gbGV2ZWxcblx0Ly8gVE9ETzogaXQgaXMgcG9zc2libGUgdG8gc3RvcmUgbWluU2l6ZSBvZiBhIHBvaW50IHRvIG9wdGltaXplIG5lZWRlIGxldmVsIGNhbGNcblx0ZnVuY3Rpb24gbG9kIChsb3gsIGxveSwgaGl4LCBoaXksIG1heExldmVsKSB7XG5cdFx0bGV0IHJhbmdlcyA9IFtdXG5cblx0XHRmb3IgKGxldCBsZXZlbCA9IDA7IGxldmVsIDwgbWF4TGV2ZWw7IGxldmVsKyspIHtcblx0XHRcdGxldCBsZXZlbEdyb3VwcyA9IGdyb3Vwc1tsZXZlbF1cblx0XHRcdGxldCBmcm9tID0gb2Zmc2V0c1tsZXZlbF1bMF1cblxuXHRcdFx0bGV0IGxldmVsR3JvdXBTdGFydCA9IGdyb3VwKGxveCwgbG95LCBsZXZlbClcblx0XHRcdGxldCBsZXZlbEdyb3VwRW5kID0gZ3JvdXAoaGl4LCBoaXksIGxldmVsKVxuXG5cdFx0XHQvLyBGSVhNRTogdXRpbGl6ZSBzdWJsZXZlbHMgdG8gc3BlZWQgdXAgc2VhcmNoIHJhbmdlIGhlcmVcblx0XHRcdGxldCBzdGFydE9mZnNldCA9IHNlYXJjaC5nZShsZXZlbEdyb3VwcywgbGV2ZWxHcm91cFN0YXJ0KVxuXHRcdFx0bGV0IGVuZE9mZnNldCA9IHNlYXJjaC5ndChsZXZlbEdyb3VwcywgbGV2ZWxHcm91cEVuZCwgc3RhcnRPZmZzZXQsIGxldmVsR3JvdXBzLmxlbmd0aCAtIDEpXG5cblx0XHRcdHJhbmdlc1tsZXZlbF0gPSBbc3RhcnRPZmZzZXQgKyBmcm9tLCBlbmRPZmZzZXQgKyBmcm9tXVxuXHRcdH1cblxuXHRcdHJldHVybiByYW5nZXNcblx0fVxuXG5cdC8vIGdldCBncm91cCBpZCBjbG9zZXN0IHRvIHRoZSB4LHkgY29vcmRpbmF0ZSwgY29ycmVzcG9uZGluZyB0byBhIGxldmVsXG5cdGZ1bmN0aW9uIGdyb3VwICh4LCB5LCBsZXZlbCkge1xuXHRcdGxldCBncm91cCA9IDFcblxuXHRcdGxldCBjeCA9IC41LCBjeSA9IC41XG5cdFx0bGV0IGRpYW0gPSAuNVxuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBsZXZlbDsgaSsrKSB7XG5cdFx0XHRncm91cCA8PD0gMlxuXG5cdFx0XHRncm91cCArPSB4IDwgY3ggPyAoeSA8IGN5ID8gMCA6IDEpIDogKHkgPCBjeSA/IDIgOiAzKVxuXG5cdFx0XHRkaWFtICo9IC41XG5cblx0XHRcdGN4ICs9IHggPCBjeCA/IC1kaWFtIDogZGlhbVxuXHRcdFx0Y3kgKz0geSA8IGN5ID8gLWRpYW0gOiBkaWFtXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGdyb3VwXG5cdH1cbn1cblxuXG4vLyBub3JtYWxpemUgcG9pbnRzIGJ5IGJvdW5kc1xuZnVuY3Rpb24gbm9ybWFsaXplIChwdHMsIGJvdW5kcykge1xuXHRsZXQgW2xveCwgbG95LCBoaXgsIGhpeV0gPSBib3VuZHNcblx0bGV0IHNjYWxlWCA9IDEuMCAvIChoaXggLSBsb3gpXG5cdGxldCBzY2FsZVkgPSAxLjAgLyAoaGl5IC0gbG95KVxuXHRsZXQgcmVzdWx0ID0gbmV3IEFycmF5KHB0cy5sZW5ndGgpXG5cblx0Zm9yIChsZXQgaSA9IDAsIG4gPSBwdHMubGVuZ3RoIC8gMjsgaSA8IG47IGkrKykge1xuXHRcdHJlc3VsdFsyKmldID0gY2xhbXAoKHB0c1syKmldIC0gbG94KSAqIHNjYWxlWCwgMCwgMSlcblx0XHRyZXN1bHRbMippKzFdID0gY2xhbXAoKHB0c1syKmkrMV0gLSBsb3kpICogc2NhbGVZLCAwLCAxKVxuXHR9XG5cblx0cmV0dXJuIHJlc3VsdFxufVxuIl0sIm5hbWVzIjpbImNvbnN0IiwiaSIsImxldCIsIngiLCJ5Il0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQUEsR0FBSyxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsc0JBQXNCLENBQUM7QUFDOUNBLEdBQUssQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQztBQUM5QkEsR0FBSyxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDO0FBQ2xDQSxHQUFLLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxjQUFjLENBQUM7QUFDekNBLEdBQUssQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQztBQUNyQ0EsR0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDO0FBQ2xDQSxHQUFLLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQztBQUM5Q0EsR0FBSyxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDO0FBQy9CQSxHQUFLLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUM7QUFDOUJBLEdBQUssQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQztBQUNqQztBQUNBQSxHQUFLLENBQUMsWUFBWSxHQUFHLFVBQVU7QUFDL0I7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLFNBQVMsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUU7QUFDdkQsQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFFLE9BQU8sR0FBRyxJQUFFO0FBQzNCO0FBQ0EsQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUM7QUFDMUM7QUFDQSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFO0FBQ3pCLEVBQUUsTUFBTSxFQUFFLDhCQUE4QjtBQUN4QyxFQUFFLFFBQVEsRUFBRSx3REFBd0Q7QUFDcEUsRUFBRSxLQUFLLEVBQUUsOENBQThDO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBLEVBQUUsQ0FBQztBQUNIO0FBQ0E7QUFDQSxDQUFDRSxHQUFHLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQztBQUM5QyxDQUFDQSxHQUFHLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDOUQsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFFO0FBQ3pDLENBQUMsSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBRTtBQUN6QztBQUNBLENBQUNBLEdBQUcsQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUM7QUFDMUM7QUFDQTtBQUNBLENBQUNBLEdBQUcsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sS0FBSyxDQUFDO0FBQy9CLENBQUNBLEdBQUcsQ0FBQyxHQUFHO0FBQ1IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBRSxPQUFPLENBQUMsS0FBSyxHQUFHLFNBQU87QUFDNUM7QUFDQSxDQUFDLElBQUksT0FBTyxPQUFPLENBQUMsS0FBSyxLQUFLLFFBQVEsRUFBRTtBQUN4QyxFQUFFLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNyQyxFQUFFO0FBQ0YsTUFBTSxJQUFJLE9BQU8sQ0FBQyxLQUFLLEVBQUU7QUFDekIsRUFBRSxHQUFHLEdBQUcsT0FBTyxDQUFDLEtBQUs7QUFDckIsRUFBRSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUUsR0FBRyxDQUFDLE1BQU0sR0FBRyxHQUFDO0FBQ3hDLEVBQUU7QUFDRixDQUFDLEtBQUtBLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUU7QUFDN0IsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztBQUNaLEVBQUU7QUFDRjtBQUNBO0FBQ0EsQ0FBQ0EsR0FBRyxDQUFDLE1BQU0sR0FBRyxFQUFFO0FBQ2hCO0FBQ0E7QUFDQSxDQUFDQSxHQUFHLENBQUMsU0FBUyxHQUFHLEVBQUU7QUFDbkI7QUFDQTtBQUNBLENBQUNBLEdBQUcsQ0FBQyxNQUFNLEdBQUcsRUFBRTtBQUNoQjtBQUNBO0FBQ0EsQ0FBQ0EsR0FBRyxDQUFDLE9BQU8sR0FBRyxFQUFFO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQ0EsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDO0FBQ2YsQ0FBQyxLQUFLQSxHQUFHLENBQUMsS0FBSyxHQUFHLENBQUMsRUFBRSxLQUFLLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRTtBQUNyRCxFQUFFQSxHQUFHLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUM7QUFDaEMsRUFBRSxJQUFJLEdBQUcsQ0FBQyxHQUFHLElBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsTUFBTSxHQUFDO0FBQzFDLE9BQU87QUFDUCxHQUFHLEtBQUtBLEdBQUcsQ0FBQ0QsR0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsVUFBVSxDQUFDLE1BQU0sRUFBRUEsR0FBQyxHQUFHLENBQUMsRUFBRUEsR0FBQyxFQUFFLEVBQUU7QUFDdEQsSUFBSSxHQUFHLENBQUNBLEdBQUMsR0FBRyxNQUFNLENBQUMsR0FBRyxVQUFVLENBQUNBLEdBQUMsQ0FBQztBQUNuQyxJQUFJO0FBQ0osR0FBRztBQUNILEVBQUVDLEdBQUcsQ0FBQyxVQUFVLEdBQUcsTUFBTSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNO0FBQ2hELEVBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQztBQUN2QyxFQUFFLE1BQU0sR0FBRyxVQUFVO0FBQ3JCLEVBQUU7QUFDRjtBQUNBLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxLQUFLO0FBQ2xCO0FBQ0EsQ0FBQyxPQUFPLEdBQUc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsU0FBUyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUU7QUFDL0MsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sSUFBRSxPQUFPLE1BQUk7QUFDOUI7QUFDQTtBQUNBLEVBQUVBLEdBQUcsQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUN4RCxFQUFFQSxHQUFHLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDekQsRUFBRUEsR0FBRyxDQUFDLFFBQVEsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQzVELEVBQUVBLEdBQUcsQ0FBQyxNQUFNLEdBQUcsVUFBVSxDQUFDLE1BQU07QUFDaEM7QUFDQSxFQUFFLEtBQUssRUFBRTtBQUNUO0FBQ0E7QUFDQTtBQUNBLEVBQUUsSUFBSSxLQUFLLEdBQUcsUUFBUSxJQUFJLEtBQUssR0FBRyxZQUFZLEVBQUU7QUFDaEQsR0FBRyxLQUFLQSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUN4QyxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNCLElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7QUFDM0IsSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQztBQUN6QyxJQUFJO0FBQ0o7QUFDQSxHQUFHLE9BQU8sTUFBTTtBQUNoQixHQUFHO0FBQ0g7QUFDQSxFQUFFLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pCLEVBQUUsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7QUFDekI7QUFDQSxFQUFFLElBQUksR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUU7QUFDdkIsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQztBQUN4QyxHQUFHLE9BQU8sTUFBTTtBQUNoQixHQUFHO0FBQ0g7QUFDQTtBQUNBLEVBQUVBLEdBQUcsQ0FBQyxFQUFFLEdBQUcsSUFBSSxHQUFHLEVBQUU7QUFDcEIsRUFBRUEsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRTtBQUM5QjtBQUNBO0FBQ0EsRUFBRUEsR0FBRyxDQUFDLElBQUksR0FBRyxFQUFFLEVBQUUsSUFBSSxHQUFHLEVBQUUsRUFBRSxJQUFJLEdBQUcsRUFBRSxFQUFFLElBQUksR0FBRyxFQUFFO0FBQ2hEO0FBQ0EsRUFBRSxLQUFLQSxHQUFHLENBQUNELEdBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUVBLEdBQUMsR0FBRyxDQUFDLEVBQUVBLEdBQUMsRUFBRSxFQUFFO0FBQzlDLEdBQUdDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDRCxHQUFDLENBQUM7QUFDbkIsSUFBSUUsR0FBQyxHQUFHLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQ3ZCLElBQUlDLEdBQUMsR0FBRyxNQUFNLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDM0IsR0FBR0QsR0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDQyxHQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUNBLEdBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ25HLEdBQUc7QUFDSDtBQUNBLEVBQUUsS0FBSyxLQUFLLENBQUM7QUFDYjtBQUNBLEVBQUUsUUFBUSxDQUFDLElBQUk7QUFDZixHQUFHLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQztBQUNyQyxHQUFHLElBQUksQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssR0FBRyxDQUFDLENBQUM7QUFDMUMsR0FBRyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0FBQzFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxHQUFHLENBQUMsQ0FBQztBQUMzQyxHQUFHO0FBQ0g7QUFDQSxFQUFFLE9BQU8sTUFBTTtBQUNmLEVBQUU7QUFDRjtBQUNBO0FBQ0EsQ0FBQyxTQUFTLEtBQUssRUFBVyxFQUFFOzs7QUFBQztBQUM3QixFQUFFRixHQUFHLENBQUMsT0FBTztBQUNiO0FBQ0EsRUFBRSxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO0FBQ3BDLEdBQUdBLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRTtBQUN2QjtBQUNBO0FBQ0EsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLEVBQUU7QUFDN0UsSUFBSSxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUM7QUFDaEIsSUFBSSxPQUFPLEdBQUcsRUFBRTtBQUNoQixJQUFJO0FBQ0o7QUFDQSxHQUFHLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFO0FBQ3ZCLElBQUksS0FBSyxFQUFFLGdCQUFnQjtBQUMzQixJQUFJLENBQUMsRUFBRSxzRUFBc0U7QUFDN0UsSUFBSSxHQUFHLEVBQUUsNEJBQTRCO0FBQ3JDLElBQUksQ0FBQztBQUNMLEdBQUc7QUFDSCxPQUFPO0FBQ1AsR0FBRyxPQUFPLEdBQUcsRUFBRTtBQUNmLEdBQUc7QUFDSDtBQUNBLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUUsSUFBSSxHQUFHLFFBQU07QUFDakM7QUFDQSxFQUFFQSxHQUFHLENBQUMsR0FBRyxHQUFHLFVBQUksVUFBSyxJQUFJLEVBQUU7QUFDM0I7QUFDQSxTQUE4QixHQUFHO0FBQ2pDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQztBQUNyQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUM7QUFDdEMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDO0FBQ3JDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQztBQUN0QztFQUxPO0VBQU07RUFBTTtFQUFNLGtCQUt0QjtBQUNIO0FBQ0EsV0FBa0MsR0FBRyxTQUFTLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxNQUFNO0VBQXhFO0VBQU87RUFBTztFQUFPLHFCQUFxRDtBQUNqRjtBQUNBLEVBQUVBLEdBQUcsQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQztBQUN0RDtBQUNBO0FBQ0EsRUFBRSxJQUFJLE9BQU8sQ0FBQyxDQUFDLElBQUksSUFBSSxFQUFFO0FBQ3pCLEdBQUdBLEdBQUcsQ0FBQyxDQUFDO0FBQ1IsR0FBRyxJQUFJLE9BQU8sT0FBTyxDQUFDLENBQUMsS0FBSyxRQUFRLElBQUUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxHQUFDO0FBQ2hFLFFBQVEsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sSUFBRSxDQUFDLEdBQUcsT0FBTyxDQUFDLEdBQUM7QUFDM0M7QUFDQSxHQUFHLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRztBQUN0QixJQUFJLElBQUksQ0FBQyxHQUFHO0FBQ1osS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvRCxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9ELEtBQUs7QUFDTCxJQUFJLFFBQVE7QUFDWixJQUFJO0FBQ0osR0FBRztBQUNILEVBQUUsUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUM7QUFDOUM7QUFDQTtBQUNBLEVBQUUsSUFBSSxPQUFPLENBQUMsR0FBRyxFQUFFO0FBQ25CLEdBQUcsT0FBTyxHQUFHLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQztBQUNuRCxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFQSxHQUFHLENBQUMsU0FBUyxHQUFHLEVBQUU7QUFDcEI7QUFDQTtBQUNBLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzNCO0FBQ0EsRUFBRSxTQUFTLE1BQU0sR0FBRyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUUsR0FBRztBQUNuRCxHQUFHLElBQUksSUFBSSxLQUFLLElBQUksSUFBSSxFQUFFLEtBQUssSUFBSSxJQUFFLFFBQU07QUFDM0M7QUFDQSxHQUFHQSxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQ3BCLEdBQUdBLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDcEI7QUFDQTtBQUNBLEdBQUcsS0FBSyxLQUFLLEdBQUcsR0FBRyxJQUFJLEtBQUssR0FBRyxHQUFHLElBQUksS0FBSyxHQUFHLEdBQUcsSUFBSSxLQUFLLEdBQUcsR0FBRyxLQUFHLFFBQU07QUFDekUsR0FBRyxLQUFLLEtBQUssSUFBSSxRQUFRLEtBQUcsUUFBTTtBQUNsQyxHQUFHLEtBQUssSUFBSSxLQUFLLEVBQUUsS0FBRyxRQUFNO0FBQzVCO0FBQ0E7QUFDQSxHQUFHQSxHQUFHLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUM7QUFDakM7QUFDQSxHQUFHLElBQUksRUFBRSxLQUFLLFNBQVMsSUFBRSxFQUFFLEdBQUcsVUFBVSxDQUFDLFFBQU07QUFDL0M7QUFDQSxHQUFHLEtBQUtBLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDbkMsSUFBSUEsR0FBRyxDQUFDLEVBQUUsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDO0FBQzFCO0FBQ0EsSUFBSUEsR0FBRyxDQUFDLEVBQUUsR0FBRyxTQUFTLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFBRTtBQUNoQyxJQUFJQSxHQUFHLENBQUMsRUFBRSxHQUFHLFNBQVMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTtBQUNwQztBQUNBLElBQUksS0FBSyxFQUFFLElBQUksSUFBSSxJQUFJLEVBQUUsSUFBSSxJQUFJLElBQUksRUFBRSxJQUFJLElBQUksSUFBSSxFQUFFLElBQUksSUFBSSxHQUFHLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7QUFDbkYsS0FBSztBQUNMLElBQUk7QUFDSjtBQUNBO0FBQ0EsR0FBR0EsR0FBRyxDQUFDLE9BQU8sR0FBRyxTQUFTLEVBQUUsS0FBSyxFQUFFO0FBQ25DLEdBQUdBLEdBQUcsQ0FBQyxJQUFJLEdBQUcsT0FBTyxFQUFFLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO0FBQ3JDLEdBQUdBLEdBQUcsQ0FBQyxJQUFJLEdBQUcsT0FBTyxFQUFFLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO0FBQ3JDLEdBQUdBLEdBQUcsQ0FBQyxJQUFJLEdBQUcsT0FBTyxFQUFFLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO0FBQ3JDLEdBQUdBLEdBQUcsQ0FBQyxJQUFJLEdBQUcsT0FBTyxFQUFFLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO0FBQ3JDLEdBQUdBLEdBQUcsQ0FBQyxHQUFHLEdBQUcsVUFBVSxDQUFDLE9BQU8sRUFBRSxJQUFJLEdBQUcsQ0FBQyxDQUFDO0FBQzFDO0FBQ0EsR0FBR0EsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRTtBQUNsQixHQUFHQSxHQUFHLENBQUMsU0FBUyxHQUFHLEtBQUssR0FBRyxDQUFDO0FBQzVCLEdBQUcsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsSUFBSSxJQUFJLElBQUksSUFBSSxJQUFJLElBQUksR0FBRyxDQUFDO0FBQ3RFLEdBQUcsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLElBQUksSUFBSSxJQUFJLElBQUksR0FBRyxDQUFDO0FBQ25FLEdBQUcsTUFBTSxFQUFFLEdBQUcsR0FBRyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLElBQUksSUFBSSxHQUFHLENBQUM7QUFDM0QsR0FBRyxNQUFNLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQztBQUN4RCxHQUFHO0FBQ0g7QUFDQSxFQUFFLFNBQVMsVUFBVSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUU7QUFDckMsR0FBR0EsR0FBRyxDQUFDLE1BQU0sR0FBRyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUM7QUFDM0IsR0FBRyxNQUFNLE1BQU0sS0FBSyxJQUFJLEVBQUU7QUFDMUIsSUFBSSxNQUFNLEdBQUcsT0FBTyxFQUFFLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO0FBQ3BDLElBQUksQ0FBQyxFQUFFO0FBQ1AsSUFBSSxJQUFJLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFFLE9BQU8sTUFBSTtBQUN2QyxJQUFJO0FBQ0osR0FBRyxPQUFPLE1BQU07QUFDaEIsR0FBRztBQUNIO0FBQ0EsRUFBRSxPQUFPLFNBQVM7QUFDbEIsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLENBQUMsU0FBUyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRTtBQUM3QyxFQUFFQSxHQUFHLENBQUMsTUFBTSxHQUFHLEVBQUU7QUFDakI7QUFDQSxFQUFFLEtBQUtBLEdBQUcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFLEtBQUssR0FBRyxRQUFRLEVBQUUsS0FBSyxFQUFFLEVBQUU7QUFDakQsR0FBR0EsR0FBRyxDQUFDLFdBQVcsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDO0FBQ2xDLEdBQUdBLEdBQUcsQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQjtBQUNBLEdBQUdBLEdBQUcsQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDO0FBQy9DLEdBQUdBLEdBQUcsQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDO0FBQzdDO0FBQ0E7QUFDQSxHQUFHQSxHQUFHLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLGVBQWUsQ0FBQztBQUM1RCxHQUFHQSxHQUFHLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLGFBQWEsRUFBRSxXQUFXLEVBQUUsV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFDN0Y7QUFDQSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFdBQVcsR0FBRyxJQUFJLEVBQUUsU0FBUyxHQUFHLElBQUksQ0FBQztBQUN6RCxHQUFHO0FBQ0g7QUFDQSxFQUFFLE9BQU8sTUFBTTtBQUNmLEVBQUU7QUFDRjtBQUNBO0FBQ0EsQ0FBQyxTQUFTLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRTtBQUM5QixFQUFFQSxHQUFHLENBQUMsS0FBSyxHQUFHLENBQUM7QUFDZjtBQUNBLEVBQUVBLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFO0FBQ3RCLEVBQUVBLEdBQUcsQ0FBQyxJQUFJLEdBQUcsRUFBRTtBQUNmO0FBQ0EsRUFBRSxLQUFLQSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQ2xDLEdBQUcsS0FBSyxLQUFLLENBQUM7QUFDZDtBQUNBLEdBQUcsS0FBSyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN4RDtBQUNBLEdBQUcsSUFBSSxJQUFJLEVBQUU7QUFDYjtBQUNBLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSTtBQUM5QixHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUk7QUFDOUIsR0FBRztBQUNIO0FBQ0EsRUFBRSxPQUFPLEtBQUs7QUFDZCxFQUFFO0FBQ0YsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLFNBQVMsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUU7QUFDakMsQ0FBTTtDQUFLO0NBQUs7Q0FBSyxvQkFBYTtBQUNsQyxDQUFDQSxHQUFHLENBQUMsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDL0IsQ0FBQ0EsR0FBRyxDQUFDLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQy9CLENBQUNBLEdBQUcsQ0FBQyxNQUFNLEdBQUcsSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQztBQUNuQztBQUNBLENBQUMsS0FBS0EsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDakQsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDdEQsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUMxRCxFQUFFO0FBQ0Y7QUFDQSxDQUFDLE9BQU8sTUFBTTtBQUNkLENBQUM7In0=\n\n//# sourceURL=webpack:///./node_modules/point-cluster/quad.js?");
-
-/***/ }),
-
-/***/ "./node_modules/point-in-big-polygon/node_modules/binary-search-bounds/search-bounds.js":
-/*!**********************************************************************************************!*\
- !*** ./node_modules/point-in-big-polygon/node_modules/binary-search-bounds/search-bounds.js ***!
- \**********************************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nfunction compileSearch(funcName, predicate, reversed, extraArgs, useNdarray, earlyOut) {\n var code = [\n \"function \", funcName, \"(a,l,h,\", extraArgs.join(\",\"), \"){\",\nearlyOut ? \"\" : \"var i=\", (reversed ? \"l-1\" : \"h+1\"),\n\";while(l<=h){\\\nvar m=(l+h)>>>1,x=a\", useNdarray ? \".get(m)\" : \"[m]\"]\n if(earlyOut) {\n if(predicate.indexOf(\"c\") < 0) {\n code.push(\";if(x===y){return m}else if(x<=y){\")\n } else {\n code.push(\";var p=c(x,y);if(p===0){return m}else if(p<=0){\")\n }\n } else {\n code.push(\";if(\", predicate, \"){i=m;\")\n }\n if(reversed) {\n code.push(\"l=m+1}else{h=m-1}\")\n } else {\n code.push(\"h=m-1}else{l=m+1}\")\n }\n code.push(\"}\")\n if(earlyOut) {\n code.push(\"return -1};\")\n } else {\n code.push(\"return i};\")\n }\n return code.join(\"\")\n}\n\nfunction compileBoundsSearch(predicate, reversed, suffix, earlyOut) {\n var result = new Function([\n compileSearch(\"A\", \"x\" + predicate + \"y\", reversed, [\"y\"], false, earlyOut),\n compileSearch(\"B\", \"x\" + predicate + \"y\", reversed, [\"y\"], true, earlyOut),\n compileSearch(\"P\", \"c(x,y)\" + predicate + \"0\", reversed, [\"y\", \"c\"], false, earlyOut),\n compileSearch(\"Q\", \"c(x,y)\" + predicate + \"0\", reversed, [\"y\", \"c\"], true, earlyOut),\n\"function dispatchBsearch\", suffix, \"(a,y,c,l,h){\\\nif(a.shape){\\\nif(typeof(c)==='function'){\\\nreturn Q(a,(l===undefined)?0:l|0,(h===undefined)?a.shape[0]-1:h|0,y,c)\\\n}else{\\\nreturn B(a,(c===undefined)?0:c|0,(l===undefined)?a.shape[0]-1:l|0,y)\\\n}}else{\\\nif(typeof(c)==='function'){\\\nreturn P(a,(l===undefined)?0:l|0,(h===undefined)?a.length-1:h|0,y,c)\\\n}else{\\\nreturn A(a,(c===undefined)?0:c|0,(l===undefined)?a.length-1:l|0,y)\\\n}}}\\\nreturn dispatchBsearch\", suffix].join(\"\"))\n return result()\n}\n\nmodule.exports = {\n ge: compileBoundsSearch(\">=\", false, \"GE\"),\n gt: compileBoundsSearch(\">\", false, \"GT\"),\n lt: compileBoundsSearch(\"<\", true, \"LT\"),\n le: compileBoundsSearch(\"<=\", true, \"LE\"),\n eq: compileBoundsSearch(\"-\", true, \"EQ\", true)\n}\n\n\n//# sourceURL=webpack:///./node_modules/point-in-big-polygon/node_modules/binary-search-bounds/search-bounds.js?");
-
-/***/ }),
-
-/***/ "./node_modules/point-in-big-polygon/pnp-big.js":
-/*!******************************************************!*\
- !*** ./node_modules/point-in-big-polygon/pnp-big.js ***!
- \******************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-eval("module.exports = preprocessPolygon\n\nvar orient = __webpack_require__(/*! robust-orientation */ \"./node_modules/robust-orientation/orientation.js\")[3]\nvar makeSlabs = __webpack_require__(/*! slab-decomposition */ \"./node_modules/slab-decomposition/slabs.js\")\nvar makeIntervalTree = __webpack_require__(/*! interval-tree-1d */ \"./node_modules/interval-tree-1d/interval-tree.js\")\nvar bsearch = __webpack_require__(/*! binary-search-bounds */ \"./node_modules/point-in-big-polygon/node_modules/binary-search-bounds/search-bounds.js\")\n\nfunction visitInterval() {\n return true\n}\n\nfunction intervalSearch(table) {\n return function(x, y) {\n var tree = table[x]\n if(tree) {\n return !!tree.queryPoint(y, visitInterval)\n }\n return false\n }\n}\n\nfunction buildVerticalIndex(segments) {\n var table = {}\n for(var i=0; i 0 && coordinates[bucket] === p[0]) {\n root = slabs[bucket-1]\n } else {\n return 1\n }\n }\n var lastOrientation = 1\n while(root) {\n var s = root.key\n var o = orient(p, s[0], s[1])\n if(s[0][0] < s[1][0]) {\n if(o < 0) {\n root = root.left\n } else if(o > 0) {\n lastOrientation = -1\n root = root.right\n } else {\n return 0\n }\n } else {\n if(o > 0) {\n root = root.left\n } else if(o < 0) {\n lastOrientation = 1\n root = root.right\n } else {\n return 0\n }\n }\n }\n return lastOrientation\n }\n}\n\nfunction classifyEmpty(p) {\n return 1\n}\n\nfunction createClassifyVertical(testVertical) {\n return function classify(p) {\n if(testVertical(p[0], p[1])) {\n return 0\n }\n return 1\n }\n}\n\nfunction createClassifyPointDegen(testVertical, testNormal) {\n return function classify(p) {\n if(testVertical(p[0], p[1])) {\n return 0\n }\n return testNormal(p)\n }\n}\n\nfunction preprocessPolygon(loops) {\n //Compute number of loops\n var numLoops = loops.length\n\n //Unpack segments\n var segments = []\n var vsegments = []\n var ptr = 0\n for(var i=0; i= -eps;\n\t\t},\n\t\tpointBetween: function(p, left, right){\n\t\t\t// p must be collinear with left->right\n\t\t\t// returns false if p == left, p == right, or left == right\n\t\t\tvar d_py_ly = p[1] - left[1];\n\t\t\tvar d_rx_lx = right[0] - left[0];\n\t\t\tvar d_px_lx = p[0] - left[0];\n\t\t\tvar d_ry_ly = right[1] - left[1];\n\n\t\t\tvar dot = d_px_lx * d_rx_lx + d_py_ly * d_ry_ly;\n\t\t\t// if `dot` is 0, then `p` == `left` or `left` == `right` (reject)\n\t\t\t// if `dot` is less than 0, then `p` is to the left of `left` (reject)\n\t\t\tif (dot < eps)\n\t\t\t\treturn false;\n\n\t\t\tvar sqlen = d_rx_lx * d_rx_lx + d_ry_ly * d_ry_ly;\n\t\t\t// if `dot` > `sqlen`, then `p` is to the right of `right` (reject)\n\t\t\t// therefore, if `dot - sqlen` is greater than 0, then `p` is to the right of `right` (reject)\n\t\t\tif (dot - sqlen > -eps)\n\t\t\t\treturn false;\n\n\t\t\treturn true;\n\t\t},\n\t\tpointsSameX: function(p1, p2){\n\t\t\treturn Math.abs(p1[0] - p2[0]) < eps;\n\t\t},\n\t\tpointsSameY: function(p1, p2){\n\t\t\treturn Math.abs(p1[1] - p2[1]) < eps;\n\t\t},\n\t\tpointsSame: function(p1, p2){\n\t\t\treturn my.pointsSameX(p1, p2) && my.pointsSameY(p1, p2);\n\t\t},\n\t\tpointsCompare: function(p1, p2){\n\t\t\t// returns -1 if p1 is smaller, 1 if p2 is smaller, 0 if equal\n\t\t\tif (my.pointsSameX(p1, p2))\n\t\t\t\treturn my.pointsSameY(p1, p2) ? 0 : (p1[1] < p2[1] ? -1 : 1);\n\t\t\treturn p1[0] < p2[0] ? -1 : 1;\n\t\t},\n\t\tpointsCollinear: function(pt1, pt2, pt3){\n\t\t\t// does pt1->pt2->pt3 make a straight line?\n\t\t\t// essentially this is just checking to see if the slope(pt1->pt2) === slope(pt2->pt3)\n\t\t\t// if slopes are equal, then they must be collinear, because they share pt2\n\t\t\tvar dx1 = pt1[0] - pt2[0];\n\t\t\tvar dy1 = pt1[1] - pt2[1];\n\t\t\tvar dx2 = pt2[0] - pt3[0];\n\t\t\tvar dy2 = pt2[1] - pt3[1];\n\t\t\treturn Math.abs(dx1 * dy2 - dx2 * dy1) < eps;\n\t\t},\n\t\tlinesIntersect: function(a0, a1, b0, b1){\n\t\t\t// returns false if the lines are coincident (e.g., parallel or on top of each other)\n\t\t\t//\n\t\t\t// returns an object if the lines intersect:\n\t\t\t// {\n\t\t\t// pt: [x, y], where the intersection point is at\n\t\t\t// alongA: where intersection point is along A,\n\t\t\t// alongB: where intersection point is along B\n\t\t\t// }\n\t\t\t//\n\t\t\t// alongA and alongB will each be one of: -2, -1, 0, 1, 2\n\t\t\t//\n\t\t\t// with the following meaning:\n\t\t\t//\n\t\t\t// -2 intersection point is before segment's first point\n\t\t\t// -1 intersection point is directly on segment's first point\n\t\t\t// 0 intersection point is between segment's first and second points (exclusive)\n\t\t\t// 1 intersection point is directly on segment's second point\n\t\t\t// 2 intersection point is after segment's second point\n\t\t\tvar adx = a1[0] - a0[0];\n\t\t\tvar ady = a1[1] - a0[1];\n\t\t\tvar bdx = b1[0] - b0[0];\n\t\t\tvar bdy = b1[1] - b0[1];\n\n\t\t\tvar axb = adx * bdy - ady * bdx;\n\t\t\tif (Math.abs(axb) < eps)\n\t\t\t\treturn false; // lines are coincident\n\n\t\t\tvar dx = a0[0] - b0[0];\n\t\t\tvar dy = a0[1] - b0[1];\n\n\t\t\tvar A = (bdx * dy - bdy * dx) / axb;\n\t\t\tvar B = (adx * dy - ady * dx) / axb;\n\n\t\t\tvar ret = {\n\t\t\t\talongA: 0,\n\t\t\t\talongB: 0,\n\t\t\t\tpt: [\n\t\t\t\t\ta0[0] + A * adx,\n\t\t\t\t\ta0[1] + A * ady\n\t\t\t\t]\n\t\t\t};\n\n\t\t\t// categorize where intersection point is along A and B\n\n\t\t\tif (A <= -eps)\n\t\t\t\tret.alongA = -2;\n\t\t\telse if (A < eps)\n\t\t\t\tret.alongA = -1;\n\t\t\telse if (A - 1 <= -eps)\n\t\t\t\tret.alongA = 0;\n\t\t\telse if (A - 1 < eps)\n\t\t\t\tret.alongA = 1;\n\t\t\telse\n\t\t\t\tret.alongA = 2;\n\n\t\t\tif (B <= -eps)\n\t\t\t\tret.alongB = -2;\n\t\t\telse if (B < eps)\n\t\t\t\tret.alongB = -1;\n\t\t\telse if (B - 1 <= -eps)\n\t\t\t\tret.alongB = 0;\n\t\t\telse if (B - 1 < eps)\n\t\t\t\tret.alongB = 1;\n\t\t\telse\n\t\t\t\tret.alongB = 2;\n\n\t\t\treturn ret;\n\t\t},\n\t\tpointInsideRegion: function(pt, region){\n\t\t\tvar x = pt[0];\n\t\t\tvar y = pt[1];\n\t\t\tvar last_x = region[region.length - 1][0];\n\t\t\tvar last_y = region[region.length - 1][1];\n\t\t\tvar inside = false;\n\t\t\tfor (var i = 0; i < region.length; i++){\n\t\t\t\tvar curr_x = region[i][0];\n\t\t\t\tvar curr_y = region[i][1];\n\n\t\t\t\t// if y is between curr_y and last_y, and\n\t\t\t\t// x is to the right of the boundary created by the line\n\t\t\t\tif ((curr_y - y > eps) != (last_y - y > eps) &&\n\t\t\t\t\t(last_x - curr_x) * (y - curr_y) / (last_y - curr_y) + curr_x - x > eps)\n\t\t\t\t\tinside = !inside\n\n\t\t\t\tlast_x = curr_x;\n\t\t\t\tlast_y = curr_y;\n\t\t\t}\n\t\t\treturn inside;\n\t\t}\n\t};\n\treturn my;\n}\n\nmodule.exports = Epsilon;\n\n\n//# sourceURL=webpack:///./node_modules/polybooljs/lib/epsilon.js?");
-
-/***/ }),
-
-/***/ "./node_modules/polybooljs/lib/geojson.js":
-/*!************************************************!*\
- !*** ./node_modules/polybooljs/lib/geojson.js ***!
- \************************************************/
-/*! no static exports found */
-/***/ (function(module, exports) {
-
-eval("// (c) Copyright 2017, Sean Connelly (@voidqk), http://syntheti.cc\n// MIT License\n// Project Home: https://github.com/voidqk/polybooljs\n\n//\n// convert between PolyBool polygon format and GeoJSON formats (Polygon and MultiPolygon)\n//\n\nvar GeoJSON = {\n\t// convert a GeoJSON object to a PolyBool polygon\n\ttoPolygon: function(PolyBool, geojson){\n\n\t\t// converts list of LineString's to segments\n\t\tfunction GeoPoly(coords){\n\t\t\t// check for empty coords\n\t\t\tif (coords.length <= 0)\n\t\t\t\treturn PolyBool.segments({ inverted: false, regions: [] });\n\n\t\t\t// convert LineString to segments\n\t\t\tfunction LineString(ls){\n\t\t\t\t// remove tail which should be the same as head\n\t\t\t\tvar reg = ls.slice(0, ls.length - 1);\n\t\t\t\treturn PolyBool.segments({ inverted: false, regions: [reg] });\n\t\t\t}\n\n\t\t\t// the first LineString is considered the outside\n\t\t\tvar out = LineString(coords[0]);\n\n\t\t\t// the rest of the LineStrings are considered interior holes, so subtract them from the\n\t\t\t// current result\n\t\t\tfor (var i = 1; i < coords.length; i++)\n\t\t\t\tout = PolyBool.selectDifference(PolyBool.combine(out, LineString(coords[i])));\n\n\t\t\treturn out;\n\t\t}\n\n\t\tif (geojson.type === 'Polygon'){\n\t\t\t// single polygon, so just convert it and we're done\n\t\t\treturn PolyBool.polygon(GeoPoly(geojson.coordinates));\n\t\t}\n\t\telse if (geojson.type === 'MultiPolygon'){\n\t\t\t// multiple polygons, so union all the polygons together\n\t\t\tvar out = PolyBool.segments({ inverted: false, regions: [] });\n\t\t\tfor (var i = 0; i < geojson.coordinates.length; i++)\n\t\t\t\tout = PolyBool.selectUnion(PolyBool.combine(out, GeoPoly(geojson.coordinates[i])));\n\t\t\treturn PolyBool.polygon(out);\n\t\t}\n\t\tthrow new Error('PolyBool: Cannot convert GeoJSON object to PolyBool polygon');\n\t},\n\n\t// convert a PolyBool polygon to a GeoJSON object\n\tfromPolygon: function(PolyBool, eps, poly){\n\t\t// make sure out polygon is clean\n\t\tpoly = PolyBool.polygon(PolyBool.segments(poly));\n\n\t\t// test if r1 is inside r2\n\t\tfunction regionInsideRegion(r1, r2){\n\t\t\t// we're guaranteed no lines intersect (because the polygon is clean), but a vertex\n\t\t\t// could be on the edge -- so we just average pt[0] and pt[1] to produce a point on the\n\t\t\t// edge of the first line, which cannot be on an edge\n\t\t\treturn eps.pointInsideRegion([\n\t\t\t\t(r1[0][0] + r1[1][0]) * 0.5,\n\t\t\t\t(r1[0][1] + r1[1][1]) * 0.5\n\t\t\t], r2);\n\t\t}\n\n\t\t// calculate inside heirarchy\n\t\t//\n\t\t// _____________________ _______ roots -> A -> F\n\t\t// | A | | F | | |\n\t\t// | _______ _______ | | ___ | +-- B +-- G\n\t\t// | | B | | C | | | | | | | |\n\t\t// | | ___ | | ___ | | | | | | | +-- D\n\t\t// | | | D | | | | E | | | | | G | | |\n\t\t// | | |___| | | |___| | | | | | | +-- C\n\t\t// | |_______| |_______| | | |___| | |\n\t\t// |_____________________| |_______| +-- E\n\n\t\tfunction newNode(region){\n\t\t\treturn {\n\t\t\t\tregion: region,\n\t\t\t\tchildren: []\n\t\t\t};\n\t\t}\n\n\t\tvar roots = newNode(null);\n\n\t\tfunction addChild(root, region){\n\t\t\t// first check if we're inside any children\n\t\t\tfor (var i = 0; i < root.children.length; i++){\n\t\t\t\tvar child = root.children[i];\n\t\t\t\tif (regionInsideRegion(region, child.region)){\n\t\t\t\t\t// we are, so insert inside them instead\n\t\t\t\t\taddChild(child, region);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// not inside any children, so check to see if any children are inside us\n\t\t\tvar node = newNode(region);\n\t\t\tfor (var i = 0; i < root.children.length; i++){\n\t\t\t\tvar child = root.children[i];\n\t\t\t\tif (regionInsideRegion(child.region, region)){\n\t\t\t\t\t// oops... move the child beneath us, and remove them from root\n\t\t\t\t\tnode.children.push(child);\n\t\t\t\t\troot.children.splice(i, 1);\n\t\t\t\t\ti--;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// now we can add ourselves\n\t\t\troot.children.push(node);\n\t\t}\n\n\t\t// add all regions to the root\n\t\tfor (var i = 0; i < poly.regions.length; i++){\n\t\t\tvar region = poly.regions[i];\n\t\t\tif (region.length < 3) // regions must have at least 3 points (sanity check)\n\t\t\t\tcontinue;\n\t\t\taddChild(roots, region);\n\t\t}\n\n\t\t// with our heirarchy, we can distinguish between exterior borders, and interior holes\n\t\t// the root nodes are exterior, children are interior, children's children are exterior,\n\t\t// children's children's children are interior, etc\n\n\t\t// while we're at it, exteriors are counter-clockwise, and interiors are clockwise\n\n\t\tfunction forceWinding(region, clockwise){\n\t\t\t// first, see if we're clockwise or counter-clockwise\n\t\t\t// https://en.wikipedia.org/wiki/Shoelace_formula\n\t\t\tvar winding = 0;\n\t\t\tvar last_x = region[region.length - 1][0];\n\t\t\tvar last_y = region[region.length - 1][1];\n\t\t\tvar copy = [];\n\t\t\tfor (var i = 0; i < region.length; i++){\n\t\t\t\tvar curr_x = region[i][0];\n\t\t\t\tvar curr_y = region[i][1];\n\t\t\t\tcopy.push([curr_x, curr_y]); // create a copy while we're at it\n\t\t\t\twinding += curr_y * last_x - curr_x * last_y;\n\t\t\t\tlast_x = curr_x;\n\t\t\t\tlast_y = curr_y;\n\t\t\t}\n\t\t\t// this assumes Cartesian coordinates (Y is positive going up)\n\t\t\tvar isclockwise = winding < 0;\n\t\t\tif (isclockwise !== clockwise)\n\t\t\t\tcopy.reverse();\n\t\t\t// while we're here, the last point must be the first point...\n\t\t\tcopy.push([copy[0][0], copy[0][1]]);\n\t\t\treturn copy;\n\t\t}\n\n\t\tvar geopolys = [];\n\n\t\tfunction addExterior(node){\n\t\t\tvar poly = [forceWinding(node.region, false)];\n\t\t\tgeopolys.push(poly);\n\t\t\t// children of exteriors are interior\n\t\t\tfor (var i = 0; i < node.children.length; i++)\n\t\t\t\tpoly.push(getInterior(node.children[i]));\n\t\t}\n\n\t\tfunction getInterior(node){\n\t\t\t// children of interiors are exterior\n\t\t\tfor (var i = 0; i < node.children.length; i++)\n\t\t\t\taddExterior(node.children[i]);\n\t\t\t// return the clockwise interior\n\t\t\treturn forceWinding(node.region, true);\n\t\t}\n\n\t\t// root nodes are exterior\n\t\tfor (var i = 0; i < roots.children.length; i++)\n\t\t\taddExterior(roots.children[i]);\n\n\t\t// lastly, construct the approrpriate GeoJSON object\n\n\t\tif (geopolys.length <= 0) // empty GeoJSON Polygon\n\t\t\treturn { type: 'Polygon', coordinates: [] };\n\t\tif (geopolys.length == 1) // use a GeoJSON Polygon\n\t\t\treturn { type: 'Polygon', coordinates: geopolys[0] };\n\t\treturn { // otherwise, use a GeoJSON MultiPolygon\n\t\t\ttype: 'MultiPolygon',\n\t\t\tcoordinates: geopolys\n\t\t};\n\t}\n};\n\nmodule.exports = GeoJSON;\n\n\n//# sourceURL=webpack:///./node_modules/polybooljs/lib/geojson.js?");
-
-/***/ }),
-
-/***/ "./node_modules/polybooljs/lib/intersecter.js":
-/*!****************************************************!*\
- !*** ./node_modules/polybooljs/lib/intersecter.js ***!
- \****************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-eval("// (c) Copyright 2016, Sean Connelly (@voidqk), http://syntheti.cc\n// MIT License\n// Project Home: https://github.com/voidqk/polybooljs\n\n//\n// this is the core work-horse\n//\n\nvar LinkedList = __webpack_require__(/*! ./linked-list */ \"./node_modules/polybooljs/lib/linked-list.js\");\n\nfunction Intersecter(selfIntersection, eps, buildLog){\n\t// selfIntersection is true/false depending on the phase of the overall algorithm\n\n\t//\n\t// segment creation\n\t//\n\n\tfunction segmentNew(start, end){\n\t\treturn {\n\t\t\tid: buildLog ? buildLog.segmentId() : -1,\n\t\t\tstart: start,\n\t\t\tend: end,\n\t\t\tmyFill: {\n\t\t\t\tabove: null, // is there fill above us?\n\t\t\t\tbelow: null // is there fill below us?\n\t\t\t},\n\t\t\totherFill: null\n\t\t};\n\t}\n\n\tfunction segmentCopy(start, end, seg){\n\t\treturn {\n\t\t\tid: buildLog ? buildLog.segmentId() : -1,\n\t\t\tstart: start,\n\t\t\tend: end,\n\t\t\tmyFill: {\n\t\t\t\tabove: seg.myFill.above,\n\t\t\t\tbelow: seg.myFill.below\n\t\t\t},\n\t\t\totherFill: null\n\t\t};\n\t}\n\n\t//\n\t// event logic\n\t//\n\n\tvar event_root = LinkedList.create();\n\n\tfunction eventCompare(p1_isStart, p1_1, p1_2, p2_isStart, p2_1, p2_2){\n\t\t// compare the selected points first\n\t\tvar comp = eps.pointsCompare(p1_1, p2_1);\n\t\tif (comp !== 0)\n\t\t\treturn comp;\n\t\t// the selected points are the same\n\n\t\tif (eps.pointsSame(p1_2, p2_2)) // if the non-selected points are the same too...\n\t\t\treturn 0; // then the segments are equal\n\n\t\tif (p1_isStart !== p2_isStart) // if one is a start and the other isn't...\n\t\t\treturn p1_isStart ? 1 : -1; // favor the one that isn't the start\n\n\t\t// otherwise, we'll have to calculate which one is below the other manually\n\t\treturn eps.pointAboveOrOnLine(p1_2,\n\t\t\tp2_isStart ? p2_1 : p2_2, // order matters\n\t\t\tp2_isStart ? p2_2 : p2_1\n\t\t) ? 1 : -1;\n\t}\n\n\tfunction eventAdd(ev, other_pt){\n\t\tevent_root.insertBefore(ev, function(here){\n\t\t\t// should ev be inserted before here?\n\t\t\tvar comp = eventCompare(\n\t\t\t\tev .isStart, ev .pt, other_pt,\n\t\t\t\there.isStart, here.pt, here.other.pt\n\t\t\t);\n\t\t\treturn comp < 0;\n\t\t});\n\t}\n\n\tfunction eventAddSegmentStart(seg, primary){\n\t\tvar ev_start = LinkedList.node({\n\t\t\tisStart: true,\n\t\t\tpt: seg.start,\n\t\t\tseg: seg,\n\t\t\tprimary: primary,\n\t\t\tother: null,\n\t\t\tstatus: null\n\t\t});\n\t\teventAdd(ev_start, seg.end);\n\t\treturn ev_start;\n\t}\n\n\tfunction eventAddSegmentEnd(ev_start, seg, primary){\n\t\tvar ev_end = LinkedList.node({\n\t\t\tisStart: false,\n\t\t\tpt: seg.end,\n\t\t\tseg: seg,\n\t\t\tprimary: primary,\n\t\t\tother: ev_start,\n\t\t\tstatus: null\n\t\t});\n\t\tev_start.other = ev_end;\n\t\teventAdd(ev_end, ev_start.pt);\n\t}\n\n\tfunction eventAddSegment(seg, primary){\n\t\tvar ev_start = eventAddSegmentStart(seg, primary);\n\t\teventAddSegmentEnd(ev_start, seg, primary);\n\t\treturn ev_start;\n\t}\n\n\tfunction eventUpdateEnd(ev, end){\n\t\t// slides an end backwards\n\t\t// (start)------------(end) to:\n\t\t// (start)---(end)\n\n\t\tif (buildLog)\n\t\t\tbuildLog.segmentChop(ev.seg, end);\n\n\t\tev.other.remove();\n\t\tev.seg.end = end;\n\t\tev.other.pt = end;\n\t\teventAdd(ev.other, ev.pt);\n\t}\n\n\tfunction eventDivide(ev, pt){\n\t\tvar ns = segmentCopy(pt, ev.seg.end, ev.seg);\n\t\teventUpdateEnd(ev, pt);\n\t\treturn eventAddSegment(ns, ev.primary);\n\t}\n\n\tfunction calculate(primaryPolyInverted, secondaryPolyInverted){\n\t\t// if selfIntersection is true then there is no secondary polygon, so that isn't used\n\n\t\t//\n\t\t// status logic\n\t\t//\n\n\t\tvar status_root = LinkedList.create();\n\n\t\tfunction statusCompare(ev1, ev2){\n\t\t\tvar a1 = ev1.seg.start;\n\t\t\tvar a2 = ev1.seg.end;\n\t\t\tvar b1 = ev2.seg.start;\n\t\t\tvar b2 = ev2.seg.end;\n\n\t\t\tif (eps.pointsCollinear(a1, b1, b2)){\n\t\t\t\tif (eps.pointsCollinear(a2, b1, b2))\n\t\t\t\t\treturn 1;//eventCompare(true, a1, a2, true, b1, b2);\n\t\t\t\treturn eps.pointAboveOrOnLine(a2, b1, b2) ? 1 : -1;\n\t\t\t}\n\t\t\treturn eps.pointAboveOrOnLine(a1, b1, b2) ? 1 : -1;\n\t\t}\n\n\t\tfunction statusFindSurrounding(ev){\n\t\t\treturn status_root.findTransition(function(here){\n\t\t\t\tvar comp = statusCompare(ev, here.ev);\n\t\t\t\treturn comp > 0;\n\t\t\t});\n\t\t}\n\n\t\tfunction checkIntersection(ev1, ev2){\n\t\t\t// returns the segment equal to ev1, or false if nothing equal\n\n\t\t\tvar seg1 = ev1.seg;\n\t\t\tvar seg2 = ev2.seg;\n\t\t\tvar a1 = seg1.start;\n\t\t\tvar a2 = seg1.end;\n\t\t\tvar b1 = seg2.start;\n\t\t\tvar b2 = seg2.end;\n\n\t\t\tif (buildLog)\n\t\t\t\tbuildLog.checkIntersection(seg1, seg2);\n\n\t\t\tvar i = eps.linesIntersect(a1, a2, b1, b2);\n\n\t\t\tif (i === false){\n\t\t\t\t// segments are parallel or coincident\n\n\t\t\t\t// if points aren't collinear, then the segments are parallel, so no intersections\n\t\t\t\tif (!eps.pointsCollinear(a1, a2, b1))\n\t\t\t\t\treturn false;\n\t\t\t\t// otherwise, segments are on top of each other somehow (aka coincident)\n\n\t\t\t\tif (eps.pointsSame(a1, b2) || eps.pointsSame(a2, b1))\n\t\t\t\t\treturn false; // segments touch at endpoints... no intersection\n\n\t\t\t\tvar a1_equ_b1 = eps.pointsSame(a1, b1);\n\t\t\t\tvar a2_equ_b2 = eps.pointsSame(a2, b2);\n\n\t\t\t\tif (a1_equ_b1 && a2_equ_b2)\n\t\t\t\t\treturn ev2; // segments are exactly equal\n\n\t\t\t\tvar a1_between = !a1_equ_b1 && eps.pointBetween(a1, b1, b2);\n\t\t\t\tvar a2_between = !a2_equ_b2 && eps.pointBetween(a2, b1, b2);\n\n\t\t\t\t// handy for debugging:\n\t\t\t\t// buildLog.log({\n\t\t\t\t//\ta1_equ_b1: a1_equ_b1,\n\t\t\t\t//\ta2_equ_b2: a2_equ_b2,\n\t\t\t\t//\ta1_between: a1_between,\n\t\t\t\t//\ta2_between: a2_between\n\t\t\t\t// });\n\n\t\t\t\tif (a1_equ_b1){\n\t\t\t\t\tif (a2_between){\n\t\t\t\t\t\t// (a1)---(a2)\n\t\t\t\t\t\t// (b1)----------(b2)\n\t\t\t\t\t\teventDivide(ev2, a2);\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\t// (a1)----------(a2)\n\t\t\t\t\t\t// (b1)---(b2)\n\t\t\t\t\t\teventDivide(ev1, b2);\n\t\t\t\t\t}\n\t\t\t\t\treturn ev2;\n\t\t\t\t}\n\t\t\t\telse if (a1_between){\n\t\t\t\t\tif (!a2_equ_b2){\n\t\t\t\t\t\t// make a2 equal to b2\n\t\t\t\t\t\tif (a2_between){\n\t\t\t\t\t\t\t// (a1)---(a2)\n\t\t\t\t\t\t\t// (b1)-----------------(b2)\n\t\t\t\t\t\t\teventDivide(ev2, a2);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse{\n\t\t\t\t\t\t\t// (a1)----------(a2)\n\t\t\t\t\t\t\t// (b1)----------(b2)\n\t\t\t\t\t\t\teventDivide(ev1, b2);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// (a1)---(a2)\n\t\t\t\t\t// (b1)----------(b2)\n\t\t\t\t\teventDivide(ev2, a1);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse{\n\t\t\t\t// otherwise, lines intersect at i.pt, which may or may not be between the endpoints\n\n\t\t\t\t// is A divided between its endpoints? (exclusive)\n\t\t\t\tif (i.alongA === 0){\n\t\t\t\t\tif (i.alongB === -1) // yes, at exactly b1\n\t\t\t\t\t\teventDivide(ev1, b1);\n\t\t\t\t\telse if (i.alongB === 0) // yes, somewhere between B's endpoints\n\t\t\t\t\t\teventDivide(ev1, i.pt);\n\t\t\t\t\telse if (i.alongB === 1) // yes, at exactly b2\n\t\t\t\t\t\teventDivide(ev1, b2);\n\t\t\t\t}\n\n\t\t\t\t// is B divided between its endpoints? (exclusive)\n\t\t\t\tif (i.alongB === 0){\n\t\t\t\t\tif (i.alongA === -1) // yes, at exactly a1\n\t\t\t\t\t\teventDivide(ev2, a1);\n\t\t\t\t\telse if (i.alongA === 0) // yes, somewhere between A's endpoints (exclusive)\n\t\t\t\t\t\teventDivide(ev2, i.pt);\n\t\t\t\t\telse if (i.alongA === 1) // yes, at exactly a2\n\t\t\t\t\t\teventDivide(ev2, a2);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t//\n\t\t// main event loop\n\t\t//\n\t\tvar segments = [];\n\t\twhile (!event_root.isEmpty()){\n\t\t\tvar ev = event_root.getHead();\n\n\t\t\tif (buildLog)\n\t\t\t\tbuildLog.vert(ev.pt[0]);\n\n\t\t\tif (ev.isStart){\n\n\t\t\t\tif (buildLog)\n\t\t\t\t\tbuildLog.segmentNew(ev.seg, ev.primary);\n\n\t\t\t\tvar surrounding = statusFindSurrounding(ev);\n\t\t\t\tvar above = surrounding.before ? surrounding.before.ev : null;\n\t\t\t\tvar below = surrounding.after ? surrounding.after.ev : null;\n\n\t\t\t\tif (buildLog){\n\t\t\t\t\tbuildLog.tempStatus(\n\t\t\t\t\t\tev.seg,\n\t\t\t\t\t\tabove ? above.seg : false,\n\t\t\t\t\t\tbelow ? below.seg : false\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tfunction checkBothIntersections(){\n\t\t\t\t\tif (above){\n\t\t\t\t\t\tvar eve = checkIntersection(ev, above);\n\t\t\t\t\t\tif (eve)\n\t\t\t\t\t\t\treturn eve;\n\t\t\t\t\t}\n\t\t\t\t\tif (below)\n\t\t\t\t\t\treturn checkIntersection(ev, below);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tvar eve = checkBothIntersections();\n\t\t\t\tif (eve){\n\t\t\t\t\t// ev and eve are equal\n\t\t\t\t\t// we'll keep eve and throw away ev\n\n\t\t\t\t\t// merge ev.seg's fill information into eve.seg\n\n\t\t\t\t\tif (selfIntersection){\n\t\t\t\t\t\tvar toggle; // are we a toggling edge?\n\t\t\t\t\t\tif (ev.seg.myFill.below === null)\n\t\t\t\t\t\t\ttoggle = true;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\ttoggle = ev.seg.myFill.above !== ev.seg.myFill.below;\n\n\t\t\t\t\t\t// merge two segments that belong to the same polygon\n\t\t\t\t\t\t// think of this as sandwiching two segments together, where `eve.seg` is\n\t\t\t\t\t\t// the bottom -- this will cause the above fill flag to toggle\n\t\t\t\t\t\tif (toggle)\n\t\t\t\t\t\t\teve.seg.myFill.above = !eve.seg.myFill.above;\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\t// merge two segments that belong to different polygons\n\t\t\t\t\t\t// each segment has distinct knowledge, so no special logic is needed\n\t\t\t\t\t\t// note that this can only happen once per segment in this phase, because we\n\t\t\t\t\t\t// are guaranteed that all self-intersections are gone\n\t\t\t\t\t\teve.seg.otherFill = ev.seg.myFill;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (buildLog)\n\t\t\t\t\t\tbuildLog.segmentUpdate(eve.seg);\n\n\t\t\t\t\tev.other.remove();\n\t\t\t\t\tev.remove();\n\t\t\t\t}\n\n\t\t\t\tif (event_root.getHead() !== ev){\n\t\t\t\t\t// something was inserted before us in the event queue, so loop back around and\n\t\t\t\t\t// process it before continuing\n\t\t\t\t\tif (buildLog)\n\t\t\t\t\t\tbuildLog.rewind(ev.seg);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t//\n\t\t\t\t// calculate fill flags\n\t\t\t\t//\n\t\t\t\tif (selfIntersection){\n\t\t\t\t\tvar toggle; // are we a toggling edge?\n\t\t\t\t\tif (ev.seg.myFill.below === null) // if we are a new segment...\n\t\t\t\t\t\ttoggle = true; // then we toggle\n\t\t\t\t\telse // we are a segment that has previous knowledge from a division\n\t\t\t\t\t\ttoggle = ev.seg.myFill.above !== ev.seg.myFill.below; // calculate toggle\n\n\t\t\t\t\t// next, calculate whether we are filled below us\n\t\t\t\t\tif (!below){ // if nothing is below us...\n\t\t\t\t\t\t// we are filled below us if the polygon is inverted\n\t\t\t\t\t\tev.seg.myFill.below = primaryPolyInverted;\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\t// otherwise, we know the answer -- it's the same if whatever is below\n\t\t\t\t\t\t// us is filled above it\n\t\t\t\t\t\tev.seg.myFill.below = below.seg.myFill.above;\n\t\t\t\t\t}\n\n\t\t\t\t\t// since now we know if we're filled below us, we can calculate whether\n\t\t\t\t\t// we're filled above us by applying toggle to whatever is below us\n\t\t\t\t\tif (toggle)\n\t\t\t\t\t\tev.seg.myFill.above = !ev.seg.myFill.below;\n\t\t\t\t\telse\n\t\t\t\t\t\tev.seg.myFill.above = ev.seg.myFill.below;\n\t\t\t\t}\n\t\t\t\telse{\n\t\t\t\t\t// now we fill in any missing transition information, since we are all-knowing\n\t\t\t\t\t// at this point\n\n\t\t\t\t\tif (ev.seg.otherFill === null){\n\t\t\t\t\t\t// if we don't have other information, then we need to figure out if we're\n\t\t\t\t\t\t// inside the other polygon\n\t\t\t\t\t\tvar inside;\n\t\t\t\t\t\tif (!below){\n\t\t\t\t\t\t\t// if nothing is below us, then we're inside if the other polygon is\n\t\t\t\t\t\t\t// inverted\n\t\t\t\t\t\t\tinside =\n\t\t\t\t\t\t\t\tev.primary ? secondaryPolyInverted : primaryPolyInverted;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse{ // otherwise, something is below us\n\t\t\t\t\t\t\t// so copy the below segment's other polygon's above\n\t\t\t\t\t\t\tif (ev.primary === below.primary)\n\t\t\t\t\t\t\t\tinside = below.seg.otherFill.above;\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tinside = below.seg.myFill.above;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tev.seg.otherFill = {\n\t\t\t\t\t\t\tabove: inside,\n\t\t\t\t\t\t\tbelow: inside\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (buildLog){\n\t\t\t\t\tbuildLog.status(\n\t\t\t\t\t\tev.seg,\n\t\t\t\t\t\tabove ? above.seg : false,\n\t\t\t\t\t\tbelow ? below.seg : false\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// insert the status and remember it for later removal\n\t\t\t\tev.other.status = surrounding.insert(LinkedList.node({ ev: ev }));\n\t\t\t}\n\t\t\telse{\n\t\t\t\tvar st = ev.status;\n\n\t\t\t\tif (st === null){\n\t\t\t\t\tthrow new Error('PolyBool: Zero-length segment detected; your epsilon is ' +\n\t\t\t\t\t\t'probably too small or too large');\n\t\t\t\t}\n\n\t\t\t\t// removing the status will create two new adjacent edges, so we'll need to check\n\t\t\t\t// for those\n\t\t\t\tif (status_root.exists(st.prev) && status_root.exists(st.next))\n\t\t\t\t\tcheckIntersection(st.prev.ev, st.next.ev);\n\n\t\t\t\tif (buildLog)\n\t\t\t\t\tbuildLog.statusRemove(st.ev.seg);\n\n\t\t\t\t// remove the status\n\t\t\t\tst.remove();\n\n\t\t\t\t// if we've reached this point, we've calculated everything there is to know, so\n\t\t\t\t// save the segment for reporting\n\t\t\t\tif (!ev.primary){\n\t\t\t\t\t// make sure `seg.myFill` actually points to the primary polygon though\n\t\t\t\t\tvar s = ev.seg.myFill;\n\t\t\t\t\tev.seg.myFill = ev.seg.otherFill;\n\t\t\t\t\tev.seg.otherFill = s;\n\t\t\t\t}\n\t\t\t\tsegments.push(ev.seg);\n\t\t\t}\n\n\t\t\t// remove the event and continue\n\t\t\tevent_root.getHead().remove();\n\t\t}\n\n\t\tif (buildLog)\n\t\t\tbuildLog.done();\n\n\t\treturn segments;\n\t}\n\n\t// return the appropriate API depending on what we're doing\n\tif (!selfIntersection){\n\t\t// performing combination of polygons, so only deal with already-processed segments\n\t\treturn {\n\t\t\tcalculate: function(segments1, inverted1, segments2, inverted2){\n\t\t\t\t// segmentsX come from the self-intersection API, or this API\n\t\t\t\t// invertedX is whether we treat that list of segments as an inverted polygon or not\n\t\t\t\t// returns segments that can be used for further operations\n\t\t\t\tsegments1.forEach(function(seg){\n\t\t\t\t\teventAddSegment(segmentCopy(seg.start, seg.end, seg), true);\n\t\t\t\t});\n\t\t\t\tsegments2.forEach(function(seg){\n\t\t\t\t\teventAddSegment(segmentCopy(seg.start, seg.end, seg), false);\n\t\t\t\t});\n\t\t\t\treturn calculate(inverted1, inverted2);\n\t\t\t}\n\t\t};\n\t}\n\n\t// otherwise, performing self-intersection, so deal with regions\n\treturn {\n\t\taddRegion: function(region){\n\t\t\t// regions are a list of points:\n\t\t\t// [ [0, 0], [100, 0], [50, 100] ]\n\t\t\t// you can add multiple regions before running calculate\n\t\t\tvar pt1;\n\t\t\tvar pt2 = region[region.length - 1];\n\t\t\tfor (var i = 0; i < region.length; i++){\n\t\t\t\tpt1 = pt2;\n\t\t\t\tpt2 = region[i];\n\n\t\t\t\tvar forward = eps.pointsCompare(pt1, pt2);\n\t\t\t\tif (forward === 0) // points are equal, so we have a zero-length segment\n\t\t\t\t\tcontinue; // just skip it\n\n\t\t\t\teventAddSegment(\n\t\t\t\t\tsegmentNew(\n\t\t\t\t\t\tforward < 0 ? pt1 : pt2,\n\t\t\t\t\t\tforward < 0 ? pt2 : pt1\n\t\t\t\t\t),\n\t\t\t\t\ttrue\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\tcalculate: function(inverted){\n\t\t\t// is the polygon inverted?\n\t\t\t// returns segments\n\t\t\treturn calculate(inverted, false);\n\t\t}\n\t};\n}\n\nmodule.exports = Intersecter;\n\n\n//# sourceURL=webpack:///./node_modules/polybooljs/lib/intersecter.js?");
-
-/***/ }),
-
-/***/ "./node_modules/polybooljs/lib/linked-list.js":
-/*!****************************************************!*\
- !*** ./node_modules/polybooljs/lib/linked-list.js ***!
- \****************************************************/
-/*! no static exports found */
-/***/ (function(module, exports) {
-
-eval("// (c) Copyright 2016, Sean Connelly (@voidqk), http://syntheti.cc\n// MIT License\n// Project Home: https://github.com/voidqk/polybooljs\n\n//\n// simple linked list implementation that allows you to traverse down nodes and save positions\n//\n\nvar LinkedList = {\n\tcreate: function(){\n\t\tvar my = {\n\t\t\troot: { root: true, next: null },\n\t\t\texists: function(node){\n\t\t\t\tif (node === null || node === my.root)\n\t\t\t\t\treturn false;\n\t\t\t\treturn true;\n\t\t\t},\n\t\t\tisEmpty: function(){\n\t\t\t\treturn my.root.next === null;\n\t\t\t},\n\t\t\tgetHead: function(){\n\t\t\t\treturn my.root.next;\n\t\t\t},\n\t\t\tinsertBefore: function(node, check){\n\t\t\t\tvar last = my.root;\n\t\t\t\tvar here = my.root.next;\n\t\t\t\twhile (here !== null){\n\t\t\t\t\tif (check(here)){\n\t\t\t\t\t\tnode.prev = here.prev;\n\t\t\t\t\t\tnode.next = here;\n\t\t\t\t\t\there.prev.next = node;\n\t\t\t\t\t\there.prev = node;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlast = here;\n\t\t\t\t\there = here.next;\n\t\t\t\t}\n\t\t\t\tlast.next = node;\n\t\t\t\tnode.prev = last;\n\t\t\t\tnode.next = null;\n\t\t\t},\n\t\t\tfindTransition: function(check){\n\t\t\t\tvar prev = my.root;\n\t\t\t\tvar here = my.root.next;\n\t\t\t\twhile (here !== null){\n\t\t\t\t\tif (check(here))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tprev = here;\n\t\t\t\t\there = here.next;\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tbefore: prev === my.root ? null : prev,\n\t\t\t\t\tafter: here,\n\t\t\t\t\tinsert: function(node){\n\t\t\t\t\t\tnode.prev = prev;\n\t\t\t\t\t\tnode.next = here;\n\t\t\t\t\t\tprev.next = node;\n\t\t\t\t\t\tif (here !== null)\n\t\t\t\t\t\t\there.prev = node;\n\t\t\t\t\t\treturn node;\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t};\n\t\treturn my;\n\t},\n\tnode: function(data){\n\t\tdata.prev = null;\n\t\tdata.next = null;\n\t\tdata.remove = function(){\n\t\t\tdata.prev.next = data.next;\n\t\t\tif (data.next)\n\t\t\t\tdata.next.prev = data.prev;\n\t\t\tdata.prev = null;\n\t\t\tdata.next = null;\n\t\t};\n\t\treturn data;\n\t}\n};\n\nmodule.exports = LinkedList;\n\n\n//# sourceURL=webpack:///./node_modules/polybooljs/lib/linked-list.js?");
-
-/***/ }),
-
-/***/ "./node_modules/polybooljs/lib/segment-chainer.js":
-/*!********************************************************!*\
- !*** ./node_modules/polybooljs/lib/segment-chainer.js ***!
- \********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports) {
-
-eval("// (c) Copyright 2016, Sean Connelly (@voidqk), http://syntheti.cc\n// MIT License\n// Project Home: https://github.com/voidqk/polybooljs\n\n//\n// converts a list of segments into a list of regions, while also removing unnecessary verticies\n//\n\nfunction SegmentChainer(segments, eps, buildLog){\n\tvar chains = [];\n\tvar regions = [];\n\n\tsegments.forEach(function(seg){\n\t\tvar pt1 = seg.start;\n\t\tvar pt2 = seg.end;\n\t\tif (eps.pointsSame(pt1, pt2)){\n\t\t\tconsole.warn('PolyBool: Warning: Zero-length segment detected; your epsilon is ' +\n\t\t\t\t'probably too small or too large');\n\t\t\treturn;\n\t\t}\n\n\t\tif (buildLog)\n\t\t\tbuildLog.chainStart(seg);\n\n\t\t// search for two chains that this segment matches\n\t\tvar first_match = {\n\t\t\tindex: 0,\n\t\t\tmatches_head: false,\n\t\t\tmatches_pt1: false\n\t\t};\n\t\tvar second_match = {\n\t\t\tindex: 0,\n\t\t\tmatches_head: false,\n\t\t\tmatches_pt1: false\n\t\t};\n\t\tvar next_match = first_match;\n\t\tfunction setMatch(index, matches_head, matches_pt1){\n\t\t\t// return true if we've matched twice\n\t\t\tnext_match.index = index;\n\t\t\tnext_match.matches_head = matches_head;\n\t\t\tnext_match.matches_pt1 = matches_pt1;\n\t\t\tif (next_match === first_match){\n\t\t\t\tnext_match = second_match;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tnext_match = null;\n\t\t\treturn true; // we've matched twice, we're done here\n\t\t}\n\t\tfor (var i = 0; i < chains.length; i++){\n\t\t\tvar chain = chains[i];\n\t\t\tvar head = chain[0];\n\t\t\tvar head2 = chain[1];\n\t\t\tvar tail = chain[chain.length - 1];\n\t\t\tvar tail2 = chain[chain.length - 2];\n\t\t\tif (eps.pointsSame(head, pt1)){\n\t\t\t\tif (setMatch(i, true, true))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (eps.pointsSame(head, pt2)){\n\t\t\t\tif (setMatch(i, true, false))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (eps.pointsSame(tail, pt1)){\n\t\t\t\tif (setMatch(i, false, true))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (eps.pointsSame(tail, pt2)){\n\t\t\t\tif (setMatch(i, false, false))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (next_match === first_match){\n\t\t\t// we didn't match anything, so create a new chain\n\t\t\tchains.push([ pt1, pt2 ]);\n\t\t\tif (buildLog)\n\t\t\t\tbuildLog.chainNew(pt1, pt2);\n\t\t\treturn;\n\t\t}\n\n\t\tif (next_match === second_match){\n\t\t\t// we matched a single chain\n\n\t\t\tif (buildLog)\n\t\t\t\tbuildLog.chainMatch(first_match.index);\n\n\t\t\t// add the other point to the apporpriate end, and check to see if we've closed the\n\t\t\t// chain into a loop\n\n\t\t\tvar index = first_match.index;\n\t\t\tvar pt = first_match.matches_pt1 ? pt2 : pt1; // if we matched pt1, then we add pt2, etc\n\t\t\tvar addToHead = first_match.matches_head; // if we matched at head, then add to the head\n\n\t\t\tvar chain = chains[index];\n\t\t\tvar grow = addToHead ? chain[0] : chain[chain.length - 1];\n\t\t\tvar grow2 = addToHead ? chain[1] : chain[chain.length - 2];\n\t\t\tvar oppo = addToHead ? chain[chain.length - 1] : chain[0];\n\t\t\tvar oppo2 = addToHead ? chain[chain.length - 2] : chain[1];\n\n\t\t\tif (eps.pointsCollinear(grow2, grow, pt)){\n\t\t\t\t// grow isn't needed because it's directly between grow2 and pt:\n\t\t\t\t// grow2 ---grow---> pt\n\t\t\t\tif (addToHead){\n\t\t\t\t\tif (buildLog)\n\t\t\t\t\t\tbuildLog.chainRemoveHead(first_match.index, pt);\n\t\t\t\t\tchain.shift();\n\t\t\t\t}\n\t\t\t\telse{\n\t\t\t\t\tif (buildLog)\n\t\t\t\t\t\tbuildLog.chainRemoveTail(first_match.index, pt);\n\t\t\t\t\tchain.pop();\n\t\t\t\t}\n\t\t\t\tgrow = grow2; // old grow is gone... new grow is what grow2 was\n\t\t\t}\n\n\t\t\tif (eps.pointsSame(oppo, pt)){\n\t\t\t\t// we're closing the loop, so remove chain from chains\n\t\t\t\tchains.splice(index, 1);\n\n\t\t\t\tif (eps.pointsCollinear(oppo2, oppo, grow)){\n\t\t\t\t\t// oppo isn't needed because it's directly between oppo2 and grow:\n\t\t\t\t\t// oppo2 ---oppo--->grow\n\t\t\t\t\tif (addToHead){\n\t\t\t\t\t\tif (buildLog)\n\t\t\t\t\t\t\tbuildLog.chainRemoveTail(first_match.index, grow);\n\t\t\t\t\t\tchain.pop();\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\tif (buildLog)\n\t\t\t\t\t\t\tbuildLog.chainRemoveHead(first_match.index, grow);\n\t\t\t\t\t\tchain.shift();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (buildLog)\n\t\t\t\t\tbuildLog.chainClose(first_match.index);\n\n\t\t\t\t// we have a closed chain!\n\t\t\t\tregions.push(chain);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// not closing a loop, so just add it to the apporpriate side\n\t\t\tif (addToHead){\n\t\t\t\tif (buildLog)\n\t\t\t\t\tbuildLog.chainAddHead(first_match.index, pt);\n\t\t\t\tchain.unshift(pt);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tif (buildLog)\n\t\t\t\t\tbuildLog.chainAddTail(first_match.index, pt);\n\t\t\t\tchain.push(pt);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// otherwise, we matched two chains, so we need to combine those chains together\n\n\t\tfunction reverseChain(index){\n\t\t\tif (buildLog)\n\t\t\t\tbuildLog.chainReverse(index);\n\t\t\tchains[index].reverse(); // gee, that's easy\n\t\t}\n\n\t\tfunction appendChain(index1, index2){\n\t\t\t// index1 gets index2 appended to it, and index2 is removed\n\t\t\tvar chain1 = chains[index1];\n\t\t\tvar chain2 = chains[index2];\n\t\t\tvar tail = chain1[chain1.length - 1];\n\t\t\tvar tail2 = chain1[chain1.length - 2];\n\t\t\tvar head = chain2[0];\n\t\t\tvar head2 = chain2[1];\n\n\t\t\tif (eps.pointsCollinear(tail2, tail, head)){\n\t\t\t\t// tail isn't needed because it's directly between tail2 and head\n\t\t\t\t// tail2 ---tail---> head\n\t\t\t\tif (buildLog)\n\t\t\t\t\tbuildLog.chainRemoveTail(index1, tail);\n\t\t\t\tchain1.pop();\n\t\t\t\ttail = tail2; // old tail is gone... new tail is what tail2 was\n\t\t\t}\n\n\t\t\tif (eps.pointsCollinear(tail, head, head2)){\n\t\t\t\t// head isn't needed because it's directly between tail and head2\n\t\t\t\t// tail ---head---> head2\n\t\t\t\tif (buildLog)\n\t\t\t\t\tbuildLog.chainRemoveHead(index2, head);\n\t\t\t\tchain2.shift();\n\t\t\t}\n\n\t\t\tif (buildLog)\n\t\t\t\tbuildLog.chainJoin(index1, index2);\n\t\t\tchains[index1] = chain1.concat(chain2);\n\t\t\tchains.splice(index2, 1);\n\t\t}\n\n\t\tvar F = first_match.index;\n\t\tvar S = second_match.index;\n\n\t\tif (buildLog)\n\t\t\tbuildLog.chainConnect(F, S);\n\n\t\tvar reverseF = chains[F].length < chains[S].length; // reverse the shorter chain, if needed\n\t\tif (first_match.matches_head){\n\t\t\tif (second_match.matches_head){\n\t\t\t\tif (reverseF){\n\t\t\t\t\t// <<<< F <<<< --- >>>> S >>>>\n\t\t\t\t\treverseChain(F);\n\t\t\t\t\t// >>>> F >>>> --- >>>> S >>>>\n\t\t\t\t\tappendChain(F, S);\n\t\t\t\t}\n\t\t\t\telse{\n\t\t\t\t\t// <<<< F <<<< --- >>>> S >>>>\n\t\t\t\t\treverseChain(S);\n\t\t\t\t\t// <<<< F <<<< --- <<<< S <<<< logically same as:\n\t\t\t\t\t// >>>> S >>>> --- >>>> F >>>>\n\t\t\t\t\tappendChain(S, F);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse{\n\t\t\t\t// <<<< F <<<< --- <<<< S <<<< logically same as:\n\t\t\t\t// >>>> S >>>> --- >>>> F >>>>\n\t\t\t\tappendChain(S, F);\n\t\t\t}\n\t\t}\n\t\telse{\n\t\t\tif (second_match.matches_head){\n\t\t\t\t// >>>> F >>>> --- >>>> S >>>>\n\t\t\t\tappendChain(F, S);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tif (reverseF){\n\t\t\t\t\t// >>>> F >>>> --- <<<< S <<<<\n\t\t\t\t\treverseChain(F);\n\t\t\t\t\t// <<<< F <<<< --- <<<< S <<<< logically same as:\n\t\t\t\t\t// >>>> S >>>> --- >>>> F >>>>\n\t\t\t\t\tappendChain(S, F);\n\t\t\t\t}\n\t\t\t\telse{\n\t\t\t\t\t// >>>> F >>>> --- <<<< S <<<<\n\t\t\t\t\treverseChain(S);\n\t\t\t\t\t// >>>> F >>>> --- >>>> S >>>>\n\t\t\t\t\tappendChain(F, S);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\treturn regions;\n}\n\nmodule.exports = SegmentChainer;\n\n\n//# sourceURL=webpack:///./node_modules/polybooljs/lib/segment-chainer.js?");
-
-/***/ }),
-
-/***/ "./node_modules/polybooljs/lib/segment-selector.js":
-/*!*********************************************************!*\
- !*** ./node_modules/polybooljs/lib/segment-selector.js ***!
- \*********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports) {
-
-eval("// (c) Copyright 2016, Sean Connelly (@voidqk), http://syntheti.cc\n// MIT License\n// Project Home: https://github.com/voidqk/polybooljs\n\n//\n// filter a list of segments based on boolean operations\n//\n\nfunction select(segments, selection, buildLog){\n\tvar result = [];\n\tsegments.forEach(function(seg){\n\t\tvar index =\n\t\t\t(seg.myFill.above ? 8 : 0) +\n\t\t\t(seg.myFill.below ? 4 : 0) +\n\t\t\t((seg.otherFill && seg.otherFill.above) ? 2 : 0) +\n\t\t\t((seg.otherFill && seg.otherFill.below) ? 1 : 0);\n\t\tif (selection[index] !== 0){\n\t\t\t// copy the segment to the results, while also calculating the fill status\n\t\t\tresult.push({\n\t\t\t\tid: buildLog ? buildLog.segmentId() : -1,\n\t\t\t\tstart: seg.start,\n\t\t\t\tend: seg.end,\n\t\t\t\tmyFill: {\n\t\t\t\t\tabove: selection[index] === 1, // 1 if filled above\n\t\t\t\t\tbelow: selection[index] === 2 // 2 if filled below\n\t\t\t\t},\n\t\t\t\totherFill: null\n\t\t\t});\n\t\t}\n\t});\n\n\tif (buildLog)\n\t\tbuildLog.selected(result);\n\n\treturn result;\n}\n\nvar SegmentSelector = {\n\tunion: function(segments, buildLog){ // primary | secondary\n\t\t// above1 below1 above2 below2 Keep? Value\n\t\t// 0 0 0 0 => no 0\n\t\t// 0 0 0 1 => yes filled below 2\n\t\t// 0 0 1 0 => yes filled above 1\n\t\t// 0 0 1 1 => no 0\n\t\t// 0 1 0 0 => yes filled below 2\n\t\t// 0 1 0 1 => yes filled below 2\n\t\t// 0 1 1 0 => no 0\n\t\t// 0 1 1 1 => no 0\n\t\t// 1 0 0 0 => yes filled above 1\n\t\t// 1 0 0 1 => no 0\n\t\t// 1 0 1 0 => yes filled above 1\n\t\t// 1 0 1 1 => no 0\n\t\t// 1 1 0 0 => no 0\n\t\t// 1 1 0 1 => no 0\n\t\t// 1 1 1 0 => no 0\n\t\t// 1 1 1 1 => no 0\n\t\treturn select(segments, [\n\t\t\t0, 2, 1, 0,\n\t\t\t2, 2, 0, 0,\n\t\t\t1, 0, 1, 0,\n\t\t\t0, 0, 0, 0\n\t\t], buildLog);\n\t},\n\tintersect: function(segments, buildLog){ // primary & secondary\n\t\t// above1 below1 above2 below2 Keep? Value\n\t\t// 0 0 0 0 => no 0\n\t\t// 0 0 0 1 => no 0\n\t\t// 0 0 1 0 => no 0\n\t\t// 0 0 1 1 => no 0\n\t\t// 0 1 0 0 => no 0\n\t\t// 0 1 0 1 => yes filled below 2\n\t\t// 0 1 1 0 => no 0\n\t\t// 0 1 1 1 => yes filled below 2\n\t\t// 1 0 0 0 => no 0\n\t\t// 1 0 0 1 => no 0\n\t\t// 1 0 1 0 => yes filled above 1\n\t\t// 1 0 1 1 => yes filled above 1\n\t\t// 1 1 0 0 => no 0\n\t\t// 1 1 0 1 => yes filled below 2\n\t\t// 1 1 1 0 => yes filled above 1\n\t\t// 1 1 1 1 => no 0\n\t\treturn select(segments, [\n\t\t\t0, 0, 0, 0,\n\t\t\t0, 2, 0, 2,\n\t\t\t0, 0, 1, 1,\n\t\t\t0, 2, 1, 0\n\t\t], buildLog);\n\t},\n\tdifference: function(segments, buildLog){ // primary - secondary\n\t\t// above1 below1 above2 below2 Keep? Value\n\t\t// 0 0 0 0 => no 0\n\t\t// 0 0 0 1 => no 0\n\t\t// 0 0 1 0 => no 0\n\t\t// 0 0 1 1 => no 0\n\t\t// 0 1 0 0 => yes filled below 2\n\t\t// 0 1 0 1 => no 0\n\t\t// 0 1 1 0 => yes filled below 2\n\t\t// 0 1 1 1 => no 0\n\t\t// 1 0 0 0 => yes filled above 1\n\t\t// 1 0 0 1 => yes filled above 1\n\t\t// 1 0 1 0 => no 0\n\t\t// 1 0 1 1 => no 0\n\t\t// 1 1 0 0 => no 0\n\t\t// 1 1 0 1 => yes filled above 1\n\t\t// 1 1 1 0 => yes filled below 2\n\t\t// 1 1 1 1 => no 0\n\t\treturn select(segments, [\n\t\t\t0, 0, 0, 0,\n\t\t\t2, 0, 2, 0,\n\t\t\t1, 1, 0, 0,\n\t\t\t0, 1, 2, 0\n\t\t], buildLog);\n\t},\n\tdifferenceRev: function(segments, buildLog){ // secondary - primary\n\t\t// above1 below1 above2 below2 Keep? Value\n\t\t// 0 0 0 0 => no 0\n\t\t// 0 0 0 1 => yes filled below 2\n\t\t// 0 0 1 0 => yes filled above 1\n\t\t// 0 0 1 1 => no 0\n\t\t// 0 1 0 0 => no 0\n\t\t// 0 1 0 1 => no 0\n\t\t// 0 1 1 0 => yes filled above 1\n\t\t// 0 1 1 1 => yes filled above 1\n\t\t// 1 0 0 0 => no 0\n\t\t// 1 0 0 1 => yes filled below 2\n\t\t// 1 0 1 0 => no 0\n\t\t// 1 0 1 1 => yes filled below 2\n\t\t// 1 1 0 0 => no 0\n\t\t// 1 1 0 1 => no 0\n\t\t// 1 1 1 0 => no 0\n\t\t// 1 1 1 1 => no 0\n\t\treturn select(segments, [\n\t\t\t0, 2, 1, 0,\n\t\t\t0, 0, 1, 1,\n\t\t\t0, 2, 0, 2,\n\t\t\t0, 0, 0, 0\n\t\t], buildLog);\n\t},\n\txor: function(segments, buildLog){ // primary ^ secondary\n\t\t// above1 below1 above2 below2 Keep? Value\n\t\t// 0 0 0 0 => no 0\n\t\t// 0 0 0 1 => yes filled below 2\n\t\t// 0 0 1 0 => yes filled above 1\n\t\t// 0 0 1 1 => no 0\n\t\t// 0 1 0 0 => yes filled below 2\n\t\t// 0 1 0 1 => no 0\n\t\t// 0 1 1 0 => no 0\n\t\t// 0 1 1 1 => yes filled above 1\n\t\t// 1 0 0 0 => yes filled above 1\n\t\t// 1 0 0 1 => no 0\n\t\t// 1 0 1 0 => no 0\n\t\t// 1 0 1 1 => yes filled below 2\n\t\t// 1 1 0 0 => no 0\n\t\t// 1 1 0 1 => yes filled above 1\n\t\t// 1 1 1 0 => yes filled below 2\n\t\t// 1 1 1 1 => no 0\n\t\treturn select(segments, [\n\t\t\t0, 2, 1, 0,\n\t\t\t2, 0, 0, 1,\n\t\t\t1, 0, 0, 2,\n\t\t\t0, 1, 2, 0\n\t\t], buildLog);\n\t}\n};\n\nmodule.exports = SegmentSelector;\n\n\n//# sourceURL=webpack:///./node_modules/polybooljs/lib/segment-selector.js?");
-
-/***/ }),
-
-/***/ "./node_modules/polytope-closest-point/lib/closest_point_2d.js":
-/*!*********************************************************************!*\
- !*** ./node_modules/polytope-closest-point/lib/closest_point_2d.js ***!
- \*********************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("//Optimized version for triangle closest point\n// Based on Eberly's WildMagick codes\n// http://www.geometrictools.com/LibMathematics/Distance/Distance.html\n\n\nvar diff = new Float64Array(4);\nvar edge0 = new Float64Array(4);\nvar edge1 = new Float64Array(4);\n\nfunction closestPoint2d(V0, V1, V2, point, result) {\n //Reallocate buffers if necessary\n if(diff.length < point.length) {\n diff = new Float64Array(point.length);\n edge0 = new Float64Array(point.length);\n edge1 = new Float64Array(point.length);\n }\n //Compute edges\n for(var i=0; i= a00) {\n s = 1.0;\n sqrDistance = a00 + 2.0*b0 + c;\n } else {\n s = -b0/a00;\n sqrDistance = b0*s + c;\n }\n } else {\n s = 0;\n if (b1 >= 0) {\n t = 0;\n sqrDistance = c;\n } else if (-b1 >= a11) {\n t = 1;\n sqrDistance = a11 + 2.0*b1 + c;\n } else {\n t = -b1/a11;\n sqrDistance = b1*t + c;\n }\n }\n } else { // region 3\n s = 0;\n if (b1 >= 0) {\n t = 0;\n sqrDistance = c;\n } else if (-b1 >= a11) {\n t = 1;\n sqrDistance = a11 + 2.0*b1 + c;\n } else {\n t = -b1/a11;\n sqrDistance = b1*t + c;\n }\n }\n } else if (t < 0) { // region 5\n t = 0;\n if (b0 >= 0) {\n s = 0;\n sqrDistance = c;\n } else if (-b0 >= a00) {\n s = 1;\n sqrDistance = a00 + 2.0*b0 + c;\n } else {\n s = -b0/a00;\n sqrDistance = b0*s + c;\n }\n } else { // region 0\n // minimum at interior point\n var invDet = 1.0 / det;\n s *= invDet;\n t *= invDet;\n sqrDistance = s*(a00*s + a01*t + 2.0*b0) + t*(a01*s + a11*t + 2.0*b1) + c;\n }\n } else {\n var tmp0, tmp1, numer, denom;\n \n if (s < 0) { // region 2\n tmp0 = a01 + b0;\n tmp1 = a11 + b1;\n if (tmp1 > tmp0) {\n numer = tmp1 - tmp0;\n denom = a00 - 2.0*a01 + a11;\n if (numer >= denom) {\n s = 1;\n t = 0;\n sqrDistance = a00 + 2.0*b0 + c;\n } else {\n s = numer/denom;\n t = 1 - s;\n sqrDistance = s*(a00*s + a01*t + 2.0*b0) +\n t*(a01*s + a11*t + 2.0*b1) + c;\n }\n } else {\n s = 0;\n if (tmp1 <= 0) {\n t = 1;\n sqrDistance = a11 + 2.0*b1 + c;\n } else if (b1 >= 0) {\n t = 0;\n sqrDistance = c;\n } else {\n t = -b1/a11;\n sqrDistance = b1*t + c;\n }\n }\n } else if (t < 0) { // region 6\n tmp0 = a01 + b1;\n tmp1 = a00 + b0;\n if (tmp1 > tmp0) {\n numer = tmp1 - tmp0;\n denom = a00 - 2.0*a01 + a11;\n if (numer >= denom) {\n t = 1;\n s = 0;\n sqrDistance = a11 + 2.0*b1 + c;\n } else {\n t = numer/denom;\n s = 1 - t;\n sqrDistance = s*(a00*s + a01*t + 2.0*b0) +\n t*(a01*s + a11*t + 2.0*b1) + c;\n }\n } else {\n t = 0;\n if (tmp1 <= 0) {\n s = 1;\n sqrDistance = a00 + 2.0*b0 + c;\n } else if (b0 >= 0) {\n s = 0;\n sqrDistance = c;\n } else {\n s = -b0/a00;\n sqrDistance = b0*s + c;\n }\n }\n } else { // region 1\n numer = a11 + b1 - a01 - b0;\n if (numer <= 0) {\n s = 0;\n t = 1;\n sqrDistance = a11 + 2.0*b1 + c;\n } else {\n denom = a00 - 2.0*a01 + a11;\n if (numer >= denom) {\n s = 1;\n t = 0;\n sqrDistance = a00 + 2.0*b0 + c;\n } else {\n s = numer/denom;\n t = 1 - s;\n sqrDistance = s*(a00*s + a01*t + 2.0*b0) +\n t*(a01*s + a11*t + 2.0*b1) + c;\n }\n }\n }\n }\n var u = 1.0 - s - t;\n for(var i=0; i indentString(stripIndent(str), count || 0, indent);\n\n\n//# sourceURL=webpack:///./node_modules/redent/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/reduce-simplicial-complex/reduce.js":
-/*!**********************************************************!*\
- !*** ./node_modules/reduce-simplicial-complex/reduce.js ***!
- \**********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nvar compareCell = __webpack_require__(/*! compare-cell */ \"./node_modules/compare-cell/compare.js\")\nvar compareOrientedCell = __webpack_require__(/*! compare-oriented-cell */ \"./node_modules/compare-oriented-cell/compare.js\")\nvar orientation = __webpack_require__(/*! cell-orientation */ \"./node_modules/cell-orientation/orientation.js\")\n\nmodule.exports = reduceCellComplex\n\nfunction reduceCellComplex(cells) {\n cells.sort(compareOrientedCell)\n var n = cells.length\n var ptr = 0\n for(var i=0; i 0) {\n var f = cells[ptr-1]\n if(compareCell(c, f) === 0 &&\n orientation(f) !== o) {\n ptr -= 1\n continue\n }\n }\n cells[ptr++] = c\n }\n cells.length = ptr\n return cells\n}\n\n\n//# sourceURL=webpack:///./node_modules/reduce-simplicial-complex/reduce.js?");
-
-/***/ }),
-
-/***/ "./node_modules/regenerator-runtime/runtime.js":
-/*!*****************************************************!*\
- !*** ./node_modules/regenerator-runtime/runtime.js ***!
- \*****************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-eval("/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nvar runtime = (function (exports) {\n \"use strict\";\n\n var Op = Object.prototype;\n var hasOwn = Op.hasOwnProperty;\n var undefined; // More compressible than void 0.\n var $Symbol = typeof Symbol === \"function\" ? Symbol : {};\n var iteratorSymbol = $Symbol.iterator || \"@@iterator\";\n var asyncIteratorSymbol = $Symbol.asyncIterator || \"@@asyncIterator\";\n var toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n function wrap(innerFn, outerFn, self, tryLocsList) {\n // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.\n var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;\n var generator = Object.create(protoGenerator.prototype);\n var context = new Context(tryLocsList || []);\n\n // The ._invoke method unifies the implementations of the .next,\n // .throw, and .return methods.\n generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n return generator;\n }\n exports.wrap = wrap;\n\n // Try/catch helper to minimize deoptimizations. Returns a completion\n // record like context.tryEntries[i].completion. This interface could\n // have been (and was previously) designed to take a closure to be\n // invoked without arguments, but in all the cases we care about we\n // already have an existing method we want to call, so there's no need\n // to create a new function object. We can even get away with assuming\n // the method takes exactly one argument, since that happens to be true\n // in every case, so we don't have to touch the arguments object. The\n // only additional allocation required is the completion record, which\n // has a stable shape and so hopefully should be cheap to allocate.\n function tryCatch(fn, obj, arg) {\n try {\n return { type: \"normal\", arg: fn.call(obj, arg) };\n } catch (err) {\n return { type: \"throw\", arg: err };\n }\n }\n\n var GenStateSuspendedStart = \"suspendedStart\";\n var GenStateSuspendedYield = \"suspendedYield\";\n var GenStateExecuting = \"executing\";\n var GenStateCompleted = \"completed\";\n\n // Returning this object from the innerFn has the same effect as\n // breaking out of the dispatch switch statement.\n var ContinueSentinel = {};\n\n // Dummy constructor functions that we use as the .constructor and\n // .constructor.prototype properties for functions that return Generator\n // objects. For full spec compliance, you may wish to configure your\n // minifier not to mangle the names of these two functions.\n function Generator() {}\n function GeneratorFunction() {}\n function GeneratorFunctionPrototype() {}\n\n // This is a polyfill for %IteratorPrototype% for environments that\n // don't natively support it.\n var IteratorPrototype = {};\n IteratorPrototype[iteratorSymbol] = function () {\n return this;\n };\n\n var getProto = Object.getPrototypeOf;\n var NativeIteratorPrototype = getProto && getProto(getProto(values([])));\n if (NativeIteratorPrototype &&\n NativeIteratorPrototype !== Op &&\n hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {\n // This environment has a native %IteratorPrototype%; use it instead\n // of the polyfill.\n IteratorPrototype = NativeIteratorPrototype;\n }\n\n var Gp = GeneratorFunctionPrototype.prototype =\n Generator.prototype = Object.create(IteratorPrototype);\n GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;\n GeneratorFunctionPrototype.constructor = GeneratorFunction;\n GeneratorFunctionPrototype[toStringTagSymbol] =\n GeneratorFunction.displayName = \"GeneratorFunction\";\n\n // Helper for defining the .next, .throw, and .return methods of the\n // Iterator interface in terms of a single ._invoke method.\n function defineIteratorMethods(prototype) {\n [\"next\", \"throw\", \"return\"].forEach(function(method) {\n prototype[method] = function(arg) {\n return this._invoke(method, arg);\n };\n });\n }\n\n exports.isGeneratorFunction = function(genFun) {\n var ctor = typeof genFun === \"function\" && genFun.constructor;\n return ctor\n ? ctor === GeneratorFunction ||\n // For the native GeneratorFunction constructor, the best we can\n // do is to check its .name property.\n (ctor.displayName || ctor.name) === \"GeneratorFunction\"\n : false;\n };\n\n exports.mark = function(genFun) {\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);\n } else {\n genFun.__proto__ = GeneratorFunctionPrototype;\n if (!(toStringTagSymbol in genFun)) {\n genFun[toStringTagSymbol] = \"GeneratorFunction\";\n }\n }\n genFun.prototype = Object.create(Gp);\n return genFun;\n };\n\n // Within the body of any async function, `await x` is transformed to\n // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test\n // `hasOwn.call(value, \"__await\")` to determine if the yielded value is\n // meant to be awaited.\n exports.awrap = function(arg) {\n return { __await: arg };\n };\n\n function AsyncIterator(generator) {\n function invoke(method, arg, resolve, reject) {\n var record = tryCatch(generator[method], generator, arg);\n if (record.type === \"throw\") {\n reject(record.arg);\n } else {\n var result = record.arg;\n var value = result.value;\n if (value &&\n typeof value === \"object\" &&\n hasOwn.call(value, \"__await\")) {\n return Promise.resolve(value.__await).then(function(value) {\n invoke(\"next\", value, resolve, reject);\n }, function(err) {\n invoke(\"throw\", err, resolve, reject);\n });\n }\n\n return Promise.resolve(value).then(function(unwrapped) {\n // When a yielded Promise is resolved, its final value becomes\n // the .value of the Promise<{value,done}> result for the\n // current iteration.\n result.value = unwrapped;\n resolve(result);\n }, function(error) {\n // If a rejected Promise was yielded, throw the rejection back\n // into the async generator function so it can be handled there.\n return invoke(\"throw\", error, resolve, reject);\n });\n }\n }\n\n var previousPromise;\n\n function enqueue(method, arg) {\n function callInvokeWithMethodAndArg() {\n return new Promise(function(resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise =\n // If enqueue has been called before, then we want to wait until\n // all previous Promises have been resolved before calling invoke,\n // so that results are always delivered in the correct order. If\n // enqueue has not been called before, then it is important to\n // call invoke immediately, without waiting on a callback to fire,\n // so that the async generator function has the opportunity to do\n // any necessary setup in a predictable way. This predictability\n // is why the Promise constructor synchronously invokes its\n // executor callback, and why async functions synchronously\n // execute code before the first await. Since we implement simple\n // async functions in terms of async generators, it is especially\n // important to get this right, even though it requires care.\n previousPromise ? previousPromise.then(\n callInvokeWithMethodAndArg,\n // Avoid propagating failures to Promises returned by later\n // invocations of the iterator.\n callInvokeWithMethodAndArg\n ) : callInvokeWithMethodAndArg();\n }\n\n // Define the unified helper method that is used to implement .next,\n // .throw, and .return (see defineIteratorMethods).\n this._invoke = enqueue;\n }\n\n defineIteratorMethods(AsyncIterator.prototype);\n AsyncIterator.prototype[asyncIteratorSymbol] = function () {\n return this;\n };\n exports.AsyncIterator = AsyncIterator;\n\n // Note that simple async functions are implemented on top of\n // AsyncIterator objects; they just return a Promise for the value of\n // the final result produced by the iterator.\n exports.async = function(innerFn, outerFn, self, tryLocsList) {\n var iter = new AsyncIterator(\n wrap(innerFn, outerFn, self, tryLocsList)\n );\n\n return exports.isGeneratorFunction(outerFn)\n ? iter // If outerFn is a generator, return the full iterator.\n : iter.next().then(function(result) {\n return result.done ? result.value : iter.next();\n });\n };\n\n function makeInvokeMethod(innerFn, self, context) {\n var state = GenStateSuspendedStart;\n\n return function invoke(method, arg) {\n if (state === GenStateExecuting) {\n throw new Error(\"Generator is already running\");\n }\n\n if (state === GenStateCompleted) {\n if (method === \"throw\") {\n throw arg;\n }\n\n // Be forgiving, per 25.3.3.3.3 of the spec:\n // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n return doneResult();\n }\n\n context.method = method;\n context.arg = arg;\n\n while (true) {\n var delegate = context.delegate;\n if (delegate) {\n var delegateResult = maybeInvokeDelegate(delegate, context);\n if (delegateResult) {\n if (delegateResult === ContinueSentinel) continue;\n return delegateResult;\n }\n }\n\n if (context.method === \"next\") {\n // Setting context._sent for legacy support of Babel's\n // function.sent implementation.\n context.sent = context._sent = context.arg;\n\n } else if (context.method === \"throw\") {\n if (state === GenStateSuspendedStart) {\n state = GenStateCompleted;\n throw context.arg;\n }\n\n context.dispatchException(context.arg);\n\n } else if (context.method === \"return\") {\n context.abrupt(\"return\", context.arg);\n }\n\n state = GenStateExecuting;\n\n var record = tryCatch(innerFn, self, context);\n if (record.type === \"normal\") {\n // If an exception is thrown from innerFn, we leave state ===\n // GenStateExecuting and loop back for another invocation.\n state = context.done\n ? GenStateCompleted\n : GenStateSuspendedYield;\n\n if (record.arg === ContinueSentinel) {\n continue;\n }\n\n return {\n value: record.arg,\n done: context.done\n };\n\n } else if (record.type === \"throw\") {\n state = GenStateCompleted;\n // Dispatch the exception by looping back around to the\n // context.dispatchException(context.arg) call above.\n context.method = \"throw\";\n context.arg = record.arg;\n }\n }\n };\n }\n\n // Call delegate.iterator[context.method](context.arg) and handle the\n // result, either by returning a { value, done } result from the\n // delegate iterator, or by modifying context.method and context.arg,\n // setting context.delegate to null, and returning the ContinueSentinel.\n function maybeInvokeDelegate(delegate, context) {\n var method = delegate.iterator[context.method];\n if (method === undefined) {\n // A .throw or .return when the delegate iterator has no .throw\n // method always terminates the yield* loop.\n context.delegate = null;\n\n if (context.method === \"throw\") {\n // Note: [\"return\"] must be used for ES3 parsing compatibility.\n if (delegate.iterator[\"return\"]) {\n // If the delegate iterator has a return method, give it a\n // chance to clean up.\n context.method = \"return\";\n context.arg = undefined;\n maybeInvokeDelegate(delegate, context);\n\n if (context.method === \"throw\") {\n // If maybeInvokeDelegate(context) changed context.method from\n // \"return\" to \"throw\", let that override the TypeError below.\n return ContinueSentinel;\n }\n }\n\n context.method = \"throw\";\n context.arg = new TypeError(\n \"The iterator does not provide a 'throw' method\");\n }\n\n return ContinueSentinel;\n }\n\n var record = tryCatch(method, delegate.iterator, context.arg);\n\n if (record.type === \"throw\") {\n context.method = \"throw\";\n context.arg = record.arg;\n context.delegate = null;\n return ContinueSentinel;\n }\n\n var info = record.arg;\n\n if (! info) {\n context.method = \"throw\";\n context.arg = new TypeError(\"iterator result is not an object\");\n context.delegate = null;\n return ContinueSentinel;\n }\n\n if (info.done) {\n // Assign the result of the finished delegate to the temporary\n // variable specified by delegate.resultName (see delegateYield).\n context[delegate.resultName] = info.value;\n\n // Resume execution at the desired location (see delegateYield).\n context.next = delegate.nextLoc;\n\n // If context.method was \"throw\" but the delegate handled the\n // exception, let the outer generator proceed normally. If\n // context.method was \"next\", forget context.arg since it has been\n // \"consumed\" by the delegate iterator. If context.method was\n // \"return\", allow the original .return call to continue in the\n // outer generator.\n if (context.method !== \"return\") {\n context.method = \"next\";\n context.arg = undefined;\n }\n\n } else {\n // Re-yield the result returned by the delegate method.\n return info;\n }\n\n // The delegate iterator is finished, so forget it and continue with\n // the outer generator.\n context.delegate = null;\n return ContinueSentinel;\n }\n\n // Define Generator.prototype.{next,throw,return} in terms of the\n // unified ._invoke helper method.\n defineIteratorMethods(Gp);\n\n Gp[toStringTagSymbol] = \"Generator\";\n\n // A Generator should always return itself as the iterator object when the\n // @@iterator function is called on it. Some browsers' implementations of the\n // iterator prototype chain incorrectly implement this, causing the Generator\n // object to not be returned from this call. This ensures that doesn't happen.\n // See https://github.com/facebook/regenerator/issues/274 for more details.\n Gp[iteratorSymbol] = function() {\n return this;\n };\n\n Gp.toString = function() {\n return \"[object Generator]\";\n };\n\n function pushTryEntry(locs) {\n var entry = { tryLoc: locs[0] };\n\n if (1 in locs) {\n entry.catchLoc = locs[1];\n }\n\n if (2 in locs) {\n entry.finallyLoc = locs[2];\n entry.afterLoc = locs[3];\n }\n\n this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = \"normal\";\n delete record.arg;\n entry.completion = record;\n }\n\n function Context(tryLocsList) {\n // The root entry object (effectively a try statement without a catch\n // or a finally block) gives us a place to store values thrown from\n // locations where there is no enclosing try statement.\n this.tryEntries = [{ tryLoc: \"root\" }];\n tryLocsList.forEach(pushTryEntry, this);\n this.reset(true);\n }\n\n exports.keys = function(object) {\n var keys = [];\n for (var key in object) {\n keys.push(key);\n }\n keys.reverse();\n\n // Rather than returning an object with a next method, we keep\n // things simple and return the next function itself.\n return function next() {\n while (keys.length) {\n var key = keys.pop();\n if (key in object) {\n next.value = key;\n next.done = false;\n return next;\n }\n }\n\n // To avoid creating an additional object, we just hang the .value\n // and .done properties off the next function object itself. This\n // also ensures that the minifier will not anonymize the function.\n next.done = true;\n return next;\n };\n };\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) {\n return iteratorMethod.call(iterable);\n }\n\n if (typeof iterable.next === \"function\") {\n return iterable;\n }\n\n if (!isNaN(iterable.length)) {\n var i = -1, next = function next() {\n while (++i < iterable.length) {\n if (hasOwn.call(iterable, i)) {\n next.value = iterable[i];\n next.done = false;\n return next;\n }\n }\n\n next.value = undefined;\n next.done = true;\n\n return next;\n };\n\n return next.next = next;\n }\n }\n\n // Return an iterator with no values.\n return { next: doneResult };\n }\n exports.values = values;\n\n function doneResult() {\n return { value: undefined, done: true };\n }\n\n Context.prototype = {\n constructor: Context,\n\n reset: function(skipTempReset) {\n this.prev = 0;\n this.next = 0;\n // Resetting context._sent for legacy support of Babel's\n // function.sent implementation.\n this.sent = this._sent = undefined;\n this.done = false;\n this.delegate = null;\n\n this.method = \"next\";\n this.arg = undefined;\n\n this.tryEntries.forEach(resetTryEntry);\n\n if (!skipTempReset) {\n for (var name in this) {\n // Not sure about the optimal order of these conditions:\n if (name.charAt(0) === \"t\" &&\n hasOwn.call(this, name) &&\n !isNaN(+name.slice(1))) {\n this[name] = undefined;\n }\n }\n }\n },\n\n stop: function() {\n this.done = true;\n\n var rootEntry = this.tryEntries[0];\n var rootRecord = rootEntry.completion;\n if (rootRecord.type === \"throw\") {\n throw rootRecord.arg;\n }\n\n return this.rval;\n },\n\n dispatchException: function(exception) {\n if (this.done) {\n throw exception;\n }\n\n var context = this;\n function handle(loc, caught) {\n record.type = \"throw\";\n record.arg = exception;\n context.next = loc;\n\n if (caught) {\n // If the dispatched exception was caught by a catch block,\n // then let that catch block handle the exception normally.\n context.method = \"next\";\n context.arg = undefined;\n }\n\n return !! caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n var record = entry.completion;\n\n if (entry.tryLoc === \"root\") {\n // Exception thrown outside of any try block that could handle\n // it, so set the completion value of the entire function to\n // throw the exception.\n return handle(\"end\");\n }\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, \"catchLoc\");\n var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n } else if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n }\n\n } else if (hasFinally) {\n if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else {\n throw new Error(\"try statement without catch or finally\");\n }\n }\n }\n },\n\n abrupt: function(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc <= this.prev &&\n hasOwn.call(entry, \"finallyLoc\") &&\n this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n if (finallyEntry &&\n (type === \"break\" ||\n type === \"continue\") &&\n finallyEntry.tryLoc <= arg &&\n arg <= finallyEntry.finallyLoc) {\n // Ignore the finally entry if control is not jumping to a\n // location outside the try/catch block.\n finallyEntry = null;\n }\n\n var record = finallyEntry ? finallyEntry.completion : {};\n record.type = type;\n record.arg = arg;\n\n if (finallyEntry) {\n this.method = \"next\";\n this.next = finallyEntry.finallyLoc;\n return ContinueSentinel;\n }\n\n return this.complete(record);\n },\n\n complete: function(record, afterLoc) {\n if (record.type === \"throw\") {\n throw record.arg;\n }\n\n if (record.type === \"break\" ||\n record.type === \"continue\") {\n this.next = record.arg;\n } else if (record.type === \"return\") {\n this.rval = this.arg = record.arg;\n this.method = \"return\";\n this.next = \"end\";\n } else if (record.type === \"normal\" && afterLoc) {\n this.next = afterLoc;\n }\n\n return ContinueSentinel;\n },\n\n finish: function(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) {\n this.complete(entry.completion, entry.afterLoc);\n resetTryEntry(entry);\n return ContinueSentinel;\n }\n }\n },\n\n \"catch\": function(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n if (record.type === \"throw\") {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n return thrown;\n }\n }\n\n // The context.catch method must only be called with a location\n // argument that corresponds to a known catch block.\n throw new Error(\"illegal catch attempt\");\n },\n\n delegateYield: function(iterable, resultName, nextLoc) {\n this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n };\n\n if (this.method === \"next\") {\n // Deliberately forget the last sent value so that we don't\n // accidentally pass it on to the delegate.\n this.arg = undefined;\n }\n\n return ContinueSentinel;\n }\n };\n\n // Regardless of whether this script is executing as a CommonJS module\n // or not, return the runtime object so that we can declare the variable\n // regeneratorRuntime in the outer scope, which allows this module to be\n // injected easily by `bin/regenerator --include-runtime script.js`.\n return exports;\n\n}(\n // If this script is executing as a CommonJS module, use module.exports\n // as the regeneratorRuntime namespace. Otherwise create a new empty\n // object. Either way, the resulting object will be used to initialize\n // the regeneratorRuntime variable at the top of this file.\n true ? module.exports : undefined\n));\n\ntry {\n regeneratorRuntime = runtime;\n} catch (accidentalStrictMode) {\n // This module should not be running in strict mode, so the above\n // assignment should always work unless something is misconfigured. Just\n // in case runtime.js accidentally runs in strict mode, we can escape\n // strict mode using a global Function call. This could conceivably fail\n // if a Content Security Policy forbids using Function, but in that case\n // the proper solution is to fix the accidental strict mode problem. If\n // you've misconfigured your bundler to force strict mode and applied a\n // CSP to forbid Function, and you're not willing to fix either of those\n // problems, please detail your unique predicament in a GitHub issue.\n Function(\"r\", \"regeneratorRuntime = r\")(runtime);\n}\n\n\n//# sourceURL=webpack:///./node_modules/regenerator-runtime/runtime.js?");
-
-/***/ }),
-
-/***/ "./node_modules/regl-error2d/index.js":
-/*!********************************************!*\
- !*** ./node_modules/regl-error2d/index.js ***!
- \********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nvar getBounds = __webpack_require__(/*! array-bounds */ \"./node_modules/array-bounds/index.js\")\nvar rgba = __webpack_require__(/*! color-normalize */ \"./node_modules/color-normalize/index.js\")\nvar updateDiff = __webpack_require__(/*! update-diff */ \"./node_modules/update-diff/index.js\")\nvar pick = __webpack_require__(/*! pick-by-alias */ \"./node_modules/pick-by-alias/index.js\")\nvar extend = __webpack_require__(/*! object-assign */ \"./node_modules/object-assign/index.js\")\nvar flatten = __webpack_require__(/*! flatten-vertex-data */ \"./node_modules/flatten-vertex-data/index.js\")\nvar ref = __webpack_require__(/*! to-float32 */ \"./node_modules/to-float32/index.js\");\nvar float32 = ref.float32;\nvar fract32 = ref.fract32;\n\nmodule.exports = Error2D\n\nvar WEIGHTS = [\n\t//direction, lineWidth shift, capSize shift\n\n\t// x-error bar\n\t[1, 0, 0, 1, 0, 0],\n\t[1, 0, 0, -1, 0, 0],\n\t[-1, 0, 0, -1, 0, 0],\n\n\t[-1, 0, 0, -1, 0, 0],\n\t[-1, 0, 0, 1, 0, 0],\n\t[1, 0, 0, 1, 0, 0],\n\n\t// x-error right cap\n\t[1, 0, -1, 0, 0, 1],\n\t[1, 0, -1, 0, 0, -1],\n\t[1, 0, 1, 0, 0, -1],\n\n\t[1, 0, 1, 0, 0, -1],\n\t[1, 0, 1, 0, 0, 1],\n\t[1, 0, -1, 0, 0, 1],\n\n\t// x-error left cap\n\t[-1, 0, -1, 0, 0, 1],\n\t[-1, 0, -1, 0, 0, -1],\n\t[-1, 0, 1, 0, 0, -1],\n\n\t[-1, 0, 1, 0, 0, -1],\n\t[-1, 0, 1, 0, 0, 1],\n\t[-1, 0, -1, 0, 0, 1],\n\n\t// y-error bar\n\t[0, 1, 1, 0, 0, 0],\n\t[0, 1, -1, 0, 0, 0],\n\t[0, -1, -1, 0, 0, 0],\n\n\t[0, -1, -1, 0, 0, 0],\n\t[0, 1, 1, 0, 0, 0],\n\t[0, -1, 1, 0, 0, 0],\n\n\t// y-error top cap\n\t[0, 1, 0, -1, 1, 0],\n\t[0, 1, 0, -1, -1, 0],\n\t[0, 1, 0, 1, -1, 0],\n\n\t[0, 1, 0, 1, 1, 0],\n\t[0, 1, 0, -1, 1, 0],\n\t[0, 1, 0, 1, -1, 0],\n\n\t// y-error bottom cap\n\t[0, -1, 0, -1, 1, 0],\n\t[0, -1, 0, -1, -1, 0],\n\t[0, -1, 0, 1, -1, 0],\n\n\t[0, -1, 0, 1, 1, 0],\n\t[0, -1, 0, -1, 1, 0],\n\t[0, -1, 0, 1, -1, 0]\n]\n\n\nfunction Error2D (regl, options) {\n\tif (typeof regl === 'function') {\n\t\tif (!options) { options = {} }\n\t\toptions.regl = regl\n\t}\n\telse {\n\t\toptions = regl\n\t}\n\tif (options.length) { options.positions = options }\n\tregl = options.regl\n\n\tif (!regl.hasExtension('ANGLE_instanced_arrays')) {\n\t\tthrow Error('regl-error2d: `ANGLE_instanced_arrays` extension should be enabled');\n\t}\n\n\t// persistent variables\n\tvar gl = regl._gl, drawErrors, positionBuffer, positionFractBuffer, colorBuffer, errorBuffer, meshBuffer,\n\t\t\tdefaults = {\n\t\t\t\tcolor: 'black',\n\t\t\t\tcapSize: 5,\n\t\t\t\tlineWidth: 1,\n\t\t\t\topacity: 1,\n\t\t\t\tviewport: null,\n\t\t\t\trange: null,\n\t\t\t\toffset: 0,\n\t\t\t\tcount: 0,\n\t\t\t\tbounds: null,\n\t\t\t\tpositions: [],\n\t\t\t\terrors: []\n\t\t\t}, groups = []\n\n\t//color per-point\n\tcolorBuffer = regl.buffer({\n\t\tusage: 'dynamic',\n\t\ttype: 'uint8',\n\t\tdata: new Uint8Array(0)\n\t})\n\t//xy-position per-point\n\tpositionBuffer = regl.buffer({\n\t\tusage: 'dynamic',\n\t\ttype: 'float',\n\t\tdata: new Uint8Array(0)\n\t})\n\t//xy-position float32-fraction\n\tpositionFractBuffer = regl.buffer({\n\t\tusage: 'dynamic',\n\t\ttype: 'float',\n\t\tdata: new Uint8Array(0)\n\t})\n\t//4 errors per-point\n\terrorBuffer = regl.buffer({\n\t\tusage: 'dynamic',\n\t\ttype: 'float',\n\t\tdata: new Uint8Array(0)\n\t})\n\t//error bar mesh\n\tmeshBuffer = regl.buffer({\n\t\tusage: 'static',\n\t\ttype: 'float',\n\t\tdata: WEIGHTS\n\t})\n\n\tupdate(options)\n\n\t//drawing method\n\tdrawErrors = regl({\n\t\tvert: \"\\n\\t\\tprecision highp float;\\n\\n\\t\\tattribute vec2 position, positionFract;\\n\\t\\tattribute vec4 error;\\n\\t\\tattribute vec4 color;\\n\\n\\t\\tattribute vec2 direction, lineOffset, capOffset;\\n\\n\\t\\tuniform vec4 viewport;\\n\\t\\tuniform float lineWidth, capSize;\\n\\t\\tuniform vec2 scale, scaleFract, translate, translateFract;\\n\\n\\t\\tvarying vec4 fragColor;\\n\\n\\t\\tvoid main() {\\n\\t\\t\\tfragColor = color / 255.;\\n\\n\\t\\t\\tvec2 pixelOffset = lineWidth * lineOffset + (capSize + lineWidth) * capOffset;\\n\\n\\t\\t\\tvec2 dxy = -step(.5, direction.xy) * error.xz + step(direction.xy, vec2(-.5)) * error.yw;\\n\\n\\t\\t\\tvec2 position = position + dxy;\\n\\n\\t\\t\\tvec2 pos = (position + translate) * scale\\n\\t\\t\\t\\t+ (positionFract + translateFract) * scale\\n\\t\\t\\t\\t+ (position + translate) * scaleFract\\n\\t\\t\\t\\t+ (positionFract + translateFract) * scaleFract;\\n\\n\\t\\t\\tpos += pixelOffset / viewport.zw;\\n\\n\\t\\t\\tgl_Position = vec4(pos * 2. - 1., 0, 1);\\n\\t\\t}\\n\\t\\t\",\n\n\t\tfrag: \"\\n\\t\\tprecision highp float;\\n\\n\\t\\tvarying vec4 fragColor;\\n\\n\\t\\tuniform float opacity;\\n\\n\\t\\tvoid main() {\\n\\t\\t\\tgl_FragColor = fragColor;\\n\\t\\t\\tgl_FragColor.a *= opacity;\\n\\t\\t}\\n\\t\\t\",\n\n\t\tuniforms: {\n\t\t\trange: regl.prop('range'),\n\t\t\tlineWidth: regl.prop('lineWidth'),\n\t\t\tcapSize: regl.prop('capSize'),\n\t\t\topacity: regl.prop('opacity'),\n\t\t\tscale: regl.prop('scale'),\n\t\t\ttranslate: regl.prop('translate'),\n\t\t\tscaleFract: regl.prop('scaleFract'),\n\t\t\ttranslateFract: regl.prop('translateFract'),\n\t\t\tviewport: function (ctx, prop) { return [prop.viewport.x, prop.viewport.y, ctx.viewportWidth, ctx.viewportHeight]; }\n\t\t},\n\n\t\tattributes: {\n\t\t\t//dynamic attributes\n\t\t\tcolor: {\n\t\t\t\tbuffer: colorBuffer,\n\t\t\t\toffset: function (ctx, prop) { return prop.offset * 4; },\n\t\t\t\tdivisor: 1,\n\t\t\t},\n\t\t\tposition: {\n\t\t\t\tbuffer: positionBuffer,\n\t\t\t\toffset: function (ctx, prop) { return prop.offset * 8; },\n\t\t\t\tdivisor: 1\n\t\t\t},\n\t\t\tpositionFract: {\n\t\t\t\tbuffer: positionFractBuffer,\n\t\t\t\toffset: function (ctx, prop) { return prop.offset * 8; },\n\t\t\t\tdivisor: 1\n\t\t\t},\n\t\t\terror: {\n\t\t\t\tbuffer: errorBuffer,\n\t\t\t\toffset: function (ctx, prop) { return prop.offset * 16; },\n\t\t\t\tdivisor: 1\n\t\t\t},\n\n\t\t\t//static attributes\n\t\t\tdirection: {\n\t\t\t\tbuffer: meshBuffer,\n\t\t\t\tstride: 24,\n\t\t\t\toffset: 0\n\t\t\t},\n\t\t\tlineOffset: {\n\t\t\t\tbuffer: meshBuffer,\n\t\t\t\tstride: 24,\n\t\t\t\toffset: 8\n\t\t\t},\n\t\t\tcapOffset: {\n\t\t\t\tbuffer: meshBuffer,\n\t\t\t\tstride: 24,\n\t\t\t\toffset: 16\n\t\t\t}\n\t\t},\n\n\t\tprimitive: 'triangles',\n\n\t\tblend: {\n\t\t\tenable: true,\n\t\t\tcolor: [0,0,0,0],\n\t\t\tequation: {\n\t\t\t\trgb: 'add',\n\t\t\t\talpha: 'add'\n\t\t\t},\n\t\t\tfunc: {\n\t\t\t\tsrcRGB: 'src alpha',\n\t\t\t\tdstRGB: 'one minus src alpha',\n\t\t\t\tsrcAlpha: 'one minus dst alpha',\n\t\t\t\tdstAlpha: 'one'\n\t\t\t}\n\t\t},\n\n\t\tdepth: {\n\t\t\tenable: false\n\t\t},\n\n\t\tscissor: {\n\t\t\tenable: true,\n\t\t\tbox: regl.prop('viewport')\n\t\t},\n\t\tviewport: regl.prop('viewport'),\n\t\tstencil: false,\n\n\t\tinstances: regl.prop('count'),\n\t\tcount: WEIGHTS.length\n\t})\n\n\t//expose API\n\textend(error2d, {\n\t\tupdate: update,\n\t\tdraw: draw,\n\t\tdestroy: destroy,\n\t\tregl: regl,\n\t\tgl: gl,\n\t\tcanvas: gl.canvas,\n\t\tgroups: groups\n\t})\n\n\treturn error2d\n\n\tfunction error2d (opts) {\n\t\t//update\n\t\tif (opts) {\n\t\t\tupdate(opts)\n\t\t}\n\n\t\t//destroy\n\t\telse if (opts === null) {\n\t\t\tdestroy()\n\t\t}\n\n\t\tdraw()\n\t}\n\n\n\t//main draw method\n\tfunction draw (options) {\n\t\tif (typeof options === 'number') { return drawGroup(options) }\n\n\t\t//make options a batch\n\t\tif (options && !Array.isArray(options)) { options = [options] }\n\n\n\t\tregl._refresh()\n\n\t\t//render multiple polylines via regl batch\n\t\tgroups.forEach(function (s, i) {\n\t\t\tif (!s) { return }\n\n\t\t\tif (options) {\n\t\t\t\tif (!options[i]) { s.draw = false }\n\t\t\t\telse { s.draw = true }\n\t\t\t}\n\n\t\t\t//ignore draw flag for one pass\n\t\t\tif (!s.draw) {\n\t\t\t\ts.draw = true;\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tdrawGroup(i)\n\t\t})\n\t}\n\n\t//draw single error group by id\n\tfunction drawGroup (s) {\n\t\tif (typeof s === 'number') { s = groups[s] }\n\t\tif (s == null) { return }\n\n\t\tif (!(s && s.count && s.color && s.opacity && s.positions && s.positions.length > 1)) { return }\n\n\t\ts.scaleRatio = [\n\t\t\ts.scale[0] * s.viewport.width,\n\t\t\ts.scale[1] * s.viewport.height\n\t\t]\n\n\t\tdrawErrors(s)\n\n\t\tif (s.after) { s.after(s) }\n\t}\n\n\tfunction update (options) {\n\t\tif (!options) { return }\n\n\t\t//direct points argument\n\t\tif (options.length != null) {\n\t\t\tif (typeof options[0] === 'number') { options = [{positions: options}] }\n\t\t}\n\n\t\t//make options a batch\n\t\telse if (!Array.isArray(options)) { options = [options] }\n\n\t\t//global count of points\n\t\tvar pointCount = 0, errorCount = 0\n\n\t\terror2d.groups = groups = options.map(function (options, i) {\n\t\t\tvar group = groups[i]\n\n\t\t\tif (!options) { return group }\n\t\t\telse if (typeof options === 'function') { options = {after: options} }\n\t\t\telse if (typeof options[0] === 'number') { options = {positions: options} }\n\n\t\t\t//copy options to avoid mutation & handle aliases\n\t\t\toptions = pick(options, {\n\t\t\t\tcolor: 'color colors fill',\n\t\t\t\tcapSize: 'capSize cap capsize cap-size',\n\t\t\t\tlineWidth: 'lineWidth line-width width line thickness',\n\t\t\t\topacity: 'opacity alpha',\n\t\t\t\trange: 'range dataBox',\n\t\t\t\tviewport: 'viewport viewBox',\n\t\t\t\terrors: 'errors error',\n\t\t\t\tpositions: 'positions position data points'\n\t\t\t})\n\n\t\t\tif (!group) {\n\t\t\t\tgroups[i] = group = {\n\t\t\t\t\tid: i,\n\t\t\t\t\tscale: null,\n\t\t\t\t\ttranslate: null,\n\t\t\t\t\tscaleFract: null,\n\t\t\t\t\ttranslateFract: null,\n\t\t\t\t\tdraw: true\n\t\t\t\t}\n\t\t\t\toptions = extend({}, defaults, options)\n\t\t\t}\n\n\t\t\tupdateDiff(group, options, [{\n\t\t\t\tlineWidth: function (v) { return +v * .5; },\n\t\t\t\tcapSize: function (v) { return +v * .5; },\n\t\t\t\topacity: parseFloat,\n\t\t\t\terrors: function (errors) {\n\t\t\t\t\terrors = flatten(errors)\n\n\t\t\t\t\terrorCount += errors.length\n\t\t\t\t\treturn errors\n\t\t\t\t},\n\t\t\t\tpositions: function (positions, state) {\n\t\t\t\t\tpositions = flatten(positions, 'float64')\n\t\t\t\t\tstate.count = Math.floor(positions.length / 2)\n\t\t\t\t\tstate.bounds = getBounds(positions, 2)\n\t\t\t\t\tstate.offset = pointCount\n\n\t\t\t\t\tpointCount += state.count\n\n\t\t\t\t\treturn positions\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcolor: function (colors, state) {\n\t\t\t\t\tvar count = state.count\n\n\t\t\t\t\tif (!colors) { colors = 'transparent' }\n\n\t\t\t\t\t// 'black' or [0,0,0,0] case\n\t\t\t\t\tif (!Array.isArray(colors) || typeof colors[0] === 'number') {\n\t\t\t\t\t\tvar color = colors\n\t\t\t\t\t\tcolors = Array(count)\n\t\t\t\t\t\tfor (var i = 0; i < count; i++) {\n\t\t\t\t\t\t\tcolors[i] = color\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (colors.length < count) { throw Error('Not enough colors') }\n\n\t\t\t\t\tvar colorData = new Uint8Array(count * 4)\n\n\t\t\t\t\t//convert colors to float arrays\n\t\t\t\t\tfor (var i$1 = 0; i$1 < count; i$1++) {\n\t\t\t\t\t\tvar c = rgba(colors[i$1], 'uint8')\n\t\t\t\t\t\tcolorData.set(c, i$1 * 4)\n\t\t\t\t\t}\n\n\t\t\t\t\treturn colorData\n\t\t\t\t},\n\n\t\t\t\trange: function (range, state, options) {\n\t\t\t\t\tvar bounds = state.bounds\n\t\t\t\t\tif (!range) { range = bounds }\n\n\t\t\t\t\tstate.scale = [1 / (range[2] - range[0]), 1 / (range[3] - range[1])]\n\t\t\t\t\tstate.translate = [-range[0], -range[1]]\n\n\t\t\t\t\tstate.scaleFract = fract32(state.scale)\n\t\t\t\t\tstate.translateFract = fract32(state.translate)\n\n\t\t\t\t\treturn range\n\t\t\t\t},\n\n\t\t\t\tviewport: function (vp) {\n\t\t\t\t\tvar viewport\n\n\t\t\t\t\tif (Array.isArray(vp)) {\n\t\t\t\t\t\tviewport = {\n\t\t\t\t\t\t\tx: vp[0],\n\t\t\t\t\t\t\ty: vp[1],\n\t\t\t\t\t\t\twidth: vp[2] - vp[0],\n\t\t\t\t\t\t\theight: vp[3] - vp[1]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (vp) {\n\t\t\t\t\t\tviewport = {\n\t\t\t\t\t\t\tx: vp.x || vp.left || 0,\n\t\t\t\t\t\t\ty: vp.y || vp.top || 0\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (vp.right) { viewport.width = vp.right - viewport.x }\n\t\t\t\t\t\telse { viewport.width = vp.w || vp.width || 0 }\n\n\t\t\t\t\t\tif (vp.bottom) { viewport.height = vp.bottom - viewport.y }\n\t\t\t\t\t\telse { viewport.height = vp.h || vp.height || 0 }\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tviewport = {\n\t\t\t\t\t\t\tx: 0, y: 0,\n\t\t\t\t\t\t\twidth: gl.drawingBufferWidth,\n\t\t\t\t\t\t\theight: gl.drawingBufferHeight\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn viewport\n\t\t\t\t}\n\t\t\t}])\n\n\t\t\treturn group\n\t\t})\n\n\t\tif (pointCount || errorCount) {\n\t\t\tvar len = groups.reduce(function (acc, group, i) {\n\t\t\t\treturn acc + (group ? group.count : 0)\n\t\t\t}, 0)\n\n\t\t\tvar positionData = new Float64Array(len * 2)\n\t\t\tvar colorData = new Uint8Array(len * 4)\n\t\t\tvar errorData = new Float32Array(len * 4)\n\n\t\t\tgroups.forEach(function (group, i) {\n\t\t\t\tif (!group) { return }\n\t\t\t\tvar positions = group.positions;\n\t\t\t\tvar count = group.count;\n\t\t\t\tvar offset = group.offset;\n\t\t\t\tvar color = group.color;\n\t\t\t\tvar errors = group.errors;\n\t\t\t\tif (!count) { return }\n\n\t\t\t\tcolorData.set(color, offset * 4)\n\t\t\t\terrorData.set(errors, offset * 4)\n\t\t\t\tpositionData.set(positions, offset * 2)\n\t\t\t})\n\n\t\t\tpositionBuffer(float32(positionData))\n\t\t\tpositionFractBuffer(fract32(positionData))\n\t\t\tcolorBuffer(colorData)\n\t\t\terrorBuffer(errorData)\n\t\t}\n\n\t}\n\n\tfunction destroy () {\n\t\tpositionBuffer.destroy()\n\t\tpositionFractBuffer.destroy()\n\t\tcolorBuffer.destroy()\n\t\terrorBuffer.destroy()\n\t\tmeshBuffer.destroy()\n\t}\n}\n\r\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbIkY6L3NvdXJjZS92dWUtcGxvdGx5LmpzL25vZGVfbW9kdWxlcy9yZWdsLWVycm9yMmQvaW5kZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnXG5cbmNvbnN0IGdldEJvdW5kcyA9IHJlcXVpcmUoJ2FycmF5LWJvdW5kcycpXG5jb25zdCByZ2JhID0gcmVxdWlyZSgnY29sb3Itbm9ybWFsaXplJylcbmNvbnN0IHVwZGF0ZURpZmYgPSByZXF1aXJlKCd1cGRhdGUtZGlmZicpXG5jb25zdCBwaWNrID0gcmVxdWlyZSgncGljay1ieS1hbGlhcycpXG5jb25zdCBleHRlbmQgPSByZXF1aXJlKCdvYmplY3QtYXNzaWduJylcbmNvbnN0IGZsYXR0ZW4gPSByZXF1aXJlKCdmbGF0dGVuLXZlcnRleC1kYXRhJylcbmNvbnN0IHtmbG9hdDMyLCBmcmFjdDMyfSA9IHJlcXVpcmUoJ3RvLWZsb2F0MzInKVxuXG5tb2R1bGUuZXhwb3J0cyA9IEVycm9yMkRcblxuY29uc3QgV0VJR0hUUyA9IFtcblx0Ly9kaXJlY3Rpb24sIGxpbmVXaWR0aCBzaGlmdCwgY2FwU2l6ZSBzaGlmdFxuXG5cdC8vIHgtZXJyb3IgYmFyXG5cdFsxLCAwLCAwLCAxLCAwLCAwXSxcblx0WzEsIDAsIDAsIC0xLCAwLCAwXSxcblx0Wy0xLCAwLCAwLCAtMSwgMCwgMF0sXG5cblx0Wy0xLCAwLCAwLCAtMSwgMCwgMF0sXG5cdFstMSwgMCwgMCwgMSwgMCwgMF0sXG5cdFsxLCAwLCAwLCAxLCAwLCAwXSxcblxuXHQvLyB4LWVycm9yIHJpZ2h0IGNhcFxuXHRbMSwgMCwgLTEsIDAsIDAsIDFdLFxuXHRbMSwgMCwgLTEsIDAsIDAsIC0xXSxcblx0WzEsIDAsIDEsIDAsIDAsIC0xXSxcblxuXHRbMSwgMCwgMSwgMCwgMCwgLTFdLFxuXHRbMSwgMCwgMSwgMCwgMCwgMV0sXG5cdFsxLCAwLCAtMSwgMCwgMCwgMV0sXG5cblx0Ly8geC1lcnJvciBsZWZ0IGNhcFxuXHRbLTEsIDAsIC0xLCAwLCAwLCAxXSxcblx0Wy0xLCAwLCAtMSwgMCwgMCwgLTFdLFxuXHRbLTEsIDAsIDEsIDAsIDAsIC0xXSxcblxuXHRbLTEsIDAsIDEsIDAsIDAsIC0xXSxcblx0Wy0xLCAwLCAxLCAwLCAwLCAxXSxcblx0Wy0xLCAwLCAtMSwgMCwgMCwgMV0sXG5cblx0Ly8geS1lcnJvciBiYXJcblx0WzAsIDEsIDEsIDAsIDAsIDBdLFxuXHRbMCwgMSwgLTEsIDAsIDAsIDBdLFxuXHRbMCwgLTEsIC0xLCAwLCAwLCAwXSxcblxuXHRbMCwgLTEsIC0xLCAwLCAwLCAwXSxcblx0WzAsIDEsIDEsIDAsIDAsIDBdLFxuXHRbMCwgLTEsIDEsIDAsIDAsIDBdLFxuXG5cdC8vIHktZXJyb3IgdG9wIGNhcFxuXHRbMCwgMSwgMCwgLTEsIDEsIDBdLFxuXHRbMCwgMSwgMCwgLTEsIC0xLCAwXSxcblx0WzAsIDEsIDAsIDEsIC0xLCAwXSxcblxuXHRbMCwgMSwgMCwgMSwgMSwgMF0sXG5cdFswLCAxLCAwLCAtMSwgMSwgMF0sXG5cdFswLCAxLCAwLCAxLCAtMSwgMF0sXG5cblx0Ly8geS1lcnJvciBib3R0b20gY2FwXG5cdFswLCAtMSwgMCwgLTEsIDEsIDBdLFxuXHRbMCwgLTEsIDAsIC0xLCAtMSwgMF0sXG5cdFswLCAtMSwgMCwgMSwgLTEsIDBdLFxuXG5cdFswLCAtMSwgMCwgMSwgMSwgMF0sXG5cdFswLCAtMSwgMCwgLTEsIDEsIDBdLFxuXHRbMCwgLTEsIDAsIDEsIC0xLCAwXVxuXVxuXG5cbmZ1bmN0aW9uIEVycm9yMkQgKHJlZ2wsIG9wdGlvbnMpIHtcblx0aWYgKHR5cGVvZiByZWdsID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0aWYgKCFvcHRpb25zKSBvcHRpb25zID0ge31cblx0XHRvcHRpb25zLnJlZ2wgPSByZWdsXG5cdH1cblx0ZWxzZSB7XG5cdFx0b3B0aW9ucyA9IHJlZ2xcblx0fVxuXHRpZiAob3B0aW9ucy5sZW5ndGgpIG9wdGlvbnMucG9zaXRpb25zID0gb3B0aW9uc1xuXHRyZWdsID0gb3B0aW9ucy5yZWdsXG5cblx0aWYgKCFyZWdsLmhhc0V4dGVuc2lvbignQU5HTEVfaW5zdGFuY2VkX2FycmF5cycpKSB7XG5cdFx0dGhyb3cgRXJyb3IoJ3JlZ2wtZXJyb3IyZDogYEFOR0xFX2luc3RhbmNlZF9hcnJheXNgIGV4dGVuc2lvbiBzaG91bGQgYmUgZW5hYmxlZCcpO1xuXHR9XG5cblx0Ly8gcGVyc2lzdGVudCB2YXJpYWJsZXNcblx0bGV0IGdsID0gcmVnbC5fZ2wsIGRyYXdFcnJvcnMsIHBvc2l0aW9uQnVmZmVyLCBwb3NpdGlvbkZyYWN0QnVmZmVyLCBjb2xvckJ1ZmZlciwgZXJyb3JCdWZmZXIsIG1lc2hCdWZmZXIsXG5cdFx0XHRkZWZhdWx0cyA9IHtcblx0XHRcdFx0Y29sb3I6ICdibGFjaycsXG5cdFx0XHRcdGNhcFNpemU6IDUsXG5cdFx0XHRcdGxpbmVXaWR0aDogMSxcblx0XHRcdFx0b3BhY2l0eTogMSxcblx0XHRcdFx0dmlld3BvcnQ6IG51bGwsXG5cdFx0XHRcdHJhbmdlOiBudWxsLFxuXHRcdFx0XHRvZmZzZXQ6IDAsXG5cdFx0XHRcdGNvdW50OiAwLFxuXHRcdFx0XHRib3VuZHM6IG51bGwsXG5cdFx0XHRcdHBvc2l0aW9uczogW10sXG5cdFx0XHRcdGVycm9yczogW11cblx0XHRcdH0sIGdyb3VwcyA9IFtdXG5cblx0Ly9jb2xvciBwZXItcG9pbnRcblx0Y29sb3JCdWZmZXIgPSByZWdsLmJ1ZmZlcih7XG5cdFx0dXNhZ2U6ICdkeW5hbWljJyxcblx0XHR0eXBlOiAndWludDgnLFxuXHRcdGRhdGE6IG5ldyBVaW50OEFycmF5KDApXG5cdH0pXG5cdC8veHktcG9zaXRpb24gcGVyLXBvaW50XG5cdHBvc2l0aW9uQnVmZmVyID0gcmVnbC5idWZmZXIoe1xuXHRcdHVzYWdlOiAnZHluYW1pYycsXG5cdFx0dHlwZTogJ2Zsb2F0Jyxcblx0XHRkYXRhOiBuZXcgVWludDhBcnJheSgwKVxuXHR9KVxuXHQvL3h5LXBvc2l0aW9uIGZsb2F0MzItZnJhY3Rpb25cblx0cG9zaXRpb25GcmFjdEJ1ZmZlciA9IHJlZ2wuYnVmZmVyKHtcblx0XHR1c2FnZTogJ2R5bmFtaWMnLFxuXHRcdHR5cGU6ICdmbG9hdCcsXG5cdFx0ZGF0YTogbmV3IFVpbnQ4QXJyYXkoMClcblx0fSlcblx0Ly80IGVycm9ycyBwZXItcG9pbnRcblx0ZXJyb3JCdWZmZXIgPSByZWdsLmJ1ZmZlcih7XG5cdFx0dXNhZ2U6ICdkeW5hbWljJyxcblx0XHR0eXBlOiAnZmxvYXQnLFxuXHRcdGRhdGE6IG5ldyBVaW50OEFycmF5KDApXG5cdH0pXG5cdC8vZXJyb3IgYmFyIG1lc2hcblx0bWVzaEJ1ZmZlciA9IHJlZ2wuYnVmZmVyKHtcblx0XHR1c2FnZTogJ3N0YXRpYycsXG5cdFx0dHlwZTogJ2Zsb2F0Jyxcblx0XHRkYXRhOiBXRUlHSFRTXG5cdH0pXG5cblx0dXBkYXRlKG9wdGlvbnMpXG5cblx0Ly9kcmF3aW5nIG1ldGhvZFxuXHRkcmF3RXJyb3JzID0gcmVnbCh7XG5cdFx0dmVydDogYFxuXHRcdHByZWNpc2lvbiBoaWdocCBmbG9hdDtcblxuXHRcdGF0dHJpYnV0ZSB2ZWMyIHBvc2l0aW9uLCBwb3NpdGlvbkZyYWN0O1xuXHRcdGF0dHJpYnV0ZSB2ZWM0IGVycm9yO1xuXHRcdGF0dHJpYnV0ZSB2ZWM0IGNvbG9yO1xuXG5cdFx0YXR0cmlidXRlIHZlYzIgZGlyZWN0aW9uLCBsaW5lT2Zmc2V0LCBjYXBPZmZzZXQ7XG5cblx0XHR1bmlmb3JtIHZlYzQgdmlld3BvcnQ7XG5cdFx0dW5pZm9ybSBmbG9hdCBsaW5lV2lkdGgsIGNhcFNpemU7XG5cdFx0dW5pZm9ybSB2ZWMyIHNjYWxlLCBzY2FsZUZyYWN0LCB0cmFuc2xhdGUsIHRyYW5zbGF0ZUZyYWN0O1xuXG5cdFx0dmFyeWluZyB2ZWM0IGZyYWdDb2xvcjtcblxuXHRcdHZvaWQgbWFpbigpIHtcblx0XHRcdGZyYWdDb2xvciA9IGNvbG9yIC8gMjU1LjtcblxuXHRcdFx0dmVjMiBwaXhlbE9mZnNldCA9IGxpbmVXaWR0aCAqIGxpbmVPZmZzZXQgKyAoY2FwU2l6ZSArIGxpbmVXaWR0aCkgKiBjYXBPZmZzZXQ7XG5cblx0XHRcdHZlYzIgZHh5ID0gLXN0ZXAoLjUsIGRpcmVjdGlvbi54eSkgKiBlcnJvci54eiArIHN0ZXAoZGlyZWN0aW9uLnh5LCB2ZWMyKC0uNSkpICogZXJyb3IueXc7XG5cblx0XHRcdHZlYzIgcG9zaXRpb24gPSBwb3NpdGlvbiArIGR4eTtcblxuXHRcdFx0dmVjMiBwb3MgPSAocG9zaXRpb24gKyB0cmFuc2xhdGUpICogc2NhbGVcblx0XHRcdFx0KyAocG9zaXRpb25GcmFjdCArIHRyYW5zbGF0ZUZyYWN0KSAqIHNjYWxlXG5cdFx0XHRcdCsgKHBvc2l0aW9uICsgdHJhbnNsYXRlKSAqIHNjYWxlRnJhY3Rcblx0XHRcdFx0KyAocG9zaXRpb25GcmFjdCArIHRyYW5zbGF0ZUZyYWN0KSAqIHNjYWxlRnJhY3Q7XG5cblx0XHRcdHBvcyArPSBwaXhlbE9mZnNldCAvIHZpZXdwb3J0Lnp3O1xuXG5cdFx0XHRnbF9Qb3NpdGlvbiA9IHZlYzQocG9zICogMi4gLSAxLiwgMCwgMSk7XG5cdFx0fVxuXHRcdGAsXG5cblx0XHRmcmFnOiBgXG5cdFx0cHJlY2lzaW9uIGhpZ2hwIGZsb2F0O1xuXG5cdFx0dmFyeWluZyB2ZWM0IGZyYWdDb2xvcjtcblxuXHRcdHVuaWZvcm0gZmxvYXQgb3BhY2l0eTtcblxuXHRcdHZvaWQgbWFpbigpIHtcblx0XHRcdGdsX0ZyYWdDb2xvciA9IGZyYWdDb2xvcjtcblx0XHRcdGdsX0ZyYWdDb2xvci5hICo9IG9wYWNpdHk7XG5cdFx0fVxuXHRcdGAsXG5cblx0XHR1bmlmb3Jtczoge1xuXHRcdFx0cmFuZ2U6IHJlZ2wucHJvcCgncmFuZ2UnKSxcblx0XHRcdGxpbmVXaWR0aDogcmVnbC5wcm9wKCdsaW5lV2lkdGgnKSxcblx0XHRcdGNhcFNpemU6IHJlZ2wucHJvcCgnY2FwU2l6ZScpLFxuXHRcdFx0b3BhY2l0eTogcmVnbC5wcm9wKCdvcGFjaXR5JyksXG5cdFx0XHRzY2FsZTogcmVnbC5wcm9wKCdzY2FsZScpLFxuXHRcdFx0dHJhbnNsYXRlOiByZWdsLnByb3AoJ3RyYW5zbGF0ZScpLFxuXHRcdFx0c2NhbGVGcmFjdDogcmVnbC5wcm9wKCdzY2FsZUZyYWN0JyksXG5cdFx0XHR0cmFuc2xhdGVGcmFjdDogcmVnbC5wcm9wKCd0cmFuc2xhdGVGcmFjdCcpLFxuXHRcdFx0dmlld3BvcnQ6IChjdHgsIHByb3ApID0+IFtwcm9wLnZpZXdwb3J0LngsIHByb3Audmlld3BvcnQueSwgY3R4LnZpZXdwb3J0V2lkdGgsIGN0eC52aWV3cG9ydEhlaWdodF1cblx0XHR9LFxuXG5cdFx0YXR0cmlidXRlczoge1xuXHRcdFx0Ly9keW5hbWljIGF0dHJpYnV0ZXNcblx0XHRcdGNvbG9yOiB7XG5cdFx0XHRcdGJ1ZmZlcjogY29sb3JCdWZmZXIsXG5cdFx0XHRcdG9mZnNldDogKGN0eCwgcHJvcCkgPT4gcHJvcC5vZmZzZXQgKiA0LFxuXHRcdFx0XHRkaXZpc29yOiAxLFxuXHRcdFx0fSxcblx0XHRcdHBvc2l0aW9uOiB7XG5cdFx0XHRcdGJ1ZmZlcjogcG9zaXRpb25CdWZmZXIsXG5cdFx0XHRcdG9mZnNldDogKGN0eCwgcHJvcCkgPT4gcHJvcC5vZmZzZXQgKiA4LFxuXHRcdFx0XHRkaXZpc29yOiAxXG5cdFx0XHR9LFxuXHRcdFx0cG9zaXRpb25GcmFjdDoge1xuXHRcdFx0XHRidWZmZXI6IHBvc2l0aW9uRnJhY3RCdWZmZXIsXG5cdFx0XHRcdG9mZnNldDogKGN0eCwgcHJvcCkgPT4gcHJvcC5vZmZzZXQgKiA4LFxuXHRcdFx0XHRkaXZpc29yOiAxXG5cdFx0XHR9LFxuXHRcdFx0ZXJyb3I6IHtcblx0XHRcdFx0YnVmZmVyOiBlcnJvckJ1ZmZlcixcblx0XHRcdFx0b2Zmc2V0OiAoY3R4LCBwcm9wKSA9PiBwcm9wLm9mZnNldCAqIDE2LFxuXHRcdFx0XHRkaXZpc29yOiAxXG5cdFx0XHR9LFxuXG5cdFx0XHQvL3N0YXRpYyBhdHRyaWJ1dGVzXG5cdFx0XHRkaXJlY3Rpb246IHtcblx0XHRcdFx0YnVmZmVyOiBtZXNoQnVmZmVyLFxuXHRcdFx0XHRzdHJpZGU6IDI0LFxuXHRcdFx0XHRvZmZzZXQ6IDBcblx0XHRcdH0sXG5cdFx0XHRsaW5lT2Zmc2V0OiB7XG5cdFx0XHRcdGJ1ZmZlcjogbWVzaEJ1ZmZlcixcblx0XHRcdFx0c3RyaWRlOiAyNCxcblx0XHRcdFx0b2Zmc2V0OiA4XG5cdFx0XHR9LFxuXHRcdFx0Y2FwT2Zmc2V0OiB7XG5cdFx0XHRcdGJ1ZmZlcjogbWVzaEJ1ZmZlcixcblx0XHRcdFx0c3RyaWRlOiAyNCxcblx0XHRcdFx0b2Zmc2V0OiAxNlxuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRwcmltaXRpdmU6ICd0cmlhbmdsZXMnLFxuXG5cdFx0YmxlbmQ6IHtcblx0XHRcdGVuYWJsZTogdHJ1ZSxcblx0XHRcdGNvbG9yOiBbMCwwLDAsMF0sXG5cdFx0XHRlcXVhdGlvbjoge1xuXHRcdFx0XHRyZ2I6ICdhZGQnLFxuXHRcdFx0XHRhbHBoYTogJ2FkZCdcblx0XHRcdH0sXG5cdFx0XHRmdW5jOiB7XG5cdFx0XHRcdHNyY1JHQjogJ3NyYyBhbHBoYScsXG5cdFx0XHRcdGRzdFJHQjogJ29uZSBtaW51cyBzcmMgYWxwaGEnLFxuXHRcdFx0XHRzcmNBbHBoYTogJ29uZSBtaW51cyBkc3QgYWxwaGEnLFxuXHRcdFx0XHRkc3RBbHBoYTogJ29uZSdcblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0ZGVwdGg6IHtcblx0XHRcdGVuYWJsZTogZmFsc2Vcblx0XHR9LFxuXG5cdFx0c2Npc3Nvcjoge1xuXHRcdFx0ZW5hYmxlOiB0cnVlLFxuXHRcdFx0Ym94OiByZWdsLnByb3AoJ3ZpZXdwb3J0Jylcblx0XHR9LFxuXHRcdHZpZXdwb3J0OiByZWdsLnByb3AoJ3ZpZXdwb3J0JyksXG5cdFx0c3RlbmNpbDogZmFsc2UsXG5cblx0XHRpbnN0YW5jZXM6IHJlZ2wucHJvcCgnY291bnQnKSxcblx0XHRjb3VudDogV0VJR0hUUy5sZW5ndGhcblx0fSlcblxuXHQvL2V4cG9zZSBBUElcblx0ZXh0ZW5kKGVycm9yMmQsIHtcblx0XHR1cGRhdGU6IHVwZGF0ZSxcblx0XHRkcmF3OiBkcmF3LFxuXHRcdGRlc3Ryb3k6IGRlc3Ryb3ksXG5cdFx0cmVnbDogcmVnbCxcblx0XHRnbDogZ2wsXG5cdFx0Y2FudmFzOiBnbC5jYW52YXMsXG5cdFx0Z3JvdXBzOiBncm91cHNcblx0fSlcblxuXHRyZXR1cm4gZXJyb3IyZFxuXG5cdGZ1bmN0aW9uIGVycm9yMmQgKG9wdHMpIHtcblx0XHQvL3VwZGF0ZVxuXHRcdGlmIChvcHRzKSB7XG5cdFx0XHR1cGRhdGUob3B0cylcblx0XHR9XG5cblx0XHQvL2Rlc3Ryb3lcblx0XHRlbHNlIGlmIChvcHRzID09PSBudWxsKSB7XG5cdFx0XHRkZXN0cm95KClcblx0XHR9XG5cblx0XHRkcmF3KClcblx0fVxuXG5cblx0Ly9tYWluIGRyYXcgbWV0aG9kXG5cdGZ1bmN0aW9uIGRyYXcgKG9wdGlvbnMpIHtcblx0XHRpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdudW1iZXInKSByZXR1cm4gZHJhd0dyb3VwKG9wdGlvbnMpXG5cblx0XHQvL21ha2Ugb3B0aW9ucyBhIGJhdGNoXG5cdFx0aWYgKG9wdGlvbnMgJiYgIUFycmF5LmlzQXJyYXkob3B0aW9ucykpIG9wdGlvbnMgPSBbb3B0aW9uc11cblxuXG5cdFx0cmVnbC5fcmVmcmVzaCgpXG5cblx0XHQvL3JlbmRlciBtdWx0aXBsZSBwb2x5bGluZXMgdmlhIHJlZ2wgYmF0Y2hcblx0XHRncm91cHMuZm9yRWFjaCgocywgaSkgPT4ge1xuXHRcdFx0aWYgKCFzKSByZXR1cm5cblxuXHRcdFx0aWYgKG9wdGlvbnMpIHtcblx0XHRcdFx0aWYgKCFvcHRpb25zW2ldKSBzLmRyYXcgPSBmYWxzZVxuXHRcdFx0XHRlbHNlIHMuZHJhdyA9IHRydWVcblx0XHRcdH1cblxuXHRcdFx0Ly9pZ25vcmUgZHJhdyBmbGFnIGZvciBvbmUgcGFzc1xuXHRcdFx0aWYgKCFzLmRyYXcpIHtcblx0XHRcdFx0cy5kcmF3ID0gdHJ1ZTtcblx0XHRcdFx0cmV0dXJuXG5cdFx0XHR9XG5cblx0XHRcdGRyYXdHcm91cChpKVxuXHRcdH0pXG5cdH1cblxuXHQvL2RyYXcgc2luZ2xlIGVycm9yIGdyb3VwIGJ5IGlkXG5cdGZ1bmN0aW9uIGRyYXdHcm91cCAocykge1xuXHRcdGlmICh0eXBlb2YgcyA9PT0gJ251bWJlcicpIHMgPSBncm91cHNbc11cblx0XHRpZiAocyA9PSBudWxsKSByZXR1cm5cblxuXHRcdGlmICghKHMgJiYgcy5jb3VudCAmJiBzLmNvbG9yICYmIHMub3BhY2l0eSAmJiBzLnBvc2l0aW9ucyAmJiBzLnBvc2l0aW9ucy5sZW5ndGggPiAxKSkgcmV0dXJuXG5cblx0XHRzLnNjYWxlUmF0aW8gPSBbXG5cdFx0XHRzLnNjYWxlWzBdICogcy52aWV3cG9ydC53aWR0aCxcblx0XHRcdHMuc2NhbGVbMV0gKiBzLnZpZXdwb3J0LmhlaWdodFxuXHRcdF1cblxuXHRcdGRyYXdFcnJvcnMocylcblxuXHRcdGlmIChzLmFmdGVyKSBzLmFmdGVyKHMpXG5cdH1cblxuXHRmdW5jdGlvbiB1cGRhdGUgKG9wdGlvbnMpIHtcblx0XHRpZiAoIW9wdGlvbnMpIHJldHVyblxuXG5cdFx0Ly9kaXJlY3QgcG9pbnRzIGFyZ3VtZW50XG5cdFx0aWYgKG9wdGlvbnMubGVuZ3RoICE9IG51bGwpIHtcblx0XHRcdGlmICh0eXBlb2Ygb3B0aW9uc1swXSA9PT0gJ251bWJlcicpIG9wdGlvbnMgPSBbe3Bvc2l0aW9uczogb3B0aW9uc31dXG5cdFx0fVxuXG5cdFx0Ly9tYWtlIG9wdGlvbnMgYSBiYXRjaFxuXHRcdGVsc2UgaWYgKCFBcnJheS5pc0FycmF5KG9wdGlvbnMpKSBvcHRpb25zID0gW29wdGlvbnNdXG5cblx0XHQvL2dsb2JhbCBjb3VudCBvZiBwb2ludHNcblx0XHRsZXQgcG9pbnRDb3VudCA9IDAsIGVycm9yQ291bnQgPSAwXG5cblx0XHRlcnJvcjJkLmdyb3VwcyA9IGdyb3VwcyA9IG9wdGlvbnMubWFwKChvcHRpb25zLCBpKSA9PiB7XG5cdFx0XHRsZXQgZ3JvdXAgPSBncm91cHNbaV1cblxuXHRcdFx0aWYgKCFvcHRpb25zKSByZXR1cm4gZ3JvdXBcblx0XHRcdGVsc2UgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnZnVuY3Rpb24nKSBvcHRpb25zID0ge2FmdGVyOiBvcHRpb25zfVxuXHRcdFx0ZWxzZSBpZiAodHlwZW9mIG9wdGlvbnNbMF0gPT09ICdudW1iZXInKSBvcHRpb25zID0ge3Bvc2l0aW9uczogb3B0aW9uc31cblxuXHRcdFx0Ly9jb3B5IG9wdGlvbnMgdG8gYXZvaWQgbXV0YXRpb24gJiBoYW5kbGUgYWxpYXNlc1xuXHRcdFx0b3B0aW9ucyA9IHBpY2sob3B0aW9ucywge1xuXHRcdFx0XHRjb2xvcjogJ2NvbG9yIGNvbG9ycyBmaWxsJyxcblx0XHRcdFx0Y2FwU2l6ZTogJ2NhcFNpemUgY2FwIGNhcHNpemUgY2FwLXNpemUnLFxuXHRcdFx0XHRsaW5lV2lkdGg6ICdsaW5lV2lkdGggbGluZS13aWR0aCB3aWR0aCBsaW5lIHRoaWNrbmVzcycsXG5cdFx0XHRcdG9wYWNpdHk6ICdvcGFjaXR5IGFscGhhJyxcblx0XHRcdFx0cmFuZ2U6ICdyYW5nZSBkYXRhQm94Jyxcblx0XHRcdFx0dmlld3BvcnQ6ICd2aWV3cG9ydCB2aWV3Qm94Jyxcblx0XHRcdFx0ZXJyb3JzOiAnZXJyb3JzIGVycm9yJyxcblx0XHRcdFx0cG9zaXRpb25zOiAncG9zaXRpb25zIHBvc2l0aW9uIGRhdGEgcG9pbnRzJ1xuXHRcdFx0fSlcblxuXHRcdFx0aWYgKCFncm91cCkge1xuXHRcdFx0XHRncm91cHNbaV0gPSBncm91cCA9IHtcblx0XHRcdFx0XHRpZDogaSxcblx0XHRcdFx0XHRzY2FsZTogbnVsbCxcblx0XHRcdFx0XHR0cmFuc2xhdGU6IG51bGwsXG5cdFx0XHRcdFx0c2NhbGVGcmFjdDogbnVsbCxcblx0XHRcdFx0XHR0cmFuc2xhdGVGcmFjdDogbnVsbCxcblx0XHRcdFx0XHRkcmF3OiB0cnVlXG5cdFx0XHRcdH1cblx0XHRcdFx0b3B0aW9ucyA9IGV4dGVuZCh7fSwgZGVmYXVsdHMsIG9wdGlvbnMpXG5cdFx0XHR9XG5cblx0XHRcdHVwZGF0ZURpZmYoZ3JvdXAsIG9wdGlvbnMsIFt7XG5cdFx0XHRcdGxpbmVXaWR0aDogdiA9PiArdiAqIC41LFxuXHRcdFx0XHRjYXBTaXplOiB2ID0+ICt2ICogLjUsXG5cdFx0XHRcdG9wYWNpdHk6IHBhcnNlRmxvYXQsXG5cdFx0XHRcdGVycm9yczogZXJyb3JzID0+IHtcblx0XHRcdFx0XHRlcnJvcnMgPSBmbGF0dGVuKGVycm9ycylcblxuXHRcdFx0XHRcdGVycm9yQ291bnQgKz0gZXJyb3JzLmxlbmd0aFxuXHRcdFx0XHRcdHJldHVybiBlcnJvcnNcblx0XHRcdFx0fSxcblx0XHRcdFx0cG9zaXRpb25zOiAocG9zaXRpb25zLCBzdGF0ZSkgPT4ge1xuXHRcdFx0XHRcdHBvc2l0aW9ucyA9IGZsYXR0ZW4ocG9zaXRpb25zLCAnZmxvYXQ2NCcpXG5cdFx0XHRcdFx0c3RhdGUuY291bnQgPSBNYXRoLmZsb29yKHBvc2l0aW9ucy5sZW5ndGggLyAyKVxuXHRcdFx0XHRcdHN0YXRlLmJvdW5kcyA9IGdldEJvdW5kcyhwb3NpdGlvbnMsIDIpXG5cdFx0XHRcdFx0c3RhdGUub2Zmc2V0ID0gcG9pbnRDb3VudFxuXG5cdFx0XHRcdFx0cG9pbnRDb3VudCArPSBzdGF0ZS5jb3VudFxuXG5cdFx0XHRcdFx0cmV0dXJuIHBvc2l0aW9uc1xuXHRcdFx0XHR9XG5cdFx0XHR9LCB7XG5cdFx0XHRcdGNvbG9yOiAoY29sb3JzLCBzdGF0ZSkgPT4ge1xuXHRcdFx0XHRcdGxldCBjb3VudCA9IHN0YXRlLmNvdW50XG5cblx0XHRcdFx0XHRpZiAoIWNvbG9ycykgY29sb3JzID0gJ3RyYW5zcGFyZW50J1xuXG5cdFx0XHRcdFx0Ly8gJ2JsYWNrJyBvciBbMCwwLDAsMF0gY2FzZVxuXHRcdFx0XHRcdGlmICghQXJyYXkuaXNBcnJheShjb2xvcnMpIHx8IHR5cGVvZiBjb2xvcnNbMF0gPT09ICdudW1iZXInKSB7XG5cdFx0XHRcdFx0XHRsZXQgY29sb3IgPSBjb2xvcnNcblx0XHRcdFx0XHRcdGNvbG9ycyA9IEFycmF5KGNvdW50KVxuXHRcdFx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG5cdFx0XHRcdFx0XHRcdGNvbG9yc1tpXSA9IGNvbG9yXG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0aWYgKGNvbG9ycy5sZW5ndGggPCBjb3VudCkgdGhyb3cgRXJyb3IoJ05vdCBlbm91Z2ggY29sb3JzJylcblxuXHRcdFx0XHRcdGxldCBjb2xvckRhdGEgPSBuZXcgVWludDhBcnJheShjb3VudCAqIDQpXG5cblx0XHRcdFx0XHQvL2NvbnZlcnQgY29sb3JzIHRvIGZsb2F0IGFycmF5c1xuXHRcdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuXHRcdFx0XHRcdFx0bGV0IGMgPSByZ2JhKGNvbG9yc1tpXSwgJ3VpbnQ4Jylcblx0XHRcdFx0XHRcdGNvbG9yRGF0YS5zZXQoYywgaSAqIDQpXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cmV0dXJuIGNvbG9yRGF0YVxuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdHJhbmdlOiAocmFuZ2UsIHN0YXRlLCBvcHRpb25zKSA9PiB7XG5cdFx0XHRcdFx0bGV0IGJvdW5kcyA9IHN0YXRlLmJvdW5kc1xuXHRcdFx0XHRcdGlmICghcmFuZ2UpIHJhbmdlID0gYm91bmRzXG5cblx0XHRcdFx0XHRzdGF0ZS5zY2FsZSA9IFsxIC8gKHJhbmdlWzJdIC0gcmFuZ2VbMF0pLCAxIC8gKHJhbmdlWzNdIC0gcmFuZ2VbMV0pXVxuXHRcdFx0XHRcdHN0YXRlLnRyYW5zbGF0ZSA9IFstcmFuZ2VbMF0sIC1yYW5nZVsxXV1cblxuXHRcdFx0XHRcdHN0YXRlLnNjYWxlRnJhY3QgPSBmcmFjdDMyKHN0YXRlLnNjYWxlKVxuXHRcdFx0XHRcdHN0YXRlLnRyYW5zbGF0ZUZyYWN0ID0gZnJhY3QzMihzdGF0ZS50cmFuc2xhdGUpXG5cblx0XHRcdFx0XHRyZXR1cm4gcmFuZ2Vcblx0XHRcdFx0fSxcblxuXHRcdFx0XHR2aWV3cG9ydDogdnAgPT4ge1xuXHRcdFx0XHRcdGxldCB2aWV3cG9ydFxuXG5cdFx0XHRcdFx0aWYgKEFycmF5LmlzQXJyYXkodnApKSB7XG5cdFx0XHRcdFx0XHR2aWV3cG9ydCA9IHtcblx0XHRcdFx0XHRcdFx0eDogdnBbMF0sXG5cdFx0XHRcdFx0XHRcdHk6IHZwWzFdLFxuXHRcdFx0XHRcdFx0XHR3aWR0aDogdnBbMl0gLSB2cFswXSxcblx0XHRcdFx0XHRcdFx0aGVpZ2h0OiB2cFszXSAtIHZwWzFdXG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGVsc2UgaWYgKHZwKSB7XG5cdFx0XHRcdFx0XHR2aWV3cG9ydCA9IHtcblx0XHRcdFx0XHRcdFx0eDogdnAueCB8fCB2cC5sZWZ0IHx8IDAsXG5cdFx0XHRcdFx0XHRcdHk6IHZwLnkgfHwgdnAudG9wIHx8IDBcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0aWYgKHZwLnJpZ2h0KSB2aWV3cG9ydC53aWR0aCA9IHZwLnJpZ2h0IC0gdmlld3BvcnQueFxuXHRcdFx0XHRcdFx0ZWxzZSB2aWV3cG9ydC53aWR0aCA9IHZwLncgfHwgdnAud2lkdGggfHwgMFxuXG5cdFx0XHRcdFx0XHRpZiAodnAuYm90dG9tKSB2aWV3cG9ydC5oZWlnaHQgPSB2cC5ib3R0b20gLSB2aWV3cG9ydC55XG5cdFx0XHRcdFx0XHRlbHNlIHZpZXdwb3J0LmhlaWdodCA9IHZwLmggfHwgdnAuaGVpZ2h0IHx8IDBcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0XHR2aWV3cG9ydCA9IHtcblx0XHRcdFx0XHRcdFx0eDogMCwgeTogMCxcblx0XHRcdFx0XHRcdFx0d2lkdGg6IGdsLmRyYXdpbmdCdWZmZXJXaWR0aCxcblx0XHRcdFx0XHRcdFx0aGVpZ2h0OiBnbC5kcmF3aW5nQnVmZmVySGVpZ2h0XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cmV0dXJuIHZpZXdwb3J0XG5cdFx0XHRcdH1cblx0XHRcdH1dKVxuXG5cdFx0XHRyZXR1cm4gZ3JvdXBcblx0XHR9KVxuXG5cdFx0aWYgKHBvaW50Q291bnQgfHwgZXJyb3JDb3VudCkge1xuXHRcdFx0bGV0IGxlbiA9IGdyb3Vwcy5yZWR1Y2UoKGFjYywgZ3JvdXAsIGkpID0+IHtcblx0XHRcdFx0cmV0dXJuIGFjYyArIChncm91cCA/IGdyb3VwLmNvdW50IDogMClcblx0XHRcdH0sIDApXG5cblx0XHRcdGxldCBwb3NpdGlvbkRhdGEgPSBuZXcgRmxvYXQ2NEFycmF5KGxlbiAqIDIpXG5cdFx0XHRsZXQgY29sb3JEYXRhID0gbmV3IFVpbnQ4QXJyYXkobGVuICogNClcblx0XHRcdGxldCBlcnJvckRhdGEgPSBuZXcgRmxvYXQzMkFycmF5KGxlbiAqIDQpXG5cblx0XHRcdGdyb3Vwcy5mb3JFYWNoKChncm91cCwgaSkgPT4ge1xuXHRcdFx0XHRpZiAoIWdyb3VwKSByZXR1cm5cblx0XHRcdFx0bGV0IHtwb3NpdGlvbnMsIGNvdW50LCBvZmZzZXQsIGNvbG9yLCBlcnJvcnN9ID0gZ3JvdXBcblx0XHRcdFx0aWYgKCFjb3VudCkgcmV0dXJuXG5cblx0XHRcdFx0Y29sb3JEYXRhLnNldChjb2xvciwgb2Zmc2V0ICogNClcblx0XHRcdFx0ZXJyb3JEYXRhLnNldChlcnJvcnMsIG9mZnNldCAqIDQpXG5cdFx0XHRcdHBvc2l0aW9uRGF0YS5zZXQocG9zaXRpb25zLCBvZmZzZXQgKiAyKVxuXHRcdFx0fSlcblxuXHRcdFx0cG9zaXRpb25CdWZmZXIoZmxvYXQzMihwb3NpdGlvbkRhdGEpKVxuXHRcdFx0cG9zaXRpb25GcmFjdEJ1ZmZlcihmcmFjdDMyKHBvc2l0aW9uRGF0YSkpXG5cdFx0XHRjb2xvckJ1ZmZlcihjb2xvckRhdGEpXG5cdFx0XHRlcnJvckJ1ZmZlcihlcnJvckRhdGEpXG5cdFx0fVxuXG5cdH1cblxuXHRmdW5jdGlvbiBkZXN0cm95ICgpIHtcblx0XHRwb3NpdGlvbkJ1ZmZlci5kZXN0cm95KClcblx0XHRwb3NpdGlvbkZyYWN0QnVmZmVyLmRlc3Ryb3koKVxuXHRcdGNvbG9yQnVmZmVyLmRlc3Ryb3koKVxuXHRcdGVycm9yQnVmZmVyLmRlc3Ryb3koKVxuXHRcdG1lc2hCdWZmZXIuZGVzdHJveSgpXG5cdH1cbn1cbiJdLCJuYW1lcyI6WyJjb25zdCIsImxldCIsImkiXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFDWjtBQUNBQSxHQUFLLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxjQUFjLENBQUM7QUFDekNBLEdBQUssQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDO0FBQ3ZDQSxHQUFLLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUM7QUFDekNBLEdBQUssQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQztBQUNyQ0EsR0FBSyxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO0FBQ3ZDQSxHQUFLLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQztPQUN0QixHQUFHLE9BQU8sQ0FBQyxZQUFZO0FBQXhDO0FBQVMsMEJBQWdDO0FBQ2hEO0FBQ0EsTUFBTSxDQUFDLE9BQU8sR0FBRyxPQUFPO0FBQ3hCO0FBQ0FBLEdBQUssQ0FBQyxPQUFPLEdBQUc7QUFDaEI7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ25CLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3BCLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDckI7QUFDQSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3JCLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3BCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNuQjtBQUNBO0FBQ0EsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDcEIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNyQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNwQjtBQUNBLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3BCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNuQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNwQjtBQUNBO0FBQ0EsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNyQixDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDdEIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNyQjtBQUNBLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDckIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDcEIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNyQjtBQUNBO0FBQ0EsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ25CLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3BCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDckI7QUFDQSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3JCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNuQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNwQjtBQUNBO0FBQ0EsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDcEIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNyQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNwQjtBQUNBLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNuQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNwQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNwQjtBQUNBO0FBQ0EsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNyQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDdEIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNyQjtBQUNBLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3BCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDckIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNyQixDQUFDO0FBQ0Q7QUFDQTtBQUNBLFNBQVMsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUU7QUFDakMsQ0FBQyxJQUFJLE9BQU8sSUFBSSxLQUFLLFVBQVUsRUFBRTtBQUNqQyxFQUFFLElBQUksQ0FBQyxPQUFPLElBQUUsT0FBTyxHQUFHLElBQUU7QUFDNUIsRUFBRSxPQUFPLENBQUMsSUFBSSxHQUFHLElBQUk7QUFDckIsRUFBRTtBQUNGLE1BQU07QUFDTixFQUFFLE9BQU8sR0FBRyxJQUFJO0FBQ2hCLEVBQUU7QUFDRixDQUFDLElBQUksT0FBTyxDQUFDLE1BQU0sSUFBRSxPQUFPLENBQUMsU0FBUyxHQUFHLFNBQU87QUFDaEQsQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUk7QUFDcEI7QUFDQSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLHdCQUF3QixDQUFDLEVBQUU7QUFDbkQsRUFBRSxNQUFNLEtBQUssQ0FBQyxvRUFBb0UsQ0FBQyxDQUFDO0FBQ3BGLEVBQUU7QUFDRjtBQUNBO0FBQ0EsQ0FBQ0MsR0FBRyxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLFVBQVUsRUFBRSxjQUFjLEVBQUUsbUJBQW1CLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxVQUFVO0FBQ3pHLEdBQUcsUUFBUSxHQUFHO0FBQ2QsSUFBSSxLQUFLLEVBQUUsT0FBTztBQUNsQixJQUFJLE9BQU8sRUFBRSxDQUFDO0FBQ2QsSUFBSSxTQUFTLEVBQUUsQ0FBQztBQUNoQixJQUFJLE9BQU8sRUFBRSxDQUFDO0FBQ2QsSUFBSSxRQUFRLEVBQUUsSUFBSTtBQUNsQixJQUFJLEtBQUssRUFBRSxJQUFJO0FBQ2YsSUFBSSxNQUFNLEVBQUUsQ0FBQztBQUNiLElBQUksS0FBSyxFQUFFLENBQUM7QUFDWixJQUFJLE1BQU0sRUFBRSxJQUFJO0FBQ2hCLElBQUksU0FBUyxFQUFFLEVBQUU7QUFDakIsSUFBSSxNQUFNLEVBQUUsRUFBRTtBQUNkLElBQUksRUFBRSxNQUFNLEdBQUcsRUFBRTtBQUNqQjtBQUNBO0FBQ0EsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUMzQixFQUFFLEtBQUssRUFBRSxTQUFTO0FBQ2xCLEVBQUUsSUFBSSxFQUFFLE9BQU87QUFDZixFQUFFLElBQUksRUFBRSxJQUFJLFVBQVUsQ0FBQyxDQUFDLENBQUM7QUFDekIsRUFBRSxDQUFDO0FBQ0g7QUFDQSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO0FBQzlCLEVBQUUsS0FBSyxFQUFFLFNBQVM7QUFDbEIsRUFBRSxJQUFJLEVBQUUsT0FBTztBQUNmLEVBQUUsSUFBSSxFQUFFLElBQUksVUFBVSxDQUFDLENBQUMsQ0FBQztBQUN6QixFQUFFLENBQUM7QUFDSDtBQUNBLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUNuQyxFQUFFLEtBQUssRUFBRSxTQUFTO0FBQ2xCLEVBQUUsSUFBSSxFQUFFLE9BQU87QUFDZixFQUFFLElBQUksRUFBRSxJQUFJLFVBQVUsQ0FBQyxDQUFDLENBQUM7QUFDekIsRUFBRSxDQUFDO0FBQ0g7QUFDQSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO0FBQzNCLEVBQUUsS0FBSyxFQUFFLFNBQVM7QUFDbEIsRUFBRSxJQUFJLEVBQUUsT0FBTztBQUNmLEVBQUUsSUFBSSxFQUFFLElBQUksVUFBVSxDQUFDLENBQUMsQ0FBQztBQUN6QixFQUFFLENBQUM7QUFDSDtBQUNBLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7QUFDMUIsRUFBRSxLQUFLLEVBQUUsUUFBUTtBQUNqQixFQUFFLElBQUksRUFBRSxPQUFPO0FBQ2YsRUFBRSxJQUFJLEVBQUUsT0FBTztBQUNmLEVBQUUsQ0FBQztBQUNIO0FBQ0EsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDO0FBQ2hCO0FBQ0E7QUFDQSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7QUFDbkIsRUFBRSxJQUFJLEVBQUUsbTdCQWlDTDtBQUNIO0FBQ0EsRUFBRSxJQUFJLEVBQUUsZ01BV0w7QUFDSDtBQUNBLEVBQUUsUUFBUSxFQUFFO0FBQ1osR0FBRyxLQUFLLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7QUFDNUIsR0FBRyxTQUFTLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7QUFDcEMsR0FBRyxPQUFPLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7QUFDaEMsR0FBRyxPQUFPLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7QUFDaEMsR0FBRyxLQUFLLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7QUFDNUIsR0FBRyxTQUFTLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7QUFDcEMsR0FBRyxVQUFVLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUM7QUFDdEMsR0FBRyxjQUFjLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztBQUM5QyxHQUFHLFFBQVEsV0FBRSxDQUFDLEdBQUcsRUFBRSxJQUFJLFdBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsYUFBYSxFQUFFLEdBQUcsQ0FBQyxjQUFjLElBQUM7QUFDckcsR0FBRztBQUNIO0FBQ0EsRUFBRSxVQUFVLEVBQUU7QUFDZDtBQUNBLEdBQUcsS0FBSyxFQUFFO0FBQ1YsSUFBSSxNQUFNLEVBQUUsV0FBVztBQUN2QixJQUFJLE1BQU0sV0FBRSxDQUFDLEdBQUcsRUFBRSxJQUFJLFdBQUssSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFDO0FBQzFDLElBQUksT0FBTyxFQUFFLENBQUM7QUFDZCxJQUFJO0FBQ0osR0FBRyxRQUFRLEVBQUU7QUFDYixJQUFJLE1BQU0sRUFBRSxjQUFjO0FBQzFCLElBQUksTUFBTSxXQUFFLENBQUMsR0FBRyxFQUFFLElBQUksV0FBSyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUM7QUFDMUMsSUFBSSxPQUFPLEVBQUUsQ0FBQztBQUNkLElBQUk7QUFDSixHQUFHLGFBQWEsRUFBRTtBQUNsQixJQUFJLE1BQU0sRUFBRSxtQkFBbUI7QUFDL0IsSUFBSSxNQUFNLFdBQUUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxXQUFLLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBQztBQUMxQyxJQUFJLE9BQU8sRUFBRSxDQUFDO0FBQ2QsSUFBSTtBQUNKLEdBQUcsS0FBSyxFQUFFO0FBQ1YsSUFBSSxNQUFNLEVBQUUsV0FBVztBQUN2QixJQUFJLE1BQU0sV0FBRSxDQUFDLEdBQUcsRUFBRSxJQUFJLFdBQUssSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFFO0FBQzNDLElBQUksT0FBTyxFQUFFLENBQUM7QUFDZCxJQUFJO0FBQ0o7QUFDQTtBQUNBLEdBQUcsU0FBUyxFQUFFO0FBQ2QsSUFBSSxNQUFNLEVBQUUsVUFBVTtBQUN0QixJQUFJLE1BQU0sRUFBRSxFQUFFO0FBQ2QsSUFBSSxNQUFNLEVBQUUsQ0FBQztBQUNiLElBQUk7QUFDSixHQUFHLFVBQVUsRUFBRTtBQUNmLElBQUksTUFBTSxFQUFFLFVBQVU7QUFDdEIsSUFBSSxNQUFNLEVBQUUsRUFBRTtBQUNkLElBQUksTUFBTSxFQUFFLENBQUM7QUFDYixJQUFJO0FBQ0osR0FBRyxTQUFTLEVBQUU7QUFDZCxJQUFJLE1BQU0sRUFBRSxVQUFVO0FBQ3RCLElBQUksTUFBTSxFQUFFLEVBQUU7QUFDZCxJQUFJLE1BQU0sRUFBRSxFQUFFO0FBQ2QsSUFBSTtBQUNKLEdBQUc7QUFDSDtBQUNBLEVBQUUsU0FBUyxFQUFFLFdBQVc7QUFDeEI7QUFDQSxFQUFFLEtBQUssRUFBRTtBQUNULEdBQUcsTUFBTSxFQUFFLElBQUk7QUFDZixHQUFHLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQixHQUFHLFFBQVEsRUFBRTtBQUNiLElBQUksR0FBRyxFQUFFLEtBQUs7QUFDZCxJQUFJLEtBQUssRUFBRSxLQUFLO0FBQ2hCLElBQUk7QUFDSixHQUFHLElBQUksRUFBRTtBQUNULElBQUksTUFBTSxFQUFFLFdBQVc7QUFDdkIsSUFBSSxNQUFNLEVBQUUscUJBQXFCO0FBQ2pDLElBQUksUUFBUSxFQUFFLHFCQUFxQjtBQUNuQyxJQUFJLFFBQVEsRUFBRSxLQUFLO0FBQ25CLElBQUk7QUFDSixHQUFHO0FBQ0g7QUFDQSxFQUFFLEtBQUssRUFBRTtBQUNULEdBQUcsTUFBTSxFQUFFLEtBQUs7QUFDaEIsR0FBRztBQUNIO0FBQ0EsRUFBRSxPQUFPLEVBQUU7QUFDWCxHQUFHLE1BQU0sRUFBRSxJQUFJO0FBQ2YsR0FBRyxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7QUFDN0IsR0FBRztBQUNILEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO0FBQ2pDLEVBQUUsT0FBTyxFQUFFLEtBQUs7QUFDaEI7QUFDQSxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztBQUMvQixFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsTUFBTTtBQUN2QixFQUFFLENBQUM7QUFDSDtBQUNBO0FBQ0EsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFO0FBQ2pCLEVBQUUsTUFBTSxFQUFFLE1BQU07QUFDaEIsRUFBRSxJQUFJLEVBQUUsSUFBSTtBQUNaLEVBQUUsT0FBTyxFQUFFLE9BQU87QUFDbEIsRUFBRSxJQUFJLEVBQUUsSUFBSTtBQUNaLEVBQUUsRUFBRSxFQUFFLEVBQUU7QUFDUixFQUFFLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTTtBQUNuQixFQUFFLE1BQU0sRUFBRSxNQUFNO0FBQ2hCLEVBQUUsQ0FBQztBQUNIO0FBQ0EsQ0FBQyxPQUFPLE9BQU87QUFDZjtBQUNBLENBQUMsU0FBUyxPQUFPLEVBQUUsSUFBSSxFQUFFO0FBQ3pCO0FBQ0EsRUFBRSxJQUFJLElBQUksRUFBRTtBQUNaLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQztBQUNmLEdBQUc7QUFDSDtBQUNBO0FBQ0EsT0FBTyxJQUFJLElBQUksS0FBSyxJQUFJLEVBQUU7QUFDMUIsR0FBRyxPQUFPLEVBQUU7QUFDWixHQUFHO0FBQ0g7QUFDQSxFQUFFLElBQUksRUFBRTtBQUNSLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxDQUFDLFNBQVMsSUFBSSxFQUFFLE9BQU8sRUFBRTtBQUN6QixFQUFFLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxJQUFFLE9BQU8sU0FBUyxDQUFDLE9BQU8sR0FBQztBQUM1RDtBQUNBO0FBQ0EsRUFBRSxJQUFJLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUUsT0FBTyxHQUFHLENBQUMsT0FBTyxHQUFDO0FBQzdEO0FBQ0E7QUFDQSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUU7QUFDakI7QUFDQTtBQUNBLEVBQUUsTUFBTSxDQUFDLE9BQU8sVUFBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUs7QUFDM0IsR0FBRyxJQUFJLENBQUMsQ0FBQyxJQUFFLFFBQU07QUFDakI7QUFDQSxHQUFHLElBQUksT0FBTyxFQUFFO0FBQ2hCLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBRSxDQUFDLENBQUMsSUFBSSxHQUFHLE9BQUs7QUFDbkMsV0FBUyxDQUFDLENBQUMsSUFBSSxHQUFHLE1BQUk7QUFDdEIsSUFBSTtBQUNKO0FBQ0E7QUFDQSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFO0FBQ2hCLElBQUksQ0FBQyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7QUFDbEIsSUFBSSxNQUFNO0FBQ1YsSUFBSTtBQUNKO0FBQ0EsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDO0FBQ2YsR0FBRyxDQUFDO0FBQ0osRUFBRTtBQUNGO0FBQ0E7QUFDQSxDQUFDLFNBQVMsU0FBUyxFQUFFLENBQUMsRUFBRTtBQUN4QixFQUFFLElBQUksT0FBTyxDQUFDLEtBQUssUUFBUSxJQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxHQUFDO0FBQzFDLEVBQUUsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFFLFFBQU07QUFDdkI7QUFDQSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxJQUFFLFFBQU07QUFDOUY7QUFDQSxFQUFFLENBQUMsQ0FBQyxVQUFVLEdBQUc7QUFDakIsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSztBQUNoQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNO0FBQ2pDLEdBQUc7QUFDSDtBQUNBLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQztBQUNmO0FBQ0EsRUFBRSxJQUFJLENBQUMsQ0FBQyxLQUFLLElBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUM7QUFDekIsRUFBRTtBQUNGO0FBQ0EsQ0FBQyxTQUFTLE1BQU0sRUFBRSxPQUFPLEVBQUU7QUFDM0IsRUFBRSxJQUFJLENBQUMsT0FBTyxJQUFFLFFBQU07QUFDdEI7QUFDQTtBQUNBLEVBQUUsSUFBSSxPQUFPLENBQUMsTUFBTSxJQUFJLElBQUksRUFBRTtBQUM5QixHQUFHLElBQUksT0FBTyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssUUFBUSxJQUFFLE9BQU8sR0FBRyxDQUFDLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxHQUFDO0FBQ3ZFLEdBQUc7QUFDSDtBQUNBO0FBQ0EsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBRSxPQUFPLEdBQUcsQ0FBQyxPQUFPLEdBQUM7QUFDdkQ7QUFDQTtBQUNBLEVBQUVBLEdBQUcsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxFQUFFLFVBQVUsR0FBRyxDQUFDO0FBQ3BDO0FBQ0EsRUFBRSxPQUFPLENBQUMsTUFBTSxHQUFHLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxVQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBSztBQUN4RCxHQUFHQSxHQUFHLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDeEI7QUFDQSxHQUFHLElBQUksQ0FBQyxPQUFPLElBQUUsT0FBTyxPQUFLO0FBQzdCLFFBQVEsSUFBSSxPQUFPLE9BQU8sS0FBSyxVQUFVLElBQUUsT0FBTyxHQUFHLENBQUMsS0FBSyxFQUFFLE9BQU8sR0FBQztBQUNyRSxRQUFRLElBQUksT0FBTyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssUUFBUSxJQUFFLE9BQU8sR0FBRyxDQUFDLFNBQVMsRUFBRSxPQUFPLEdBQUM7QUFDMUU7QUFDQTtBQUNBLEdBQUcsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUU7QUFDM0IsSUFBSSxLQUFLLEVBQUUsbUJBQW1CO0FBQzlCLElBQUksT0FBTyxFQUFFLDhCQUE4QjtBQUMzQyxJQUFJLFNBQVMsRUFBRSwyQ0FBMkM7QUFDMUQsSUFBSSxPQUFPLEVBQUUsZUFBZTtBQUM1QixJQUFJLEtBQUssRUFBRSxlQUFlO0FBQzFCLElBQUksUUFBUSxFQUFFLGtCQUFrQjtBQUNoQyxJQUFJLE1BQU0sRUFBRSxjQUFjO0FBQzFCLElBQUksU0FBUyxFQUFFLGdDQUFnQztBQUMvQyxJQUFJLENBQUM7QUFDTDtBQUNBLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRTtBQUNmLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssR0FBRztBQUN4QixLQUFLLEVBQUUsRUFBRSxDQUFDO0FBQ1YsS0FBSyxLQUFLLEVBQUUsSUFBSTtBQUNoQixLQUFLLFNBQVMsRUFBRSxJQUFJO0FBQ3BCLEtBQUssVUFBVSxFQUFFLElBQUk7QUFDckIsS0FBSyxjQUFjLEVBQUUsSUFBSTtBQUN6QixLQUFLLElBQUksRUFBRSxJQUFJO0FBQ2YsS0FBSztBQUNMLElBQUksT0FBTyxHQUFHLE1BQU0sQ0FBQyxFQUFFLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQztBQUMzQyxJQUFJO0FBQ0o7QUFDQSxHQUFHLFVBQVUsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLENBQUM7QUFDL0IsSUFBSSxTQUFTLFlBQUUsRUFBQyxVQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUU7QUFDM0IsSUFBSSxPQUFPLFlBQUUsRUFBQyxVQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUU7QUFDekIsSUFBSSxPQUFPLEVBQUUsVUFBVTtBQUN2QixJQUFJLE1BQU0sWUFBRSxPQUFNLENBQUk7QUFDdEIsS0FBSyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztBQUM3QjtBQUNBLEtBQUssVUFBVSxJQUFJLE1BQU0sQ0FBQyxNQUFNO0FBQ2hDLEtBQUssT0FBTyxNQUFNO0FBQ2xCLEtBQUs7QUFDTCxJQUFJLFNBQVMsV0FBRSxDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUs7QUFDckMsS0FBSyxTQUFTLEdBQUcsT0FBTyxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUM7QUFDOUMsS0FBSyxLQUFLLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFDbkQsS0FBSyxLQUFLLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO0FBQzNDLEtBQUssS0FBSyxDQUFDLE1BQU0sR0FBRyxVQUFVO0FBQzlCO0FBQ0EsS0FBSyxVQUFVLElBQUksS0FBSyxDQUFDLEtBQUs7QUFDOUI7QUFDQSxLQUFLLE9BQU8sU0FBUztBQUNyQixLQUFLO0FBQ0wsSUFBSSxFQUFFO0FBQ04sSUFBSSxLQUFLLFdBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFLO0FBQzlCLEtBQUtBLEdBQUcsQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUs7QUFDNUI7QUFDQSxLQUFLLElBQUksQ0FBQyxNQUFNLElBQUUsTUFBTSxHQUFHLGVBQWE7QUFDeEM7QUFDQTtBQUNBLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssUUFBUSxFQUFFO0FBQ2xFLE1BQU1BLEdBQUcsQ0FBQyxLQUFLLEdBQUcsTUFBTTtBQUN4QixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDO0FBQzNCLE1BQU0sS0FBS0EsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUN0QyxPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLO0FBQ3hCLE9BQU87QUFDUCxNQUFNO0FBQ047QUFDQSxLQUFLLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxLQUFLLElBQUUsTUFBTSxLQUFLLENBQUMsbUJBQW1CLEdBQUM7QUFDaEU7QUFDQSxLQUFLQSxHQUFHLENBQUMsU0FBUyxHQUFHLElBQUksVUFBVSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7QUFDOUM7QUFDQTtBQUNBLEtBQUssS0FBS0EsR0FBRyxDQUFDQyxHQUFDLEdBQUcsQ0FBQyxFQUFFQSxHQUFDLEdBQUcsS0FBSyxFQUFFQSxHQUFDLEVBQUUsRUFBRTtBQUNyQyxNQUFNRCxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUNDLEdBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQztBQUN0QyxNQUFNLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFQSxHQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLE1BQU07QUFDTjtBQUNBLEtBQUssT0FBTyxTQUFTO0FBQ3JCLEtBQUs7QUFDTDtBQUNBLElBQUksS0FBSyxXQUFFLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUs7QUFDdEMsS0FBS0QsR0FBRyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTTtBQUM5QixLQUFLLElBQUksQ0FBQyxLQUFLLElBQUUsS0FBSyxHQUFHLFFBQU07QUFDL0I7QUFDQSxLQUFLLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pFLEtBQUssS0FBSyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdDO0FBQ0EsS0FBSyxLQUFLLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO0FBQzVDLEtBQUssS0FBSyxDQUFDLGNBQWMsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztBQUNwRDtBQUNBLEtBQUssT0FBTyxLQUFLO0FBQ2pCLEtBQUs7QUFDTDtBQUNBLElBQUksUUFBUSxZQUFFLEdBQUUsQ0FBSTtBQUNwQixLQUFLQSxHQUFHLENBQUMsUUFBUTtBQUNqQjtBQUNBLEtBQUssSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQzVCLE1BQU0sUUFBUSxHQUFHO0FBQ2pCLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDZixPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2YsT0FBTyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDM0IsT0FBTyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDNUIsT0FBTztBQUNQLE1BQU07QUFDTixVQUFVLElBQUksRUFBRSxFQUFFO0FBQ2xCLE1BQU0sUUFBUSxHQUFHO0FBQ2pCLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksSUFBSSxDQUFDO0FBQzlCLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQzdCLE9BQU87QUFDUDtBQUNBLE1BQU0sSUFBSSxFQUFFLENBQUMsS0FBSyxJQUFFLFFBQVEsQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsR0FBQztBQUMxRCxhQUFXLFFBQVEsQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxJQUFJLEdBQUM7QUFDakQ7QUFDQSxNQUFNLElBQUksRUFBRSxDQUFDLE1BQU0sSUFBRSxRQUFRLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLEdBQUM7QUFDN0QsYUFBVyxRQUFRLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sSUFBSSxHQUFDO0FBQ25ELE1BQU07QUFDTixVQUFVO0FBQ1YsTUFBTSxRQUFRLEdBQUc7QUFDakIsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0FBQ2pCLE9BQU8sS0FBSyxFQUFFLEVBQUUsQ0FBQyxrQkFBa0I7QUFDbkMsT0FBTyxNQUFNLEVBQUUsRUFBRSxDQUFDLG1CQUFtQjtBQUNyQyxPQUFPO0FBQ1AsTUFBTTtBQUNOO0FBQ0EsS0FBSyxPQUFPLFFBQVE7QUFDcEIsS0FBSztBQUNMLElBQUksQ0FBQyxDQUFDO0FBQ047QUFDQSxHQUFHLE9BQU8sS0FBSztBQUNmLEdBQUcsQ0FBQztBQUNKO0FBQ0EsRUFBRSxJQUFJLFVBQVUsSUFBSSxVQUFVLEVBQUU7QUFDaEMsR0FBR0EsR0FBRyxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUMsTUFBTSxVQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUs7QUFDOUMsSUFBSSxPQUFPLEdBQUcsR0FBRyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztBQUMxQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQ1I7QUFDQSxHQUFHQSxHQUFHLENBQUMsWUFBWSxHQUFHLElBQUksWUFBWSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDL0MsR0FBR0EsR0FBRyxDQUFDLFNBQVMsR0FBRyxJQUFJLFVBQVUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQzFDLEdBQUdBLEdBQUcsQ0FBQyxTQUFTLEdBQUcsSUFBSSxZQUFZLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUM1QztBQUNBLEdBQUcsTUFBTSxDQUFDLE9BQU8sVUFBQyxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUs7QUFDaEMsSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFFLFFBQU07QUFDdEIsSUFBUztJQUFXO0lBQU87SUFBUTtJQUFPLDBCQUFlO0FBQ3pELElBQUksSUFBSSxDQUFDLEtBQUssSUFBRSxRQUFNO0FBQ3RCO0FBQ0EsSUFBSSxTQUFTLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBQ3BDLElBQUksU0FBUyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxHQUFHLENBQUMsQ0FBQztBQUNyQyxJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFDM0MsSUFBSSxDQUFDO0FBQ0w7QUFDQSxHQUFHLGNBQWMsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDeEMsR0FBRyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDN0MsR0FBRyxXQUFXLENBQUMsU0FBUyxDQUFDO0FBQ3pCLEdBQUcsV0FBVyxDQUFDLFNBQVMsQ0FBQztBQUN6QixHQUFHO0FBQ0g7QUFDQSxFQUFFO0FBQ0Y7QUFDQSxDQUFDLFNBQVMsT0FBTyxJQUFJO0FBQ3JCLEVBQUUsY0FBYyxDQUFDLE9BQU8sRUFBRTtBQUMxQixFQUFFLG1CQUFtQixDQUFDLE9BQU8sRUFBRTtBQUMvQixFQUFFLFdBQVcsQ0FBQyxPQUFPLEVBQUU7QUFDdkIsRUFBRSxXQUFXLENBQUMsT0FBTyxFQUFFO0FBQ3ZCLEVBQUUsVUFBVSxDQUFDLE9BQU8sRUFBRTtBQUN0QixFQUFFO0FBQ0YsQ0FBQzsifQ==\n\n//# sourceURL=webpack:///./node_modules/regl-error2d/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/regl-line2d/index.js":
-/*!*******************************************!*\
- !*** ./node_modules/regl-line2d/index.js ***!
- \*******************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\n\nvar rgba = __webpack_require__(/*! color-normalize */ \"./node_modules/color-normalize/index.js\")\nvar getBounds = __webpack_require__(/*! array-bounds */ \"./node_modules/array-bounds/index.js\")\nvar extend = __webpack_require__(/*! object-assign */ \"./node_modules/object-assign/index.js\")\nvar glslify = __webpack_require__(/*! glslify */ \"./node_modules/glslify/browser.js\")\nvar pick = __webpack_require__(/*! pick-by-alias */ \"./node_modules/pick-by-alias/index.js\")\nvar flatten = __webpack_require__(/*! flatten-vertex-data */ \"./node_modules/flatten-vertex-data/index.js\")\nvar triangulate = __webpack_require__(/*! earcut */ \"./node_modules/earcut/src/earcut.js\")\nvar normalize = __webpack_require__(/*! array-normalize */ \"./node_modules/array-normalize/index.js\")\nvar ref = __webpack_require__(/*! to-float32 */ \"./node_modules/to-float32/index.js\");\nvar float32 = ref.float32;\nvar fract32 = ref.fract32;\nvar WeakMap = __webpack_require__(/*! es6-weak-map */ \"./node_modules/es6-weak-map/index.js\")\nvar parseRect = __webpack_require__(/*! parse-rect */ \"./node_modules/parse-rect/index.js\")\n\n\nmodule.exports = Line2D\n\n\n/** @constructor */\nfunction Line2D (regl, options) {\n\tif (!(this instanceof Line2D)) { return new Line2D(regl, options) }\n\n\tif (typeof regl === 'function') {\n\t\tif (!options) { options = {} }\n\t\toptions.regl = regl\n\t}\n\telse {\n\t\toptions = regl\n\t}\n\tif (options.length) { options.positions = options }\n\tregl = options.regl\n\n\tif (!regl.hasExtension('ANGLE_instanced_arrays')) {\n\t\tthrow Error('regl-error2d: `ANGLE_instanced_arrays` extension should be enabled');\n\t}\n\n\t// persistent variables\n\tthis.gl = regl._gl\n\tthis.regl = regl\n\n\t// list of options for lines\n\tthis.passes = []\n\n\t// cached shaders instance\n\tthis.shaders = Line2D.shaders.has(regl) ? Line2D.shaders.get(regl) : Line2D.shaders.set(regl, Line2D.createShaders(regl)).get(regl)\n\n\n\t// init defaults\n\tthis.update(options)\n}\n\n\nLine2D.dashMult = 2\nLine2D.maxPatternLength = 256\nLine2D.precisionThreshold = 3e6\nLine2D.maxPoints = 1e4\nLine2D.maxLines = 2048\n\n\n// cache of created draw calls per-regl instance\nLine2D.shaders = new WeakMap()\n\n\n// create static shaders once\nLine2D.createShaders = function (regl) {\n\tvar offsetBuffer = regl.buffer({\n\t\tusage: 'static',\n\t\ttype: 'float',\n\t\tdata: [0,1, 0,0, 1,1, 1,0]\n\t})\n\n\tvar shaderOptions = {\n\t\tprimitive: 'triangle strip',\n\t\tinstances: regl.prop('count'),\n\t\tcount: 4,\n\t\toffset: 0,\n\n\t\tuniforms: {\n\t\t\tmiterMode: function (ctx, prop) { return prop.join === 'round' ? 2 : 1; },\n\t\t\tmiterLimit: regl.prop('miterLimit'),\n\t\t\tscale: regl.prop('scale'),\n\t\t\tscaleFract: regl.prop('scaleFract'),\n\t\t\ttranslateFract: regl.prop('translateFract'),\n\t\t\ttranslate: regl.prop('translate'),\n\t\t\tthickness: regl.prop('thickness'),\n\t\t\tdashPattern: regl.prop('dashTexture'),\n\t\t\topacity: regl.prop('opacity'),\n\t\t\tpixelRatio: regl.context('pixelRatio'),\n\t\t\tid: regl.prop('id'),\n\t\t\tdashSize: regl.prop('dashLength'),\n\t\t\tviewport: function (c, p) { return [p.viewport.x, p.viewport.y, c.viewportWidth, c.viewportHeight]; },\n\t\t\tdepth: regl.prop('depth')\n\t\t},\n\n\t\tblend: {\n\t\t\tenable: true,\n\t\t\tcolor: [0,0,0,0],\n\t\t\tequation: {\n\t\t\t\trgb: 'add',\n\t\t\t\talpha: 'add'\n\t\t\t},\n\t\t\tfunc: {\n\t\t\t\tsrcRGB: 'src alpha',\n\t\t\t\tdstRGB: 'one minus src alpha',\n\t\t\t\tsrcAlpha: 'one minus dst alpha',\n\t\t\t\tdstAlpha: 'one'\n\t\t\t}\n\t\t},\n\t\tdepth: {\n\t\t\tenable: function (c, p) {\n\t\t\t\treturn !p.overlay\n\t\t\t}\n\t\t},\n\t\tstencil: {enable: false},\n\t\tscissor: {\n\t\t\tenable: true,\n\t\t\tbox: regl.prop('viewport')\n\t\t},\n\t\tviewport: regl.prop('viewport')\n\t}\n\n\n\t// simplified rectangular line shader\n\tvar drawRectLine = regl(extend({\n\t\tvert: glslify([\"precision highp float;\\n#define GLSLIFY 1\\n\\nattribute vec2 aCoord, bCoord, aCoordFract, bCoordFract;\\nattribute vec4 color;\\nattribute float lineEnd, lineTop;\\n\\nuniform vec2 scale, scaleFract, translate, translateFract;\\nuniform float thickness, pixelRatio, id, depth;\\nuniform vec4 viewport;\\n\\nvarying vec4 fragColor;\\nvarying vec2 tangent;\\n\\nvec2 project(vec2 position, vec2 positionFract, vec2 scale, vec2 scaleFract, vec2 translate, vec2 translateFract) {\\n\\t// the order is important\\n\\treturn position * scale + translate\\n + positionFract * scale + translateFract\\n + position * scaleFract\\n + positionFract * scaleFract;\\n}\\n\\nvoid main() {\\n\\tfloat lineStart = 1. - lineEnd;\\n\\tfloat lineOffset = lineTop * 2. - 1.;\\n\\n\\tvec2 diff = (bCoord + bCoordFract - aCoord - aCoordFract);\\n\\ttangent = normalize(diff * scale * viewport.zw);\\n\\tvec2 normal = vec2(-tangent.y, tangent.x);\\n\\n\\tvec2 position = project(aCoord, aCoordFract, scale, scaleFract, translate, translateFract) * lineStart\\n\\t\\t+ project(bCoord, bCoordFract, scale, scaleFract, translate, translateFract) * lineEnd\\n\\n\\t\\t+ thickness * normal * .5 * lineOffset / viewport.zw;\\n\\n\\tgl_Position = vec4(position * 2.0 - 1.0, depth, 1);\\n\\n\\tfragColor = color / 255.;\\n}\\n\"]),\n\t\tfrag: glslify([\"precision highp float;\\n#define GLSLIFY 1\\n\\nuniform sampler2D dashPattern;\\n\\nuniform float dashSize, pixelRatio, thickness, opacity, id;\\n\\nvarying vec4 fragColor;\\nvarying vec2 tangent;\\n\\nvoid main() {\\n\\tfloat alpha = 1.;\\n\\n\\tfloat t = fract(dot(tangent, gl_FragCoord.xy) / dashSize) * .5 + .25;\\n\\tfloat dash = texture2D(dashPattern, vec2(t, .5)).r;\\n\\n\\tgl_FragColor = fragColor;\\n\\tgl_FragColor.a *= alpha * opacity * dash;\\n}\\n\"]),\n\n\t\tattributes: {\n\t\t\t// if point is at the end of segment\n\t\t\tlineEnd: {\n\t\t\t\tbuffer: offsetBuffer,\n\t\t\t\tdivisor: 0,\n\t\t\t\tstride: 8,\n\t\t\t\toffset: 0\n\t\t\t},\n\t\t\t// if point is at the top of segment\n\t\t\tlineTop: {\n\t\t\t\tbuffer: offsetBuffer,\n\t\t\t\tdivisor: 0,\n\t\t\t\tstride: 8,\n\t\t\t\toffset: 4\n\t\t\t},\n\t\t\t// beginning of line coordinate\n\t\t\taCoord: {\n\t\t\t\tbuffer: regl.prop('positionBuffer'),\n\t\t\t\tstride: 8,\n\t\t\t\toffset: 8,\n\t\t\t\tdivisor: 1\n\t\t\t},\n\t\t\t// end of line coordinate\n\t\t\tbCoord: {\n\t\t\t\tbuffer: regl.prop('positionBuffer'),\n\t\t\t\tstride: 8,\n\t\t\t\toffset: 16,\n\t\t\t\tdivisor: 1\n\t\t\t},\n\t\t\taCoordFract: {\n\t\t\t\tbuffer: regl.prop('positionFractBuffer'),\n\t\t\t\tstride: 8,\n\t\t\t\toffset: 8,\n\t\t\t\tdivisor: 1\n\t\t\t},\n\t\t\tbCoordFract: {\n\t\t\t\tbuffer: regl.prop('positionFractBuffer'),\n\t\t\t\tstride: 8,\n\t\t\t\toffset: 16,\n\t\t\t\tdivisor: 1\n\t\t\t},\n\t\t\tcolor: {\n\t\t\t\tbuffer: regl.prop('colorBuffer'),\n\t\t\t\tstride: 4,\n\t\t\t\toffset: 0,\n\t\t\t\tdivisor: 1\n\t\t\t}\n\t\t}\n\t}, shaderOptions))\n\n\t// create regl draw\n\tvar drawMiterLine\n\n\ttry {\n\t\tdrawMiterLine = regl(extend({\n\t\t\t// culling removes polygon creasing\n\t\t\tcull: {\n\t\t\t\tenable: true,\n\t\t\t\tface: 'back'\n\t\t\t},\n\n\t\t\tvert: glslify([\"precision highp float;\\n#define GLSLIFY 1\\n\\nattribute vec2 aCoord, bCoord, nextCoord, prevCoord;\\nattribute vec4 aColor, bColor;\\nattribute float lineEnd, lineTop;\\n\\nuniform vec2 scale, translate;\\nuniform float thickness, pixelRatio, id, depth;\\nuniform vec4 viewport;\\nuniform float miterLimit, miterMode;\\n\\nvarying vec4 fragColor;\\nvarying vec4 startCutoff, endCutoff;\\nvarying vec2 tangent;\\nvarying vec2 startCoord, endCoord;\\nvarying float enableStartMiter, enableEndMiter;\\n\\nconst float REVERSE_THRESHOLD = -.875;\\nconst float MIN_DIFF = 1e-6;\\n\\n// TODO: possible optimizations: avoid overcalculating all for vertices and calc just one instead\\n// TODO: precalculate dot products, normalize things beforehead etc.\\n// TODO: refactor to rectangular algorithm\\n\\nfloat distToLine(vec2 p, vec2 a, vec2 b) {\\n\\tvec2 diff = b - a;\\n\\tvec2 perp = normalize(vec2(-diff.y, diff.x));\\n\\treturn dot(p - a, perp);\\n}\\n\\nbool isNaN( float val ){\\n return ( val < 0.0 || 0.0 < val || val == 0.0 ) ? false : true;\\n}\\n\\nvoid main() {\\n\\tvec2 aCoord = aCoord, bCoord = bCoord, prevCoord = prevCoord, nextCoord = nextCoord;\\n\\n vec2 adjustedScale;\\n adjustedScale.x = (abs(scale.x) < MIN_DIFF) ? MIN_DIFF : scale.x;\\n adjustedScale.y = (abs(scale.y) < MIN_DIFF) ? MIN_DIFF : scale.y;\\n\\n vec2 scaleRatio = adjustedScale * viewport.zw;\\n\\tvec2 normalWidth = thickness / scaleRatio;\\n\\n\\tfloat lineStart = 1. - lineEnd;\\n\\tfloat lineBot = 1. - lineTop;\\n\\n\\tfragColor = (lineStart * aColor + lineEnd * bColor) / 255.;\\n\\n\\tif (isNaN(aCoord.x) || isNaN(aCoord.y) || isNaN(bCoord.x) || isNaN(bCoord.y)) return;\\n\\n\\tif (aCoord == prevCoord) prevCoord = aCoord + normalize(bCoord - aCoord);\\n\\tif (bCoord == nextCoord) nextCoord = bCoord - normalize(bCoord - aCoord);\\n\\n\\tvec2 prevDiff = aCoord - prevCoord;\\n\\tvec2 currDiff = bCoord - aCoord;\\n\\tvec2 nextDiff = nextCoord - bCoord;\\n\\n\\tvec2 prevTangent = normalize(prevDiff * scaleRatio);\\n\\tvec2 currTangent = normalize(currDiff * scaleRatio);\\n\\tvec2 nextTangent = normalize(nextDiff * scaleRatio);\\n\\n\\tvec2 prevNormal = vec2(-prevTangent.y, prevTangent.x);\\n\\tvec2 currNormal = vec2(-currTangent.y, currTangent.x);\\n\\tvec2 nextNormal = vec2(-nextTangent.y, nextTangent.x);\\n\\n\\tvec2 startJoinDirection = normalize(prevTangent - currTangent);\\n\\tvec2 endJoinDirection = normalize(currTangent - nextTangent);\\n\\n\\t// collapsed/unidirectional segment cases\\n\\t// FIXME: there should be more elegant solution\\n\\tvec2 prevTanDiff = abs(prevTangent - currTangent);\\n\\tvec2 nextTanDiff = abs(nextTangent - currTangent);\\n\\tif (max(prevTanDiff.x, prevTanDiff.y) < MIN_DIFF) {\\n\\t\\tstartJoinDirection = currNormal;\\n\\t}\\n\\tif (max(nextTanDiff.x, nextTanDiff.y) < MIN_DIFF) {\\n\\t\\tendJoinDirection = currNormal;\\n\\t}\\n\\tif (aCoord == bCoord) {\\n\\t\\tendJoinDirection = startJoinDirection;\\n\\t\\tcurrNormal = prevNormal;\\n\\t\\tcurrTangent = prevTangent;\\n\\t}\\n\\n\\ttangent = currTangent;\\n\\n\\t//calculate join shifts relative to normals\\n\\tfloat startJoinShift = dot(currNormal, startJoinDirection);\\n\\tfloat endJoinShift = dot(currNormal, endJoinDirection);\\n\\n\\tfloat startMiterRatio = abs(1. / startJoinShift);\\n\\tfloat endMiterRatio = abs(1. / endJoinShift);\\n\\n\\tvec2 startJoin = startJoinDirection * startMiterRatio;\\n\\tvec2 endJoin = endJoinDirection * endMiterRatio;\\n\\n\\tvec2 startTopJoin, startBotJoin, endTopJoin, endBotJoin;\\n\\tstartTopJoin = sign(startJoinShift) * startJoin * .5;\\n\\tstartBotJoin = -startTopJoin;\\n\\n\\tendTopJoin = sign(endJoinShift) * endJoin * .5;\\n\\tendBotJoin = -endTopJoin;\\n\\n\\tvec2 aTopCoord = aCoord + normalWidth * startTopJoin;\\n\\tvec2 bTopCoord = bCoord + normalWidth * endTopJoin;\\n\\tvec2 aBotCoord = aCoord + normalWidth * startBotJoin;\\n\\tvec2 bBotCoord = bCoord + normalWidth * endBotJoin;\\n\\n\\t//miter anti-clipping\\n\\tfloat baClipping = distToLine(bCoord, aCoord, aBotCoord) / dot(normalize(normalWidth * endBotJoin), normalize(normalWidth.yx * vec2(-startBotJoin.y, startBotJoin.x)));\\n\\tfloat abClipping = distToLine(aCoord, bCoord, bTopCoord) / dot(normalize(normalWidth * startBotJoin), normalize(normalWidth.yx * vec2(-endBotJoin.y, endBotJoin.x)));\\n\\n\\t//prevent close to reverse direction switch\\n\\tbool prevReverse = dot(currTangent, prevTangent) <= REVERSE_THRESHOLD && abs(dot(currTangent, prevNormal)) * min(length(prevDiff), length(currDiff)) < length(normalWidth * currNormal);\\n\\tbool nextReverse = dot(currTangent, nextTangent) <= REVERSE_THRESHOLD && abs(dot(currTangent, nextNormal)) * min(length(nextDiff), length(currDiff)) < length(normalWidth * currNormal);\\n\\n\\tif (prevReverse) {\\n\\t\\t//make join rectangular\\n\\t\\tvec2 miterShift = normalWidth * startJoinDirection * miterLimit * .5;\\n\\t\\tfloat normalAdjust = 1. - min(miterLimit / startMiterRatio, 1.);\\n\\t\\taBotCoord = aCoord + miterShift - normalAdjust * normalWidth * currNormal * .5;\\n\\t\\taTopCoord = aCoord + miterShift + normalAdjust * normalWidth * currNormal * .5;\\n\\t}\\n\\telse if (!nextReverse && baClipping > 0. && baClipping < length(normalWidth * endBotJoin)) {\\n\\t\\t//handle miter clipping\\n\\t\\tbTopCoord -= normalWidth * endTopJoin;\\n\\t\\tbTopCoord += normalize(endTopJoin * normalWidth) * baClipping;\\n\\t}\\n\\n\\tif (nextReverse) {\\n\\t\\t//make join rectangular\\n\\t\\tvec2 miterShift = normalWidth * endJoinDirection * miterLimit * .5;\\n\\t\\tfloat normalAdjust = 1. - min(miterLimit / endMiterRatio, 1.);\\n\\t\\tbBotCoord = bCoord + miterShift - normalAdjust * normalWidth * currNormal * .5;\\n\\t\\tbTopCoord = bCoord + miterShift + normalAdjust * normalWidth * currNormal * .5;\\n\\t}\\n\\telse if (!prevReverse && abClipping > 0. && abClipping < length(normalWidth * startBotJoin)) {\\n\\t\\t//handle miter clipping\\n\\t\\taBotCoord -= normalWidth * startBotJoin;\\n\\t\\taBotCoord += normalize(startBotJoin * normalWidth) * abClipping;\\n\\t}\\n\\n\\tvec2 aTopPosition = (aTopCoord) * adjustedScale + translate;\\n\\tvec2 aBotPosition = (aBotCoord) * adjustedScale + translate;\\n\\n\\tvec2 bTopPosition = (bTopCoord) * adjustedScale + translate;\\n\\tvec2 bBotPosition = (bBotCoord) * adjustedScale + translate;\\n\\n\\t//position is normalized 0..1 coord on the screen\\n\\tvec2 position = (aTopPosition * lineTop + aBotPosition * lineBot) * lineStart + (bTopPosition * lineTop + bBotPosition * lineBot) * lineEnd;\\n\\n\\tstartCoord = aCoord * scaleRatio + translate * viewport.zw + viewport.xy;\\n\\tendCoord = bCoord * scaleRatio + translate * viewport.zw + viewport.xy;\\n\\n\\tgl_Position = vec4(position * 2.0 - 1.0, depth, 1);\\n\\n\\tenableStartMiter = step(dot(currTangent, prevTangent), .5);\\n\\tenableEndMiter = step(dot(currTangent, nextTangent), .5);\\n\\n\\t//bevel miter cutoffs\\n\\tif (miterMode == 1.) {\\n\\t\\tif (enableStartMiter == 1.) {\\n\\t\\t\\tvec2 startMiterWidth = vec2(startJoinDirection) * thickness * miterLimit * .5;\\n\\t\\t\\tstartCutoff = vec4(aCoord, aCoord);\\n\\t\\t\\tstartCutoff.zw += vec2(-startJoinDirection.y, startJoinDirection.x) / scaleRatio;\\n\\t\\t\\tstartCutoff = startCutoff * scaleRatio.xyxy + translate.xyxy * viewport.zwzw;\\n\\t\\t\\tstartCutoff += viewport.xyxy;\\n\\t\\t\\tstartCutoff += startMiterWidth.xyxy;\\n\\t\\t}\\n\\n\\t\\tif (enableEndMiter == 1.) {\\n\\t\\t\\tvec2 endMiterWidth = vec2(endJoinDirection) * thickness * miterLimit * .5;\\n\\t\\t\\tendCutoff = vec4(bCoord, bCoord);\\n\\t\\t\\tendCutoff.zw += vec2(-endJoinDirection.y, endJoinDirection.x) / scaleRatio;\\n\\t\\t\\tendCutoff = endCutoff * scaleRatio.xyxy + translate.xyxy * viewport.zwzw;\\n\\t\\t\\tendCutoff += viewport.xyxy;\\n\\t\\t\\tendCutoff += endMiterWidth.xyxy;\\n\\t\\t}\\n\\t}\\n\\n\\t//round miter cutoffs\\n\\telse if (miterMode == 2.) {\\n\\t\\tif (enableStartMiter == 1.) {\\n\\t\\t\\tvec2 startMiterWidth = vec2(startJoinDirection) * thickness * abs(dot(startJoinDirection, currNormal)) * .5;\\n\\t\\t\\tstartCutoff = vec4(aCoord, aCoord);\\n\\t\\t\\tstartCutoff.zw += vec2(-startJoinDirection.y, startJoinDirection.x) / scaleRatio;\\n\\t\\t\\tstartCutoff = startCutoff * scaleRatio.xyxy + translate.xyxy * viewport.zwzw;\\n\\t\\t\\tstartCutoff += viewport.xyxy;\\n\\t\\t\\tstartCutoff += startMiterWidth.xyxy;\\n\\t\\t}\\n\\n\\t\\tif (enableEndMiter == 1.) {\\n\\t\\t\\tvec2 endMiterWidth = vec2(endJoinDirection) * thickness * abs(dot(endJoinDirection, currNormal)) * .5;\\n\\t\\t\\tendCutoff = vec4(bCoord, bCoord);\\n\\t\\t\\tendCutoff.zw += vec2(-endJoinDirection.y, endJoinDirection.x) / scaleRatio;\\n\\t\\t\\tendCutoff = endCutoff * scaleRatio.xyxy + translate.xyxy * viewport.zwzw;\\n\\t\\t\\tendCutoff += viewport.xyxy;\\n\\t\\t\\tendCutoff += endMiterWidth.xyxy;\\n\\t\\t}\\n\\t}\\n}\\n\"]),\n\t\t\tfrag: glslify([\"precision highp float;\\n#define GLSLIFY 1\\n\\nuniform sampler2D dashPattern;\\nuniform float dashSize, pixelRatio, thickness, opacity, id, miterMode;\\n\\nvarying vec4 fragColor;\\nvarying vec2 tangent;\\nvarying vec4 startCutoff, endCutoff;\\nvarying vec2 startCoord, endCoord;\\nvarying float enableStartMiter, enableEndMiter;\\n\\nfloat distToLine(vec2 p, vec2 a, vec2 b) {\\n\\tvec2 diff = b - a;\\n\\tvec2 perp = normalize(vec2(-diff.y, diff.x));\\n\\treturn dot(p - a, perp);\\n}\\n\\nvoid main() {\\n\\tfloat alpha = 1., distToStart, distToEnd;\\n\\tfloat cutoff = thickness * .5;\\n\\n\\t//bevel miter\\n\\tif (miterMode == 1.) {\\n\\t\\tif (enableStartMiter == 1.) {\\n\\t\\t\\tdistToStart = distToLine(gl_FragCoord.xy, startCutoff.xy, startCutoff.zw);\\n\\t\\t\\tif (distToStart < -1.) {\\n\\t\\t\\t\\tdiscard;\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\t\\talpha *= min(max(distToStart + 1., 0.), 1.);\\n\\t\\t}\\n\\n\\t\\tif (enableEndMiter == 1.) {\\n\\t\\t\\tdistToEnd = distToLine(gl_FragCoord.xy, endCutoff.xy, endCutoff.zw);\\n\\t\\t\\tif (distToEnd < -1.) {\\n\\t\\t\\t\\tdiscard;\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\t\\talpha *= min(max(distToEnd + 1., 0.), 1.);\\n\\t\\t}\\n\\t}\\n\\n\\t// round miter\\n\\telse if (miterMode == 2.) {\\n\\t\\tif (enableStartMiter == 1.) {\\n\\t\\t\\tdistToStart = distToLine(gl_FragCoord.xy, startCutoff.xy, startCutoff.zw);\\n\\t\\t\\tif (distToStart < 0.) {\\n\\t\\t\\t\\tfloat radius = length(gl_FragCoord.xy - startCoord);\\n\\n\\t\\t\\t\\tif(radius > cutoff + .5) {\\n\\t\\t\\t\\t\\tdiscard;\\n\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t}\\n\\n\\t\\t\\t\\talpha -= smoothstep(cutoff - .5, cutoff + .5, radius);\\n\\t\\t\\t}\\n\\t\\t}\\n\\n\\t\\tif (enableEndMiter == 1.) {\\n\\t\\t\\tdistToEnd = distToLine(gl_FragCoord.xy, endCutoff.xy, endCutoff.zw);\\n\\t\\t\\tif (distToEnd < 0.) {\\n\\t\\t\\t\\tfloat radius = length(gl_FragCoord.xy - endCoord);\\n\\n\\t\\t\\t\\tif(radius > cutoff + .5) {\\n\\t\\t\\t\\t\\tdiscard;\\n\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t}\\n\\n\\t\\t\\t\\talpha -= smoothstep(cutoff - .5, cutoff + .5, radius);\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\tfloat t = fract(dot(tangent, gl_FragCoord.xy) / dashSize) * .5 + .25;\\n\\tfloat dash = texture2D(dashPattern, vec2(t, .5)).r;\\n\\n\\tgl_FragColor = fragColor;\\n\\tgl_FragColor.a *= alpha * opacity * dash;\\n}\\n\"]),\n\n\t\t\tattributes: {\n\t\t\t\t// is line end\n\t\t\t\tlineEnd: {\n\t\t\t\t\tbuffer: offsetBuffer,\n\t\t\t\t\tdivisor: 0,\n\t\t\t\t\tstride: 8,\n\t\t\t\t\toffset: 0\n\t\t\t\t},\n\t\t\t\t// is line top\n\t\t\t\tlineTop: {\n\t\t\t\t\tbuffer: offsetBuffer,\n\t\t\t\t\tdivisor: 0,\n\t\t\t\t\tstride: 8,\n\t\t\t\t\toffset: 4\n\t\t\t\t},\n\t\t\t\t// left color\n\t\t\t\taColor: {\n\t\t\t\t\tbuffer: regl.prop('colorBuffer'),\n\t\t\t\t\tstride: 4,\n\t\t\t\t\toffset: 0,\n\t\t\t\t\tdivisor: 1\n\t\t\t\t},\n\t\t\t\t// right color\n\t\t\t\tbColor: {\n\t\t\t\t\tbuffer: regl.prop('colorBuffer'),\n\t\t\t\t\tstride: 4,\n\t\t\t\t\toffset: 4,\n\t\t\t\t\tdivisor: 1\n\t\t\t\t},\n\t\t\t\tprevCoord: {\n\t\t\t\t\tbuffer: regl.prop('positionBuffer'),\n\t\t\t\t\tstride: 8,\n\t\t\t\t\toffset: 0,\n\t\t\t\t\tdivisor: 1\n\t\t\t\t},\n\t\t\t\taCoord: {\n\t\t\t\t\tbuffer: regl.prop('positionBuffer'),\n\t\t\t\t\tstride: 8,\n\t\t\t\t\toffset: 8,\n\t\t\t\t\tdivisor: 1\n\t\t\t\t},\n\t\t\t\tbCoord: {\n\t\t\t\t\tbuffer: regl.prop('positionBuffer'),\n\t\t\t\t\tstride: 8,\n\t\t\t\t\toffset: 16,\n\t\t\t\t\tdivisor: 1\n\t\t\t\t},\n\t\t\t\tnextCoord: {\n\t\t\t\t\tbuffer: regl.prop('positionBuffer'),\n\t\t\t\t\tstride: 8,\n\t\t\t\t\toffset: 24,\n\t\t\t\t\tdivisor: 1\n\t\t\t\t}\n\t\t\t}\n\t\t}, shaderOptions))\n\t} catch (e) {\n\t\t// IE/bad Webkit fallback\n\t\tdrawMiterLine = drawRectLine\n\t}\n\n\t// fill shader\n\tvar drawFill = regl({\n\t\tprimitive: 'triangle',\n\t\telements: function (ctx, prop) { return prop.triangles; },\n\t\toffset: 0,\n\n\t\tvert: glslify([\"precision highp float;\\n#define GLSLIFY 1\\n\\nattribute vec2 position, positionFract;\\n\\nuniform vec4 color;\\nuniform vec2 scale, scaleFract, translate, translateFract;\\nuniform float pixelRatio, id;\\nuniform vec4 viewport;\\nuniform float opacity;\\n\\nvarying vec4 fragColor;\\n\\nconst float MAX_LINES = 256.;\\n\\nvoid main() {\\n\\tfloat depth = (MAX_LINES - 4. - id) / (MAX_LINES);\\n\\n\\tvec2 position = position * scale + translate\\n + positionFract * scale + translateFract\\n + position * scaleFract\\n + positionFract * scaleFract;\\n\\n\\tgl_Position = vec4(position * 2.0 - 1.0, depth, 1);\\n\\n\\tfragColor = color / 255.;\\n\\tfragColor.a *= opacity;\\n}\\n\"]),\n\t\tfrag: glslify([\"precision highp float;\\n#define GLSLIFY 1\\n\\nvarying vec4 fragColor;\\n\\nvoid main() {\\n\\tgl_FragColor = fragColor;\\n}\\n\"]),\n\n\t\tuniforms: {\n\t\t\tscale: regl.prop('scale'),\n\t\t\tcolor: regl.prop('fill'),\n\t\t\tscaleFract: regl.prop('scaleFract'),\n\t\t\ttranslateFract: regl.prop('translateFract'),\n\t\t\ttranslate: regl.prop('translate'),\n\t\t\topacity: regl.prop('opacity'),\n\t\t\tpixelRatio: regl.context('pixelRatio'),\n\t\t\tid: regl.prop('id'),\n\t\t\tviewport: function (ctx, prop) { return [prop.viewport.x, prop.viewport.y, ctx.viewportWidth, ctx.viewportHeight]; }\n\t\t},\n\n\t\tattributes: {\n\t\t\tposition: {\n\t\t\t\tbuffer: regl.prop('positionBuffer'),\n\t\t\t\tstride: 8,\n\t\t\t\toffset: 8\n\t\t\t},\n\t\t\tpositionFract: {\n\t\t\t\tbuffer: regl.prop('positionFractBuffer'),\n\t\t\t\tstride: 8,\n\t\t\t\toffset: 8\n\t\t\t}\n\t\t},\n\n\t\tblend: shaderOptions.blend,\n\n\t\tdepth: { enable: false },\n\t\tscissor: shaderOptions.scissor,\n\t\tstencil: shaderOptions.stencil,\n\t\tviewport: shaderOptions.viewport\n\t})\n\n\treturn {\n\t\tfill: drawFill, rect: drawRectLine, miter: drawMiterLine\n\t}\n}\n\n\n// used to for new lines instances\nLine2D.defaults = {\n\tdashes: null,\n\tjoin: 'miter',\n\tmiterLimit: 1,\n\tthickness: 10,\n\tcap: 'square',\n\tcolor: 'black',\n\topacity: 1,\n\toverlay: false,\n\tviewport: null,\n\trange: null,\n\tclose: false,\n\tfill: null\n}\n\n\nLine2D.prototype.render = function () {\n\tvar ref;\n\n\tvar args = [], len = arguments.length;\n\twhile ( len-- ) args[ len ] = arguments[ len ];\n\tif (args.length) {\n\t\t(ref = this).update.apply(ref, args)\n\t}\n\n\tthis.draw()\n}\n\n\nLine2D.prototype.draw = function () {\n\tvar this$1 = this;\n\tvar args = [], len = arguments.length;\n\twhile ( len-- ) args[ len ] = arguments[ len ];\n\n\t// render multiple polylines via regl batch\n\t(args.length ? args : this.passes).forEach(function (s, i) {\n\t\tvar ref;\n\n\t\t// render array pass as a list of passes\n\t\tif (s && Array.isArray(s)) { return (ref = this$1).draw.apply(ref, s) }\n\n\t\tif (typeof s === 'number') { s = this$1.passes[s] }\n\n\t\tif (!(s && s.count > 1 && s.opacity)) { return }\n\n\t\tthis$1.regl._refresh()\n\n\t\tif (s.fill && s.triangles && s.triangles.length > 2) {\n\t\t\tthis$1.shaders.fill(s)\n\t\t}\n\n\t\tif (!s.thickness) { return }\n\n\t\t// high scale is only available for rect mode with precision\n\t\tif (s.scale[0] * s.viewport.width > Line2D.precisionThreshold || s.scale[1] * s.viewport.height > Line2D.precisionThreshold) {\n\t\t\tthis$1.shaders.rect(s)\n\t\t}\n\n\t\t// thin this.passes or too many points are rendered as simplified rect shader\n\t\telse if (s.join === 'rect' || (!s.join && (s.thickness <= 2 || s.count >= Line2D.maxPoints))) {\n\t\t\tthis$1.shaders.rect(s)\n\t\t}\n\t\telse {\n\t\t\tthis$1.shaders.miter(s)\n\t\t}\n\t})\n\n\treturn this\n}\n\nLine2D.prototype.update = function (options) {\n\tvar this$1 = this;\n\n\tif (!options) { return }\n\n\tif (options.length != null) {\n\t\tif (typeof options[0] === 'number') { options = [{positions: options}] }\n\t}\n\n\t// make options a batch\n\telse if (!Array.isArray(options)) { options = [options] }\n\n\tvar ref = this;\n\tvar regl = ref.regl;\n\tvar gl = ref.gl;\n\n\t// process per-line settings\n\toptions.forEach(function (o, i) {\n\t\tvar state = this$1.passes[i]\n\n\t\tif (o === undefined) { return }\n\n\t\t// null-argument removes pass\n\t\tif (o === null) {\n\t\t\tthis$1.passes[i] = null\n\t\t\treturn\n\t\t}\n\n\t\tif (typeof o[0] === 'number') { o = {positions: o} }\n\n\t\t// handle aliases\n\t\to = pick(o, {\n\t\t\tpositions: 'positions points data coords',\n\t\t\tthickness: 'thickness lineWidth lineWidths line-width linewidth width stroke-width strokewidth strokeWidth',\n\t\t\tjoin: 'lineJoin linejoin join type mode',\n\t\t\tmiterLimit: 'miterlimit miterLimit',\n\t\t\tdashes: 'dash dashes dasharray dash-array dashArray',\n\t\t\tcolor: 'color colour stroke colors colours stroke-color strokeColor',\n\t\t\tfill: 'fill fill-color fillColor',\n\t\t\topacity: 'alpha opacity',\n\t\t\toverlay: 'overlay crease overlap intersect',\n\t\t\tclose: 'closed close closed-path closePath',\n\t\t\trange: 'range dataBox',\n\t\t\tviewport: 'viewport viewBox',\n\t\t\thole: 'holes hole hollow'\n\t\t})\n\n\t\t// init state\n\t\tif (!state) {\n\t\t\tthis$1.passes[i] = state = {\n\t\t\t\tid: i,\n\t\t\t\tscale: null,\n\t\t\t\tscaleFract: null,\n\t\t\t\ttranslate: null,\n\t\t\t\ttranslateFract: null,\n\t\t\t\tcount: 0,\n\t\t\t\thole: [],\n\t\t\t\tdepth: 0,\n\n\t\t\t\tdashLength: 1,\n\t\t\t\tdashTexture: regl.texture({\n\t\t\t\t\tchannels: 1,\n\t\t\t\t\tdata: new Uint8Array([255]),\n\t\t\t\t\twidth: 1,\n\t\t\t\t\theight: 1,\n\t\t\t\t\tmag: 'linear',\n\t\t\t\t\tmin: 'linear'\n\t\t\t\t}),\n\n\t\t\t\tcolorBuffer: regl.buffer({\n\t\t\t\t\tusage: 'dynamic',\n\t\t\t\t\ttype: 'uint8',\n\t\t\t\t\tdata: new Uint8Array()\n\t\t\t\t}),\n\t\t\t\tpositionBuffer: regl.buffer({\n\t\t\t\t\tusage: 'dynamic',\n\t\t\t\t\ttype: 'float',\n\t\t\t\t\tdata: new Uint8Array()\n\t\t\t\t}),\n\t\t\t\tpositionFractBuffer: regl.buffer({\n\t\t\t\t\tusage: 'dynamic',\n\t\t\t\t\ttype: 'float',\n\t\t\t\t\tdata: new Uint8Array()\n\t\t\t\t})\n\t\t\t}\n\n\t\t\to = extend({}, Line2D.defaults, o)\n\t\t}\n\t\tif (o.thickness != null) { state.thickness = parseFloat(o.thickness) }\n\t\tif (o.opacity != null) { state.opacity = parseFloat(o.opacity) }\n\t\tif (o.miterLimit != null) { state.miterLimit = parseFloat(o.miterLimit) }\n\t\tif (o.overlay != null) {\n\t\t\tstate.overlay = !!o.overlay\n\t\t\tif (i < Line2D.maxLines) {\n\t\t\t\tstate.depth = 2 * (Line2D.maxLines - 1 - i % Line2D.maxLines) / Line2D.maxLines - 1.;\n\t\t\t}\n\t\t}\n\t\tif (o.join != null) { state.join = o.join }\n\t\tif (o.hole != null) { state.hole = o.hole }\n\t\tif (o.fill != null) { state.fill = !o.fill ? null : rgba(o.fill, 'uint8') }\n\t\tif (o.viewport != null) { state.viewport = parseRect(o.viewport) }\n\n\t\tif (!state.viewport) {\n\t\t\tstate.viewport = parseRect([\n\t\t\t\tgl.drawingBufferWidth,\n\t\t\t\tgl.drawingBufferHeight\n\t\t\t])\n\t\t}\n\n\t\tif (o.close != null) { state.close = o.close }\n\n\t\t// reset positions\n\t\tif (o.positions === null) { o.positions = [] }\n\t\tif (o.positions) {\n\t\t\tvar positions, count\n\n\t\t\t// if positions are an object with x/y\n\t\t\tif (o.positions.x && o.positions.y) {\n\t\t\t\tvar xPos = o.positions.x\n\t\t\t\tvar yPos = o.positions.y\n\t\t\t\tcount = state.count = Math.max(\n\t\t\t\t\txPos.length,\n\t\t\t\t\tyPos.length\n\t\t\t\t)\n\t\t\t\tpositions = new Float64Array(count * 2)\n\t\t\t\tfor (var i$1 = 0; i$1 < count; i$1++) {\n\t\t\t\t\tpositions[i$1 * 2] = xPos[i$1]\n\t\t\t\t\tpositions[i$1 * 2 + 1] = yPos[i$1]\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tpositions = flatten(o.positions, 'float64')\n\t\t\t\tcount = state.count = Math.floor(positions.length / 2)\n\t\t\t}\n\n\t\t\tvar bounds = state.bounds = getBounds(positions, 2)\n\n\t\t\t// create fill positions\n\t\t\t// FIXME: fill positions can be set only along with positions\n\t\t\tif (state.fill) {\n\t\t\t\tvar pos = []\n\n\t\t\t\t// filter bad vertices and remap triangles to ensure shape\n\t\t\t\tvar ids = {}\n\t\t\t\tvar lastId = 0\n\n\t\t\t\tfor (var i$2 = 0, ptr = 0, l = state.count; i$2 < l; i$2++) {\n\t\t\t\t\tvar x = positions[i$2*2]\n\t\t\t\t\tvar y = positions[i$2*2 + 1]\n\t\t\t\t\tif (isNaN(x) || isNaN(y) || x == null || y == null) {\n\t\t\t\t\t\tx = positions[lastId*2]\n\t\t\t\t\t\ty = positions[lastId*2 + 1]\n\t\t\t\t\t\tids[i$2] = lastId\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tlastId = i$2\n\t\t\t\t\t}\n\t\t\t\t\tpos[ptr++] = x\n\t\t\t\t\tpos[ptr++] = y\n\t\t\t\t}\n\n\t\t\t\tvar triangles = triangulate(pos, state.hole || [])\n\n\t\t\t\tfor (var i$3 = 0, l$1 = triangles.length; i$3 < l$1; i$3++) {\n\t\t\t\t\tif (ids[triangles[i$3]] != null) { triangles[i$3] = ids[triangles[i$3]] }\n\t\t\t\t}\n\n\t\t\t\tstate.triangles = triangles\n\t\t\t}\n\n\t\t\t// update position buffers\n\t\t\tvar npos = new Float64Array(positions)\n\t\t\tnormalize(npos, 2, bounds)\n\n\t\t\tvar positionData = new Float64Array(count * 2 + 6)\n\n\t\t\t// rotate first segment join\n\t\t\tif (state.close) {\n\t\t\t\tif (positions[0] === positions[count*2 - 2] &&\n\t\t\t\t\tpositions[1] === positions[count*2 - 1]) {\n\t\t\t\t\tpositionData[0] = npos[count*2 - 4]\n\t\t\t\t\tpositionData[1] = npos[count*2 - 3]\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tpositionData[0] = npos[count*2 - 2]\n\t\t\t\t\tpositionData[1] = npos[count*2 - 1]\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tpositionData[0] = npos[0]\n\t\t\t\tpositionData[1] = npos[1]\n\t\t\t}\n\n\t\t\tpositionData.set(npos, 2)\n\n\t\t\t// add last segment\n\t\t\tif (state.close) {\n\t\t\t\t// ignore coinciding start/end\n\t\t\t\tif (positions[0] === positions[count*2 - 2] &&\n\t\t\t\t\tpositions[1] === positions[count*2 - 1]) {\n\t\t\t\t\tpositionData[count*2 + 2] = npos[2]\n\t\t\t\t\tpositionData[count*2 + 3] = npos[3]\n\t\t\t\t\tstate.count -= 1\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tpositionData[count*2 + 2] = npos[0]\n\t\t\t\t\tpositionData[count*2 + 3] = npos[1]\n\t\t\t\t\tpositionData[count*2 + 4] = npos[2]\n\t\t\t\t\tpositionData[count*2 + 5] = npos[3]\n\t\t\t\t}\n\t\t\t}\n\t\t\t// add stub\n\t\t\telse {\n\t\t\t\tpositionData[count*2 + 2] = npos[count*2 - 2]\n\t\t\t\tpositionData[count*2 + 3] = npos[count*2 - 1]\n\t\t\t\tpositionData[count*2 + 4] = npos[count*2 - 2]\n\t\t\t\tpositionData[count*2 + 5] = npos[count*2 - 1]\n\t\t\t}\n\n\t\t\tstate.positionBuffer(float32(positionData))\n\t\t\tstate.positionFractBuffer(fract32(positionData))\n\t\t}\n\n\t\tif (o.range) {\n\t\t\tstate.range = o.range\n\t\t} else if (!state.range) {\n\t\t\tstate.range = state.bounds\n\t\t}\n\n\t\tif ((o.range || o.positions) && state.count) {\n\t\t\tvar bounds$1 = state.bounds\n\n\t\t\tvar boundsW = bounds$1[2] - bounds$1[0],\n\t\t\t\tboundsH = bounds$1[3] - bounds$1[1]\n\n\t\t\tvar rangeW = state.range[2] - state.range[0],\n\t\t\t\trangeH = state.range[3] - state.range[1]\n\n\t\t\tstate.scale = [\n\t\t\t\tboundsW / rangeW,\n\t\t\t\tboundsH / rangeH\n\t\t\t]\n\t\t\tstate.translate = [\n\t\t\t\t-state.range[0] / rangeW + bounds$1[0] / rangeW || 0,\n\t\t\t\t-state.range[1] / rangeH + bounds$1[1] / rangeH || 0\n\t\t\t]\n\n\t\t\tstate.scaleFract = fract32(state.scale)\n\t\t\tstate.translateFract = fract32(state.translate)\n\t\t}\n\n\t\tif (o.dashes) {\n\t\t\tvar dashLength = 0., dashData\n\n\t\t\tif (!o.dashes || o.dashes.length < 2) {\n\t\t\t\tdashLength = 1.\n\t\t\t\tdashData = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255])\n\t\t\t}\n\n\t\t\telse {\n\t\t\t\tdashLength = 0.;\n\t\t\t\tfor(var i$4 = 0; i$4 < o.dashes.length; ++i$4) {\n\t\t\t\t\tdashLength += o.dashes[i$4]\n\t\t\t\t}\n\t\t\t\tdashData = new Uint8Array(dashLength * Line2D.dashMult)\n\t\t\t\tvar ptr$1 = 0\n\t\t\t\tvar fillColor = 255\n\n\t\t\t\t// repeat texture two times to provide smooth 0-step\n\t\t\t\tfor (var k = 0; k < 2; k++) {\n\t\t\t\t\tfor(var i$5 = 0; i$5 < o.dashes.length; ++i$5) {\n\t\t\t\t\t\tfor(var j = 0, l$2 = o.dashes[i$5] * Line2D.dashMult * .5; j < l$2; ++j) {\n\t\t\t\t\t\t\tdashData[ptr$1++] = fillColor\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfillColor ^= 255\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tstate.dashLength = dashLength\n\t\t\tstate.dashTexture({\n\t\t\t\tchannels: 1,\n\t\t\t\tdata: dashData,\n\t\t\t\twidth: dashData.length,\n\t\t\t\theight: 1,\n\t\t\t\tmag: 'linear',\n\t\t\t\tmin: 'linear'\n\t\t\t}, 0, 0)\n\t\t}\n\n\t\tif (o.color) {\n\t\t\tvar count$1 = state.count\n\t\t\tvar colors = o.color\n\n\t\t\tif (!colors) { colors = 'transparent' }\n\n\t\t\tvar colorData = new Uint8Array(count$1 * 4 + 4)\n\n\t\t\t// convert colors to typed arrays\n\t\t\tif (!Array.isArray(colors) || typeof colors[0] === 'number') {\n\t\t\t\tvar c = rgba(colors, 'uint8')\n\n\t\t\t\tfor (var i$6 = 0; i$6 < count$1 + 1; i$6++) {\n\t\t\t\t\tcolorData.set(c, i$6 * 4)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (var i$7 = 0; i$7 < count$1; i$7++) {\n\t\t\t\t\tvar c$1 = rgba(colors[i$7], 'uint8')\n\t\t\t\t\tcolorData.set(c$1, i$7 * 4)\n\t\t\t\t}\n\t\t\t\tcolorData.set(rgba(colors[0], 'uint8'), count$1 * 4)\n\t\t\t}\n\n\t\t\tstate.colorBuffer({\n\t\t\t\tusage: 'dynamic',\n\t\t\t\ttype: 'uint8',\n\t\t\t\tdata: colorData\n\t\t\t})\n\t\t}\n\t})\n\n\t// remove unmentioned passes\n\tif (options.length < this.passes.length) {\n\t\tfor (var i = options.length; i < this.passes.length; i++) {\n\t\t\tvar pass = this.passes[i]\n\t\t\tif (!pass) { continue }\n\t\t\tpass.colorBuffer.destroy()\n\t\t\tpass.positionBuffer.destroy()\n\t\t\tpass.dashTexture.destroy()\n\t\t}\n\t\tthis.passes.length = options.length\n\t}\n\n\t// remove null items\n\tvar passes = []\n\tfor (var i$1 = 0; i$1 < this.passes.length; i$1++) {\n\t\tif (this.passes[i$1] !== null) { passes.push(this.passes[i$1]) }\n\t}\n\tthis.passes = passes\n\n\treturn this\n}\n\nLine2D.prototype.destroy = function () {\n\tthis.passes.forEach(function (pass) {\n\t\tpass.colorBuffer.destroy()\n\t\tpass.positionBuffer.destroy()\n\t\tpass.dashTexture.destroy()\n\t})\n\n\tthis.passes.length = 0\n\n\treturn this\n}\n\n\r\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbIkY6L3NvdXJjZS92dWUtcGxvdGx5LmpzL25vZGVfbW9kdWxlcy9yZWdsLWxpbmUyZC9pbmRleC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCdcblxuXG5jb25zdCByZ2JhID0gcmVxdWlyZSgnY29sb3Itbm9ybWFsaXplJylcbmNvbnN0IGdldEJvdW5kcyA9IHJlcXVpcmUoJ2FycmF5LWJvdW5kcycpXG5jb25zdCBleHRlbmQgPSByZXF1aXJlKCdvYmplY3QtYXNzaWduJylcbmNvbnN0IGdsc2xpZnkgPSByZXF1aXJlKCdnbHNsaWZ5JylcbmNvbnN0IHBpY2sgPSByZXF1aXJlKCdwaWNrLWJ5LWFsaWFzJylcbmNvbnN0IGZsYXR0ZW4gPSByZXF1aXJlKCdmbGF0dGVuLXZlcnRleC1kYXRhJylcbmNvbnN0IHRyaWFuZ3VsYXRlID0gcmVxdWlyZSgnZWFyY3V0JylcbmNvbnN0IG5vcm1hbGl6ZSA9IHJlcXVpcmUoJ2FycmF5LW5vcm1hbGl6ZScpXG5jb25zdCB7IGZsb2F0MzIsIGZyYWN0MzIgfSA9IHJlcXVpcmUoJ3RvLWZsb2F0MzInKVxuY29uc3QgV2Vha01hcCA9IHJlcXVpcmUoJ2VzNi13ZWFrLW1hcCcpXG5jb25zdCBwYXJzZVJlY3QgPSByZXF1aXJlKCdwYXJzZS1yZWN0JylcblxuXG5tb2R1bGUuZXhwb3J0cyA9IExpbmUyRFxuXG5cbi8qKiBAY29uc3RydWN0b3IgKi9cbmZ1bmN0aW9uIExpbmUyRCAocmVnbCwgb3B0aW9ucykge1xuXHRpZiAoISh0aGlzIGluc3RhbmNlb2YgTGluZTJEKSkgcmV0dXJuIG5ldyBMaW5lMkQocmVnbCwgb3B0aW9ucylcblxuXHRpZiAodHlwZW9mIHJlZ2wgPT09ICdmdW5jdGlvbicpIHtcblx0XHRpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fVxuXHRcdG9wdGlvbnMucmVnbCA9IHJlZ2xcblx0fVxuXHRlbHNlIHtcblx0XHRvcHRpb25zID0gcmVnbFxuXHR9XG5cdGlmIChvcHRpb25zLmxlbmd0aCkgb3B0aW9ucy5wb3NpdGlvbnMgPSBvcHRpb25zXG5cdHJlZ2wgPSBvcHRpb25zLnJlZ2xcblxuXHRpZiAoIXJlZ2wuaGFzRXh0ZW5zaW9uKCdBTkdMRV9pbnN0YW5jZWRfYXJyYXlzJykpIHtcblx0XHR0aHJvdyBFcnJvcigncmVnbC1lcnJvcjJkOiBgQU5HTEVfaW5zdGFuY2VkX2FycmF5c2AgZXh0ZW5zaW9uIHNob3VsZCBiZSBlbmFibGVkJyk7XG5cdH1cblxuXHQvLyBwZXJzaXN0ZW50IHZhcmlhYmxlc1xuXHR0aGlzLmdsID0gcmVnbC5fZ2xcblx0dGhpcy5yZWdsID0gcmVnbFxuXG5cdC8vIGxpc3Qgb2Ygb3B0aW9ucyBmb3IgbGluZXNcblx0dGhpcy5wYXNzZXMgPSBbXVxuXG5cdC8vIGNhY2hlZCBzaGFkZXJzIGluc3RhbmNlXG5cdHRoaXMuc2hhZGVycyA9IExpbmUyRC5zaGFkZXJzLmhhcyhyZWdsKSA/IExpbmUyRC5zaGFkZXJzLmdldChyZWdsKSA6IExpbmUyRC5zaGFkZXJzLnNldChyZWdsLCBMaW5lMkQuY3JlYXRlU2hhZGVycyhyZWdsKSkuZ2V0KHJlZ2wpXG5cblxuXHQvLyBpbml0IGRlZmF1bHRzXG5cdHRoaXMudXBkYXRlKG9wdGlvbnMpXG59XG5cblxuTGluZTJELmRhc2hNdWx0ID0gMlxuTGluZTJELm1heFBhdHRlcm5MZW5ndGggPSAyNTZcbkxpbmUyRC5wcmVjaXNpb25UaHJlc2hvbGQgPSAzZTZcbkxpbmUyRC5tYXhQb2ludHMgPSAxZTRcbkxpbmUyRC5tYXhMaW5lcyA9IDIwNDhcblxuXG4vLyBjYWNoZSBvZiBjcmVhdGVkIGRyYXcgY2FsbHMgcGVyLXJlZ2wgaW5zdGFuY2VcbkxpbmUyRC5zaGFkZXJzID0gbmV3IFdlYWtNYXAoKVxuXG5cbi8vIGNyZWF0ZSBzdGF0aWMgc2hhZGVycyBvbmNlXG5MaW5lMkQuY3JlYXRlU2hhZGVycyA9IGZ1bmN0aW9uIChyZWdsKSB7XG5cdGxldCBvZmZzZXRCdWZmZXIgPSByZWdsLmJ1ZmZlcih7XG5cdFx0dXNhZ2U6ICdzdGF0aWMnLFxuXHRcdHR5cGU6ICdmbG9hdCcsXG5cdFx0ZGF0YTogWzAsMSwgMCwwLCAxLDEsIDEsMF1cblx0fSlcblxuXHRsZXQgc2hhZGVyT3B0aW9ucyA9IHtcblx0XHRwcmltaXRpdmU6ICd0cmlhbmdsZSBzdHJpcCcsXG5cdFx0aW5zdGFuY2VzOiByZWdsLnByb3AoJ2NvdW50JyksXG5cdFx0Y291bnQ6IDQsXG5cdFx0b2Zmc2V0OiAwLFxuXG5cdFx0dW5pZm9ybXM6IHtcblx0XHRcdG1pdGVyTW9kZTogKGN0eCwgcHJvcCkgPT4gcHJvcC5qb2luID09PSAncm91bmQnID8gMiA6IDEsXG5cdFx0XHRtaXRlckxpbWl0OiByZWdsLnByb3AoJ21pdGVyTGltaXQnKSxcblx0XHRcdHNjYWxlOiByZWdsLnByb3AoJ3NjYWxlJyksXG5cdFx0XHRzY2FsZUZyYWN0OiByZWdsLnByb3AoJ3NjYWxlRnJhY3QnKSxcblx0XHRcdHRyYW5zbGF0ZUZyYWN0OiByZWdsLnByb3AoJ3RyYW5zbGF0ZUZyYWN0JyksXG5cdFx0XHR0cmFuc2xhdGU6IHJlZ2wucHJvcCgndHJhbnNsYXRlJyksXG5cdFx0XHR0aGlja25lc3M6IHJlZ2wucHJvcCgndGhpY2tuZXNzJyksXG5cdFx0XHRkYXNoUGF0dGVybjogcmVnbC5wcm9wKCdkYXNoVGV4dHVyZScpLFxuXHRcdFx0b3BhY2l0eTogcmVnbC5wcm9wKCdvcGFjaXR5JyksXG5cdFx0XHRwaXhlbFJhdGlvOiByZWdsLmNvbnRleHQoJ3BpeGVsUmF0aW8nKSxcblx0XHRcdGlkOiByZWdsLnByb3AoJ2lkJyksXG5cdFx0XHRkYXNoU2l6ZTogcmVnbC5wcm9wKCdkYXNoTGVuZ3RoJyksXG5cdFx0XHR2aWV3cG9ydDogKGMsIHApID0+IFtwLnZpZXdwb3J0LngsIHAudmlld3BvcnQueSwgYy52aWV3cG9ydFdpZHRoLCBjLnZpZXdwb3J0SGVpZ2h0XSxcblx0XHRcdGRlcHRoOiByZWdsLnByb3AoJ2RlcHRoJylcblx0XHR9LFxuXG5cdFx0YmxlbmQ6IHtcblx0XHRcdGVuYWJsZTogdHJ1ZSxcblx0XHRcdGNvbG9yOiBbMCwwLDAsMF0sXG5cdFx0XHRlcXVhdGlvbjoge1xuXHRcdFx0XHRyZ2I6ICdhZGQnLFxuXHRcdFx0XHRhbHBoYTogJ2FkZCdcblx0XHRcdH0sXG5cdFx0XHRmdW5jOiB7XG5cdFx0XHRcdHNyY1JHQjogJ3NyYyBhbHBoYScsXG5cdFx0XHRcdGRzdFJHQjogJ29uZSBtaW51cyBzcmMgYWxwaGEnLFxuXHRcdFx0XHRzcmNBbHBoYTogJ29uZSBtaW51cyBkc3QgYWxwaGEnLFxuXHRcdFx0XHRkc3RBbHBoYTogJ29uZSdcblx0XHRcdH1cblx0XHR9LFxuXHRcdGRlcHRoOiB7XG5cdFx0XHRlbmFibGU6IChjLCBwKSA9PiB7XG5cdFx0XHRcdHJldHVybiAhcC5vdmVybGF5XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRzdGVuY2lsOiB7ZW5hYmxlOiBmYWxzZX0sXG5cdFx0c2Npc3Nvcjoge1xuXHRcdFx0ZW5hYmxlOiB0cnVlLFxuXHRcdFx0Ym94OiByZWdsLnByb3AoJ3ZpZXdwb3J0Jylcblx0XHR9LFxuXHRcdHZpZXdwb3J0OiByZWdsLnByb3AoJ3ZpZXdwb3J0Jylcblx0fVxuXG5cblx0Ly8gc2ltcGxpZmllZCByZWN0YW5ndWxhciBsaW5lIHNoYWRlclxuXHRsZXQgZHJhd1JlY3RMaW5lID0gcmVnbChleHRlbmQoe1xuXHRcdHZlcnQ6IGdsc2xpZnkoW1wicHJlY2lzaW9uIGhpZ2hwIGZsb2F0O1xcbiNkZWZpbmUgR0xTTElGWSAxXFxuXFxuYXR0cmlidXRlIHZlYzIgYUNvb3JkLCBiQ29vcmQsIGFDb29yZEZyYWN0LCBiQ29vcmRGcmFjdDtcXG5hdHRyaWJ1dGUgdmVjNCBjb2xvcjtcXG5hdHRyaWJ1dGUgZmxvYXQgbGluZUVuZCwgbGluZVRvcDtcXG5cXG51bmlmb3JtIHZlYzIgc2NhbGUsIHNjYWxlRnJhY3QsIHRyYW5zbGF0ZSwgdHJhbnNsYXRlRnJhY3Q7XFxudW5pZm9ybSBmbG9hdCB0aGlja25lc3MsIHBpeGVsUmF0aW8sIGlkLCBkZXB0aDtcXG51bmlmb3JtIHZlYzQgdmlld3BvcnQ7XFxuXFxudmFyeWluZyB2ZWM0IGZyYWdDb2xvcjtcXG52YXJ5aW5nIHZlYzIgdGFuZ2VudDtcXG5cXG52ZWMyIHByb2plY3QodmVjMiBwb3NpdGlvbiwgdmVjMiBwb3NpdGlvbkZyYWN0LCB2ZWMyIHNjYWxlLCB2ZWMyIHNjYWxlRnJhY3QsIHZlYzIgdHJhbnNsYXRlLCB2ZWMyIHRyYW5zbGF0ZUZyYWN0KSB7XFxuXFx0Ly8gdGhlIG9yZGVyIGlzIGltcG9ydGFudFxcblxcdHJldHVybiBwb3NpdGlvbiAqIHNjYWxlICsgdHJhbnNsYXRlXFxuICAgICAgICsgcG9zaXRpb25GcmFjdCAqIHNjYWxlICsgdHJhbnNsYXRlRnJhY3RcXG4gICAgICAgKyBwb3NpdGlvbiAqIHNjYWxlRnJhY3RcXG4gICAgICAgKyBwb3NpdGlvbkZyYWN0ICogc2NhbGVGcmFjdDtcXG59XFxuXFxudm9pZCBtYWluKCkge1xcblxcdGZsb2F0IGxpbmVTdGFydCA9IDEuIC0gbGluZUVuZDtcXG5cXHRmbG9hdCBsaW5lT2Zmc2V0ID0gbGluZVRvcCAqIDIuIC0gMS47XFxuXFxuXFx0dmVjMiBkaWZmID0gKGJDb29yZCArIGJDb29yZEZyYWN0IC0gYUNvb3JkIC0gYUNvb3JkRnJhY3QpO1xcblxcdHRhbmdlbnQgPSBub3JtYWxpemUoZGlmZiAqIHNjYWxlICogdmlld3BvcnQuencpO1xcblxcdHZlYzIgbm9ybWFsID0gdmVjMigtdGFuZ2VudC55LCB0YW5nZW50LngpO1xcblxcblxcdHZlYzIgcG9zaXRpb24gPSBwcm9qZWN0KGFDb29yZCwgYUNvb3JkRnJhY3QsIHNjYWxlLCBzY2FsZUZyYWN0LCB0cmFuc2xhdGUsIHRyYW5zbGF0ZUZyYWN0KSAqIGxpbmVTdGFydFxcblxcdFxcdCsgcHJvamVjdChiQ29vcmQsIGJDb29yZEZyYWN0LCBzY2FsZSwgc2NhbGVGcmFjdCwgdHJhbnNsYXRlLCB0cmFuc2xhdGVGcmFjdCkgKiBsaW5lRW5kXFxuXFxuXFx0XFx0KyB0aGlja25lc3MgKiBub3JtYWwgKiAuNSAqIGxpbmVPZmZzZXQgLyB2aWV3cG9ydC56dztcXG5cXG5cXHRnbF9Qb3NpdGlvbiA9IHZlYzQocG9zaXRpb24gKiAyLjAgLSAxLjAsIGRlcHRoLCAxKTtcXG5cXG5cXHRmcmFnQ29sb3IgPSBjb2xvciAvIDI1NS47XFxufVxcblwiXSksXG5cdFx0ZnJhZzogZ2xzbGlmeShbXCJwcmVjaXNpb24gaGlnaHAgZmxvYXQ7XFxuI2RlZmluZSBHTFNMSUZZIDFcXG5cXG51bmlmb3JtIHNhbXBsZXIyRCBkYXNoUGF0dGVybjtcXG5cXG51bmlmb3JtIGZsb2F0IGRhc2hTaXplLCBwaXhlbFJhdGlvLCB0aGlja25lc3MsIG9wYWNpdHksIGlkO1xcblxcbnZhcnlpbmcgdmVjNCBmcmFnQ29sb3I7XFxudmFyeWluZyB2ZWMyIHRhbmdlbnQ7XFxuXFxudm9pZCBtYWluKCkge1xcblxcdGZsb2F0IGFscGhhID0gMS47XFxuXFxuXFx0ZmxvYXQgdCA9IGZyYWN0KGRvdCh0YW5nZW50LCBnbF9GcmFnQ29vcmQueHkpIC8gZGFzaFNpemUpICogLjUgKyAuMjU7XFxuXFx0ZmxvYXQgZGFzaCA9IHRleHR1cmUyRChkYXNoUGF0dGVybiwgdmVjMih0LCAuNSkpLnI7XFxuXFxuXFx0Z2xfRnJhZ0NvbG9yID0gZnJhZ0NvbG9yO1xcblxcdGdsX0ZyYWdDb2xvci5hICo9IGFscGhhICogb3BhY2l0eSAqIGRhc2g7XFxufVxcblwiXSksXG5cblx0XHRhdHRyaWJ1dGVzOiB7XG5cdFx0XHQvLyBpZiBwb2ludCBpcyBhdCB0aGUgZW5kIG9mIHNlZ21lbnRcblx0XHRcdGxpbmVFbmQ6IHtcblx0XHRcdFx0YnVmZmVyOiBvZmZzZXRCdWZmZXIsXG5cdFx0XHRcdGRpdmlzb3I6IDAsXG5cdFx0XHRcdHN0cmlkZTogOCxcblx0XHRcdFx0b2Zmc2V0OiAwXG5cdFx0XHR9LFxuXHRcdFx0Ly8gaWYgcG9pbnQgaXMgYXQgdGhlIHRvcCBvZiBzZWdtZW50XG5cdFx0XHRsaW5lVG9wOiB7XG5cdFx0XHRcdGJ1ZmZlcjogb2Zmc2V0QnVmZmVyLFxuXHRcdFx0XHRkaXZpc29yOiAwLFxuXHRcdFx0XHRzdHJpZGU6IDgsXG5cdFx0XHRcdG9mZnNldDogNFxuXHRcdFx0fSxcblx0XHRcdC8vIGJlZ2lubmluZyBvZiBsaW5lIGNvb3JkaW5hdGVcblx0XHRcdGFDb29yZDoge1xuXHRcdFx0XHRidWZmZXI6IHJlZ2wucHJvcCgncG9zaXRpb25CdWZmZXInKSxcblx0XHRcdFx0c3RyaWRlOiA4LFxuXHRcdFx0XHRvZmZzZXQ6IDgsXG5cdFx0XHRcdGRpdmlzb3I6IDFcblx0XHRcdH0sXG5cdFx0XHQvLyBlbmQgb2YgbGluZSBjb29yZGluYXRlXG5cdFx0XHRiQ29vcmQ6IHtcblx0XHRcdFx0YnVmZmVyOiByZWdsLnByb3AoJ3Bvc2l0aW9uQnVmZmVyJyksXG5cdFx0XHRcdHN0cmlkZTogOCxcblx0XHRcdFx0b2Zmc2V0OiAxNixcblx0XHRcdFx0ZGl2aXNvcjogMVxuXHRcdFx0fSxcblx0XHRcdGFDb29yZEZyYWN0OiB7XG5cdFx0XHRcdGJ1ZmZlcjogcmVnbC5wcm9wKCdwb3NpdGlvbkZyYWN0QnVmZmVyJyksXG5cdFx0XHRcdHN0cmlkZTogOCxcblx0XHRcdFx0b2Zmc2V0OiA4LFxuXHRcdFx0XHRkaXZpc29yOiAxXG5cdFx0XHR9LFxuXHRcdFx0YkNvb3JkRnJhY3Q6IHtcblx0XHRcdFx0YnVmZmVyOiByZWdsLnByb3AoJ3Bvc2l0aW9uRnJhY3RCdWZmZXInKSxcblx0XHRcdFx0c3RyaWRlOiA4LFxuXHRcdFx0XHRvZmZzZXQ6IDE2LFxuXHRcdFx0XHRkaXZpc29yOiAxXG5cdFx0XHR9LFxuXHRcdFx0Y29sb3I6IHtcblx0XHRcdFx0YnVmZmVyOiByZWdsLnByb3AoJ2NvbG9yQnVmZmVyJyksXG5cdFx0XHRcdHN0cmlkZTogNCxcblx0XHRcdFx0b2Zmc2V0OiAwLFxuXHRcdFx0XHRkaXZpc29yOiAxXG5cdFx0XHR9XG5cdFx0fVxuXHR9LCBzaGFkZXJPcHRpb25zKSlcblxuXHQvLyBjcmVhdGUgcmVnbCBkcmF3XG5cdGxldCBkcmF3TWl0ZXJMaW5lXG5cblx0dHJ5IHtcblx0XHRkcmF3TWl0ZXJMaW5lID0gcmVnbChleHRlbmQoe1xuXHRcdFx0Ly8gY3VsbGluZyByZW1vdmVzIHBvbHlnb24gY3JlYXNpbmdcblx0XHRcdGN1bGw6IHtcblx0XHRcdFx0ZW5hYmxlOiB0cnVlLFxuXHRcdFx0XHRmYWNlOiAnYmFjaydcblx0XHRcdH0sXG5cblx0XHRcdHZlcnQ6IGdsc2xpZnkoW1wicHJlY2lzaW9uIGhpZ2hwIGZsb2F0O1xcbiNkZWZpbmUgR0xTTElGWSAxXFxuXFxuYXR0cmlidXRlIHZlYzIgYUNvb3JkLCBiQ29vcmQsIG5leHRDb29yZCwgcHJldkNvb3JkO1xcbmF0dHJpYnV0ZSB2ZWM0IGFDb2xvciwgYkNvbG9yO1xcbmF0dHJpYnV0ZSBmbG9hdCBsaW5lRW5kLCBsaW5lVG9wO1xcblxcbnVuaWZvcm0gdmVjMiBzY2FsZSwgdHJhbnNsYXRlO1xcbnVuaWZvcm0gZmxvYXQgdGhpY2tuZXNzLCBwaXhlbFJhdGlvLCBpZCwgZGVwdGg7XFxudW5pZm9ybSB2ZWM0IHZpZXdwb3J0O1xcbnVuaWZvcm0gZmxvYXQgbWl0ZXJMaW1pdCwgbWl0ZXJNb2RlO1xcblxcbnZhcnlpbmcgdmVjNCBmcmFnQ29sb3I7XFxudmFyeWluZyB2ZWM0IHN0YXJ0Q3V0b2ZmLCBlbmRDdXRvZmY7XFxudmFyeWluZyB2ZWMyIHRhbmdlbnQ7XFxudmFyeWluZyB2ZWMyIHN0YXJ0Q29vcmQsIGVuZENvb3JkO1xcbnZhcnlpbmcgZmxvYXQgZW5hYmxlU3RhcnRNaXRlciwgZW5hYmxlRW5kTWl0ZXI7XFxuXFxuY29uc3QgZmxvYXQgUkVWRVJTRV9USFJFU0hPTEQgPSAtLjg3NTtcXG5jb25zdCBmbG9hdCBNSU5fRElGRiA9IDFlLTY7XFxuXFxuLy8gVE9ETzogcG9zc2libGUgb3B0aW1pemF0aW9uczogYXZvaWQgb3ZlcmNhbGN1bGF0aW5nIGFsbCBmb3IgdmVydGljZXMgYW5kIGNhbGMganVzdCBvbmUgaW5zdGVhZFxcbi8vIFRPRE86IHByZWNhbGN1bGF0ZSBkb3QgcHJvZHVjdHMsIG5vcm1hbGl6ZSB0aGluZ3MgYmVmb3JlaGVhZCBldGMuXFxuLy8gVE9ETzogcmVmYWN0b3IgdG8gcmVjdGFuZ3VsYXIgYWxnb3JpdGhtXFxuXFxuZmxvYXQgZGlzdFRvTGluZSh2ZWMyIHAsIHZlYzIgYSwgdmVjMiBiKSB7XFxuXFx0dmVjMiBkaWZmID0gYiAtIGE7XFxuXFx0dmVjMiBwZXJwID0gbm9ybWFsaXplKHZlYzIoLWRpZmYueSwgZGlmZi54KSk7XFxuXFx0cmV0dXJuIGRvdChwIC0gYSwgcGVycCk7XFxufVxcblxcbmJvb2wgaXNOYU4oIGZsb2F0IHZhbCApe1xcbiAgcmV0dXJuICggdmFsIDwgMC4wIHx8IDAuMCA8IHZhbCB8fCB2YWwgPT0gMC4wICkgPyBmYWxzZSA6IHRydWU7XFxufVxcblxcbnZvaWQgbWFpbigpIHtcXG5cXHR2ZWMyIGFDb29yZCA9IGFDb29yZCwgYkNvb3JkID0gYkNvb3JkLCBwcmV2Q29vcmQgPSBwcmV2Q29vcmQsIG5leHRDb29yZCA9IG5leHRDb29yZDtcXG5cXG4gIHZlYzIgYWRqdXN0ZWRTY2FsZTtcXG4gIGFkanVzdGVkU2NhbGUueCA9IChhYnMoc2NhbGUueCkgPCBNSU5fRElGRikgPyBNSU5fRElGRiA6IHNjYWxlLng7XFxuICBhZGp1c3RlZFNjYWxlLnkgPSAoYWJzKHNjYWxlLnkpIDwgTUlOX0RJRkYpID8gTUlOX0RJRkYgOiBzY2FsZS55O1xcblxcbiAgdmVjMiBzY2FsZVJhdGlvID0gYWRqdXN0ZWRTY2FsZSAqIHZpZXdwb3J0Lnp3O1xcblxcdHZlYzIgbm9ybWFsV2lkdGggPSB0aGlja25lc3MgLyBzY2FsZVJhdGlvO1xcblxcblxcdGZsb2F0IGxpbmVTdGFydCA9IDEuIC0gbGluZUVuZDtcXG5cXHRmbG9hdCBsaW5lQm90ID0gMS4gLSBsaW5lVG9wO1xcblxcblxcdGZyYWdDb2xvciA9IChsaW5lU3RhcnQgKiBhQ29sb3IgKyBsaW5lRW5kICogYkNvbG9yKSAvIDI1NS47XFxuXFxuXFx0aWYgKGlzTmFOKGFDb29yZC54KSB8fCBpc05hTihhQ29vcmQueSkgfHwgaXNOYU4oYkNvb3JkLngpIHx8IGlzTmFOKGJDb29yZC55KSkgcmV0dXJuO1xcblxcblxcdGlmIChhQ29vcmQgPT0gcHJldkNvb3JkKSBwcmV2Q29vcmQgPSBhQ29vcmQgKyBub3JtYWxpemUoYkNvb3JkIC0gYUNvb3JkKTtcXG5cXHRpZiAoYkNvb3JkID09IG5leHRDb29yZCkgbmV4dENvb3JkID0gYkNvb3JkIC0gbm9ybWFsaXplKGJDb29yZCAtIGFDb29yZCk7XFxuXFxuXFx0dmVjMiBwcmV2RGlmZiA9IGFDb29yZCAtIHByZXZDb29yZDtcXG5cXHR2ZWMyIGN1cnJEaWZmID0gYkNvb3JkIC0gYUNvb3JkO1xcblxcdHZlYzIgbmV4dERpZmYgPSBuZXh0Q29vcmQgLSBiQ29vcmQ7XFxuXFxuXFx0dmVjMiBwcmV2VGFuZ2VudCA9IG5vcm1hbGl6ZShwcmV2RGlmZiAqIHNjYWxlUmF0aW8pO1xcblxcdHZlYzIgY3VyclRhbmdlbnQgPSBub3JtYWxpemUoY3VyckRpZmYgKiBzY2FsZVJhdGlvKTtcXG5cXHR2ZWMyIG5leHRUYW5nZW50ID0gbm9ybWFsaXplKG5leHREaWZmICogc2NhbGVSYXRpbyk7XFxuXFxuXFx0dmVjMiBwcmV2Tm9ybWFsID0gdmVjMigtcHJldlRhbmdlbnQueSwgcHJldlRhbmdlbnQueCk7XFxuXFx0dmVjMiBjdXJyTm9ybWFsID0gdmVjMigtY3VyclRhbmdlbnQueSwgY3VyclRhbmdlbnQueCk7XFxuXFx0dmVjMiBuZXh0Tm9ybWFsID0gdmVjMigtbmV4dFRhbmdlbnQueSwgbmV4dFRhbmdlbnQueCk7XFxuXFxuXFx0dmVjMiBzdGFydEpvaW5EaXJlY3Rpb24gPSBub3JtYWxpemUocHJldlRhbmdlbnQgLSBjdXJyVGFuZ2VudCk7XFxuXFx0dmVjMiBlbmRKb2luRGlyZWN0aW9uID0gbm9ybWFsaXplKGN1cnJUYW5nZW50IC0gbmV4dFRhbmdlbnQpO1xcblxcblxcdC8vIGNvbGxhcHNlZC91bmlkaXJlY3Rpb25hbCBzZWdtZW50IGNhc2VzXFxuXFx0Ly8gRklYTUU6IHRoZXJlIHNob3VsZCBiZSBtb3JlIGVsZWdhbnQgc29sdXRpb25cXG5cXHR2ZWMyIHByZXZUYW5EaWZmID0gYWJzKHByZXZUYW5nZW50IC0gY3VyclRhbmdlbnQpO1xcblxcdHZlYzIgbmV4dFRhbkRpZmYgPSBhYnMobmV4dFRhbmdlbnQgLSBjdXJyVGFuZ2VudCk7XFxuXFx0aWYgKG1heChwcmV2VGFuRGlmZi54LCBwcmV2VGFuRGlmZi55KSA8IE1JTl9ESUZGKSB7XFxuXFx0XFx0c3RhcnRKb2luRGlyZWN0aW9uID0gY3Vyck5vcm1hbDtcXG5cXHR9XFxuXFx0aWYgKG1heChuZXh0VGFuRGlmZi54LCBuZXh0VGFuRGlmZi55KSA8IE1JTl9ESUZGKSB7XFxuXFx0XFx0ZW5kSm9pbkRpcmVjdGlvbiA9IGN1cnJOb3JtYWw7XFxuXFx0fVxcblxcdGlmIChhQ29vcmQgPT0gYkNvb3JkKSB7XFxuXFx0XFx0ZW5kSm9pbkRpcmVjdGlvbiA9IHN0YXJ0Sm9pbkRpcmVjdGlvbjtcXG5cXHRcXHRjdXJyTm9ybWFsID0gcHJldk5vcm1hbDtcXG5cXHRcXHRjdXJyVGFuZ2VudCA9IHByZXZUYW5nZW50O1xcblxcdH1cXG5cXG5cXHR0YW5nZW50ID0gY3VyclRhbmdlbnQ7XFxuXFxuXFx0Ly9jYWxjdWxhdGUgam9pbiBzaGlmdHMgcmVsYXRpdmUgdG8gbm9ybWFsc1xcblxcdGZsb2F0IHN0YXJ0Sm9pblNoaWZ0ID0gZG90KGN1cnJOb3JtYWwsIHN0YXJ0Sm9pbkRpcmVjdGlvbik7XFxuXFx0ZmxvYXQgZW5kSm9pblNoaWZ0ID0gZG90KGN1cnJOb3JtYWwsIGVuZEpvaW5EaXJlY3Rpb24pO1xcblxcblxcdGZsb2F0IHN0YXJ0TWl0ZXJSYXRpbyA9IGFicygxLiAvIHN0YXJ0Sm9pblNoaWZ0KTtcXG5cXHRmbG9hdCBlbmRNaXRlclJhdGlvID0gYWJzKDEuIC8gZW5kSm9pblNoaWZ0KTtcXG5cXG5cXHR2ZWMyIHN0YXJ0Sm9pbiA9IHN0YXJ0Sm9pbkRpcmVjdGlvbiAqIHN0YXJ0TWl0ZXJSYXRpbztcXG5cXHR2ZWMyIGVuZEpvaW4gPSBlbmRKb2luRGlyZWN0aW9uICogZW5kTWl0ZXJSYXRpbztcXG5cXG5cXHR2ZWMyIHN0YXJ0VG9wSm9pbiwgc3RhcnRCb3RKb2luLCBlbmRUb3BKb2luLCBlbmRCb3RKb2luO1xcblxcdHN0YXJ0VG9wSm9pbiA9IHNpZ24oc3RhcnRKb2luU2hpZnQpICogc3RhcnRKb2luICogLjU7XFxuXFx0c3RhcnRCb3RKb2luID0gLXN0YXJ0VG9wSm9pbjtcXG5cXG5cXHRlbmRUb3BKb2luID0gc2lnbihlbmRKb2luU2hpZnQpICogZW5kSm9pbiAqIC41O1xcblxcdGVuZEJvdEpvaW4gPSAtZW5kVG9wSm9pbjtcXG5cXG5cXHR2ZWMyIGFUb3BDb29yZCA9IGFDb29yZCArIG5vcm1hbFdpZHRoICogc3RhcnRUb3BKb2luO1xcblxcdHZlYzIgYlRvcENvb3JkID0gYkNvb3JkICsgbm9ybWFsV2lkdGggKiBlbmRUb3BKb2luO1xcblxcdHZlYzIgYUJvdENvb3JkID0gYUNvb3JkICsgbm9ybWFsV2lkdGggKiBzdGFydEJvdEpvaW47XFxuXFx0dmVjMiBiQm90Q29vcmQgPSBiQ29vcmQgKyBub3JtYWxXaWR0aCAqIGVuZEJvdEpvaW47XFxuXFxuXFx0Ly9taXRlciBhbnRpLWNsaXBwaW5nXFxuXFx0ZmxvYXQgYmFDbGlwcGluZyA9IGRpc3RUb0xpbmUoYkNvb3JkLCBhQ29vcmQsIGFCb3RDb29yZCkgLyBkb3Qobm9ybWFsaXplKG5vcm1hbFdpZHRoICogZW5kQm90Sm9pbiksIG5vcm1hbGl6ZShub3JtYWxXaWR0aC55eCAqIHZlYzIoLXN0YXJ0Qm90Sm9pbi55LCBzdGFydEJvdEpvaW4ueCkpKTtcXG5cXHRmbG9hdCBhYkNsaXBwaW5nID0gZGlzdFRvTGluZShhQ29vcmQsIGJDb29yZCwgYlRvcENvb3JkKSAvIGRvdChub3JtYWxpemUobm9ybWFsV2lkdGggKiBzdGFydEJvdEpvaW4pLCBub3JtYWxpemUobm9ybWFsV2lkdGgueXggKiB2ZWMyKC1lbmRCb3RKb2luLnksIGVuZEJvdEpvaW4ueCkpKTtcXG5cXG5cXHQvL3ByZXZlbnQgY2xvc2UgdG8gcmV2ZXJzZSBkaXJlY3Rpb24gc3dpdGNoXFxuXFx0Ym9vbCBwcmV2UmV2ZXJzZSA9IGRvdChjdXJyVGFuZ2VudCwgcHJldlRhbmdlbnQpIDw9IFJFVkVSU0VfVEhSRVNIT0xEICYmIGFicyhkb3QoY3VyclRhbmdlbnQsIHByZXZOb3JtYWwpKSAqIG1pbihsZW5ndGgocHJldkRpZmYpLCBsZW5ndGgoY3VyckRpZmYpKSA8ICBsZW5ndGgobm9ybWFsV2lkdGggKiBjdXJyTm9ybWFsKTtcXG5cXHRib29sIG5leHRSZXZlcnNlID0gZG90KGN1cnJUYW5nZW50LCBuZXh0VGFuZ2VudCkgPD0gUkVWRVJTRV9USFJFU0hPTEQgJiYgYWJzKGRvdChjdXJyVGFuZ2VudCwgbmV4dE5vcm1hbCkpICogbWluKGxlbmd0aChuZXh0RGlmZiksIGxlbmd0aChjdXJyRGlmZikpIDwgIGxlbmd0aChub3JtYWxXaWR0aCAqIGN1cnJOb3JtYWwpO1xcblxcblxcdGlmIChwcmV2UmV2ZXJzZSkge1xcblxcdFxcdC8vbWFrZSBqb2luIHJlY3Rhbmd1bGFyXFxuXFx0XFx0dmVjMiBtaXRlclNoaWZ0ID0gbm9ybWFsV2lkdGggKiBzdGFydEpvaW5EaXJlY3Rpb24gKiBtaXRlckxpbWl0ICogLjU7XFxuXFx0XFx0ZmxvYXQgbm9ybWFsQWRqdXN0ID0gMS4gLSBtaW4obWl0ZXJMaW1pdCAvIHN0YXJ0TWl0ZXJSYXRpbywgMS4pO1xcblxcdFxcdGFCb3RDb29yZCA9IGFDb29yZCArIG1pdGVyU2hpZnQgLSBub3JtYWxBZGp1c3QgKiBub3JtYWxXaWR0aCAqIGN1cnJOb3JtYWwgKiAuNTtcXG5cXHRcXHRhVG9wQ29vcmQgPSBhQ29vcmQgKyBtaXRlclNoaWZ0ICsgbm9ybWFsQWRqdXN0ICogbm9ybWFsV2lkdGggKiBjdXJyTm9ybWFsICogLjU7XFxuXFx0fVxcblxcdGVsc2UgaWYgKCFuZXh0UmV2ZXJzZSAmJiBiYUNsaXBwaW5nID4gMC4gJiYgYmFDbGlwcGluZyA8IGxlbmd0aChub3JtYWxXaWR0aCAqIGVuZEJvdEpvaW4pKSB7XFxuXFx0XFx0Ly9oYW5kbGUgbWl0ZXIgY2xpcHBpbmdcXG5cXHRcXHRiVG9wQ29vcmQgLT0gbm9ybWFsV2lkdGggKiBlbmRUb3BKb2luO1xcblxcdFxcdGJUb3BDb29yZCArPSBub3JtYWxpemUoZW5kVG9wSm9pbiAqIG5vcm1hbFdpZHRoKSAqIGJhQ2xpcHBpbmc7XFxuXFx0fVxcblxcblxcdGlmIChuZXh0UmV2ZXJzZSkge1xcblxcdFxcdC8vbWFrZSBqb2luIHJlY3Rhbmd1bGFyXFxuXFx0XFx0dmVjMiBtaXRlclNoaWZ0ID0gbm9ybWFsV2lkdGggKiBlbmRKb2luRGlyZWN0aW9uICogbWl0ZXJMaW1pdCAqIC41O1xcblxcdFxcdGZsb2F0IG5vcm1hbEFkanVzdCA9IDEuIC0gbWluKG1pdGVyTGltaXQgLyBlbmRNaXRlclJhdGlvLCAxLik7XFxuXFx0XFx0YkJvdENvb3JkID0gYkNvb3JkICsgbWl0ZXJTaGlmdCAtIG5vcm1hbEFkanVzdCAqIG5vcm1hbFdpZHRoICogY3Vyck5vcm1hbCAqIC41O1xcblxcdFxcdGJUb3BDb29yZCA9IGJDb29yZCArIG1pdGVyU2hpZnQgKyBub3JtYWxBZGp1c3QgKiBub3JtYWxXaWR0aCAqIGN1cnJOb3JtYWwgKiAuNTtcXG5cXHR9XFxuXFx0ZWxzZSBpZiAoIXByZXZSZXZlcnNlICYmIGFiQ2xpcHBpbmcgPiAwLiAmJiBhYkNsaXBwaW5nIDwgbGVuZ3RoKG5vcm1hbFdpZHRoICogc3RhcnRCb3RKb2luKSkge1xcblxcdFxcdC8vaGFuZGxlIG1pdGVyIGNsaXBwaW5nXFxuXFx0XFx0YUJvdENvb3JkIC09IG5vcm1hbFdpZHRoICogc3RhcnRCb3RKb2luO1xcblxcdFxcdGFCb3RDb29yZCArPSBub3JtYWxpemUoc3RhcnRCb3RKb2luICogbm9ybWFsV2lkdGgpICogYWJDbGlwcGluZztcXG5cXHR9XFxuXFxuXFx0dmVjMiBhVG9wUG9zaXRpb24gPSAoYVRvcENvb3JkKSAqIGFkanVzdGVkU2NhbGUgKyB0cmFuc2xhdGU7XFxuXFx0dmVjMiBhQm90UG9zaXRpb24gPSAoYUJvdENvb3JkKSAqIGFkanVzdGVkU2NhbGUgKyB0cmFuc2xhdGU7XFxuXFxuXFx0dmVjMiBiVG9wUG9zaXRpb24gPSAoYlRvcENvb3JkKSAqIGFkanVzdGVkU2NhbGUgKyB0cmFuc2xhdGU7XFxuXFx0dmVjMiBiQm90UG9zaXRpb24gPSAoYkJvdENvb3JkKSAqIGFkanVzdGVkU2NhbGUgKyB0cmFuc2xhdGU7XFxuXFxuXFx0Ly9wb3NpdGlvbiBpcyBub3JtYWxpemVkIDAuLjEgY29vcmQgb24gdGhlIHNjcmVlblxcblxcdHZlYzIgcG9zaXRpb24gPSAoYVRvcFBvc2l0aW9uICogbGluZVRvcCArIGFCb3RQb3NpdGlvbiAqIGxpbmVCb3QpICogbGluZVN0YXJ0ICsgKGJUb3BQb3NpdGlvbiAqIGxpbmVUb3AgKyBiQm90UG9zaXRpb24gKiBsaW5lQm90KSAqIGxpbmVFbmQ7XFxuXFxuXFx0c3RhcnRDb29yZCA9IGFDb29yZCAqIHNjYWxlUmF0aW8gKyB0cmFuc2xhdGUgKiB2aWV3cG9ydC56dyArIHZpZXdwb3J0Lnh5O1xcblxcdGVuZENvb3JkID0gYkNvb3JkICogc2NhbGVSYXRpbyArIHRyYW5zbGF0ZSAqIHZpZXdwb3J0Lnp3ICsgdmlld3BvcnQueHk7XFxuXFxuXFx0Z2xfUG9zaXRpb24gPSB2ZWM0KHBvc2l0aW9uICAqIDIuMCAtIDEuMCwgZGVwdGgsIDEpO1xcblxcblxcdGVuYWJsZVN0YXJ0TWl0ZXIgPSBzdGVwKGRvdChjdXJyVGFuZ2VudCwgcHJldlRhbmdlbnQpLCAuNSk7XFxuXFx0ZW5hYmxlRW5kTWl0ZXIgPSBzdGVwKGRvdChjdXJyVGFuZ2VudCwgbmV4dFRhbmdlbnQpLCAuNSk7XFxuXFxuXFx0Ly9iZXZlbCBtaXRlciBjdXRvZmZzXFxuXFx0aWYgKG1pdGVyTW9kZSA9PSAxLikge1xcblxcdFxcdGlmIChlbmFibGVTdGFydE1pdGVyID09IDEuKSB7XFxuXFx0XFx0XFx0dmVjMiBzdGFydE1pdGVyV2lkdGggPSB2ZWMyKHN0YXJ0Sm9pbkRpcmVjdGlvbikgKiB0aGlja25lc3MgKiBtaXRlckxpbWl0ICogLjU7XFxuXFx0XFx0XFx0c3RhcnRDdXRvZmYgPSB2ZWM0KGFDb29yZCwgYUNvb3JkKTtcXG5cXHRcXHRcXHRzdGFydEN1dG9mZi56dyArPSB2ZWMyKC1zdGFydEpvaW5EaXJlY3Rpb24ueSwgc3RhcnRKb2luRGlyZWN0aW9uLngpIC8gc2NhbGVSYXRpbztcXG5cXHRcXHRcXHRzdGFydEN1dG9mZiA9IHN0YXJ0Q3V0b2ZmICogc2NhbGVSYXRpby54eXh5ICsgdHJhbnNsYXRlLnh5eHkgKiB2aWV3cG9ydC56d3p3O1xcblxcdFxcdFxcdHN0YXJ0Q3V0b2ZmICs9IHZpZXdwb3J0Lnh5eHk7XFxuXFx0XFx0XFx0c3RhcnRDdXRvZmYgKz0gc3RhcnRNaXRlcldpZHRoLnh5eHk7XFxuXFx0XFx0fVxcblxcblxcdFxcdGlmIChlbmFibGVFbmRNaXRlciA9PSAxLikge1xcblxcdFxcdFxcdHZlYzIgZW5kTWl0ZXJXaWR0aCA9IHZlYzIoZW5kSm9pbkRpcmVjdGlvbikgKiB0aGlja25lc3MgKiBtaXRlckxpbWl0ICogLjU7XFxuXFx0XFx0XFx0ZW5kQ3V0b2ZmID0gdmVjNChiQ29vcmQsIGJDb29yZCk7XFxuXFx0XFx0XFx0ZW5kQ3V0b2ZmLnp3ICs9IHZlYzIoLWVuZEpvaW5EaXJlY3Rpb24ueSwgZW5kSm9pbkRpcmVjdGlvbi54KSAgLyBzY2FsZVJhdGlvO1xcblxcdFxcdFxcdGVuZEN1dG9mZiA9IGVuZEN1dG9mZiAqIHNjYWxlUmF0aW8ueHl4eSArIHRyYW5zbGF0ZS54eXh5ICogdmlld3BvcnQuend6dztcXG5cXHRcXHRcXHRlbmRDdXRvZmYgKz0gdmlld3BvcnQueHl4eTtcXG5cXHRcXHRcXHRlbmRDdXRvZmYgKz0gZW5kTWl0ZXJXaWR0aC54eXh5O1xcblxcdFxcdH1cXG5cXHR9XFxuXFxuXFx0Ly9yb3VuZCBtaXRlciBjdXRvZmZzXFxuXFx0ZWxzZSBpZiAobWl0ZXJNb2RlID09IDIuKSB7XFxuXFx0XFx0aWYgKGVuYWJsZVN0YXJ0TWl0ZXIgPT0gMS4pIHtcXG5cXHRcXHRcXHR2ZWMyIHN0YXJ0TWl0ZXJXaWR0aCA9IHZlYzIoc3RhcnRKb2luRGlyZWN0aW9uKSAqIHRoaWNrbmVzcyAqIGFicyhkb3Qoc3RhcnRKb2luRGlyZWN0aW9uLCBjdXJyTm9ybWFsKSkgKiAuNTtcXG5cXHRcXHRcXHRzdGFydEN1dG9mZiA9IHZlYzQoYUNvb3JkLCBhQ29vcmQpO1xcblxcdFxcdFxcdHN0YXJ0Q3V0b2ZmLnp3ICs9IHZlYzIoLXN0YXJ0Sm9pbkRpcmVjdGlvbi55LCBzdGFydEpvaW5EaXJlY3Rpb24ueCkgLyBzY2FsZVJhdGlvO1xcblxcdFxcdFxcdHN0YXJ0Q3V0b2ZmID0gc3RhcnRDdXRvZmYgKiBzY2FsZVJhdGlvLnh5eHkgKyB0cmFuc2xhdGUueHl4eSAqIHZpZXdwb3J0Lnp3enc7XFxuXFx0XFx0XFx0c3RhcnRDdXRvZmYgKz0gdmlld3BvcnQueHl4eTtcXG5cXHRcXHRcXHRzdGFydEN1dG9mZiArPSBzdGFydE1pdGVyV2lkdGgueHl4eTtcXG5cXHRcXHR9XFxuXFxuXFx0XFx0aWYgKGVuYWJsZUVuZE1pdGVyID09IDEuKSB7XFxuXFx0XFx0XFx0dmVjMiBlbmRNaXRlcldpZHRoID0gdmVjMihlbmRKb2luRGlyZWN0aW9uKSAqIHRoaWNrbmVzcyAqIGFicyhkb3QoZW5kSm9pbkRpcmVjdGlvbiwgY3Vyck5vcm1hbCkpICogLjU7XFxuXFx0XFx0XFx0ZW5kQ3V0b2ZmID0gdmVjNChiQ29vcmQsIGJDb29yZCk7XFxuXFx0XFx0XFx0ZW5kQ3V0b2ZmLnp3ICs9IHZlYzIoLWVuZEpvaW5EaXJlY3Rpb24ueSwgZW5kSm9pbkRpcmVjdGlvbi54KSAgLyBzY2FsZVJhdGlvO1xcblxcdFxcdFxcdGVuZEN1dG9mZiA9IGVuZEN1dG9mZiAqIHNjYWxlUmF0aW8ueHl4eSArIHRyYW5zbGF0ZS54eXh5ICogdmlld3BvcnQuend6dztcXG5cXHRcXHRcXHRlbmRDdXRvZmYgKz0gdmlld3BvcnQueHl4eTtcXG5cXHRcXHRcXHRlbmRDdXRvZmYgKz0gZW5kTWl0ZXJXaWR0aC54eXh5O1xcblxcdFxcdH1cXG5cXHR9XFxufVxcblwiXSksXG5cdFx0XHRmcmFnOiBnbHNsaWZ5KFtcInByZWNpc2lvbiBoaWdocCBmbG9hdDtcXG4jZGVmaW5lIEdMU0xJRlkgMVxcblxcbnVuaWZvcm0gc2FtcGxlcjJEIGRhc2hQYXR0ZXJuO1xcbnVuaWZvcm0gZmxvYXQgZGFzaFNpemUsIHBpeGVsUmF0aW8sIHRoaWNrbmVzcywgb3BhY2l0eSwgaWQsIG1pdGVyTW9kZTtcXG5cXG52YXJ5aW5nIHZlYzQgZnJhZ0NvbG9yO1xcbnZhcnlpbmcgdmVjMiB0YW5nZW50O1xcbnZhcnlpbmcgdmVjNCBzdGFydEN1dG9mZiwgZW5kQ3V0b2ZmO1xcbnZhcnlpbmcgdmVjMiBzdGFydENvb3JkLCBlbmRDb29yZDtcXG52YXJ5aW5nIGZsb2F0IGVuYWJsZVN0YXJ0TWl0ZXIsIGVuYWJsZUVuZE1pdGVyO1xcblxcbmZsb2F0IGRpc3RUb0xpbmUodmVjMiBwLCB2ZWMyIGEsIHZlYzIgYikge1xcblxcdHZlYzIgZGlmZiA9IGIgLSBhO1xcblxcdHZlYzIgcGVycCA9IG5vcm1hbGl6ZSh2ZWMyKC1kaWZmLnksIGRpZmYueCkpO1xcblxcdHJldHVybiBkb3QocCAtIGEsIHBlcnApO1xcbn1cXG5cXG52b2lkIG1haW4oKSB7XFxuXFx0ZmxvYXQgYWxwaGEgPSAxLiwgZGlzdFRvU3RhcnQsIGRpc3RUb0VuZDtcXG5cXHRmbG9hdCBjdXRvZmYgPSB0aGlja25lc3MgKiAuNTtcXG5cXG5cXHQvL2JldmVsIG1pdGVyXFxuXFx0aWYgKG1pdGVyTW9kZSA9PSAxLikge1xcblxcdFxcdGlmIChlbmFibGVTdGFydE1pdGVyID09IDEuKSB7XFxuXFx0XFx0XFx0ZGlzdFRvU3RhcnQgPSBkaXN0VG9MaW5lKGdsX0ZyYWdDb29yZC54eSwgc3RhcnRDdXRvZmYueHksIHN0YXJ0Q3V0b2ZmLnp3KTtcXG5cXHRcXHRcXHRpZiAoZGlzdFRvU3RhcnQgPCAtMS4pIHtcXG5cXHRcXHRcXHRcXHRkaXNjYXJkO1xcblxcdFxcdFxcdFxcdHJldHVybjtcXG5cXHRcXHRcXHR9XFxuXFx0XFx0XFx0YWxwaGEgKj0gbWluKG1heChkaXN0VG9TdGFydCArIDEuLCAwLiksIDEuKTtcXG5cXHRcXHR9XFxuXFxuXFx0XFx0aWYgKGVuYWJsZUVuZE1pdGVyID09IDEuKSB7XFxuXFx0XFx0XFx0ZGlzdFRvRW5kID0gZGlzdFRvTGluZShnbF9GcmFnQ29vcmQueHksIGVuZEN1dG9mZi54eSwgZW5kQ3V0b2ZmLnp3KTtcXG5cXHRcXHRcXHRpZiAoZGlzdFRvRW5kIDwgLTEuKSB7XFxuXFx0XFx0XFx0XFx0ZGlzY2FyZDtcXG5cXHRcXHRcXHRcXHRyZXR1cm47XFxuXFx0XFx0XFx0fVxcblxcdFxcdFxcdGFscGhhICo9IG1pbihtYXgoZGlzdFRvRW5kICsgMS4sIDAuKSwgMS4pO1xcblxcdFxcdH1cXG5cXHR9XFxuXFxuXFx0Ly8gcm91bmQgbWl0ZXJcXG5cXHRlbHNlIGlmIChtaXRlck1vZGUgPT0gMi4pIHtcXG5cXHRcXHRpZiAoZW5hYmxlU3RhcnRNaXRlciA9PSAxLikge1xcblxcdFxcdFxcdGRpc3RUb1N0YXJ0ID0gZGlzdFRvTGluZShnbF9GcmFnQ29vcmQueHksIHN0YXJ0Q3V0b2ZmLnh5LCBzdGFydEN1dG9mZi56dyk7XFxuXFx0XFx0XFx0aWYgKGRpc3RUb1N0YXJ0IDwgMC4pIHtcXG5cXHRcXHRcXHRcXHRmbG9hdCByYWRpdXMgPSBsZW5ndGgoZ2xfRnJhZ0Nvb3JkLnh5IC0gc3RhcnRDb29yZCk7XFxuXFxuXFx0XFx0XFx0XFx0aWYocmFkaXVzID4gY3V0b2ZmICsgLjUpIHtcXG5cXHRcXHRcXHRcXHRcXHRkaXNjYXJkO1xcblxcdFxcdFxcdFxcdFxcdHJldHVybjtcXG5cXHRcXHRcXHRcXHR9XFxuXFxuXFx0XFx0XFx0XFx0YWxwaGEgLT0gc21vb3Roc3RlcChjdXRvZmYgLSAuNSwgY3V0b2ZmICsgLjUsIHJhZGl1cyk7XFxuXFx0XFx0XFx0fVxcblxcdFxcdH1cXG5cXG5cXHRcXHRpZiAoZW5hYmxlRW5kTWl0ZXIgPT0gMS4pIHtcXG5cXHRcXHRcXHRkaXN0VG9FbmQgPSBkaXN0VG9MaW5lKGdsX0ZyYWdDb29yZC54eSwgZW5kQ3V0b2ZmLnh5LCBlbmRDdXRvZmYuencpO1xcblxcdFxcdFxcdGlmIChkaXN0VG9FbmQgPCAwLikge1xcblxcdFxcdFxcdFxcdGZsb2F0IHJhZGl1cyA9IGxlbmd0aChnbF9GcmFnQ29vcmQueHkgLSBlbmRDb29yZCk7XFxuXFxuXFx0XFx0XFx0XFx0aWYocmFkaXVzID4gY3V0b2ZmICsgLjUpIHtcXG5cXHRcXHRcXHRcXHRcXHRkaXNjYXJkO1xcblxcdFxcdFxcdFxcdFxcdHJldHVybjtcXG5cXHRcXHRcXHRcXHR9XFxuXFxuXFx0XFx0XFx0XFx0YWxwaGEgLT0gc21vb3Roc3RlcChjdXRvZmYgLSAuNSwgY3V0b2ZmICsgLjUsIHJhZGl1cyk7XFxuXFx0XFx0XFx0fVxcblxcdFxcdH1cXG5cXHR9XFxuXFxuXFx0ZmxvYXQgdCA9IGZyYWN0KGRvdCh0YW5nZW50LCBnbF9GcmFnQ29vcmQueHkpIC8gZGFzaFNpemUpICogLjUgKyAuMjU7XFxuXFx0ZmxvYXQgZGFzaCA9IHRleHR1cmUyRChkYXNoUGF0dGVybiwgdmVjMih0LCAuNSkpLnI7XFxuXFxuXFx0Z2xfRnJhZ0NvbG9yID0gZnJhZ0NvbG9yO1xcblxcdGdsX0ZyYWdDb2xvci5hICo9IGFscGhhICogb3BhY2l0eSAqIGRhc2g7XFxufVxcblwiXSksXG5cblx0XHRcdGF0dHJpYnV0ZXM6IHtcblx0XHRcdFx0Ly8gaXMgbGluZSBlbmRcblx0XHRcdFx0bGluZUVuZDoge1xuXHRcdFx0XHRcdGJ1ZmZlcjogb2Zmc2V0QnVmZmVyLFxuXHRcdFx0XHRcdGRpdmlzb3I6IDAsXG5cdFx0XHRcdFx0c3RyaWRlOiA4LFxuXHRcdFx0XHRcdG9mZnNldDogMFxuXHRcdFx0XHR9LFxuXHRcdFx0XHQvLyBpcyBsaW5lIHRvcFxuXHRcdFx0XHRsaW5lVG9wOiB7XG5cdFx0XHRcdFx0YnVmZmVyOiBvZmZzZXRCdWZmZXIsXG5cdFx0XHRcdFx0ZGl2aXNvcjogMCxcblx0XHRcdFx0XHRzdHJpZGU6IDgsXG5cdFx0XHRcdFx0b2Zmc2V0OiA0XG5cdFx0XHRcdH0sXG5cdFx0XHRcdC8vIGxlZnQgY29sb3Jcblx0XHRcdFx0YUNvbG9yOiB7XG5cdFx0XHRcdFx0YnVmZmVyOiByZWdsLnByb3AoJ2NvbG9yQnVmZmVyJyksXG5cdFx0XHRcdFx0c3RyaWRlOiA0LFxuXHRcdFx0XHRcdG9mZnNldDogMCxcblx0XHRcdFx0XHRkaXZpc29yOiAxXG5cdFx0XHRcdH0sXG5cdFx0XHRcdC8vIHJpZ2h0IGNvbG9yXG5cdFx0XHRcdGJDb2xvcjoge1xuXHRcdFx0XHRcdGJ1ZmZlcjogcmVnbC5wcm9wKCdjb2xvckJ1ZmZlcicpLFxuXHRcdFx0XHRcdHN0cmlkZTogNCxcblx0XHRcdFx0XHRvZmZzZXQ6IDQsXG5cdFx0XHRcdFx0ZGl2aXNvcjogMVxuXHRcdFx0XHR9LFxuXHRcdFx0XHRwcmV2Q29vcmQ6IHtcblx0XHRcdFx0XHRidWZmZXI6IHJlZ2wucHJvcCgncG9zaXRpb25CdWZmZXInKSxcblx0XHRcdFx0XHRzdHJpZGU6IDgsXG5cdFx0XHRcdFx0b2Zmc2V0OiAwLFxuXHRcdFx0XHRcdGRpdmlzb3I6IDFcblx0XHRcdFx0fSxcblx0XHRcdFx0YUNvb3JkOiB7XG5cdFx0XHRcdFx0YnVmZmVyOiByZWdsLnByb3AoJ3Bvc2l0aW9uQnVmZmVyJyksXG5cdFx0XHRcdFx0c3RyaWRlOiA4LFxuXHRcdFx0XHRcdG9mZnNldDogOCxcblx0XHRcdFx0XHRkaXZpc29yOiAxXG5cdFx0XHRcdH0sXG5cdFx0XHRcdGJDb29yZDoge1xuXHRcdFx0XHRcdGJ1ZmZlcjogcmVnbC5wcm9wKCdwb3NpdGlvbkJ1ZmZlcicpLFxuXHRcdFx0XHRcdHN0cmlkZTogOCxcblx0XHRcdFx0XHRvZmZzZXQ6IDE2LFxuXHRcdFx0XHRcdGRpdmlzb3I6IDFcblx0XHRcdFx0fSxcblx0XHRcdFx0bmV4dENvb3JkOiB7XG5cdFx0XHRcdFx0YnVmZmVyOiByZWdsLnByb3AoJ3Bvc2l0aW9uQnVmZmVyJyksXG5cdFx0XHRcdFx0c3RyaWRlOiA4LFxuXHRcdFx0XHRcdG9mZnNldDogMjQsXG5cdFx0XHRcdFx0ZGl2aXNvcjogMVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSwgc2hhZGVyT3B0aW9ucykpXG5cdH0gY2F0Y2ggKGUpIHtcblx0XHQvLyBJRS9iYWQgV2Via2l0IGZhbGxiYWNrXG5cdFx0ZHJhd01pdGVyTGluZSA9IGRyYXdSZWN0TGluZVxuXHR9XG5cblx0Ly8gZmlsbCBzaGFkZXJcblx0bGV0IGRyYXdGaWxsID0gcmVnbCh7XG5cdFx0cHJpbWl0aXZlOiAndHJpYW5nbGUnLFxuXHRcdGVsZW1lbnRzOiAoY3R4LCBwcm9wKSA9PiBwcm9wLnRyaWFuZ2xlcyxcblx0XHRvZmZzZXQ6IDAsXG5cblx0XHR2ZXJ0OiBnbHNsaWZ5KFtcInByZWNpc2lvbiBoaWdocCBmbG9hdDtcXG4jZGVmaW5lIEdMU0xJRlkgMVxcblxcbmF0dHJpYnV0ZSB2ZWMyIHBvc2l0aW9uLCBwb3NpdGlvbkZyYWN0O1xcblxcbnVuaWZvcm0gdmVjNCBjb2xvcjtcXG51bmlmb3JtIHZlYzIgc2NhbGUsIHNjYWxlRnJhY3QsIHRyYW5zbGF0ZSwgdHJhbnNsYXRlRnJhY3Q7XFxudW5pZm9ybSBmbG9hdCBwaXhlbFJhdGlvLCBpZDtcXG51bmlmb3JtIHZlYzQgdmlld3BvcnQ7XFxudW5pZm9ybSBmbG9hdCBvcGFjaXR5O1xcblxcbnZhcnlpbmcgdmVjNCBmcmFnQ29sb3I7XFxuXFxuY29uc3QgZmxvYXQgTUFYX0xJTkVTID0gMjU2LjtcXG5cXG52b2lkIG1haW4oKSB7XFxuXFx0ZmxvYXQgZGVwdGggPSAoTUFYX0xJTkVTIC0gNC4gLSBpZCkgLyAoTUFYX0xJTkVTKTtcXG5cXG5cXHR2ZWMyIHBvc2l0aW9uID0gcG9zaXRpb24gKiBzY2FsZSArIHRyYW5zbGF0ZVxcbiAgICAgICArIHBvc2l0aW9uRnJhY3QgKiBzY2FsZSArIHRyYW5zbGF0ZUZyYWN0XFxuICAgICAgICsgcG9zaXRpb24gKiBzY2FsZUZyYWN0XFxuICAgICAgICsgcG9zaXRpb25GcmFjdCAqIHNjYWxlRnJhY3Q7XFxuXFxuXFx0Z2xfUG9zaXRpb24gPSB2ZWM0KHBvc2l0aW9uICogMi4wIC0gMS4wLCBkZXB0aCwgMSk7XFxuXFxuXFx0ZnJhZ0NvbG9yID0gY29sb3IgLyAyNTUuO1xcblxcdGZyYWdDb2xvci5hICo9IG9wYWNpdHk7XFxufVxcblwiXSksXG5cdFx0ZnJhZzogZ2xzbGlmeShbXCJwcmVjaXNpb24gaGlnaHAgZmxvYXQ7XFxuI2RlZmluZSBHTFNMSUZZIDFcXG5cXG52YXJ5aW5nIHZlYzQgZnJhZ0NvbG9yO1xcblxcbnZvaWQgbWFpbigpIHtcXG5cXHRnbF9GcmFnQ29sb3IgPSBmcmFnQ29sb3I7XFxufVxcblwiXSksXG5cblx0XHR1bmlmb3Jtczoge1xuXHRcdFx0c2NhbGU6IHJlZ2wucHJvcCgnc2NhbGUnKSxcblx0XHRcdGNvbG9yOiByZWdsLnByb3AoJ2ZpbGwnKSxcblx0XHRcdHNjYWxlRnJhY3Q6IHJlZ2wucHJvcCgnc2NhbGVGcmFjdCcpLFxuXHRcdFx0dHJhbnNsYXRlRnJhY3Q6IHJlZ2wucHJvcCgndHJhbnNsYXRlRnJhY3QnKSxcblx0XHRcdHRyYW5zbGF0ZTogcmVnbC5wcm9wKCd0cmFuc2xhdGUnKSxcblx0XHRcdG9wYWNpdHk6IHJlZ2wucHJvcCgnb3BhY2l0eScpLFxuXHRcdFx0cGl4ZWxSYXRpbzogcmVnbC5jb250ZXh0KCdwaXhlbFJhdGlvJyksXG5cdFx0XHRpZDogcmVnbC5wcm9wKCdpZCcpLFxuXHRcdFx0dmlld3BvcnQ6IChjdHgsIHByb3ApID0+IFtwcm9wLnZpZXdwb3J0LngsIHByb3Audmlld3BvcnQueSwgY3R4LnZpZXdwb3J0V2lkdGgsIGN0eC52aWV3cG9ydEhlaWdodF1cblx0XHR9LFxuXG5cdFx0YXR0cmlidXRlczoge1xuXHRcdFx0cG9zaXRpb246IHtcblx0XHRcdFx0YnVmZmVyOiByZWdsLnByb3AoJ3Bvc2l0aW9uQnVmZmVyJyksXG5cdFx0XHRcdHN0cmlkZTogOCxcblx0XHRcdFx0b2Zmc2V0OiA4XG5cdFx0XHR9LFxuXHRcdFx0cG9zaXRpb25GcmFjdDoge1xuXHRcdFx0XHRidWZmZXI6IHJlZ2wucHJvcCgncG9zaXRpb25GcmFjdEJ1ZmZlcicpLFxuXHRcdFx0XHRzdHJpZGU6IDgsXG5cdFx0XHRcdG9mZnNldDogOFxuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRibGVuZDogc2hhZGVyT3B0aW9ucy5ibGVuZCxcblxuXHRcdGRlcHRoOiB7IGVuYWJsZTogZmFsc2UgfSxcblx0XHRzY2lzc29yOiBzaGFkZXJPcHRpb25zLnNjaXNzb3IsXG5cdFx0c3RlbmNpbDogc2hhZGVyT3B0aW9ucy5zdGVuY2lsLFxuXHRcdHZpZXdwb3J0OiBzaGFkZXJPcHRpb25zLnZpZXdwb3J0XG5cdH0pXG5cblx0cmV0dXJuIHtcblx0XHRmaWxsOiBkcmF3RmlsbCwgcmVjdDogZHJhd1JlY3RMaW5lLCBtaXRlcjogZHJhd01pdGVyTGluZVxuXHR9XG59XG5cblxuLy8gdXNlZCB0byBmb3IgbmV3IGxpbmVzIGluc3RhbmNlc1xuTGluZTJELmRlZmF1bHRzID0ge1xuXHRkYXNoZXM6IG51bGwsXG5cdGpvaW46ICdtaXRlcicsXG5cdG1pdGVyTGltaXQ6IDEsXG5cdHRoaWNrbmVzczogMTAsXG5cdGNhcDogJ3NxdWFyZScsXG5cdGNvbG9yOiAnYmxhY2snLFxuXHRvcGFjaXR5OiAxLFxuXHRvdmVybGF5OiBmYWxzZSxcblx0dmlld3BvcnQ6IG51bGwsXG5cdHJhbmdlOiBudWxsLFxuXHRjbG9zZTogZmFsc2UsXG5cdGZpbGw6IG51bGxcbn1cblxuXG5MaW5lMkQucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICguLi5hcmdzKSB7XG5cdGlmIChhcmdzLmxlbmd0aCkge1xuXHRcdHRoaXMudXBkYXRlKC4uLmFyZ3MpXG5cdH1cblxuXHR0aGlzLmRyYXcoKVxufVxuXG5cbkxpbmUyRC5wcm90b3R5cGUuZHJhdyA9IGZ1bmN0aW9uICguLi5hcmdzKSB7XG5cdC8vIHJlbmRlciBtdWx0aXBsZSBwb2x5bGluZXMgdmlhIHJlZ2wgYmF0Y2hcblx0KGFyZ3MubGVuZ3RoID8gYXJncyA6IHRoaXMucGFzc2VzKS5mb3JFYWNoKChzLCBpKSA9PiB7XG5cdFx0Ly8gcmVuZGVyIGFycmF5IHBhc3MgYXMgYSBsaXN0IG9mIHBhc3Nlc1xuXHRcdGlmIChzICYmIEFycmF5LmlzQXJyYXkocykpIHJldHVybiB0aGlzLmRyYXcoLi4ucylcblxuXHRcdGlmICh0eXBlb2YgcyA9PT0gJ251bWJlcicpIHMgPSB0aGlzLnBhc3Nlc1tzXVxuXG5cdFx0aWYgKCEocyAmJiBzLmNvdW50ID4gMSAmJiBzLm9wYWNpdHkpKSByZXR1cm5cblxuXHRcdHRoaXMucmVnbC5fcmVmcmVzaCgpXG5cblx0XHRpZiAocy5maWxsICYmIHMudHJpYW5nbGVzICYmIHMudHJpYW5nbGVzLmxlbmd0aCA+IDIpIHtcblx0XHRcdHRoaXMuc2hhZGVycy5maWxsKHMpXG5cdFx0fVxuXG5cdFx0aWYgKCFzLnRoaWNrbmVzcykgcmV0dXJuXG5cblx0XHQvLyBoaWdoIHNjYWxlIGlzIG9ubHkgYXZhaWxhYmxlIGZvciByZWN0IG1vZGUgd2l0aCBwcmVjaXNpb25cblx0XHRpZiAocy5zY2FsZVswXSAqIHMudmlld3BvcnQud2lkdGggPiBMaW5lMkQucHJlY2lzaW9uVGhyZXNob2xkIHx8IHMuc2NhbGVbMV0gKiBzLnZpZXdwb3J0LmhlaWdodCA+IExpbmUyRC5wcmVjaXNpb25UaHJlc2hvbGQpIHtcblx0XHRcdHRoaXMuc2hhZGVycy5yZWN0KHMpXG5cdFx0fVxuXG5cdFx0Ly8gdGhpbiB0aGlzLnBhc3NlcyBvciB0b28gbWFueSBwb2ludHMgYXJlIHJlbmRlcmVkIGFzIHNpbXBsaWZpZWQgcmVjdCBzaGFkZXJcblx0XHRlbHNlIGlmIChzLmpvaW4gPT09ICdyZWN0JyB8fCAoIXMuam9pbiAmJiAocy50aGlja25lc3MgPD0gMiB8fCBzLmNvdW50ID49IExpbmUyRC5tYXhQb2ludHMpKSkge1xuXHRcdFx0dGhpcy5zaGFkZXJzLnJlY3Qocylcblx0XHR9XG5cdFx0ZWxzZSB7XG5cdFx0XHR0aGlzLnNoYWRlcnMubWl0ZXIocylcblx0XHR9XG5cdH0pXG5cblx0cmV0dXJuIHRoaXNcbn1cblxuTGluZTJELnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuXHRpZiAoIW9wdGlvbnMpIHJldHVyblxuXG5cdGlmIChvcHRpb25zLmxlbmd0aCAhPSBudWxsKSB7XG5cdFx0aWYgKHR5cGVvZiBvcHRpb25zWzBdID09PSAnbnVtYmVyJykgb3B0aW9ucyA9IFt7cG9zaXRpb25zOiBvcHRpb25zfV1cblx0fVxuXG5cdC8vIG1ha2Ugb3B0aW9ucyBhIGJhdGNoXG5cdGVsc2UgaWYgKCFBcnJheS5pc0FycmF5KG9wdGlvbnMpKSBvcHRpb25zID0gW29wdGlvbnNdXG5cblx0bGV0IHsgcmVnbCwgZ2wgfSA9IHRoaXNcblxuXHQvLyBwcm9jZXNzIHBlci1saW5lIHNldHRpbmdzXG5cdG9wdGlvbnMuZm9yRWFjaCgobywgaSkgPT4ge1xuXHRcdGxldCBzdGF0ZSA9IHRoaXMucGFzc2VzW2ldXG5cblx0XHRpZiAobyA9PT0gdW5kZWZpbmVkKSByZXR1cm5cblxuXHRcdC8vIG51bGwtYXJndW1lbnQgcmVtb3ZlcyBwYXNzXG5cdFx0aWYgKG8gPT09IG51bGwpIHtcblx0XHRcdHRoaXMucGFzc2VzW2ldID0gbnVsbFxuXHRcdFx0cmV0dXJuXG5cdFx0fVxuXG5cdFx0aWYgKHR5cGVvZiBvWzBdID09PSAnbnVtYmVyJykgbyA9IHtwb3NpdGlvbnM6IG99XG5cblx0XHQvLyBoYW5kbGUgYWxpYXNlc1xuXHRcdG8gPSBwaWNrKG8sIHtcblx0XHRcdHBvc2l0aW9uczogJ3Bvc2l0aW9ucyBwb2ludHMgZGF0YSBjb29yZHMnLFxuXHRcdFx0dGhpY2tuZXNzOiAndGhpY2tuZXNzIGxpbmVXaWR0aCBsaW5lV2lkdGhzIGxpbmUtd2lkdGggbGluZXdpZHRoIHdpZHRoIHN0cm9rZS13aWR0aCBzdHJva2V3aWR0aCBzdHJva2VXaWR0aCcsXG5cdFx0XHRqb2luOiAnbGluZUpvaW4gbGluZWpvaW4gam9pbiB0eXBlIG1vZGUnLFxuXHRcdFx0bWl0ZXJMaW1pdDogJ21pdGVybGltaXQgbWl0ZXJMaW1pdCcsXG5cdFx0XHRkYXNoZXM6ICdkYXNoIGRhc2hlcyBkYXNoYXJyYXkgZGFzaC1hcnJheSBkYXNoQXJyYXknLFxuXHRcdFx0Y29sb3I6ICdjb2xvciBjb2xvdXIgc3Ryb2tlIGNvbG9ycyBjb2xvdXJzIHN0cm9rZS1jb2xvciBzdHJva2VDb2xvcicsXG5cdFx0XHRmaWxsOiAnZmlsbCBmaWxsLWNvbG9yIGZpbGxDb2xvcicsXG5cdFx0XHRvcGFjaXR5OiAnYWxwaGEgb3BhY2l0eScsXG5cdFx0XHRvdmVybGF5OiAnb3ZlcmxheSBjcmVhc2Ugb3ZlcmxhcCBpbnRlcnNlY3QnLFxuXHRcdFx0Y2xvc2U6ICdjbG9zZWQgY2xvc2UgY2xvc2VkLXBhdGggY2xvc2VQYXRoJyxcblx0XHRcdHJhbmdlOiAncmFuZ2UgZGF0YUJveCcsXG5cdFx0XHR2aWV3cG9ydDogJ3ZpZXdwb3J0IHZpZXdCb3gnLFxuXHRcdFx0aG9sZTogJ2hvbGVzIGhvbGUgaG9sbG93J1xuXHRcdH0pXG5cblx0XHQvLyBpbml0IHN0YXRlXG5cdFx0aWYgKCFzdGF0ZSkge1xuXHRcdFx0dGhpcy5wYXNzZXNbaV0gPSBzdGF0ZSA9IHtcblx0XHRcdFx0aWQ6IGksXG5cdFx0XHRcdHNjYWxlOiBudWxsLFxuXHRcdFx0XHRzY2FsZUZyYWN0OiBudWxsLFxuXHRcdFx0XHR0cmFuc2xhdGU6IG51bGwsXG5cdFx0XHRcdHRyYW5zbGF0ZUZyYWN0OiBudWxsLFxuXHRcdFx0XHRjb3VudDogMCxcblx0XHRcdFx0aG9sZTogW10sXG5cdFx0XHRcdGRlcHRoOiAwLFxuXG5cdFx0XHRcdGRhc2hMZW5ndGg6IDEsXG5cdFx0XHRcdGRhc2hUZXh0dXJlOiByZWdsLnRleHR1cmUoe1xuXHRcdFx0XHRcdGNoYW5uZWxzOiAxLFxuXHRcdFx0XHRcdGRhdGE6IG5ldyBVaW50OEFycmF5KFsyNTVdKSxcblx0XHRcdFx0XHR3aWR0aDogMSxcblx0XHRcdFx0XHRoZWlnaHQ6IDEsXG5cdFx0XHRcdFx0bWFnOiAnbGluZWFyJyxcblx0XHRcdFx0XHRtaW46ICdsaW5lYXInXG5cdFx0XHRcdH0pLFxuXG5cdFx0XHRcdGNvbG9yQnVmZmVyOiByZWdsLmJ1ZmZlcih7XG5cdFx0XHRcdFx0dXNhZ2U6ICdkeW5hbWljJyxcblx0XHRcdFx0XHR0eXBlOiAndWludDgnLFxuXHRcdFx0XHRcdGRhdGE6IG5ldyBVaW50OEFycmF5KClcblx0XHRcdFx0fSksXG5cdFx0XHRcdHBvc2l0aW9uQnVmZmVyOiByZWdsLmJ1ZmZlcih7XG5cdFx0XHRcdFx0dXNhZ2U6ICdkeW5hbWljJyxcblx0XHRcdFx0XHR0eXBlOiAnZmxvYXQnLFxuXHRcdFx0XHRcdGRhdGE6IG5ldyBVaW50OEFycmF5KClcblx0XHRcdFx0fSksXG5cdFx0XHRcdHBvc2l0aW9uRnJhY3RCdWZmZXI6IHJlZ2wuYnVmZmVyKHtcblx0XHRcdFx0XHR1c2FnZTogJ2R5bmFtaWMnLFxuXHRcdFx0XHRcdHR5cGU6ICdmbG9hdCcsXG5cdFx0XHRcdFx0ZGF0YTogbmV3IFVpbnQ4QXJyYXkoKVxuXHRcdFx0XHR9KVxuXHRcdFx0fVxuXG5cdFx0XHRvID0gZXh0ZW5kKHt9LCBMaW5lMkQuZGVmYXVsdHMsIG8pXG5cdFx0fVxuXHRcdGlmIChvLnRoaWNrbmVzcyAhPSBudWxsKSBzdGF0ZS50aGlja25lc3MgPSBwYXJzZUZsb2F0KG8udGhpY2tuZXNzKVxuXHRcdGlmIChvLm9wYWNpdHkgIT0gbnVsbCkgc3RhdGUub3BhY2l0eSA9IHBhcnNlRmxvYXQoby5vcGFjaXR5KVxuXHRcdGlmIChvLm1pdGVyTGltaXQgIT0gbnVsbCkgc3RhdGUubWl0ZXJMaW1pdCA9IHBhcnNlRmxvYXQoby5taXRlckxpbWl0KVxuXHRcdGlmIChvLm92ZXJsYXkgIT0gbnVsbCkge1xuXHRcdFx0c3RhdGUub3ZlcmxheSA9ICEhby5vdmVybGF5XG5cdFx0XHRpZiAoaSA8IExpbmUyRC5tYXhMaW5lcykge1xuXHRcdFx0XHRzdGF0ZS5kZXB0aCA9IDIgKiAoTGluZTJELm1heExpbmVzIC0gMSAtIGkgJSBMaW5lMkQubWF4TGluZXMpIC8gTGluZTJELm1heExpbmVzIC0gMS47XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmIChvLmpvaW4gIT0gbnVsbCkgc3RhdGUuam9pbiA9IG8uam9pblxuXHRcdGlmIChvLmhvbGUgIT0gbnVsbCkgc3RhdGUuaG9sZSA9IG8uaG9sZVxuXHRcdGlmIChvLmZpbGwgIT0gbnVsbCkgc3RhdGUuZmlsbCA9ICFvLmZpbGwgPyBudWxsIDogcmdiYShvLmZpbGwsICd1aW50OCcpXG5cdFx0aWYgKG8udmlld3BvcnQgIT0gbnVsbCkgc3RhdGUudmlld3BvcnQgPSBwYXJzZVJlY3Qoby52aWV3cG9ydClcblxuXHRcdGlmICghc3RhdGUudmlld3BvcnQpIHtcblx0XHRcdHN0YXRlLnZpZXdwb3J0ID0gcGFyc2VSZWN0KFtcblx0XHRcdFx0Z2wuZHJhd2luZ0J1ZmZlcldpZHRoLFxuXHRcdFx0XHRnbC5kcmF3aW5nQnVmZmVySGVpZ2h0XG5cdFx0XHRdKVxuXHRcdH1cblxuXHRcdGlmIChvLmNsb3NlICE9IG51bGwpIHN0YXRlLmNsb3NlID0gby5jbG9zZVxuXG5cdFx0Ly8gcmVzZXQgcG9zaXRpb25zXG5cdFx0aWYgKG8ucG9zaXRpb25zID09PSBudWxsKSBvLnBvc2l0aW9ucyA9IFtdXG5cdFx0aWYgKG8ucG9zaXRpb25zKSB7XG5cdFx0XHRsZXQgcG9zaXRpb25zLCBjb3VudFxuXG5cdFx0XHQvLyBpZiBwb3NpdGlvbnMgYXJlIGFuIG9iamVjdCB3aXRoIHgveVxuXHRcdFx0aWYgKG8ucG9zaXRpb25zLnggJiYgby5wb3NpdGlvbnMueSkge1xuXHRcdFx0XHRsZXQgeFBvcyA9IG8ucG9zaXRpb25zLnhcblx0XHRcdFx0bGV0IHlQb3MgPSBvLnBvc2l0aW9ucy55XG5cdFx0XHRcdGNvdW50ID0gc3RhdGUuY291bnQgPSBNYXRoLm1heChcblx0XHRcdFx0XHR4UG9zLmxlbmd0aCxcblx0XHRcdFx0XHR5UG9zLmxlbmd0aFxuXHRcdFx0XHQpXG5cdFx0XHRcdHBvc2l0aW9ucyA9IG5ldyBGbG9hdDY0QXJyYXkoY291bnQgKiAyKVxuXHRcdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcblx0XHRcdFx0XHRwb3NpdGlvbnNbaSAqIDJdID0geFBvc1tpXVxuXHRcdFx0XHRcdHBvc2l0aW9uc1tpICogMiArIDFdID0geVBvc1tpXVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0cG9zaXRpb25zID0gZmxhdHRlbihvLnBvc2l0aW9ucywgJ2Zsb2F0NjQnKVxuXHRcdFx0XHRjb3VudCA9IHN0YXRlLmNvdW50ID0gTWF0aC5mbG9vcihwb3NpdGlvbnMubGVuZ3RoIC8gMilcblx0XHRcdH1cblxuXHRcdFx0bGV0IGJvdW5kcyA9IHN0YXRlLmJvdW5kcyA9IGdldEJvdW5kcyhwb3NpdGlvbnMsIDIpXG5cblx0XHRcdC8vIGNyZWF0ZSBmaWxsIHBvc2l0aW9uc1xuXHRcdFx0Ly8gRklYTUU6IGZpbGwgcG9zaXRpb25zIGNhbiBiZSBzZXQgb25seSBhbG9uZyB3aXRoIHBvc2l0aW9uc1xuXHRcdFx0aWYgKHN0YXRlLmZpbGwpIHtcblx0XHRcdFx0bGV0IHBvcyA9IFtdXG5cblx0XHRcdFx0Ly8gZmlsdGVyIGJhZCB2ZXJ0aWNlcyBhbmQgcmVtYXAgdHJpYW5nbGVzIHRvIGVuc3VyZSBzaGFwZVxuXHRcdFx0XHRsZXQgaWRzID0ge31cblx0XHRcdFx0bGV0IGxhc3RJZCA9IDBcblxuXHRcdFx0XHRmb3IgKGxldCBpID0gMCwgcHRyID0gMCwgbCA9IHN0YXRlLmNvdW50OyBpIDwgbDsgaSsrKSB7XG5cdFx0XHRcdFx0bGV0IHggPSBwb3NpdGlvbnNbaSoyXVxuXHRcdFx0XHRcdGxldCB5ID0gcG9zaXRpb25zW2kqMiArIDFdXG5cdFx0XHRcdFx0aWYgKGlzTmFOKHgpIHx8IGlzTmFOKHkpIHx8IHggPT0gbnVsbCB8fCB5ID09IG51bGwpIHtcblx0XHRcdFx0XHRcdHggPSBwb3NpdGlvbnNbbGFzdElkKjJdXG5cdFx0XHRcdFx0XHR5ID0gcG9zaXRpb25zW2xhc3RJZCoyICsgMV1cblx0XHRcdFx0XHRcdGlkc1tpXSA9IGxhc3RJZFxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdGxhc3RJZCA9IGlcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cG9zW3B0cisrXSA9IHhcblx0XHRcdFx0XHRwb3NbcHRyKytdID0geVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0bGV0IHRyaWFuZ2xlcyA9IHRyaWFuZ3VsYXRlKHBvcywgc3RhdGUuaG9sZSB8fCBbXSlcblxuXHRcdFx0XHRmb3IgKGxldCBpID0gMCwgbCA9IHRyaWFuZ2xlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcblx0XHRcdFx0XHRpZiAoaWRzW3RyaWFuZ2xlc1tpXV0gIT0gbnVsbCkgdHJpYW5nbGVzW2ldID0gaWRzW3RyaWFuZ2xlc1tpXV1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHN0YXRlLnRyaWFuZ2xlcyA9IHRyaWFuZ2xlc1xuXHRcdFx0fVxuXG5cdFx0XHQvLyB1cGRhdGUgcG9zaXRpb24gYnVmZmVyc1xuXHRcdFx0bGV0IG5wb3MgPSBuZXcgRmxvYXQ2NEFycmF5KHBvc2l0aW9ucylcblx0XHRcdG5vcm1hbGl6ZShucG9zLCAyLCBib3VuZHMpXG5cblx0XHRcdGxldCBwb3NpdGlvbkRhdGEgPSBuZXcgRmxvYXQ2NEFycmF5KGNvdW50ICogMiArIDYpXG5cblx0XHRcdC8vIHJvdGF0ZSBmaXJzdCBzZWdtZW50IGpvaW5cblx0XHRcdGlmIChzdGF0ZS5jbG9zZSkge1xuXHRcdFx0XHRpZiAocG9zaXRpb25zWzBdID09PSBwb3NpdGlvbnNbY291bnQqMiAtIDJdICYmXG5cdFx0XHRcdFx0cG9zaXRpb25zWzFdID09PSBwb3NpdGlvbnNbY291bnQqMiAtIDFdKSB7XG5cdFx0XHRcdFx0cG9zaXRpb25EYXRhWzBdID0gbnBvc1tjb3VudCoyIC0gNF1cblx0XHRcdFx0XHRwb3NpdGlvbkRhdGFbMV0gPSBucG9zW2NvdW50KjIgLSAzXVxuXHRcdFx0XHR9XG5cdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdHBvc2l0aW9uRGF0YVswXSA9IG5wb3NbY291bnQqMiAtIDJdXG5cdFx0XHRcdFx0cG9zaXRpb25EYXRhWzFdID0gbnBvc1tjb3VudCoyIC0gMV1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0ZWxzZSB7XG5cdFx0XHRcdHBvc2l0aW9uRGF0YVswXSA9IG5wb3NbMF1cblx0XHRcdFx0cG9zaXRpb25EYXRhWzFdID0gbnBvc1sxXVxuXHRcdFx0fVxuXG5cdFx0XHRwb3NpdGlvbkRhdGEuc2V0KG5wb3MsIDIpXG5cblx0XHRcdC8vIGFkZCBsYXN0IHNlZ21lbnRcblx0XHRcdGlmIChzdGF0ZS5jbG9zZSkge1xuXHRcdFx0XHQvLyBpZ25vcmUgY29pbmNpZGluZyBzdGFydC9lbmRcblx0XHRcdFx0aWYgKHBvc2l0aW9uc1swXSA9PT0gcG9zaXRpb25zW2NvdW50KjIgLSAyXSAmJlxuXHRcdFx0XHRcdHBvc2l0aW9uc1sxXSA9PT0gcG9zaXRpb25zW2NvdW50KjIgLSAxXSkge1xuXHRcdFx0XHRcdHBvc2l0aW9uRGF0YVtjb3VudCoyICsgMl0gPSBucG9zWzJdXG5cdFx0XHRcdFx0cG9zaXRpb25EYXRhW2NvdW50KjIgKyAzXSA9IG5wb3NbM11cblx0XHRcdFx0XHRzdGF0ZS5jb3VudCAtPSAxXG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0cG9zaXRpb25EYXRhW2NvdW50KjIgKyAyXSA9IG5wb3NbMF1cblx0XHRcdFx0XHRwb3NpdGlvbkRhdGFbY291bnQqMiArIDNdID0gbnBvc1sxXVxuXHRcdFx0XHRcdHBvc2l0aW9uRGF0YVtjb3VudCoyICsgNF0gPSBucG9zWzJdXG5cdFx0XHRcdFx0cG9zaXRpb25EYXRhW2NvdW50KjIgKyA1XSA9IG5wb3NbM11cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Ly8gYWRkIHN0dWJcblx0XHRcdGVsc2Uge1xuXHRcdFx0XHRwb3NpdGlvbkRhdGFbY291bnQqMiArIDJdID0gbnBvc1tjb3VudCoyIC0gMl1cblx0XHRcdFx0cG9zaXRpb25EYXRhW2NvdW50KjIgKyAzXSA9IG5wb3NbY291bnQqMiAtIDFdXG5cdFx0XHRcdHBvc2l0aW9uRGF0YVtjb3VudCoyICsgNF0gPSBucG9zW2NvdW50KjIgLSAyXVxuXHRcdFx0XHRwb3NpdGlvbkRhdGFbY291bnQqMiArIDVdID0gbnBvc1tjb3VudCoyIC0gMV1cblx0XHRcdH1cblxuXHRcdFx0c3RhdGUucG9zaXRpb25CdWZmZXIoZmxvYXQzMihwb3NpdGlvbkRhdGEpKVxuXHRcdFx0c3RhdGUucG9zaXRpb25GcmFjdEJ1ZmZlcihmcmFjdDMyKHBvc2l0aW9uRGF0YSkpXG5cdFx0fVxuXG5cdFx0aWYgKG8ucmFuZ2UpIHtcblx0XHRcdHN0YXRlLnJhbmdlID0gby5yYW5nZVxuXHRcdH0gZWxzZSBpZiAoIXN0YXRlLnJhbmdlKSB7XG5cdFx0XHRzdGF0ZS5yYW5nZSA9IHN0YXRlLmJvdW5kc1xuXHRcdH1cblxuXHRcdGlmICgoby5yYW5nZSB8fCBvLnBvc2l0aW9ucykgJiYgc3RhdGUuY291bnQpIHtcblx0XHRcdGxldCBib3VuZHMgPSBzdGF0ZS5ib3VuZHNcblxuXHRcdFx0bGV0IGJvdW5kc1cgPSBib3VuZHNbMl0gLSBib3VuZHNbMF0sXG5cdFx0XHRcdGJvdW5kc0ggPSBib3VuZHNbM10gLSBib3VuZHNbMV1cblxuXHRcdFx0bGV0IHJhbmdlVyA9IHN0YXRlLnJhbmdlWzJdIC0gc3RhdGUucmFuZ2VbMF0sXG5cdFx0XHRcdHJhbmdlSCA9IHN0YXRlLnJhbmdlWzNdIC0gc3RhdGUucmFuZ2VbMV1cblxuXHRcdFx0c3RhdGUuc2NhbGUgPSBbXG5cdFx0XHRcdGJvdW5kc1cgLyByYW5nZVcsXG5cdFx0XHRcdGJvdW5kc0ggLyByYW5nZUhcblx0XHRcdF1cblx0XHRcdHN0YXRlLnRyYW5zbGF0ZSA9IFtcblx0XHRcdFx0LXN0YXRlLnJhbmdlWzBdIC8gcmFuZ2VXICsgYm91bmRzWzBdIC8gcmFuZ2VXIHx8IDAsXG5cdFx0XHRcdC1zdGF0ZS5yYW5nZVsxXSAvIHJhbmdlSCArIGJvdW5kc1sxXSAvIHJhbmdlSCB8fCAwXG5cdFx0XHRdXG5cblx0XHRcdHN0YXRlLnNjYWxlRnJhY3QgPSBmcmFjdDMyKHN0YXRlLnNjYWxlKVxuXHRcdFx0c3RhdGUudHJhbnNsYXRlRnJhY3QgPSBmcmFjdDMyKHN0YXRlLnRyYW5zbGF0ZSlcblx0XHR9XG5cblx0XHRpZiAoby5kYXNoZXMpIHtcblx0XHRcdGxldCBkYXNoTGVuZ3RoID0gMC4sIGRhc2hEYXRhXG5cblx0XHRcdGlmICghby5kYXNoZXMgfHwgby5kYXNoZXMubGVuZ3RoIDwgMikge1xuXHRcdFx0XHRkYXNoTGVuZ3RoID0gMS5cblx0XHRcdFx0ZGFzaERhdGEgPSBuZXcgVWludDhBcnJheShbMjU1LCAyNTUsIDI1NSwgMjU1LCAyNTUsIDI1NSwgMjU1LCAyNTVdKVxuXHRcdFx0fVxuXG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0ZGFzaExlbmd0aCA9IDAuO1xuXHRcdFx0XHRmb3IobGV0IGkgPSAwOyBpIDwgby5kYXNoZXMubGVuZ3RoOyArK2kpIHtcblx0XHRcdFx0XHRkYXNoTGVuZ3RoICs9IG8uZGFzaGVzW2ldXG5cdFx0XHRcdH1cblx0XHRcdFx0ZGFzaERhdGEgPSBuZXcgVWludDhBcnJheShkYXNoTGVuZ3RoICogTGluZTJELmRhc2hNdWx0KVxuXHRcdFx0XHRsZXQgcHRyID0gMFxuXHRcdFx0XHRsZXQgZmlsbENvbG9yID0gMjU1XG5cblx0XHRcdFx0Ly8gcmVwZWF0IHRleHR1cmUgdHdvIHRpbWVzIHRvIHByb3ZpZGUgc21vb3RoIDAtc3RlcFxuXHRcdFx0XHRmb3IgKGxldCBrID0gMDsgayA8IDI7IGsrKykge1xuXHRcdFx0XHRcdGZvcihsZXQgaSA9IDA7IGkgPCBvLmRhc2hlcy5sZW5ndGg7ICsraSkge1xuXHRcdFx0XHRcdFx0Zm9yKGxldCBqID0gMCwgbCA9IG8uZGFzaGVzW2ldICogTGluZTJELmRhc2hNdWx0ICogLjU7IGogPCBsOyArK2opIHtcblx0XHRcdFx0XHRcdFx0ZGFzaERhdGFbcHRyKytdID0gZmlsbENvbG9yXG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRmaWxsQ29sb3IgXj0gMjU1XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHN0YXRlLmRhc2hMZW5ndGggPSBkYXNoTGVuZ3RoXG5cdFx0XHRzdGF0ZS5kYXNoVGV4dHVyZSh7XG5cdFx0XHRcdGNoYW5uZWxzOiAxLFxuXHRcdFx0XHRkYXRhOiBkYXNoRGF0YSxcblx0XHRcdFx0d2lkdGg6IGRhc2hEYXRhLmxlbmd0aCxcblx0XHRcdFx0aGVpZ2h0OiAxLFxuXHRcdFx0XHRtYWc6ICdsaW5lYXInLFxuXHRcdFx0XHRtaW46ICdsaW5lYXInXG5cdFx0XHR9LCAwLCAwKVxuXHRcdH1cblxuXHRcdGlmIChvLmNvbG9yKSB7XG5cdFx0XHRsZXQgY291bnQgPSBzdGF0ZS5jb3VudFxuXHRcdFx0bGV0IGNvbG9ycyA9IG8uY29sb3JcblxuXHRcdFx0aWYgKCFjb2xvcnMpIGNvbG9ycyA9ICd0cmFuc3BhcmVudCdcblxuXHRcdFx0bGV0IGNvbG9yRGF0YSA9IG5ldyBVaW50OEFycmF5KGNvdW50ICogNCArIDQpXG5cblx0XHRcdC8vIGNvbnZlcnQgY29sb3JzIHRvIHR5cGVkIGFycmF5c1xuXHRcdFx0aWYgKCFBcnJheS5pc0FycmF5KGNvbG9ycykgfHwgdHlwZW9mIGNvbG9yc1swXSA9PT0gJ251bWJlcicpIHtcblx0XHRcdFx0bGV0IGMgPSByZ2JhKGNvbG9ycywgJ3VpbnQ4JylcblxuXHRcdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50ICsgMTsgaSsrKSB7XG5cdFx0XHRcdFx0Y29sb3JEYXRhLnNldChjLCBpICogNClcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG5cdFx0XHRcdFx0bGV0IGMgPSByZ2JhKGNvbG9yc1tpXSwgJ3VpbnQ4Jylcblx0XHRcdFx0XHRjb2xvckRhdGEuc2V0KGMsIGkgKiA0KVxuXHRcdFx0XHR9XG5cdFx0XHRcdGNvbG9yRGF0YS5zZXQocmdiYShjb2xvcnNbMF0sICd1aW50OCcpLCBjb3VudCAqIDQpXG5cdFx0XHR9XG5cblx0XHRcdHN0YXRlLmNvbG9yQnVmZmVyKHtcblx0XHRcdFx0dXNhZ2U6ICdkeW5hbWljJyxcblx0XHRcdFx0dHlwZTogJ3VpbnQ4Jyxcblx0XHRcdFx0ZGF0YTogY29sb3JEYXRhXG5cdFx0XHR9KVxuXHRcdH1cblx0fSlcblxuXHQvLyByZW1vdmUgdW5tZW50aW9uZWQgcGFzc2VzXG5cdGlmIChvcHRpb25zLmxlbmd0aCA8IHRoaXMucGFzc2VzLmxlbmd0aCkge1xuXHRcdGZvciAobGV0IGkgPSBvcHRpb25zLmxlbmd0aDsgaSA8IHRoaXMucGFzc2VzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRsZXQgcGFzcyA9IHRoaXMucGFzc2VzW2ldXG5cdFx0XHRpZiAoIXBhc3MpIGNvbnRpbnVlXG5cdFx0XHRwYXNzLmNvbG9yQnVmZmVyLmRlc3Ryb3koKVxuXHRcdFx0cGFzcy5wb3NpdGlvbkJ1ZmZlci5kZXN0cm95KClcblx0XHRcdHBhc3MuZGFzaFRleHR1cmUuZGVzdHJveSgpXG5cdFx0fVxuXHRcdHRoaXMucGFzc2VzLmxlbmd0aCA9IG9wdGlvbnMubGVuZ3RoXG5cdH1cblxuXHQvLyByZW1vdmUgbnVsbCBpdGVtc1xuXHRsZXQgcGFzc2VzID0gW11cblx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnBhc3Nlcy5sZW5ndGg7IGkrKykge1xuXHRcdGlmICh0aGlzLnBhc3Nlc1tpXSAhPT0gbnVsbCkgcGFzc2VzLnB1c2godGhpcy5wYXNzZXNbaV0pXG5cdH1cblx0dGhpcy5wYXNzZXMgPSBwYXNzZXNcblxuXHRyZXR1cm4gdGhpc1xufVxuXG5MaW5lMkQucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG5cdHRoaXMucGFzc2VzLmZvckVhY2gocGFzcyA9PiB7XG5cdFx0cGFzcy5jb2xvckJ1ZmZlci5kZXN0cm95KClcblx0XHRwYXNzLnBvc2l0aW9uQnVmZmVyLmRlc3Ryb3koKVxuXHRcdHBhc3MuZGFzaFRleHR1cmUuZGVzdHJveSgpXG5cdH0pXG5cblx0dGhpcy5wYXNzZXMubGVuZ3RoID0gMFxuXG5cdHJldHVybiB0aGlzXG59XG5cbiJdLCJuYW1lcyI6WyJjb25zdCIsImxldCIsInRoaXMiLCJpIiwiY291bnQiLCJib3VuZHMiLCJwdHIiLCJsIiwiYyJdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUNaO0FBQ0E7QUFDQUEsR0FBSyxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7QUFDdkNBLEdBQUssQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQztBQUN6Q0EsR0FBSyxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO0FBQ3ZDQSxHQUFLLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUM7QUFDbENBLEdBQUssQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQztBQUNyQ0EsR0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMscUJBQXFCLENBQUM7QUFDOUNBLEdBQUssQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQztBQUNyQ0EsR0FBSyxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7T0FDbEIsR0FBRyxPQUFPLENBQUMsWUFBWTtBQUF6QztBQUFTLDBCQUFpQztBQUNsREEsR0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDO0FBQ3ZDQSxHQUFLLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUM7QUFDdkM7QUFDQTtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsTUFBTTtBQUN2QjtBQUNBO0FBQ0E7QUFDQSxTQUFTLE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFO0FBQ2hDLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxZQUFZLE1BQU0sQ0FBQyxJQUFFLE9BQU8sSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFLE9BQU8sR0FBQztBQUNoRTtBQUNBLENBQUMsSUFBSSxPQUFPLElBQUksS0FBSyxVQUFVLEVBQUU7QUFDakMsRUFBRSxJQUFJLENBQUMsT0FBTyxJQUFFLE9BQU8sR0FBRyxJQUFFO0FBQzVCLEVBQUUsT0FBTyxDQUFDLElBQUksR0FBRyxJQUFJO0FBQ3JCLEVBQUU7QUFDRixNQUFNO0FBQ04sRUFBRSxPQUFPLEdBQUcsSUFBSTtBQUNoQixFQUFFO0FBQ0YsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxNQUFNLElBQUUsT0FBTyxDQUFDLFNBQVMsR0FBRyxTQUFPO0FBQ2hELENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJO0FBQ3BCO0FBQ0EsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyx3QkFBd0IsQ0FBQyxFQUFFO0FBQ25ELEVBQUUsTUFBTSxLQUFLLENBQUMsb0VBQW9FLENBQUMsQ0FBQztBQUNwRixFQUFFO0FBQ0Y7QUFDQTtBQUNBLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRztBQUNuQixDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSTtBQUNqQjtBQUNBO0FBQ0EsQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUU7QUFDakI7QUFDQTtBQUNBLENBQUMsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUM7QUFDcEk7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQztBQUNyQixDQUFDO0FBQ0Q7QUFDQTtBQUNBLE1BQU0sQ0FBQyxRQUFRLEdBQUcsQ0FBQztBQUNuQixNQUFNLENBQUMsZ0JBQWdCLEdBQUcsR0FBRztBQUM3QixNQUFNLENBQUMsa0JBQWtCLEdBQUcsR0FBRztBQUMvQixNQUFNLENBQUMsU0FBUyxHQUFHLEdBQUc7QUFDdEIsTUFBTSxDQUFDLFFBQVEsR0FBRyxJQUFJO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxPQUFPLEVBQUU7QUFDOUI7QUFDQTtBQUNBO0FBQ0EsTUFBTSxDQUFDLGFBQWEsR0FBRyxVQUFVLElBQUksRUFBRTtBQUN2QyxDQUFDQyxHQUFHLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7QUFDaEMsRUFBRSxLQUFLLEVBQUUsUUFBUTtBQUNqQixFQUFFLElBQUksRUFBRSxPQUFPO0FBQ2YsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzVCLEVBQUUsQ0FBQztBQUNIO0FBQ0EsQ0FBQ0EsR0FBRyxDQUFDLGFBQWEsR0FBRztBQUNyQixFQUFFLFNBQVMsRUFBRSxnQkFBZ0I7QUFDN0IsRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7QUFDL0IsRUFBRSxLQUFLLEVBQUUsQ0FBQztBQUNWLEVBQUUsTUFBTSxFQUFFLENBQUM7QUFDWDtBQUNBLEVBQUUsUUFBUSxFQUFFO0FBQ1osR0FBRyxTQUFTLFdBQUUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxXQUFLLElBQUksQ0FBQyxJQUFJLEtBQUssT0FBTyxHQUFHLENBQUMsR0FBRyxJQUFDO0FBQzFELEdBQUcsVUFBVSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO0FBQ3RDLEdBQUcsS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO0FBQzVCLEdBQUcsVUFBVSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO0FBQ3RDLEdBQUcsY0FBYyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7QUFDOUMsR0FBRyxTQUFTLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7QUFDcEMsR0FBRyxTQUFTLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7QUFDcEMsR0FBRyxXQUFXLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUM7QUFDeEMsR0FBRyxPQUFPLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7QUFDaEMsR0FBRyxVQUFVLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUM7QUFDekMsR0FBRyxFQUFFLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDdEIsR0FBRyxRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUM7QUFDcEMsR0FBRyxRQUFRLFdBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxXQUFLLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUMsY0FBYyxJQUFDO0FBQ3RGLEdBQUcsS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO0FBQzVCLEdBQUc7QUFDSDtBQUNBLEVBQUUsS0FBSyxFQUFFO0FBQ1QsR0FBRyxNQUFNLEVBQUUsSUFBSTtBQUNmLEdBQUcsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25CLEdBQUcsUUFBUSxFQUFFO0FBQ2IsSUFBSSxHQUFHLEVBQUUsS0FBSztBQUNkLElBQUksS0FBSyxFQUFFLEtBQUs7QUFDaEIsSUFBSTtBQUNKLEdBQUcsSUFBSSxFQUFFO0FBQ1QsSUFBSSxNQUFNLEVBQUUsV0FBVztBQUN2QixJQUFJLE1BQU0sRUFBRSxxQkFBcUI7QUFDakMsSUFBSSxRQUFRLEVBQUUscUJBQXFCO0FBQ25DLElBQUksUUFBUSxFQUFFLEtBQUs7QUFDbkIsSUFBSTtBQUNKLEdBQUc7QUFDSCxFQUFFLEtBQUssRUFBRTtBQUNULEdBQUcsTUFBTSxXQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBSztBQUNyQixJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTztBQUNyQixJQUFJO0FBQ0osR0FBRztBQUNILEVBQUUsT0FBTyxFQUFFLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQztBQUMxQixFQUFFLE9BQU8sRUFBRTtBQUNYLEdBQUcsTUFBTSxFQUFFLElBQUk7QUFDZixHQUFHLEdBQUcsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQztBQUM3QixHQUFHO0FBQ0gsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7QUFDakMsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLENBQUNBLEdBQUcsQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUNoQyxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQyxndkNBQWd2QyxDQUFDLENBQUM7QUFDbndDLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDLHViQUF1YixDQUFDLENBQUM7QUFDMWM7QUFDQSxFQUFFLFVBQVUsRUFBRTtBQUNkO0FBQ0EsR0FBRyxPQUFPLEVBQUU7QUFDWixJQUFJLE1BQU0sRUFBRSxZQUFZO0FBQ3hCLElBQUksT0FBTyxFQUFFLENBQUM7QUFDZCxJQUFJLE1BQU0sRUFBRSxDQUFDO0FBQ2IsSUFBSSxNQUFNLEVBQUUsQ0FBQztBQUNiLElBQUk7QUFDSjtBQUNBLEdBQUcsT0FBTyxFQUFFO0FBQ1osSUFBSSxNQUFNLEVBQUUsWUFBWTtBQUN4QixJQUFJLE9BQU8sRUFBRSxDQUFDO0FBQ2QsSUFBSSxNQUFNLEVBQUUsQ0FBQztBQUNiLElBQUksTUFBTSxFQUFFLENBQUM7QUFDYixJQUFJO0FBQ0o7QUFDQSxHQUFHLE1BQU0sRUFBRTtBQUNYLElBQUksTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7QUFDdkMsSUFBSSxNQUFNLEVBQUUsQ0FBQztBQUNiLElBQUksTUFBTSxFQUFFLENBQUM7QUFDYixJQUFJLE9BQU8sRUFBRSxDQUFDO0FBQ2QsSUFBSTtBQUNKO0FBQ0EsR0FBRyxNQUFNLEVBQUU7QUFDWCxJQUFJLE1BQU0sRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDO0FBQ3ZDLElBQUksTUFBTSxFQUFFLENBQUM7QUFDYixJQUFJLE1BQU0sRUFBRSxFQUFFO0FBQ2QsSUFBSSxPQUFPLEVBQUUsQ0FBQztBQUNkLElBQUk7QUFDSixHQUFHLFdBQVcsRUFBRTtBQUNoQixJQUFJLE1BQU0sRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDO0FBQzVDLElBQUksTUFBTSxFQUFFLENBQUM7QUFDYixJQUFJLE1BQU0sRUFBRSxDQUFDO0FBQ2IsSUFBSSxPQUFPLEVBQUUsQ0FBQztBQUNkLElBQUk7QUFDSixHQUFHLFdBQVcsRUFBRTtBQUNoQixJQUFJLE1BQU0sRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDO0FBQzVDLElBQUksTUFBTSxFQUFFLENBQUM7QUFDYixJQUFJLE1BQU0sRUFBRSxFQUFFO0FBQ2QsSUFBSSxPQUFPLEVBQUUsQ0FBQztBQUNkLElBQUk7QUFDSixHQUFHLEtBQUssRUFBRTtBQUNWLElBQUksTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDO0FBQ3BDLElBQUksTUFBTSxFQUFFLENBQUM7QUFDYixJQUFJLE1BQU0sRUFBRSxDQUFDO0FBQ2IsSUFBSSxPQUFPLEVBQUUsQ0FBQztBQUNkLElBQUk7QUFDSixHQUFHO0FBQ0gsRUFBRSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0FBQ25CO0FBQ0E7QUFDQSxDQUFDQSxHQUFHLENBQUMsYUFBYTtBQUNsQjtBQUNBLENBQUMsSUFBSTtBQUNMLEVBQUUsYUFBYSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7QUFDOUI7QUFDQSxHQUFHLElBQUksRUFBRTtBQUNULElBQUksTUFBTSxFQUFFLElBQUk7QUFDaEIsSUFBSSxJQUFJLEVBQUUsTUFBTTtBQUNoQixJQUFJO0FBQ0o7QUFDQSxHQUFHLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQywydlFBQTJ2USxDQUFDLENBQUM7QUFDL3dRLEdBQUcsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDLCtrRUFBK2tFLENBQUMsQ0FBQztBQUNubUU7QUFDQSxHQUFHLFVBQVUsRUFBRTtBQUNmO0FBQ0EsSUFBSSxPQUFPLEVBQUU7QUFDYixLQUFLLE1BQU0sRUFBRSxZQUFZO0FBQ3pCLEtBQUssT0FBTyxFQUFFLENBQUM7QUFDZixLQUFLLE1BQU0sRUFBRSxDQUFDO0FBQ2QsS0FBSyxNQUFNLEVBQUUsQ0FBQztBQUNkLEtBQUs7QUFDTDtBQUNBLElBQUksT0FBTyxFQUFFO0FBQ2IsS0FBSyxNQUFNLEVBQUUsWUFBWTtBQUN6QixLQUFLLE9BQU8sRUFBRSxDQUFDO0FBQ2YsS0FBSyxNQUFNLEVBQUUsQ0FBQztBQUNkLEtBQUssTUFBTSxFQUFFLENBQUM7QUFDZCxLQUFLO0FBQ0w7QUFDQSxJQUFJLE1BQU0sRUFBRTtBQUNaLEtBQUssTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDO0FBQ3JDLEtBQUssTUFBTSxFQUFFLENBQUM7QUFDZCxLQUFLLE1BQU0sRUFBRSxDQUFDO0FBQ2QsS0FBSyxPQUFPLEVBQUUsQ0FBQztBQUNmLEtBQUs7QUFDTDtBQUNBLElBQUksTUFBTSxFQUFFO0FBQ1osS0FBSyxNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUM7QUFDckMsS0FBSyxNQUFNLEVBQUUsQ0FBQztBQUNkLEtBQUssTUFBTSxFQUFFLENBQUM7QUFDZCxLQUFLLE9BQU8sRUFBRSxDQUFDO0FBQ2YsS0FBSztBQUNMLElBQUksU0FBUyxFQUFFO0FBQ2YsS0FBSyxNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztBQUN4QyxLQUFLLE1BQU0sRUFBRSxDQUFDO0FBQ2QsS0FBSyxNQUFNLEVBQUUsQ0FBQztBQUNkLEtBQUssT0FBTyxFQUFFLENBQUM7QUFDZixLQUFLO0FBQ0wsSUFBSSxNQUFNLEVBQUU7QUFDWixLQUFLLE1BQU0sRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDO0FBQ3hDLEtBQUssTUFBTSxFQUFFLENBQUM7QUFDZCxLQUFLLE1BQU0sRUFBRSxDQUFDO0FBQ2QsS0FBSyxPQUFPLEVBQUUsQ0FBQztBQUNmLEtBQUs7QUFDTCxJQUFJLE1BQU0sRUFBRTtBQUNaLEtBQUssTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7QUFDeEMsS0FBSyxNQUFNLEVBQUUsQ0FBQztBQUNkLEtBQUssTUFBTSxFQUFFLEVBQUU7QUFDZixLQUFLLE9BQU8sRUFBRSxDQUFDO0FBQ2YsS0FBSztBQUNMLElBQUksU0FBUyxFQUFFO0FBQ2YsS0FBSyxNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztBQUN4QyxLQUFLLE1BQU0sRUFBRSxDQUFDO0FBQ2QsS0FBSyxNQUFNLEVBQUUsRUFBRTtBQUNmLEtBQUssT0FBTyxFQUFFLENBQUM7QUFDZixLQUFLO0FBQ0wsSUFBSTtBQUNKLEdBQUcsRUFBRSxhQUFhLENBQUMsQ0FBQztBQUNwQixFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUU7QUFDYjtBQUNBLEVBQUUsYUFBYSxHQUFHLFlBQVk7QUFDOUIsRUFBRTtBQUNGO0FBQ0E7QUFDQSxDQUFDQSxHQUFHLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztBQUNyQixFQUFFLFNBQVMsRUFBRSxVQUFVO0FBQ3ZCLEVBQUUsUUFBUSxXQUFFLENBQUMsR0FBRyxFQUFFLElBQUksV0FBSyxJQUFJLENBQUMsWUFBUztBQUN6QyxFQUFFLE1BQU0sRUFBRSxDQUFDO0FBQ1g7QUFDQSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQyw0cEJBQTRwQixDQUFDLENBQUM7QUFDL3FCLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDLHlIQUF5SCxDQUFDLENBQUM7QUFDNUk7QUFDQSxFQUFFLFFBQVEsRUFBRTtBQUNaLEdBQUcsS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO0FBQzVCLEdBQUcsS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO0FBQzNCLEdBQUcsVUFBVSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO0FBQ3RDLEdBQUcsY0FBYyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7QUFDOUMsR0FBRyxTQUFTLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7QUFDcEMsR0FBRyxPQUFPLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7QUFDaEMsR0FBRyxVQUFVLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUM7QUFDekMsR0FBRyxFQUFFLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDdEIsR0FBRyxRQUFRLFdBQUUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxXQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLGFBQWEsRUFBRSxHQUFHLENBQUMsY0FBYyxJQUFDO0FBQ3JHLEdBQUc7QUFDSDtBQUNBLEVBQUUsVUFBVSxFQUFFO0FBQ2QsR0FBRyxRQUFRLEVBQUU7QUFDYixJQUFJLE1BQU0sRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDO0FBQ3ZDLElBQUksTUFBTSxFQUFFLENBQUM7QUFDYixJQUFJLE1BQU0sRUFBRSxDQUFDO0FBQ2IsSUFBSTtBQUNKLEdBQUcsYUFBYSxFQUFFO0FBQ2xCLElBQUksTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUM7QUFDNUMsSUFBSSxNQUFNLEVBQUUsQ0FBQztBQUNiLElBQUksTUFBTSxFQUFFLENBQUM7QUFDYixJQUFJO0FBQ0osR0FBRztBQUNIO0FBQ0EsRUFBRSxLQUFLLEVBQUUsYUFBYSxDQUFDLEtBQUs7QUFDNUI7QUFDQSxFQUFFLEtBQUssRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7QUFDMUIsRUFBRSxPQUFPLEVBQUUsYUFBYSxDQUFDLE9BQU87QUFDaEMsRUFBRSxPQUFPLEVBQUUsYUFBYSxDQUFDLE9BQU87QUFDaEMsRUFBRSxRQUFRLEVBQUUsYUFBYSxDQUFDLFFBQVE7QUFDbEMsRUFBRSxDQUFDO0FBQ0g7QUFDQSxDQUFDLE9BQU87QUFDUixFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsYUFBYTtBQUMxRCxFQUFFO0FBQ0YsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLE1BQU0sQ0FBQyxRQUFRLEdBQUc7QUFDbEIsQ0FBQyxNQUFNLEVBQUUsSUFBSTtBQUNiLENBQUMsSUFBSSxFQUFFLE9BQU87QUFDZCxDQUFDLFVBQVUsRUFBRSxDQUFDO0FBQ2QsQ0FBQyxTQUFTLEVBQUUsRUFBRTtBQUNkLENBQUMsR0FBRyxFQUFFLFFBQVE7QUFDZCxDQUFDLEtBQUssRUFBRSxPQUFPO0FBQ2YsQ0FBQyxPQUFPLEVBQUUsQ0FBQztBQUNYLENBQUMsT0FBTyxFQUFFLEtBQUs7QUFDZixDQUFDLFFBQVEsRUFBRSxJQUFJO0FBQ2YsQ0FBQyxLQUFLLEVBQUUsSUFBSTtBQUNaLENBQUMsS0FBSyxFQUFFLEtBQUs7QUFDYixDQUFDLElBQUksRUFBRSxJQUFJO0FBQ1gsQ0FBQztBQUNEO0FBQ0E7QUFDQSxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxVQUFpQixFQUFFOzs7O2dEQUFDO0FBQzlDLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO0FBQ2xCLFNBQUUsS0FBSSxDQUFDLFlBQU0sTUFBSSxJQUFJLENBQUM7QUFDdEIsRUFBRTtBQUNGO0FBQ0EsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFO0FBQ1osQ0FBQztBQUNEO0FBQ0E7QUFDQSxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksR0FBRyxVQUFpQixFQUFFOzs7O0FBQUM7QUFDNUM7QUFDQSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sVUFBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUs7O0FBQUM7QUFDdkQ7QUFDQSxFQUFFLElBQUksQ0FBQyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUUsY0FBT0MsT0FBSSxDQUFDLFVBQUksTUFBSSxDQUFDLEdBQUM7QUFDbkQ7QUFDQSxFQUFFLElBQUksT0FBTyxDQUFDLEtBQUssUUFBUSxJQUFFLENBQUMsR0FBR0EsTUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUM7QUFDL0M7QUFDQSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUUsUUFBTTtBQUM5QztBQUNBLEVBQUVBLE1BQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFO0FBQ3RCO0FBQ0EsRUFBRSxJQUFJLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7QUFDdkQsR0FBR0EsTUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEdBQUc7QUFDSDtBQUNBLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLElBQUUsUUFBTTtBQUMxQjtBQUNBO0FBQ0EsRUFBRSxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixFQUFFO0FBQy9ILEdBQUdBLE1BQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUN2QixHQUFHO0FBQ0g7QUFDQTtBQUNBLE9BQU8sSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUU7QUFDaEcsR0FBR0EsTUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLEdBQUc7QUFDSCxPQUFPO0FBQ1AsR0FBR0EsTUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLEdBQUc7QUFDSCxFQUFFLENBQUM7QUFDSDtBQUNBLENBQUMsT0FBTyxJQUFJO0FBQ1osQ0FBQztBQUNEO0FBQ0EsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsVUFBVSxPQUFPLEVBQUU7O0FBQUM7QUFDOUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFFLFFBQU07QUFDckI7QUFDQSxDQUFDLElBQUksT0FBTyxDQUFDLE1BQU0sSUFBSSxJQUFJLEVBQUU7QUFDN0IsRUFBRSxJQUFJLE9BQU8sT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLFFBQVEsSUFBRSxPQUFPLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsR0FBQztBQUN0RSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUUsT0FBTyxHQUFHLENBQUMsT0FBTyxHQUFDO0FBQ3REO0FBQ0EsUUFBaUIsR0FBRztDQUFiO0NBQU0sZ0JBQVc7QUFDeEI7QUFDQTtBQUNBLENBQUMsT0FBTyxDQUFDLE9BQU8sVUFBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUs7QUFDM0IsRUFBRUQsR0FBRyxDQUFDLEtBQUssR0FBR0MsTUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDNUI7QUFDQSxFQUFFLElBQUksQ0FBQyxLQUFLLFNBQVMsSUFBRSxRQUFNO0FBQzdCO0FBQ0E7QUFDQSxFQUFFLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRTtBQUNsQixHQUFHQSxNQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUk7QUFDeEIsR0FBRyxNQUFNO0FBQ1QsR0FBRztBQUNIO0FBQ0EsRUFBRSxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLFFBQVEsSUFBRSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxHQUFDO0FBQ2xEO0FBQ0E7QUFDQSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxFQUFFO0FBQ2QsR0FBRyxTQUFTLEVBQUUsOEJBQThCO0FBQzVDLEdBQUcsU0FBUyxFQUFFLGdHQUFnRztBQUM5RyxHQUFHLElBQUksRUFBRSxrQ0FBa0M7QUFDM0MsR0FBRyxVQUFVLEVBQUUsdUJBQXVCO0FBQ3RDLEdBQUcsTUFBTSxFQUFFLDRDQUE0QztBQUN2RCxHQUFHLEtBQUssRUFBRSw2REFBNkQ7QUFDdkUsR0FBRyxJQUFJLEVBQUUsMkJBQTJCO0FBQ3BDLEdBQUcsT0FBTyxFQUFFLGVBQWU7QUFDM0IsR0FBRyxPQUFPLEVBQUUsa0NBQWtDO0FBQzlDLEdBQUcsS0FBSyxFQUFFLG9DQUFvQztBQUM5QyxHQUFHLEtBQUssRUFBRSxlQUFlO0FBQ3pCLEdBQUcsUUFBUSxFQUFFLGtCQUFrQjtBQUMvQixHQUFHLElBQUksRUFBRSxtQkFBbUI7QUFDNUIsR0FBRyxDQUFDO0FBQ0o7QUFDQTtBQUNBLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRTtBQUNkLEdBQUdBLE1BQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHO0FBQzVCLElBQUksRUFBRSxFQUFFLENBQUM7QUFDVCxJQUFJLEtBQUssRUFBRSxJQUFJO0FBQ2YsSUFBSSxVQUFVLEVBQUUsSUFBSTtBQUNwQixJQUFJLFNBQVMsRUFBRSxJQUFJO0FBQ25CLElBQUksY0FBYyxFQUFFLElBQUk7QUFDeEIsSUFBSSxLQUFLLEVBQUUsQ0FBQztBQUNaLElBQUksSUFBSSxFQUFFLEVBQUU7QUFDWixJQUFJLEtBQUssRUFBRSxDQUFDO0FBQ1o7QUFDQSxJQUFJLFVBQVUsRUFBRSxDQUFDO0FBQ2pCLElBQUksV0FBVyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUM7QUFDOUIsS0FBSyxRQUFRLEVBQUUsQ0FBQztBQUNoQixLQUFLLElBQUksRUFBRSxJQUFJLFVBQVUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2hDLEtBQUssS0FBSyxFQUFFLENBQUM7QUFDYixLQUFLLE1BQU0sRUFBRSxDQUFDO0FBQ2QsS0FBSyxHQUFHLEVBQUUsUUFBUTtBQUNsQixLQUFLLEdBQUcsRUFBRSxRQUFRO0FBQ2xCLEtBQUssQ0FBQztBQUNOO0FBQ0EsSUFBSSxXQUFXLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUM3QixLQUFLLEtBQUssRUFBRSxTQUFTO0FBQ3JCLEtBQUssSUFBSSxFQUFFLE9BQU87QUFDbEIsS0FBSyxJQUFJLEVBQUUsSUFBSSxVQUFVLEVBQUU7QUFDM0IsS0FBSyxDQUFDO0FBQ04sSUFBSSxjQUFjLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUNoQyxLQUFLLEtBQUssRUFBRSxTQUFTO0FBQ3JCLEtBQUssSUFBSSxFQUFFLE9BQU87QUFDbEIsS0FBSyxJQUFJLEVBQUUsSUFBSSxVQUFVLEVBQUU7QUFDM0IsS0FBSyxDQUFDO0FBQ04sSUFBSSxtQkFBbUIsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDO0FBQ3JDLEtBQUssS0FBSyxFQUFFLFNBQVM7QUFDckIsS0FBSyxJQUFJLEVBQUUsT0FBTztBQUNsQixLQUFLLElBQUksRUFBRSxJQUFJLFVBQVUsRUFBRTtBQUMzQixLQUFLLENBQUM7QUFDTixJQUFJO0FBQ0o7QUFDQSxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0FBQ3JDLEdBQUc7QUFDSCxFQUFFLElBQUksQ0FBQyxDQUFDLFNBQVMsSUFBSSxJQUFJLElBQUUsS0FBSyxDQUFDLFNBQVMsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsR0FBQztBQUNwRSxFQUFFLElBQUksQ0FBQyxDQUFDLE9BQU8sSUFBSSxJQUFJLElBQUUsS0FBSyxDQUFDLE9BQU8sR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBQztBQUM5RCxFQUFFLElBQUksQ0FBQyxDQUFDLFVBQVUsSUFBSSxJQUFJLElBQUUsS0FBSyxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLFVBQVUsR0FBQztBQUN2RSxFQUFFLElBQUksQ0FBQyxDQUFDLE9BQU8sSUFBSSxJQUFJLEVBQUU7QUFDekIsR0FBRyxLQUFLLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTztBQUM5QixHQUFHLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxRQUFRLEVBQUU7QUFDNUIsSUFBSSxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsTUFBTSxDQUFDLFFBQVEsR0FBRyxFQUFFLENBQUM7QUFDekYsSUFBSTtBQUNKLEdBQUc7QUFDSCxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLElBQUUsS0FBSyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsTUFBSTtBQUN6QyxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLElBQUUsS0FBSyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsTUFBSTtBQUN6QyxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLElBQUUsS0FBSyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLE9BQU8sR0FBQztBQUN6RSxFQUFFLElBQUksQ0FBQyxDQUFDLFFBQVEsSUFBSSxJQUFJLElBQUUsS0FBSyxDQUFDLFFBQVEsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsR0FBQztBQUNoRTtBQUNBLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUU7QUFDdkIsR0FBRyxLQUFLLENBQUMsUUFBUSxHQUFHLFNBQVMsQ0FBQztBQUM5QixJQUFJLEVBQUUsQ0FBQyxrQkFBa0I7QUFDekIsSUFBSSxFQUFFLENBQUMsbUJBQW1CO0FBQzFCLElBQUksQ0FBQztBQUNMLEdBQUc7QUFDSDtBQUNBLEVBQUUsSUFBSSxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksSUFBRSxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxPQUFLO0FBQzVDO0FBQ0E7QUFDQSxFQUFFLElBQUksQ0FBQyxDQUFDLFNBQVMsS0FBSyxJQUFJLElBQUUsQ0FBQyxDQUFDLFNBQVMsR0FBRyxJQUFFO0FBQzVDLEVBQUUsSUFBSSxDQUFDLENBQUMsU0FBUyxFQUFFO0FBQ25CLEdBQUdELEdBQUcsQ0FBQyxTQUFTLEVBQUUsS0FBSztBQUN2QjtBQUNBO0FBQ0EsR0FBRyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFO0FBQ3ZDLElBQUlBLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQzVCLElBQUlBLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQzVCLElBQUksS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUc7QUFDbEMsS0FBSyxJQUFJLENBQUMsTUFBTTtBQUNoQixLQUFLLElBQUksQ0FBQyxNQUFNO0FBQ2hCLEtBQUs7QUFDTCxJQUFJLFNBQVMsR0FBRyxJQUFJLFlBQVksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO0FBQzNDLElBQUksS0FBS0EsR0FBRyxDQUFDRSxHQUFDLEdBQUcsQ0FBQyxFQUFFQSxHQUFDLEdBQUcsS0FBSyxFQUFFQSxHQUFDLEVBQUUsRUFBRTtBQUNwQyxLQUFLLFNBQVMsQ0FBQ0EsR0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQ0EsR0FBQyxDQUFDO0FBQy9CLEtBQUssU0FBUyxDQUFDQSxHQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQ0EsR0FBQyxDQUFDO0FBQ25DLEtBQUs7QUFDTCxJQUFJO0FBQ0osUUFBUTtBQUNSLElBQUksU0FBUyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQztBQUMvQyxJQUFJLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFDMUQsSUFBSTtBQUNKO0FBQ0EsR0FBR0YsR0FBRyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO0FBQ3REO0FBQ0E7QUFDQTtBQUNBLEdBQUcsSUFBSSxLQUFLLENBQUMsSUFBSSxFQUFFO0FBQ25CLElBQUlBLEdBQUcsQ0FBQyxHQUFHLEdBQUcsRUFBRTtBQUNoQjtBQUNBO0FBQ0EsSUFBSUEsR0FBRyxDQUFDLEdBQUcsR0FBRyxFQUFFO0FBQ2hCLElBQUlBLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQztBQUNsQjtBQUNBLElBQUksS0FBS0EsR0FBRyxDQUFDRSxHQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLEVBQUVBLEdBQUMsR0FBRyxDQUFDLEVBQUVBLEdBQUMsRUFBRSxFQUFFO0FBQzFELEtBQUtGLEdBQUcsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDRSxHQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNCLEtBQUtGLEdBQUcsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDRSxHQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMvQixLQUFLLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUU7QUFDekQsTUFBTSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDN0IsTUFBTSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2pDLE1BQU0sR0FBRyxDQUFDQSxHQUFDLENBQUMsR0FBRyxNQUFNO0FBQ3JCLE1BQU07QUFDTixVQUFVO0FBQ1YsTUFBTSxNQUFNLEdBQUdBLEdBQUM7QUFDaEIsTUFBTTtBQUNOLEtBQUssR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQztBQUNuQixLQUFLLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUM7QUFDbkIsS0FBSztBQUNMO0FBQ0EsSUFBSUYsR0FBRyxDQUFDLFNBQVMsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO0FBQ3REO0FBQ0EsSUFBSSxLQUFLQSxHQUFHLENBQUNFLEdBQUMsR0FBRyxDQUFDLEVBQUVJLEdBQUMsR0FBRyxTQUFTLENBQUMsTUFBTSxFQUFFSixHQUFDLEdBQUdJLEdBQUMsRUFBRUosR0FBQyxFQUFFLEVBQUU7QUFDdEQsS0FBSyxJQUFJLEdBQUcsQ0FBQyxTQUFTLENBQUNBLEdBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFFLFNBQVMsQ0FBQ0EsR0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQ0EsR0FBQyxDQUFDLEdBQUM7QUFDcEUsS0FBSztBQUNMO0FBQ0EsSUFBSSxLQUFLLENBQUMsU0FBUyxHQUFHLFNBQVM7QUFDL0IsSUFBSTtBQUNKO0FBQ0E7QUFDQSxHQUFHRixHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksWUFBWSxDQUFDLFNBQVMsQ0FBQztBQUN6QyxHQUFHLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQztBQUM3QjtBQUNBLEdBQUdBLEdBQUcsQ0FBQyxZQUFZLEdBQUcsSUFBSSxZQUFZLENBQUMsS0FBSyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDckQ7QUFDQTtBQUNBLEdBQUcsSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFO0FBQ3BCLElBQUksSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQy9DLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFO0FBQzlDLEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN4QyxLQUFLLFlBQVksQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDeEMsS0FBSztBQUNMLFNBQVM7QUFDVCxLQUFLLFlBQVksQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDeEMsS0FBSyxZQUFZLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3hDLEtBQUs7QUFDTCxJQUFJO0FBQ0osUUFBUTtBQUNSLElBQUksWUFBWSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDN0IsSUFBSSxZQUFZLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUM3QixJQUFJO0FBQ0o7QUFDQSxHQUFHLFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUM1QjtBQUNBO0FBQ0EsR0FBRyxJQUFJLEtBQUssQ0FBQyxLQUFLLEVBQUU7QUFDcEI7QUFDQSxJQUFJLElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMvQyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRTtBQUM5QyxLQUFLLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDeEMsS0FBSyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3hDLEtBQUssS0FBSyxDQUFDLEtBQUssSUFBSSxDQUFDO0FBQ3JCLEtBQUs7QUFDTCxTQUFTO0FBQ1QsS0FBSyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3hDLEtBQUssWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUN4QyxLQUFLLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDeEMsS0FBSyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3hDLEtBQUs7QUFDTCxJQUFJO0FBQ0o7QUFDQSxRQUFRO0FBQ1IsSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDakQsSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDakQsSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDakQsSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDakQsSUFBSTtBQUNKO0FBQ0EsR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUM5QyxHQUFHLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDbkQsR0FBRztBQUNIO0FBQ0EsRUFBRSxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUU7QUFDZixHQUFHLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEtBQUs7QUFDeEIsR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFO0FBQzNCLEdBQUcsS0FBSyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBTTtBQUM3QixHQUFHO0FBQ0g7QUFDQSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFO0FBQy9DLEdBQUdBLEdBQUcsQ0FBQ0ksUUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNO0FBQzVCO0FBQ0EsR0FBR0osR0FBRyxDQUFDLE9BQU8sR0FBR0ksUUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHQSxRQUFNLENBQUMsQ0FBQyxDQUFDO0FBQ3RDLElBQUksT0FBTyxHQUFHQSxRQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUdBLFFBQU0sQ0FBQyxDQUFDLENBQUM7QUFDbkM7QUFDQSxHQUFHSixHQUFHLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDL0MsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUM1QztBQUNBLEdBQUcsS0FBSyxDQUFDLEtBQUssR0FBRztBQUNqQixJQUFJLE9BQU8sR0FBRyxNQUFNO0FBQ3BCLElBQUksT0FBTyxHQUFHLE1BQU07QUFDcEIsSUFBSTtBQUNKLEdBQUcsS0FBSyxDQUFDLFNBQVMsR0FBRztBQUNyQixJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLEdBQUdJLFFBQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLElBQUksQ0FBQztBQUN0RCxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLEdBQUdBLFFBQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLElBQUksQ0FBQztBQUN0RCxJQUFJO0FBQ0o7QUFDQSxHQUFHLEtBQUssQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7QUFDMUMsR0FBRyxLQUFLLENBQUMsY0FBYyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO0FBQ2xELEdBQUc7QUFDSDtBQUNBLEVBQUUsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFO0FBQ2hCLEdBQUdKLEdBQUcsQ0FBQyxVQUFVLEdBQUcsRUFBRSxFQUFFLFFBQVE7QUFDaEM7QUFDQSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtBQUN6QyxJQUFJLFVBQVUsR0FBRyxFQUFFO0FBQ25CLElBQUksUUFBUSxHQUFHLElBQUksVUFBVSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ3ZFLElBQUk7QUFDSjtBQUNBLFFBQVE7QUFDUixJQUFJLFVBQVUsR0FBRyxFQUFFLENBQUM7QUFDcEIsSUFBSSxJQUFJQSxHQUFHLENBQUNFLEdBQUMsR0FBRyxDQUFDLEVBQUVBLEdBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFQSxHQUFDLEVBQUU7QUFDN0MsS0FBSyxVQUFVLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQ0EsR0FBQyxDQUFDO0FBQzlCLEtBQUs7QUFDTCxJQUFJLFFBQVEsR0FBRyxJQUFJLFVBQVUsQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQztBQUMzRCxJQUFJRixHQUFHLENBQUNLLEtBQUcsR0FBRyxDQUFDO0FBQ2YsSUFBSUwsR0FBRyxDQUFDLFNBQVMsR0FBRyxHQUFHO0FBQ3ZCO0FBQ0E7QUFDQSxJQUFJLEtBQUtBLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDaEMsS0FBSyxJQUFJQSxHQUFHLENBQUNFLEdBQUMsR0FBRyxDQUFDLEVBQUVBLEdBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFQSxHQUFDLEVBQUU7QUFDOUMsTUFBTSxJQUFJRixHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRU0sR0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUNKLEdBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxRQUFRLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBR0ksR0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFO0FBQ3pFLE9BQU8sUUFBUSxDQUFDRCxLQUFHLEVBQUUsQ0FBQyxHQUFHLFNBQVM7QUFDbEMsT0FBTztBQUNQLE1BQU0sU0FBUyxJQUFJLEdBQUc7QUFDdEIsTUFBTTtBQUNOLEtBQUs7QUFDTCxJQUFJO0FBQ0o7QUFDQSxHQUFHLEtBQUssQ0FBQyxVQUFVLEdBQUcsVUFBVTtBQUNoQyxHQUFHLEtBQUssQ0FBQyxXQUFXLENBQUM7QUFDckIsSUFBSSxRQUFRLEVBQUUsQ0FBQztBQUNmLElBQUksSUFBSSxFQUFFLFFBQVE7QUFDbEIsSUFBSSxLQUFLLEVBQUUsUUFBUSxDQUFDLE1BQU07QUFDMUIsSUFBSSxNQUFNLEVBQUUsQ0FBQztBQUNiLElBQUksR0FBRyxFQUFFLFFBQVE7QUFDakIsSUFBSSxHQUFHLEVBQUUsUUFBUTtBQUNqQixJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNYLEdBQUc7QUFDSDtBQUNBLEVBQUUsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFO0FBQ2YsR0FBR0wsR0FBRyxDQUFDRyxPQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUs7QUFDMUIsR0FBR0gsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsS0FBSztBQUN2QjtBQUNBLEdBQUcsSUFBSSxDQUFDLE1BQU0sSUFBRSxNQUFNLEdBQUcsZUFBYTtBQUN0QztBQUNBLEdBQUdBLEdBQUcsQ0FBQyxTQUFTLEdBQUcsSUFBSSxVQUFVLENBQUNHLE9BQUssR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2hEO0FBQ0E7QUFDQSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLFFBQVEsRUFBRTtBQUNoRSxJQUFJSCxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDO0FBQ2pDO0FBQ0EsSUFBSSxLQUFLQSxHQUFHLENBQUNFLEdBQUMsR0FBRyxDQUFDLEVBQUVBLEdBQUMsR0FBR0MsT0FBSyxHQUFHLENBQUMsRUFBRUQsR0FBQyxFQUFFLEVBQUU7QUFDeEMsS0FBSyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRUEsR0FBQyxHQUFHLENBQUMsQ0FBQztBQUM1QixLQUFLO0FBQ0wsSUFBSSxNQUFNO0FBQ1YsSUFBSSxLQUFLRixHQUFHLENBQUNFLEdBQUMsR0FBRyxDQUFDLEVBQUVBLEdBQUMsR0FBR0MsT0FBSyxFQUFFRCxHQUFDLEVBQUUsRUFBRTtBQUNwQyxLQUFLRixHQUFHLENBQUNPLEdBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDTCxHQUFDLENBQUMsRUFBRSxPQUFPLENBQUM7QUFDckMsS0FBSyxTQUFTLENBQUMsR0FBRyxDQUFDSyxHQUFDLEVBQUVMLEdBQUMsR0FBRyxDQUFDLENBQUM7QUFDNUIsS0FBSztBQUNMLElBQUksU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxFQUFFQyxPQUFLLEdBQUcsQ0FBQyxDQUFDO0FBQ3RELElBQUk7QUFDSjtBQUNBLEdBQUcsS0FBSyxDQUFDLFdBQVcsQ0FBQztBQUNyQixJQUFJLEtBQUssRUFBRSxTQUFTO0FBQ3BCLElBQUksSUFBSSxFQUFFLE9BQU87QUFDakIsSUFBSSxJQUFJLEVBQUUsU0FBUztBQUNuQixJQUFJLENBQUM7QUFDTCxHQUFHO0FBQ0gsRUFBRSxDQUFDO0FBQ0g7QUFDQTtBQUNBLENBQUMsSUFBSSxPQUFPLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFO0FBQzFDLEVBQUUsS0FBS0gsR0FBRyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUM1RCxHQUFHQSxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0FBQzVCLEdBQUcsSUFBSSxDQUFDLElBQUksSUFBRSxVQUFRO0FBQ3RCLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUU7QUFDN0IsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRTtBQUNoQyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFO0FBQzdCLEdBQUc7QUFDSCxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNO0FBQ3JDLEVBQUU7QUFDRjtBQUNBO0FBQ0EsQ0FBQ0EsR0FBRyxDQUFDLE1BQU0sR0FBRyxFQUFFO0FBQ2hCLENBQUMsS0FBS0EsR0FBRyxDQUFDRSxHQUFDLEdBQUcsQ0FBQyxFQUFFQSxHQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUVBLEdBQUMsRUFBRSxFQUFFO0FBQzlDLEVBQUUsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDQSxHQUFDLENBQUMsS0FBSyxJQUFJLElBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDQSxHQUFDLENBQUMsR0FBQztBQUMxRCxFQUFFO0FBQ0YsQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU07QUFDckI7QUFDQSxDQUFDLE9BQU8sSUFBSTtBQUNaLENBQUM7QUFDRDtBQUNBLE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxHQUFHLFlBQVk7QUFDdkMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sV0FBQyxLQUFJLENBQUk7QUFDN0IsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRTtBQUM1QixFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFO0FBQy9CLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUU7QUFDNUIsRUFBRSxDQUFDO0FBQ0g7QUFDQSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUM7QUFDdkI7QUFDQSxDQUFDLE9BQU8sSUFBSTtBQUNaLENBQUM7QUFDRDsifQ==\n\n//# sourceURL=webpack:///./node_modules/regl-line2d/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/regl-scatter2d/bundle.js":
-/*!***********************************************!*\
- !*** ./node_modules/regl-scatter2d/bundle.js ***!
- \***********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nfunction _slicedToArray(arr, i) {\n return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();\n}\n\nfunction _toConsumableArray(arr) {\n return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();\n}\n\nfunction _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) {\n for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];\n\n return arr2;\n }\n}\n\nfunction _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}\n\nfunction _iterableToArray(iter) {\n if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter);\n}\n\nfunction _iterableToArrayLimit(arr, i) {\n var _arr = [];\n var _n = true;\n var _d = false;\n var _e = undefined;\n\n try {\n for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}\n\nfunction _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance\");\n}\n\nfunction _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance\");\n}\n\nvar rgba = __webpack_require__(/*! color-normalize */ \"./node_modules/color-normalize/index.js\");\n\nvar getBounds = __webpack_require__(/*! array-bounds */ \"./node_modules/array-bounds/index.js\");\n\nvar colorId = __webpack_require__(/*! color-id */ \"./node_modules/color-id/index.js\");\n\nvar cluster = __webpack_require__(/*! point-cluster */ \"./node_modules/point-cluster/index.js\");\n\nvar extend = __webpack_require__(/*! object-assign */ \"./node_modules/object-assign/index.js\");\n\nvar glslify = __webpack_require__(/*! glslify */ \"./node_modules/glslify/browser.js\");\n\nvar pick = __webpack_require__(/*! pick-by-alias */ \"./node_modules/pick-by-alias/index.js\");\n\nvar updateDiff = __webpack_require__(/*! update-diff */ \"./node_modules/update-diff/index.js\");\n\nvar flatten = __webpack_require__(/*! flatten-vertex-data */ \"./node_modules/flatten-vertex-data/index.js\");\n\nvar ie = __webpack_require__(/*! is-iexplorer */ \"./node_modules/is-iexplorer/index.js\");\n\nvar f32 = __webpack_require__(/*! to-float32 */ \"./node_modules/to-float32/index.js\");\n\nvar parseRect = __webpack_require__(/*! parse-rect */ \"./node_modules/parse-rect/index.js\");\n\nvar scatter = Scatter;\n\nfunction Scatter(regl, options) {\n var _this = this;\n\n if (!(this instanceof Scatter)) return new Scatter(regl, options);\n\n if (typeof regl === 'function') {\n if (!options) options = {};\n options.regl = regl;\n } else {\n options = regl;\n regl = null;\n }\n\n if (options && options.length) options.positions = options;\n regl = options.regl; // persistent variables\n\n var gl = regl._gl,\n paletteTexture,\n palette = [],\n paletteIds = {},\n // state\n groups = [],\n // textures for marker keys\n markerTextures = [null],\n markerCache = [null];\n var maxColors = 255,\n maxSize = 100; // direct color buffer mode\n // IE does not support palette anyways\n\n this.tooManyColors = ie; // texture with color palette\n\n paletteTexture = regl.texture({\n data: new Uint8Array(maxColors * 4),\n width: maxColors,\n height: 1,\n type: 'uint8',\n format: 'rgba',\n wrapS: 'clamp',\n wrapT: 'clamp',\n mag: 'nearest',\n min: 'nearest'\n });\n extend(this, {\n regl: regl,\n gl: gl,\n groups: groups,\n markerCache: markerCache,\n markerTextures: markerTextures,\n palette: palette,\n paletteIds: paletteIds,\n paletteTexture: paletteTexture,\n maxColors: maxColors,\n maxSize: maxSize,\n canvas: gl.canvas\n });\n this.update(options); // common shader options\n\n var shaderOptions = {\n uniforms: {\n pixelRatio: regl.context('pixelRatio'),\n palette: paletteTexture,\n paletteSize: function paletteSize(ctx, prop) {\n return [_this.tooManyColors ? 0 : maxColors, paletteTexture.height];\n },\n scale: regl.prop('scale'),\n scaleFract: regl.prop('scaleFract'),\n translate: regl.prop('translate'),\n translateFract: regl.prop('translateFract'),\n opacity: regl.prop('opacity'),\n marker: regl.prop('markerTexture')\n },\n attributes: {\n // FIXME: optimize these parts\n x: function x(ctx, prop) {\n return prop.xAttr || {\n buffer: prop.positionBuffer,\n stride: 8,\n offset: 0\n };\n },\n y: function y(ctx, prop) {\n return prop.yAttr || {\n buffer: prop.positionBuffer,\n stride: 8,\n offset: 4\n };\n },\n xFract: function xFract(ctx, prop) {\n return prop.xAttr ? {\n constant: [0, 0]\n } : {\n buffer: prop.positionFractBuffer,\n stride: 8,\n offset: 0\n };\n },\n yFract: function yFract(ctx, prop) {\n return prop.yAttr ? {\n constant: [0, 0]\n } : {\n buffer: prop.positionFractBuffer,\n stride: 8,\n offset: 4\n };\n },\n size: function size(ctx, prop) {\n return prop.size.length ? {\n buffer: prop.sizeBuffer,\n stride: 2,\n offset: 0\n } : {\n constant: [Math.round(prop.size * 255 / _this.maxSize)]\n };\n },\n borderSize: function borderSize(ctx, prop) {\n return prop.borderSize.length ? {\n buffer: prop.sizeBuffer,\n stride: 2,\n offset: 1\n } : {\n constant: [Math.round(prop.borderSize * 255 / _this.maxSize)]\n };\n },\n colorId: function colorId(ctx, prop) {\n return prop.color.length ? {\n buffer: prop.colorBuffer,\n stride: _this.tooManyColors ? 8 : 4,\n offset: 0\n } : {\n constant: _this.tooManyColors ? palette.slice(prop.color * 4, prop.color * 4 + 4) : [prop.color]\n };\n },\n borderColorId: function borderColorId(ctx, prop) {\n return prop.borderColor.length ? {\n buffer: prop.colorBuffer,\n stride: _this.tooManyColors ? 8 : 4,\n offset: _this.tooManyColors ? 4 : 2\n } : {\n constant: _this.tooManyColors ? palette.slice(prop.borderColor * 4, prop.borderColor * 4 + 4) : [prop.borderColor]\n };\n },\n isActive: function isActive(ctx, prop) {\n return prop.activation === true ? {\n constant: [1]\n } : prop.activation ? prop.activation : {\n constant: [0]\n };\n }\n },\n blend: {\n enable: true,\n color: [0, 0, 0, 1],\n // photoshop blending\n func: {\n srcRGB: 'src alpha',\n dstRGB: 'one minus src alpha',\n srcAlpha: 'one minus dst alpha',\n dstAlpha: 'one'\n }\n },\n scissor: {\n enable: true,\n box: regl.prop('viewport')\n },\n viewport: regl.prop('viewport'),\n stencil: {\n enable: false\n },\n depth: {\n enable: false\n },\n elements: regl.prop('elements'),\n count: regl.prop('count'),\n offset: regl.prop('offset'),\n primitive: 'points' // draw sdf-marker\n\n };\n var markerOptions = extend({}, shaderOptions);\n markerOptions.frag = glslify([\"precision highp float;\\n#define GLSLIFY 1\\n\\nvarying vec4 fragColor, fragBorderColor;\\nvarying float fragWidth, fragBorderColorLevel, fragColorLevel;\\n\\nuniform sampler2D marker;\\nuniform float pixelRatio, opacity;\\n\\nfloat smoothStep(float x, float y) {\\n return 1.0 / (1.0 + exp(50.0*(x - y)));\\n}\\n\\nvoid main() {\\n float dist = texture2D(marker, gl_PointCoord).r, delta = fragWidth;\\n\\n // max-distance alpha\\n if (dist < 0.003) discard;\\n\\n // null-border case\\n if (fragBorderColorLevel == fragColorLevel || fragBorderColor.a == 0.) {\\n float colorAmt = smoothstep(.5 - delta, .5 + delta, dist);\\n gl_FragColor = vec4(fragColor.rgb, colorAmt * fragColor.a * opacity);\\n }\\n else {\\n float borderColorAmt = smoothstep(fragBorderColorLevel - delta, fragBorderColorLevel + delta, dist);\\n float colorAmt = smoothstep(fragColorLevel - delta, fragColorLevel + delta, dist);\\n\\n vec4 color = fragBorderColor;\\n color.a *= borderColorAmt;\\n color = mix(color, fragColor, colorAmt);\\n color.a *= opacity;\\n\\n gl_FragColor = color;\\n }\\n\\n}\\n\"]);\n markerOptions.vert = glslify([\"precision highp float;\\n#define GLSLIFY 1\\n\\nattribute float x, y, xFract, yFract;\\nattribute float size, borderSize;\\nattribute vec4 colorId, borderColorId;\\nattribute float isActive;\\n\\nuniform vec2 scale, scaleFract, translate, translateFract, paletteSize;\\nuniform float pixelRatio;\\nuniform sampler2D palette;\\n\\nconst float maxSize = 100.;\\nconst float borderLevel = .5;\\n\\nvarying vec4 fragColor, fragBorderColor;\\nvarying float fragPointSize, fragBorderRadius, fragWidth, fragBorderColorLevel, fragColorLevel;\\n\\nbool isDirect = (paletteSize.x < 1.);\\n\\nvec4 getColor(vec4 id) {\\n return isDirect ? id / 255. : texture2D(palette,\\n vec2(\\n (id.x + .5) / paletteSize.x,\\n (id.y + .5) / paletteSize.y\\n )\\n );\\n}\\n\\nvoid main() {\\n if (isActive == 0.) return;\\n\\n vec2 position = vec2(x, y);\\n vec2 positionFract = vec2(xFract, yFract);\\n\\n vec4 color = getColor(colorId);\\n vec4 borderColor = getColor(borderColorId);\\n\\n float size = size * maxSize / 255.;\\n float borderSize = borderSize * maxSize / 255.;\\n\\n gl_PointSize = 2. * size * pixelRatio;\\n fragPointSize = size * pixelRatio;\\n\\n vec2 pos = (position + translate) * scale\\n + (positionFract + translateFract) * scale\\n + (position + translate) * scaleFract\\n + (positionFract + translateFract) * scaleFract;\\n\\n gl_Position = vec4(pos * 2. - 1., 0, 1);\\n\\n fragColor = color;\\n fragBorderColor = borderColor;\\n fragWidth = 1. / gl_PointSize;\\n\\n fragBorderColorLevel = clamp(borderLevel - borderLevel * borderSize / size, 0., 1.);\\n fragColorLevel = clamp(borderLevel + (1. - borderLevel) * borderSize / size, 0., 1.);\\n}\"]);\n this.drawMarker = regl(markerOptions); // draw circle\n\n var circleOptions = extend({}, shaderOptions);\n circleOptions.frag = glslify([\"precision highp float;\\n#define GLSLIFY 1\\n\\nvarying vec4 fragColor, fragBorderColor;\\n\\nuniform float opacity;\\nvarying float fragBorderRadius, fragWidth;\\n\\nfloat smoothStep(float edge0, float edge1, float x) {\\n\\tfloat t;\\n\\tt = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\\n\\treturn t * t * (3.0 - 2.0 * t);\\n}\\n\\nvoid main() {\\n\\tfloat radius, alpha = 1.0, delta = fragWidth;\\n\\n\\tradius = length(2.0 * gl_PointCoord.xy - 1.0);\\n\\n\\tif (radius > 1.0 + delta) {\\n\\t\\tdiscard;\\n\\t}\\n\\n\\talpha -= smoothstep(1.0 - delta, 1.0 + delta, radius);\\n\\n\\tfloat borderRadius = fragBorderRadius;\\n\\tfloat ratio = smoothstep(borderRadius - delta, borderRadius + delta, radius);\\n\\tvec4 color = mix(fragColor, fragBorderColor, ratio);\\n\\tcolor.a *= alpha * opacity;\\n\\tgl_FragColor = color;\\n}\\n\"]);\n circleOptions.vert = glslify([\"precision highp float;\\n#define GLSLIFY 1\\n\\nattribute float x, y, xFract, yFract;\\nattribute float size, borderSize;\\nattribute vec4 colorId, borderColorId;\\nattribute float isActive;\\n\\nuniform vec2 scale, scaleFract, translate, translateFract;\\nuniform float pixelRatio;\\nuniform sampler2D palette;\\nuniform vec2 paletteSize;\\n\\nconst float maxSize = 100.;\\n\\nvarying vec4 fragColor, fragBorderColor;\\nvarying float fragBorderRadius, fragWidth;\\n\\nbool isDirect = (paletteSize.x < 1.);\\n\\nvec4 getColor(vec4 id) {\\n return isDirect ? id / 255. : texture2D(palette,\\n vec2(\\n (id.x + .5) / paletteSize.x,\\n (id.y + .5) / paletteSize.y\\n )\\n );\\n}\\n\\nvoid main() {\\n // ignore inactive points\\n if (isActive == 0.) return;\\n\\n vec2 position = vec2(x, y);\\n vec2 positionFract = vec2(xFract, yFract);\\n\\n vec4 color = getColor(colorId);\\n vec4 borderColor = getColor(borderColorId);\\n\\n float size = size * maxSize / 255.;\\n float borderSize = borderSize * maxSize / 255.;\\n\\n gl_PointSize = (size + borderSize) * pixelRatio;\\n\\n vec2 pos = (position + translate) * scale\\n + (positionFract + translateFract) * scale\\n + (position + translate) * scaleFract\\n + (positionFract + translateFract) * scaleFract;\\n\\n gl_Position = vec4(pos * 2. - 1., 0, 1);\\n\\n fragBorderRadius = 1. - 2. * borderSize / (size + borderSize);\\n fragColor = color;\\n fragBorderColor = borderColor.a == 0. || borderSize == 0. ? vec4(color.rgb, 0.) : borderColor;\\n fragWidth = 1. / gl_PointSize;\\n}\\n\"]); // polyfill IE\n\n if (ie) {\n circleOptions.frag = circleOptions.frag.replace('smoothstep', 'smoothStep');\n markerOptions.frag = markerOptions.frag.replace('smoothstep', 'smoothStep');\n }\n\n this.drawCircle = regl(circleOptions);\n} // single pass defaults\n\n\nScatter.defaults = {\n color: 'black',\n borderColor: 'transparent',\n borderSize: 0,\n size: 12,\n opacity: 1,\n marker: undefined,\n viewport: null,\n range: null,\n pixelSize: null,\n count: 0,\n offset: 0,\n bounds: null,\n positions: [],\n snap: 1e4 // update & redraw\n\n};\n\nScatter.prototype.render = function () {\n if (arguments.length) {\n this.update.apply(this, arguments);\n }\n\n this.draw();\n return this;\n}; // draw all groups or only indicated ones\n\n\nScatter.prototype.draw = function () {\n var _this2 = this;\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n var groups = this.groups; // if directly array passed - treat as passes\n\n if (args.length === 1 && Array.isArray(args[0]) && (args[0][0] === null || Array.isArray(args[0][0]))) {\n args = args[0];\n } // FIXME: remove once https://github.com/regl-project/regl/issues/474 resolved\n\n\n this.regl._refresh();\n\n if (args.length) {\n for (var i = 0; i < args.length; i++) {\n this.drawItem(i, args[i]);\n }\n } // draw all passes\n else {\n groups.forEach(function (group, i) {\n _this2.drawItem(i);\n });\n }\n\n return this;\n}; // draw specific scatter group\n\n\nScatter.prototype.drawItem = function (id, els) {\n var groups = this.groups;\n var group = groups[id]; // debug viewport\n // let { viewport } = group\n // gl.enable(gl.SCISSOR_TEST);\n // gl.scissor(viewport.x, viewport.y, viewport.width, viewport.height);\n // gl.clearColor(0, 0, 0, .5);\n // gl.clear(gl.COLOR_BUFFER_BIT);\n\n if (typeof els === 'number') {\n id = els;\n group = groups[els];\n els = null;\n }\n\n if (!(group && group.count && group.opacity)) return; // draw circles\n\n if (group.activation[0]) {\n // TODO: optimize this performance by making groups and regl.this props\n this.drawCircle(this.getMarkerDrawOptions(0, group, els));\n } // draw all other available markers\n\n\n var batch = [];\n\n for (var i = 1; i < group.activation.length; i++) {\n if (!group.activation[i] || group.activation[i] !== true && !group.activation[i].data.length) continue;\n batch.push.apply(batch, _toConsumableArray(this.getMarkerDrawOptions(i, group, els)));\n }\n\n if (batch.length) {\n this.drawMarker(batch);\n }\n}; // get options for the marker ids\n\n\nScatter.prototype.getMarkerDrawOptions = function (markerId, group, elements) {\n var range = group.range,\n tree = group.tree,\n viewport = group.viewport,\n activation = group.activation,\n selectionBuffer = group.selectionBuffer,\n count = group.count;\n var regl = this.regl; // direct points\n\n if (!tree) {\n // if elements array - draw unclustered points\n if (elements) {\n return [extend({}, group, {\n markerTexture: this.markerTextures[markerId],\n activation: activation[markerId],\n count: elements.length,\n elements: elements,\n offset: 0\n })];\n }\n\n return [extend({}, group, {\n markerTexture: this.markerTextures[markerId],\n activation: activation[markerId],\n offset: 0\n })];\n } // clustered points\n\n\n var batch = [];\n var lod = tree.range(range, {\n lod: true,\n px: [(range[2] - range[0]) / viewport.width, (range[3] - range[1]) / viewport.height]\n }); // enable elements by using selection buffer\n\n if (elements) {\n var markerActivation = activation[markerId];\n var mask = markerActivation.data;\n var data = new Uint8Array(count);\n\n for (var i = 0; i < elements.length; i++) {\n var id = elements[i];\n data[id] = mask ? mask[id] : 1;\n }\n\n selectionBuffer.subdata(data);\n }\n\n for (var l = lod.length; l--;) {\n var _lod$l = _slicedToArray(lod[l], 2),\n from = _lod$l[0],\n to = _lod$l[1];\n\n batch.push(extend({}, group, {\n markerTexture: this.markerTextures[markerId],\n activation: elements ? selectionBuffer : activation[markerId],\n offset: from,\n count: to - from\n }));\n }\n\n return batch;\n}; // update groups options\n\n\nScatter.prototype.update = function () {\n var _this3 = this;\n\n for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n\n if (!args.length) return; // passes are as single array\n\n if (args.length === 1 && Array.isArray(args[0])) args = args[0];\n var groups = this.groups,\n gl = this.gl,\n regl = this.regl,\n maxSize = this.maxSize,\n maxColors = this.maxColors,\n palette = this.palette;\n this.groups = groups = args.map(function (options, i) {\n var group = groups[i];\n if (options === undefined) return group;\n if (options === null) options = {\n positions: null\n };else if (typeof options === 'function') options = {\n ondraw: options\n };else if (typeof options[0] === 'number') options = {\n positions: options // copy options to avoid mutation & handle aliases\n\n };\n options = pick(options, {\n positions: 'positions data points',\n snap: 'snap cluster lod tree',\n size: 'sizes size radius',\n borderSize: 'borderSizes borderSize border-size bordersize borderWidth borderWidths border-width borderwidth stroke-width strokeWidth strokewidth outline',\n color: 'colors color fill fill-color fillColor',\n borderColor: 'borderColors borderColor stroke stroke-color strokeColor',\n marker: 'markers marker shape',\n range: 'range dataBox databox',\n viewport: 'viewport viewPort viewBox viewbox',\n opacity: 'opacity alpha transparency',\n bounds: 'bound bounds boundaries limits',\n tooManyColors: 'tooManyColors palette paletteMode optimizePalette enablePalette'\n });\n if (options.positions === null) options.positions = [];\n if (options.tooManyColors != null) _this3.tooManyColors = options.tooManyColors;\n\n if (!group) {\n groups[i] = group = {\n id: i,\n scale: null,\n translate: null,\n scaleFract: null,\n translateFract: null,\n // buffers for active markers\n activation: [],\n // buffer for filtered markers\n selectionBuffer: regl.buffer({\n data: new Uint8Array(0),\n usage: 'stream',\n type: 'uint8'\n }),\n // buffers with data: it is faster to switch them per-pass\n // than provide one congregate buffer\n sizeBuffer: regl.buffer({\n data: new Uint8Array(0),\n usage: 'dynamic',\n type: 'uint8'\n }),\n colorBuffer: regl.buffer({\n data: new Uint8Array(0),\n usage: 'dynamic',\n type: 'uint8'\n }),\n positionBuffer: regl.buffer({\n data: new Uint8Array(0),\n usage: 'dynamic',\n type: 'float'\n }),\n positionFractBuffer: regl.buffer({\n data: new Uint8Array(0),\n usage: 'dynamic',\n type: 'float'\n })\n };\n options = extend({}, Scatter.defaults, options);\n } // force update triggers\n\n\n if (options.positions && !('marker' in options)) {\n options.marker = group.marker;\n delete group.marker;\n } // updating markers cause recalculating snapping\n\n\n if (options.marker && !('positions' in options)) {\n options.positions = group.positions;\n delete group.positions;\n } // global count of points\n\n\n var hasSize = 0,\n hasColor = 0;\n updateDiff(group, options, [{\n snap: true,\n size: function size(s, group) {\n if (s == null) s = Scatter.defaults.size;\n hasSize += s && s.length ? 1 : 0;\n return s;\n },\n borderSize: function borderSize(s, group) {\n if (s == null) s = Scatter.defaults.borderSize;\n hasSize += s && s.length ? 1 : 0;\n return s;\n },\n opacity: parseFloat,\n // add colors to palette, save references\n color: function color(c, group) {\n if (c == null) c = Scatter.defaults.color;\n c = _this3.updateColor(c);\n hasColor++;\n return c;\n },\n borderColor: function borderColor(c, group) {\n if (c == null) c = Scatter.defaults.borderColor;\n c = _this3.updateColor(c);\n hasColor++;\n return c;\n },\n bounds: function bounds(_bounds, group, options) {\n if (!('range' in options)) options.range = null;\n return _bounds;\n },\n positions: function positions(_positions, group, options) {\n var snap = group.snap;\n var positionBuffer = group.positionBuffer,\n positionFractBuffer = group.positionFractBuffer,\n selectionBuffer = group.selectionBuffer; // separate buffers for x/y coordinates\n\n if (_positions.x || _positions.y) {\n if (_positions.x.length) {\n group.xAttr = {\n buffer: regl.buffer(_positions.x),\n offset: 0,\n stride: 4,\n count: _positions.x.length\n };\n } else {\n group.xAttr = {\n buffer: _positions.x.buffer,\n offset: _positions.x.offset * 4 || 0,\n stride: (_positions.x.stride || 1) * 4,\n count: _positions.x.count\n };\n }\n\n if (_positions.y.length) {\n group.yAttr = {\n buffer: regl.buffer(_positions.y),\n offset: 0,\n stride: 4,\n count: _positions.y.length\n };\n } else {\n group.yAttr = {\n buffer: _positions.y.buffer,\n offset: _positions.y.offset * 4 || 0,\n stride: (_positions.y.stride || 1) * 4,\n count: _positions.y.count\n };\n }\n\n group.count = Math.max(group.xAttr.count, group.yAttr.count);\n return _positions;\n }\n\n _positions = flatten(_positions, 'float64');\n var count = group.count = Math.floor(_positions.length / 2);\n var bounds = group.bounds = count ? getBounds(_positions, 2) : null; // if range is not provided updated - recalc it\n\n if (!options.range && !group.range) {\n delete group.range;\n options.range = bounds;\n } // reset marker\n\n\n if (!options.marker && !group.marker) {\n delete group.marker;\n options.marker = null;\n } // build cluster tree if required\n\n\n if (snap && (snap === true || count > snap)) {\n group.tree = cluster(_positions, {\n bounds: bounds\n });\n } // existing tree instance\n else if (snap && snap.length) {\n group.tree = snap;\n }\n\n if (group.tree) {\n var opts = {\n primitive: 'points',\n usage: 'static',\n data: group.tree,\n type: 'uint32'\n };\n if (group.elements) group.elements(opts);else group.elements = regl.elements(opts);\n } // update position buffers\n\n\n positionBuffer({\n data: f32.float(_positions),\n usage: 'dynamic'\n });\n positionFractBuffer({\n data: f32.fract(_positions),\n usage: 'dynamic'\n }); // expand selectionBuffer\n\n selectionBuffer({\n data: new Uint8Array(count),\n type: 'uint8',\n usage: 'stream'\n });\n return _positions;\n }\n }, {\n // create marker ids corresponding to known marker textures\n marker: function marker(markers, group, options) {\n var activation = group.activation; // reset marker elements\n\n activation.forEach(function (buffer) {\n return buffer && buffer.destroy && buffer.destroy();\n });\n activation.length = 0; // single sdf marker\n\n if (!markers || typeof markers[0] === 'number') {\n var id = _this3.addMarker(markers);\n\n activation[id] = true;\n } // per-point markers use mask buffers to enable markers in vert shader\n else {\n var markerMasks = [];\n\n for (var _i = 0, l = Math.min(markers.length, group.count); _i < l; _i++) {\n var _id = _this3.addMarker(markers[_i]);\n\n if (!markerMasks[_id]) markerMasks[_id] = new Uint8Array(group.count); // enable marker by default\n\n markerMasks[_id][_i] = 1;\n }\n\n for (var _id2 = 0; _id2 < markerMasks.length; _id2++) {\n if (!markerMasks[_id2]) continue;\n var opts = {\n data: markerMasks[_id2],\n type: 'uint8',\n usage: 'static'\n };\n\n if (!activation[_id2]) {\n activation[_id2] = regl.buffer(opts);\n } else {\n activation[_id2](opts);\n }\n\n activation[_id2].data = markerMasks[_id2];\n }\n }\n\n return markers;\n },\n range: function range(_range, group, options) {\n var bounds = group.bounds; // FIXME: why do we need this?\n\n if (!bounds) return;\n if (!_range) _range = bounds;\n group.scale = [1 / (_range[2] - _range[0]), 1 / (_range[3] - _range[1])];\n group.translate = [-_range[0], -_range[1]];\n group.scaleFract = f32.fract(group.scale);\n group.translateFract = f32.fract(group.translate);\n return _range;\n },\n viewport: function viewport(vp) {\n var rect = parseRect(vp || [gl.drawingBufferWidth, gl.drawingBufferHeight]); // normalize viewport to the canvas coordinates\n // rect.y = gl.drawingBufferHeight - rect.height - rect.y\n\n return rect;\n }\n }]); // update size buffer, if needed\n\n if (hasSize) {\n var _group = group,\n count = _group.count,\n size = _group.size,\n borderSize = _group.borderSize,\n sizeBuffer = _group.sizeBuffer;\n var sizes = new Uint8Array(count * 2);\n\n if (size.length || borderSize.length) {\n for (var _i2 = 0; _i2 < count; _i2++) {\n // we downscale size to allow for fractions\n sizes[_i2 * 2] = Math.round((size[_i2] == null ? size : size[_i2]) * 255 / maxSize);\n sizes[_i2 * 2 + 1] = Math.round((borderSize[_i2] == null ? borderSize : borderSize[_i2]) * 255 / maxSize);\n }\n }\n\n sizeBuffer({\n data: sizes,\n usage: 'dynamic'\n });\n } // update color buffer if needed\n\n\n if (hasColor) {\n var _group2 = group,\n _count = _group2.count,\n color = _group2.color,\n borderColor = _group2.borderColor,\n colorBuffer = _group2.colorBuffer;\n var colors; // if too many colors - put colors to buffer directly\n\n if (_this3.tooManyColors) {\n if (color.length || borderColor.length) {\n colors = new Uint8Array(_count * 8);\n\n for (var _i3 = 0; _i3 < _count; _i3++) {\n var _colorId = color[_i3];\n colors[_i3 * 8] = palette[_colorId * 4];\n colors[_i3 * 8 + 1] = palette[_colorId * 4 + 1];\n colors[_i3 * 8 + 2] = palette[_colorId * 4 + 2];\n colors[_i3 * 8 + 3] = palette[_colorId * 4 + 3];\n var borderColorId = borderColor[_i3];\n colors[_i3 * 8 + 4] = palette[borderColorId * 4];\n colors[_i3 * 8 + 5] = palette[borderColorId * 4 + 1];\n colors[_i3 * 8 + 6] = palette[borderColorId * 4 + 2];\n colors[_i3 * 8 + 7] = palette[borderColorId * 4 + 3];\n }\n }\n } // if limited amount of colors - keep palette color picking\n // that saves significant memory\n else {\n if (color.length || borderColor.length) {\n // we need slight data increase by 2 due to vec4 borderId in shader\n colors = new Uint8Array(_count * 4 + 2);\n\n for (var _i4 = 0; _i4 < _count; _i4++) {\n // put color coords in palette texture\n if (color[_i4] != null) {\n colors[_i4 * 4] = color[_i4] % maxColors;\n colors[_i4 * 4 + 1] = Math.floor(color[_i4] / maxColors);\n }\n\n if (borderColor[_i4] != null) {\n colors[_i4 * 4 + 2] = borderColor[_i4] % maxColors;\n colors[_i4 * 4 + 3] = Math.floor(borderColor[_i4] / maxColors);\n }\n }\n }\n }\n\n colorBuffer({\n data: colors || new Uint8Array(0),\n type: 'uint8',\n usage: 'dynamic'\n });\n }\n\n return group;\n });\n}; // get (and create) marker texture id\n\n\nScatter.prototype.addMarker = function (sdf) {\n var markerTextures = this.markerTextures,\n regl = this.regl,\n markerCache = this.markerCache;\n var pos = sdf == null ? 0 : markerCache.indexOf(sdf);\n if (pos >= 0) return pos; // convert sdf to 0..255 range\n\n var distArr;\n\n if (sdf instanceof Uint8Array || sdf instanceof Uint8ClampedArray) {\n distArr = sdf;\n } else {\n distArr = new Uint8Array(sdf.length);\n\n for (var i = 0, l = sdf.length; i < l; i++) {\n distArr[i] = sdf[i] * 255;\n }\n }\n\n var radius = Math.floor(Math.sqrt(distArr.length));\n pos = markerTextures.length;\n markerCache.push(sdf);\n markerTextures.push(regl.texture({\n channels: 1,\n data: distArr,\n radius: radius,\n mag: 'linear',\n min: 'linear'\n }));\n return pos;\n}; // register color to palette, return it's index or list of indexes\n\n\nScatter.prototype.updateColor = function (colors) {\n var paletteIds = this.paletteIds,\n palette = this.palette,\n maxColors = this.maxColors;\n\n if (!Array.isArray(colors)) {\n colors = [colors];\n }\n\n var idx = []; // if color groups - flatten them\n\n if (typeof colors[0] === 'number') {\n var grouped = [];\n\n if (Array.isArray(colors)) {\n for (var i = 0; i < colors.length; i += 4) {\n grouped.push(colors.slice(i, i + 4));\n }\n } else {\n for (var _i5 = 0; _i5 < colors.length; _i5 += 4) {\n grouped.push(colors.subarray(_i5, _i5 + 4));\n }\n }\n\n colors = grouped;\n }\n\n for (var _i6 = 0; _i6 < colors.length; _i6++) {\n var color = colors[_i6];\n color = rgba(color, 'uint8');\n var id = colorId(color, false); // if new color - save it\n\n if (paletteIds[id] == null) {\n var pos = palette.length;\n paletteIds[id] = Math.floor(pos / 4);\n palette[pos] = color[0];\n palette[pos + 1] = color[1];\n palette[pos + 2] = color[2];\n palette[pos + 3] = color[3];\n }\n\n idx[_i6] = paletteIds[id];\n } // detect if too many colors in palette\n\n\n if (!this.tooManyColors && palette.length > maxColors * 4) this.tooManyColors = true; // limit max color\n\n this.updatePalette(palette); // keep static index for single-color property\n\n return idx.length === 1 ? idx[0] : idx;\n};\n\nScatter.prototype.updatePalette = function (palette) {\n if (this.tooManyColors) return;\n var maxColors = this.maxColors,\n paletteTexture = this.paletteTexture;\n var requiredHeight = Math.ceil(palette.length * .25 / maxColors); // pad data\n\n if (requiredHeight > 1) {\n palette = palette.slice();\n\n for (var i = palette.length * .25 % maxColors; i < requiredHeight * maxColors; i++) {\n palette.push(0, 0, 0, 0);\n }\n } // ensure height\n\n\n if (paletteTexture.height < requiredHeight) {\n paletteTexture.resize(maxColors, requiredHeight);\n } // update full data\n\n\n paletteTexture.subimage({\n width: Math.min(palette.length * .25, maxColors),\n height: requiredHeight,\n data: palette\n }, 0, 0);\n}; // remove unused stuff\n\n\nScatter.prototype.destroy = function () {\n this.groups.forEach(function (group) {\n group.sizeBuffer.destroy();\n group.positionBuffer.destroy();\n group.positionFractBuffer.destroy();\n group.colorBuffer.destroy();\n group.activation.forEach(function (b) {\n return b && b.destroy && b.destroy();\n });\n group.selectionBuffer.destroy();\n if (group.elements) group.elements.destroy();\n });\n this.groups.length = 0;\n this.paletteTexture.destroy();\n this.markerTextures.forEach(function (txt) {\n return txt && txt.destroy && txt.destroy();\n });\n return this;\n};\n\nvar extend$1 = __webpack_require__(/*! object-assign */ \"./node_modules/object-assign/index.js\");\n\nvar reglScatter2d = function reglScatter2d(regl, options) {\n var scatter$$1 = new scatter(regl, options);\n var render = scatter$$1.render.bind(scatter$$1); // expose API\n\n extend$1(render, {\n render: render,\n update: scatter$$1.update.bind(scatter$$1),\n draw: scatter$$1.draw.bind(scatter$$1),\n destroy: scatter$$1.destroy.bind(scatter$$1),\n regl: scatter$$1.regl,\n gl: scatter$$1.gl,\n canvas: scatter$$1.gl.canvas,\n groups: scatter$$1.groups,\n markers: scatter$$1.markerCache,\n palette: scatter$$1.palette\n });\n return render;\n};\n\nmodule.exports = reglScatter2d;\n\n\n//# sourceURL=webpack:///./node_modules/regl-scatter2d/bundle.js?");
-
-/***/ }),
-
-/***/ "./node_modules/regl-splom/index.js":
-/*!******************************************!*\
- !*** ./node_modules/regl-splom/index.js ***!
- \******************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\r\n\r\n\r\nvar createScatter = __webpack_require__(/*! regl-scatter2d */ \"./node_modules/regl-scatter2d/bundle.js\")\r\nvar pick = __webpack_require__(/*! pick-by-alias */ \"./node_modules/pick-by-alias/index.js\")\r\nvar getBounds = __webpack_require__(/*! array-bounds */ \"./node_modules/array-bounds/index.js\")\r\nvar raf = __webpack_require__(/*! raf */ \"./node_modules/raf/index.js\")\r\nvar arrRange = __webpack_require__(/*! array-range */ \"./node_modules/array-range/index.js\")\r\nvar rect = __webpack_require__(/*! parse-rect */ \"./node_modules/parse-rect/index.js\")\r\nvar flatten = __webpack_require__(/*! flatten-vertex-data */ \"./node_modules/flatten-vertex-data/index.js\")\r\n\r\n\r\nmodule.exports = SPLOM\r\n\r\n\r\n// @constructor\r\nfunction SPLOM (regl, options) {\r\n\tif (!(this instanceof SPLOM)) { return new SPLOM(regl, options) }\r\n\r\n\t// render passes\r\n\tthis.traces = []\r\n\r\n\t// passes for scatter, combined across traces\r\n\tthis.passes = {}\r\n\r\n\tthis.regl = regl\r\n\r\n\t// main scatter drawing instance\r\n\tthis.scatter = createScatter(regl)\r\n\r\n\tthis.canvas = this.scatter.canvas\r\n}\r\n\r\n\r\n// update & draw passes once per frame\r\nSPLOM.prototype.render = function () {\n\tvar this$1 = this;\n\tvar ref;\n\n\tvar args = [], len = arguments.length;\n\twhile ( len-- ) args[ len ] = arguments[ len ];\r\n\tif (args.length) {\r\n\t\t(ref = this).update.apply(ref, args)\r\n\t}\r\n\r\n\tif (this.regl.attributes.preserveDrawingBuffer) { return this.draw() }\r\n\r\n\t// make sure draw is not called more often than once a frame\r\n\tif (this.dirty) {\r\n\t\tif (this.planned == null) {\r\n\t\t\tthis.planned = raf(function () {\r\n\t\t\t\tthis$1.draw()\r\n\t\t\t\tthis$1.dirty = true\r\n\t\t\t\tthis$1.planned = null\r\n\t\t\t})\r\n\t\t}\r\n\t}\r\n\telse {\r\n\t\tthis.draw()\r\n\t\tthis.dirty = true\r\n\t\traf(function () {\r\n\t\t\tthis$1.dirty = false\r\n\t\t})\r\n\t}\r\n\r\n\treturn this\r\n}\r\n\r\n\r\n// update passes\r\nSPLOM.prototype.update = function () {\n\tvar ref;\n\n\tvar args = [], len = arguments.length;\n\twhile ( len-- ) args[ len ] = arguments[ len ];\r\n\tif (!args.length) { return }\r\n\r\n\tfor (var i = 0; i < args.length; i++) {\r\n\t\tthis.updateItem(i, args[i])\r\n\t}\r\n\r\n\t// remove nulled passes\r\n\tthis.traces = this.traces.filter(Boolean)\r\n\r\n\t// FIXME: update passes independently\r\n\tvar passes = []\r\n\tvar offset = 0\r\n\tfor (var i$1 = 0; i$1 < this.traces.length; i$1++) {\r\n\t\tvar trace = this.traces[i$1]\r\n\t\tvar tracePasses = this.traces[i$1].passes\r\n\t\tfor (var j = 0; j < tracePasses.length; j++) {\r\n\t\t\tpasses.push(this.passes[tracePasses[j]])\r\n\t\t}\r\n\t\t// save offset of passes\r\n\t\ttrace.passOffset = offset\r\n\t\toffset += trace.passes.length\r\n\t}\r\n\r\n\t(ref = this.scatter).update.apply(ref, passes)\r\n\r\n\treturn this\r\n}\r\n\r\n\r\n// update trace by index, not supposed to be called directly\r\nSPLOM.prototype.updateItem = function (i, options) {\r\n\tvar ref = this;\n\tvar regl = ref.regl;\r\n\r\n\t// remove pass if null\r\n\tif (options === null) {\r\n\t\tthis.traces[i] = null\r\n\t\treturn this\r\n\t}\r\n\r\n\tif (!options) { return this }\r\n\r\n\tvar o = pick(options, {\r\n\t\tdata: 'data items columns rows values dimensions samples x',\r\n\t\tsnap: 'snap cluster',\r\n\t\tsize: 'sizes size radius',\r\n\t\tcolor: 'colors color fill fill-color fillColor',\r\n\t\topacity: 'opacity alpha transparency opaque',\r\n\t\tborderSize: 'borderSizes borderSize border-size bordersize borderWidth borderWidths border-width borderwidth stroke-width strokeWidth strokewidth outline',\r\n\t\tborderColor: 'borderColors borderColor bordercolor stroke stroke-color strokeColor',\r\n\t\tmarker: 'markers marker shape',\r\n\t\trange: 'range ranges databox dataBox',\r\n\t\tviewport: 'viewport viewBox viewbox',\r\n\t\tdomain: 'domain domains area areas',\r\n\t\tpadding: 'pad padding paddings pads margin margins',\r\n\t\ttranspose: 'transpose transposed',\r\n\t\tdiagonal: 'diagonal diag showDiagonal',\r\n\t\tupper: 'upper up top upperhalf upperHalf showupperhalf showUpper showUpperHalf',\r\n\t\tlower: 'lower low bottom lowerhalf lowerHalf showlowerhalf showLowerHalf showLower'\r\n\t})\r\n\r\n\t// we provide regl buffer per-trace, since trace data can be changed\r\n\tvar trace = (this.traces[i] || (this.traces[i] = {\r\n\t\tid: i,\r\n\t\tbuffer: regl.buffer({\r\n\t\t\tusage: 'dynamic',\r\n\t\t\ttype: 'float',\r\n\t\t\tdata: new Uint8Array()\r\n\t\t}),\r\n\t\tcolor: 'black',\r\n\t\tmarker: null,\r\n\t\tsize: 12,\r\n\t\tborderColor: 'transparent',\r\n\t\tborderSize: 1,\r\n\t\tviewport: rect([regl._gl.drawingBufferWidth, regl._gl.drawingBufferHeight]),\r\n\t\tpadding: [0, 0, 0, 0],\r\n\t\topacity: 1,\r\n\t\tdiagonal: true,\r\n\t\tupper: true,\r\n\t\tlower: true\r\n\t}))\r\n\r\n\r\n\t// save styles\r\n\tif (o.color != null) {\r\n\t\ttrace.color = o.color\r\n\t}\r\n\tif (o.size != null) {\r\n\t\ttrace.size = o.size\r\n\t}\r\n\tif (o.marker != null) {\r\n\t\ttrace.marker = o.marker\r\n\t}\r\n\tif (o.borderColor != null) {\r\n\t\ttrace.borderColor = o.borderColor\r\n\t}\r\n\tif (o.borderSize != null) {\r\n\t\ttrace.borderSize = o.borderSize\r\n\t}\r\n\tif (o.opacity != null) {\r\n\t\ttrace.opacity = o.opacity\r\n\t}\r\n\tif (o.viewport) {\r\n\t\ttrace.viewport = rect(o.viewport)\r\n\t}\r\n\tif (o.diagonal != null) { trace.diagonal = o.diagonal }\r\n\tif (o.upper != null) { trace.upper = o.upper }\r\n\tif (o.lower != null) { trace.lower = o.lower }\r\n\r\n\t// put flattened data into buffer\r\n\tif (o.data) {\r\n\t\ttrace.buffer(flatten(o.data))\r\n\t\ttrace.columns = o.data.length\r\n\t\ttrace.count = o.data[0].length\r\n\r\n\t\t// detect bounds per-column\r\n\t\ttrace.bounds = []\r\n\r\n\t\tfor (var i$1 = 0; i$1 < trace.columns; i$1++) {\r\n\t\t\ttrace.bounds[i$1] = getBounds(o.data[i$1], 1)\r\n\t\t}\r\n\t}\r\n\r\n\t// add proper range updating markers\r\n\tvar multirange\r\n\tif (o.range) {\r\n\t\ttrace.range = o.range\r\n\t\tmultirange = trace.range && typeof trace.range[0] !== 'number'\r\n\t}\r\n\r\n\tif (o.domain) {\r\n\t\ttrace.domain = o.domain\r\n\t}\r\n\tvar multipadding = false\r\n\tif (o.padding != null) {\r\n\t\t// multiple paddings\r\n\t\tif (Array.isArray(o.padding) && o.padding.length === trace.columns && typeof o.padding[o.padding.length - 1] === 'number') {\r\n\t\t\ttrace.padding = o.padding.map(getPad)\r\n\t\t\tmultipadding = true\r\n\t\t}\r\n\t\t// single padding\r\n\t\telse {\r\n\t\t\ttrace.padding = getPad(o.padding)\r\n\t\t}\r\n\t}\r\n\r\n\t// create passes\r\n\tvar m = trace.columns\r\n\tvar n = trace.count\r\n\r\n\tvar w = trace.viewport.width\r\n\tvar h = trace.viewport.height\r\n\tvar left = trace.viewport.x\r\n\tvar top = trace.viewport.y\r\n\tvar iw = w / m\r\n\tvar ih = h / m\r\n\r\n\ttrace.passes = []\r\n\r\n\tfor (var i$2 = 0; i$2 < m; i$2++) {\r\n\t\tfor (var j = 0; j < m; j++) {\r\n\t\t\tif (!trace.diagonal && j === i$2) { continue }\r\n\t\t\tif (!trace.upper && i$2 > j) { continue }\r\n\t\t\tif (!trace.lower && i$2 < j) { continue }\r\n\r\n\t\t\tvar key = passId(trace.id, i$2, j)\r\n\r\n\t\t\tvar pass = this.passes[key] || (this.passes[key] = {})\r\n\r\n\t\t\tif (o.data) {\r\n\t\t\t\tif (o.transpose) {\r\n\t\t\t\t\tpass.positions = {\r\n\t\t\t\t\t\tx: {buffer: trace.buffer, offset: j, count: n, stride: m},\r\n\t\t\t\t\t\ty: {buffer: trace.buffer, offset: i$2, count: n, stride: m}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\tpass.positions = {\r\n\t\t\t\t\t\tx: {buffer: trace.buffer, offset: j * n, count: n},\r\n\t\t\t\t\t\ty: {buffer: trace.buffer, offset: i$2 * n, count: n}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tpass.bounds = getBox(trace.bounds, i$2, j)\r\n\t\t\t}\r\n\r\n\t\t\tif (o.domain || o.viewport || o.data) {\r\n\t\t\t\tvar pad = multipadding ? getBox(trace.padding, i$2, j) : trace.padding\r\n\t\t\t\tif (trace.domain) {\r\n\t\t\t\t\tvar ref$1 = getBox(trace.domain, i$2, j);\n\t\t\t\t\tvar lox = ref$1[0];\n\t\t\t\t\tvar loy = ref$1[1];\n\t\t\t\t\tvar hix = ref$1[2];\n\t\t\t\t\tvar hiy = ref$1[3];\r\n\r\n\t\t\t\t\tpass.viewport = [\r\n\t\t\t\t\t\tleft + lox * w + pad[0],\r\n\t\t\t\t\t\ttop + loy * h + pad[1],\r\n\t\t\t\t\t\tleft + hix * w - pad[2],\r\n\t\t\t\t\t\ttop + hiy * h - pad[3]\r\n\t\t\t\t\t]\r\n\t\t\t\t}\r\n\t\t\t\t// consider auto-domain equipartial\r\n\t\t\t\telse {\r\n\t\t\t\t\tpass.viewport = [\r\n\t\t\t\t\t\tleft + j * iw + iw * pad[0],\r\n\t\t\t\t\t\ttop + i$2 * ih + ih * pad[1],\r\n\t\t\t\t\t\tleft + (j + 1) * iw - iw * pad[2],\r\n\t\t\t\t\t\ttop + (i$2 + 1) * ih - ih * pad[3]\r\n\t\t\t\t\t]\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (o.color) { pass.color = trace.color }\r\n\t\t\tif (o.size) { pass.size = trace.size }\r\n\t\t\tif (o.marker) { pass.marker = trace.marker }\r\n\t\t\tif (o.borderSize) { pass.borderSize = trace.borderSize }\r\n\t\t\tif (o.borderColor) { pass.borderColor = trace.borderColor }\r\n\t\t\tif (o.opacity) { pass.opacity = trace.opacity }\r\n\r\n\t\t\tif (o.range) {\r\n\t\t\t\tpass.range = multirange ? getBox(trace.range, i$2, j) : trace.range || pass.bounds\r\n\t\t\t}\r\n\r\n\t\t\ttrace.passes.push(key)\r\n\t\t}\r\n\t}\r\n\r\n\treturn this\r\n}\r\n\r\n\r\n// draw all or passed passes\r\nSPLOM.prototype.draw = function () {\n\tvar ref$2;\n\n\tvar args = [], len = arguments.length;\n\twhile ( len-- ) args[ len ] = arguments[ len ];\r\n\tif (!args.length) {\r\n\t\tthis.scatter.draw()\r\n\t}\r\n\telse {\r\n\t\tvar idx = []\r\n\t\tfor (var i = 0; i < args.length; i++) {\r\n\t\t\t// draw(0, 2, 5) - draw traces\r\n\t\t\tif (typeof args[i] === 'number' ) {\r\n\t\t\t\tvar ref = this.traces[args[i]];\n\t\t\t\tvar passes = ref.passes;\n\t\t\t\tvar passOffset = ref.passOffset;\r\n\t\t\t\tidx.push.apply(idx, arrRange(passOffset, passOffset + passes.length))\r\n\t\t\t}\r\n\t\t\t// draw([0, 1, 2 ...], [3, 4, 5]) - draw points\r\n\t\t\telse if (args[i].length) {\r\n\t\t\t\tvar els = args[i]\r\n\t\t\t\tvar ref$1 = this.traces[i];\n\t\t\t\tvar passes$1 = ref$1.passes;\n\t\t\t\tvar passOffset$1 = ref$1.passOffset;\r\n\t\t\t\tpasses$1 = passes$1.map(function (passId, i) {\r\n\t\t\t\t\tidx[passOffset$1 + i] = els\r\n\t\t\t\t})\r\n\t\t\t}\r\n\t\t}\r\n\t\t(ref$2 = this.scatter).draw.apply(ref$2, idx)\r\n\t}\r\n\r\n\treturn this\r\n}\r\n\r\n\r\n// dispose resources\r\nSPLOM.prototype.destroy = function () {\r\n\tthis.traces.forEach(function (trace) {\r\n\t\tif (trace.buffer && trace.buffer.destroy) { trace.buffer.destroy() }\r\n\t})\r\n\tthis.traces = null\r\n\tthis.passes = null\r\n\r\n\tthis.scatter.destroy()\r\n\r\n\treturn this\r\n}\r\n\r\n\r\n// return pass corresponding to trace i- j- square\r\nfunction passId (trace, i, j) {\r\n\tvar id = (trace.id != null ? trace.id : trace)\r\n\tvar n = i\r\n\tvar m = j\r\n\tvar key = id << 16 | (n & 0xff) << 8 | m & 0xff\r\n\r\n\treturn key\r\n}\r\n\r\n\r\n// return bounding box corresponding to a pass\r\nfunction getBox (items, i, j) {\r\n\tvar ilox, iloy, ihix, ihiy, jlox, jloy, jhix, jhiy\r\n\tvar iitem = items[i], jitem = items[j]\r\n\r\n\tif (iitem.length > 2) {\r\n\t\tilox = iitem[0]\r\n\t\tihix = iitem[2]\r\n\t\tiloy = iitem[1]\r\n\t\tihiy = iitem[3]\r\n\t}\r\n\telse if (iitem.length) {\r\n\t\tilox = iloy = iitem[0]\r\n\t\tihix = ihiy = iitem[1]\r\n\t}\r\n\telse {\r\n\t\tilox = iitem.x\r\n\t\tiloy = iitem.y\r\n\t\tihix = iitem.x + iitem.width\r\n\t\tihiy = iitem.y + iitem.height\r\n\t}\r\n\r\n\tif (jitem.length > 2) {\r\n\t\tjlox = jitem[0]\r\n\t\tjhix = jitem[2]\r\n\t\tjloy = jitem[1]\r\n\t\tjhiy = jitem[3]\r\n\t}\r\n\telse if (jitem.length) {\r\n\t\tjlox = jloy = jitem[0]\r\n\t\tjhix = jhiy = jitem[1]\r\n\t}\r\n\telse {\r\n\t\tjlox = jitem.x\r\n\t\tjloy = jitem.y\r\n\t\tjhix = jitem.x + jitem.width\r\n\t\tjhiy = jitem.y + jitem.height\r\n\t}\r\n\r\n\treturn [ jlox, iloy, jhix, ihiy ]\r\n}\r\n\r\n\r\nfunction getPad (arg) {\r\n\tif (typeof arg === 'number') { return [arg, arg, arg, arg] }\r\n\telse if (arg.length === 2) { return [arg[0], arg[1], arg[0], arg[1]] }\r\n\telse {\r\n\t\tvar box = rect(arg)\r\n\t\treturn [box.x, box.y, box.x + box.width, box.y + box.height]\r\n\t}\r\n}\r\n\r\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbIkY6L3NvdXJjZS92dWUtcGxvdGx5LmpzL25vZGVfbW9kdWxlcy9yZWdsLXNwbG9tL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0J1xyXG5cclxuXHJcbmNvbnN0IGNyZWF0ZVNjYXR0ZXIgPSByZXF1aXJlKCdyZWdsLXNjYXR0ZXIyZCcpXHJcbmNvbnN0IHBpY2sgPSByZXF1aXJlKCdwaWNrLWJ5LWFsaWFzJylcclxuY29uc3QgZ2V0Qm91bmRzID0gcmVxdWlyZSgnYXJyYXktYm91bmRzJylcclxuY29uc3QgcmFmID0gcmVxdWlyZSgncmFmJylcclxuY29uc3QgYXJyUmFuZ2UgPSByZXF1aXJlKCdhcnJheS1yYW5nZScpXHJcbmNvbnN0IHJlY3QgPSByZXF1aXJlKCdwYXJzZS1yZWN0JylcclxuY29uc3QgZmxhdHRlbiA9IHJlcXVpcmUoJ2ZsYXR0ZW4tdmVydGV4LWRhdGEnKVxyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gU1BMT01cclxuXHJcblxyXG4vLyBAY29uc3RydWN0b3JcclxuZnVuY3Rpb24gU1BMT00gKHJlZ2wsIG9wdGlvbnMpIHtcclxuXHRpZiAoISh0aGlzIGluc3RhbmNlb2YgU1BMT00pKSByZXR1cm4gbmV3IFNQTE9NKHJlZ2wsIG9wdGlvbnMpXHJcblxyXG5cdC8vIHJlbmRlciBwYXNzZXNcclxuXHR0aGlzLnRyYWNlcyA9IFtdXHJcblxyXG5cdC8vIHBhc3NlcyBmb3Igc2NhdHRlciwgY29tYmluZWQgYWNyb3NzIHRyYWNlc1xyXG5cdHRoaXMucGFzc2VzID0ge31cclxuXHJcblx0dGhpcy5yZWdsID0gcmVnbFxyXG5cclxuXHQvLyBtYWluIHNjYXR0ZXIgZHJhd2luZyBpbnN0YW5jZVxyXG5cdHRoaXMuc2NhdHRlciA9IGNyZWF0ZVNjYXR0ZXIocmVnbClcclxuXHJcblx0dGhpcy5jYW52YXMgPSB0aGlzLnNjYXR0ZXIuY2FudmFzXHJcbn1cclxuXHJcblxyXG4vLyB1cGRhdGUgJiBkcmF3IHBhc3NlcyBvbmNlIHBlciBmcmFtZVxyXG5TUExPTS5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKC4uLmFyZ3MpIHtcclxuXHRpZiAoYXJncy5sZW5ndGgpIHtcclxuXHRcdHRoaXMudXBkYXRlKC4uLmFyZ3MpXHJcblx0fVxyXG5cclxuXHRpZiAodGhpcy5yZWdsLmF0dHJpYnV0ZXMucHJlc2VydmVEcmF3aW5nQnVmZmVyKSByZXR1cm4gdGhpcy5kcmF3KClcclxuXHJcblx0Ly8gbWFrZSBzdXJlIGRyYXcgaXMgbm90IGNhbGxlZCBtb3JlIG9mdGVuIHRoYW4gb25jZSBhIGZyYW1lXHJcblx0aWYgKHRoaXMuZGlydHkpIHtcclxuXHRcdGlmICh0aGlzLnBsYW5uZWQgPT0gbnVsbCkge1xyXG5cdFx0XHR0aGlzLnBsYW5uZWQgPSByYWYoKCkgPT4ge1xyXG5cdFx0XHRcdHRoaXMuZHJhdygpXHJcblx0XHRcdFx0dGhpcy5kaXJ0eSA9IHRydWVcclxuXHRcdFx0XHR0aGlzLnBsYW5uZWQgPSBudWxsXHJcblx0XHRcdH0pXHJcblx0XHR9XHJcblx0fVxyXG5cdGVsc2Uge1xyXG5cdFx0dGhpcy5kcmF3KClcclxuXHRcdHRoaXMuZGlydHkgPSB0cnVlXHJcblx0XHRyYWYoKCkgPT4ge1xyXG5cdFx0XHR0aGlzLmRpcnR5ID0gZmFsc2VcclxuXHRcdH0pXHJcblx0fVxyXG5cclxuXHRyZXR1cm4gdGhpc1xyXG59XHJcblxyXG5cclxuLy8gdXBkYXRlIHBhc3Nlc1xyXG5TUExPTS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKC4uLmFyZ3MpIHtcclxuXHRpZiAoIWFyZ3MubGVuZ3RoKSByZXR1cm5cclxuXHJcblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XHJcblx0XHR0aGlzLnVwZGF0ZUl0ZW0oaSwgYXJnc1tpXSlcclxuXHR9XHJcblxyXG5cdC8vIHJlbW92ZSBudWxsZWQgcGFzc2VzXHJcblx0dGhpcy50cmFjZXMgPSB0aGlzLnRyYWNlcy5maWx0ZXIoQm9vbGVhbilcclxuXHJcblx0Ly8gRklYTUU6IHVwZGF0ZSBwYXNzZXMgaW5kZXBlbmRlbnRseVxyXG5cdGxldCBwYXNzZXMgPSBbXVxyXG5cdGxldCBvZmZzZXQgPSAwXHJcblx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnRyYWNlcy5sZW5ndGg7IGkrKykge1xyXG5cdFx0bGV0IHRyYWNlID0gdGhpcy50cmFjZXNbaV1cclxuXHRcdGxldCB0cmFjZVBhc3NlcyA9IHRoaXMudHJhY2VzW2ldLnBhc3Nlc1xyXG5cdFx0Zm9yIChsZXQgaiA9IDA7IGogPCB0cmFjZVBhc3Nlcy5sZW5ndGg7IGorKykge1xyXG5cdFx0XHRwYXNzZXMucHVzaCh0aGlzLnBhc3Nlc1t0cmFjZVBhc3Nlc1tqXV0pXHJcblx0XHR9XHJcblx0XHQvLyBzYXZlIG9mZnNldCBvZiBwYXNzZXNcclxuXHRcdHRyYWNlLnBhc3NPZmZzZXQgPSBvZmZzZXRcclxuXHRcdG9mZnNldCArPSB0cmFjZS5wYXNzZXMubGVuZ3RoXHJcblx0fVxyXG5cclxuXHR0aGlzLnNjYXR0ZXIudXBkYXRlKC4uLnBhc3NlcylcclxuXHJcblx0cmV0dXJuIHRoaXNcclxufVxyXG5cclxuXHJcbi8vIHVwZGF0ZSB0cmFjZSBieSBpbmRleCwgbm90IHN1cHBvc2VkIHRvIGJlIGNhbGxlZCBkaXJlY3RseVxyXG5TUExPTS5wcm90b3R5cGUudXBkYXRlSXRlbSA9IGZ1bmN0aW9uIChpLCBvcHRpb25zKSB7XHJcblx0bGV0IHsgcmVnbCB9ID0gdGhpc1xyXG5cclxuXHQvLyByZW1vdmUgcGFzcyBpZiBudWxsXHJcblx0aWYgKG9wdGlvbnMgPT09IG51bGwpIHtcclxuXHRcdHRoaXMudHJhY2VzW2ldID0gbnVsbFxyXG5cdFx0cmV0dXJuIHRoaXNcclxuXHR9XHJcblxyXG5cdGlmICghb3B0aW9ucykgcmV0dXJuIHRoaXNcclxuXHJcblx0bGV0IG8gPSBwaWNrKG9wdGlvbnMsIHtcclxuXHRcdGRhdGE6ICdkYXRhIGl0ZW1zIGNvbHVtbnMgcm93cyB2YWx1ZXMgZGltZW5zaW9ucyBzYW1wbGVzIHgnLFxyXG5cdFx0c25hcDogJ3NuYXAgY2x1c3RlcicsXHJcblx0XHRzaXplOiAnc2l6ZXMgc2l6ZSByYWRpdXMnLFxyXG5cdFx0Y29sb3I6ICdjb2xvcnMgY29sb3IgZmlsbCBmaWxsLWNvbG9yIGZpbGxDb2xvcicsXHJcblx0XHRvcGFjaXR5OiAnb3BhY2l0eSBhbHBoYSB0cmFuc3BhcmVuY3kgb3BhcXVlJyxcclxuXHRcdGJvcmRlclNpemU6ICdib3JkZXJTaXplcyBib3JkZXJTaXplIGJvcmRlci1zaXplIGJvcmRlcnNpemUgYm9yZGVyV2lkdGggYm9yZGVyV2lkdGhzIGJvcmRlci13aWR0aCBib3JkZXJ3aWR0aCBzdHJva2Utd2lkdGggc3Ryb2tlV2lkdGggc3Ryb2tld2lkdGggb3V0bGluZScsXHJcblx0XHRib3JkZXJDb2xvcjogJ2JvcmRlckNvbG9ycyBib3JkZXJDb2xvciBib3JkZXJjb2xvciBzdHJva2Ugc3Ryb2tlLWNvbG9yIHN0cm9rZUNvbG9yJyxcclxuXHRcdG1hcmtlcjogJ21hcmtlcnMgbWFya2VyIHNoYXBlJyxcclxuXHRcdHJhbmdlOiAncmFuZ2UgcmFuZ2VzIGRhdGFib3ggZGF0YUJveCcsXHJcblx0XHR2aWV3cG9ydDogJ3ZpZXdwb3J0IHZpZXdCb3ggdmlld2JveCcsXHJcblx0XHRkb21haW46ICdkb21haW4gZG9tYWlucyBhcmVhIGFyZWFzJyxcclxuXHRcdHBhZGRpbmc6ICdwYWQgcGFkZGluZyBwYWRkaW5ncyBwYWRzIG1hcmdpbiBtYXJnaW5zJyxcclxuXHRcdHRyYW5zcG9zZTogJ3RyYW5zcG9zZSB0cmFuc3Bvc2VkJyxcclxuXHRcdGRpYWdvbmFsOiAnZGlhZ29uYWwgZGlhZyBzaG93RGlhZ29uYWwnLFxyXG5cdFx0dXBwZXI6ICd1cHBlciB1cCB0b3AgdXBwZXJoYWxmIHVwcGVySGFsZiBzaG93dXBwZXJoYWxmIHNob3dVcHBlciBzaG93VXBwZXJIYWxmJyxcclxuXHRcdGxvd2VyOiAnbG93ZXIgbG93IGJvdHRvbSBsb3dlcmhhbGYgbG93ZXJIYWxmIHNob3dsb3dlcmhhbGYgc2hvd0xvd2VySGFsZiBzaG93TG93ZXInXHJcblx0fSlcclxuXHJcblx0Ly8gd2UgcHJvdmlkZSByZWdsIGJ1ZmZlciBwZXItdHJhY2UsIHNpbmNlIHRyYWNlIGRhdGEgY2FuIGJlIGNoYW5nZWRcclxuXHRsZXQgdHJhY2UgPSAodGhpcy50cmFjZXNbaV0gfHwgKHRoaXMudHJhY2VzW2ldID0ge1xyXG5cdFx0aWQ6IGksXHJcblx0XHRidWZmZXI6IHJlZ2wuYnVmZmVyKHtcclxuXHRcdFx0dXNhZ2U6ICdkeW5hbWljJyxcclxuXHRcdFx0dHlwZTogJ2Zsb2F0JyxcclxuXHRcdFx0ZGF0YTogbmV3IFVpbnQ4QXJyYXkoKVxyXG5cdFx0fSksXHJcblx0XHRjb2xvcjogJ2JsYWNrJyxcclxuXHRcdG1hcmtlcjogbnVsbCxcclxuXHRcdHNpemU6IDEyLFxyXG5cdFx0Ym9yZGVyQ29sb3I6ICd0cmFuc3BhcmVudCcsXHJcblx0XHRib3JkZXJTaXplOiAxLFxyXG5cdFx0dmlld3BvcnQ6ICByZWN0KFtyZWdsLl9nbC5kcmF3aW5nQnVmZmVyV2lkdGgsIHJlZ2wuX2dsLmRyYXdpbmdCdWZmZXJIZWlnaHRdKSxcclxuXHRcdHBhZGRpbmc6IFswLCAwLCAwLCAwXSxcclxuXHRcdG9wYWNpdHk6IDEsXHJcblx0XHRkaWFnb25hbDogdHJ1ZSxcclxuXHRcdHVwcGVyOiB0cnVlLFxyXG5cdFx0bG93ZXI6IHRydWVcclxuXHR9KSlcclxuXHJcblxyXG5cdC8vIHNhdmUgc3R5bGVzXHJcblx0aWYgKG8uY29sb3IgIT0gbnVsbCkge1xyXG5cdFx0dHJhY2UuY29sb3IgPSBvLmNvbG9yXHJcblx0fVxyXG5cdGlmIChvLnNpemUgIT0gbnVsbCkge1xyXG5cdFx0dHJhY2Uuc2l6ZSA9IG8uc2l6ZVxyXG5cdH1cclxuXHRpZiAoby5tYXJrZXIgIT0gbnVsbCkge1xyXG5cdFx0dHJhY2UubWFya2VyID0gby5tYXJrZXJcclxuXHR9XHJcblx0aWYgKG8uYm9yZGVyQ29sb3IgIT0gbnVsbCkge1xyXG5cdFx0dHJhY2UuYm9yZGVyQ29sb3IgPSBvLmJvcmRlckNvbG9yXHJcblx0fVxyXG5cdGlmIChvLmJvcmRlclNpemUgIT0gbnVsbCkge1xyXG5cdFx0dHJhY2UuYm9yZGVyU2l6ZSA9IG8uYm9yZGVyU2l6ZVxyXG5cdH1cclxuXHRpZiAoby5vcGFjaXR5ICE9IG51bGwpIHtcclxuXHRcdHRyYWNlLm9wYWNpdHkgPSBvLm9wYWNpdHlcclxuXHR9XHJcblx0aWYgKG8udmlld3BvcnQpIHtcclxuXHRcdHRyYWNlLnZpZXdwb3J0ID0gcmVjdChvLnZpZXdwb3J0KVxyXG5cdH1cclxuXHRpZiAoby5kaWFnb25hbCAhPSBudWxsKSB0cmFjZS5kaWFnb25hbCA9IG8uZGlhZ29uYWxcclxuXHRpZiAoby51cHBlciAhPSBudWxsKSB0cmFjZS51cHBlciA9IG8udXBwZXJcclxuXHRpZiAoby5sb3dlciAhPSBudWxsKSB0cmFjZS5sb3dlciA9IG8ubG93ZXJcclxuXHJcblx0Ly8gcHV0IGZsYXR0ZW5lZCBkYXRhIGludG8gYnVmZmVyXHJcblx0aWYgKG8uZGF0YSkge1xyXG5cdFx0dHJhY2UuYnVmZmVyKGZsYXR0ZW4oby5kYXRhKSlcclxuXHRcdHRyYWNlLmNvbHVtbnMgPSBvLmRhdGEubGVuZ3RoXHJcblx0XHR0cmFjZS5jb3VudCA9IG8uZGF0YVswXS5sZW5ndGhcclxuXHJcblx0XHQvLyBkZXRlY3QgYm91bmRzIHBlci1jb2x1bW5cclxuXHRcdHRyYWNlLmJvdW5kcyA9IFtdXHJcblxyXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0cmFjZS5jb2x1bW5zOyBpKyspIHtcclxuXHRcdFx0dHJhY2UuYm91bmRzW2ldID0gZ2V0Qm91bmRzKG8uZGF0YVtpXSwgMSlcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8vIGFkZCBwcm9wZXIgcmFuZ2UgdXBkYXRpbmcgbWFya2Vyc1xyXG5cdGxldCBtdWx0aXJhbmdlXHJcblx0aWYgKG8ucmFuZ2UpIHtcclxuXHRcdHRyYWNlLnJhbmdlID0gby5yYW5nZVxyXG5cdFx0bXVsdGlyYW5nZSA9IHRyYWNlLnJhbmdlICYmIHR5cGVvZiB0cmFjZS5yYW5nZVswXSAhPT0gJ251bWJlcidcclxuXHR9XHJcblxyXG5cdGlmIChvLmRvbWFpbikge1xyXG5cdFx0dHJhY2UuZG9tYWluID0gby5kb21haW5cclxuXHR9XHJcblx0bGV0IG11bHRpcGFkZGluZyA9IGZhbHNlXHJcblx0aWYgKG8ucGFkZGluZyAhPSBudWxsKSB7XHJcblx0XHQvLyBtdWx0aXBsZSBwYWRkaW5nc1xyXG5cdFx0aWYgKEFycmF5LmlzQXJyYXkoby5wYWRkaW5nKSAmJiBvLnBhZGRpbmcubGVuZ3RoID09PSB0cmFjZS5jb2x1bW5zICYmIHR5cGVvZiBvLnBhZGRpbmdbby5wYWRkaW5nLmxlbmd0aCAtIDFdID09PSAnbnVtYmVyJykge1xyXG5cdFx0XHR0cmFjZS5wYWRkaW5nID0gby5wYWRkaW5nLm1hcChnZXRQYWQpXHJcblx0XHRcdG11bHRpcGFkZGluZyA9IHRydWVcclxuXHRcdH1cclxuXHRcdC8vIHNpbmdsZSBwYWRkaW5nXHJcblx0XHRlbHNlIHtcclxuXHRcdFx0dHJhY2UucGFkZGluZyA9IGdldFBhZChvLnBhZGRpbmcpXHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyBjcmVhdGUgcGFzc2VzXHJcblx0bGV0IG0gPSB0cmFjZS5jb2x1bW5zXHJcblx0bGV0IG4gPSB0cmFjZS5jb3VudFxyXG5cclxuXHRsZXQgdyA9IHRyYWNlLnZpZXdwb3J0LndpZHRoXHJcblx0bGV0IGggPSB0cmFjZS52aWV3cG9ydC5oZWlnaHRcclxuXHRsZXQgbGVmdCA9IHRyYWNlLnZpZXdwb3J0LnhcclxuXHRsZXQgdG9wID0gdHJhY2Uudmlld3BvcnQueVxyXG5cdGxldCBpdyA9IHcgLyBtXHJcblx0bGV0IGloID0gaCAvIG1cclxuXHJcblx0dHJhY2UucGFzc2VzID0gW11cclxuXHJcblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBtOyBpKyspIHtcclxuXHRcdGZvciAobGV0IGogPSAwOyBqIDwgbTsgaisrKSB7XHJcblx0XHRcdGlmICghdHJhY2UuZGlhZ29uYWwgJiYgaiA9PT0gaSkgY29udGludWVcclxuXHRcdFx0aWYgKCF0cmFjZS51cHBlciAmJiBpID4gaikgY29udGludWVcclxuXHRcdFx0aWYgKCF0cmFjZS5sb3dlciAmJiBpIDwgaikgY29udGludWVcclxuXHJcblx0XHRcdGxldCBrZXkgPSBwYXNzSWQodHJhY2UuaWQsIGksIGopXHJcblxyXG5cdFx0XHRsZXQgcGFzcyA9IHRoaXMucGFzc2VzW2tleV0gfHwgKHRoaXMucGFzc2VzW2tleV0gPSB7fSlcclxuXHJcblx0XHRcdGlmIChvLmRhdGEpIHtcclxuXHRcdFx0XHRpZiAoby50cmFuc3Bvc2UpIHtcclxuXHRcdFx0XHRcdHBhc3MucG9zaXRpb25zID0ge1xyXG5cdFx0XHRcdFx0XHR4OiB7YnVmZmVyOiB0cmFjZS5idWZmZXIsIG9mZnNldDogaiwgY291bnQ6IG4sIHN0cmlkZTogbX0sXHJcblx0XHRcdFx0XHRcdHk6IHtidWZmZXI6IHRyYWNlLmJ1ZmZlciwgb2Zmc2V0OiBpLCBjb3VudDogbiwgc3RyaWRlOiBtfVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRlbHNlIHtcclxuXHRcdFx0XHRcdHBhc3MucG9zaXRpb25zID0ge1xyXG5cdFx0XHRcdFx0XHR4OiB7YnVmZmVyOiB0cmFjZS5idWZmZXIsIG9mZnNldDogaiAqIG4sIGNvdW50OiBufSxcclxuXHRcdFx0XHRcdFx0eToge2J1ZmZlcjogdHJhY2UuYnVmZmVyLCBvZmZzZXQ6IGkgKiBuLCBjb3VudDogbn1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdHBhc3MuYm91bmRzID0gZ2V0Qm94KHRyYWNlLmJvdW5kcywgaSwgailcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKG8uZG9tYWluIHx8IG8udmlld3BvcnQgfHwgby5kYXRhKSB7XHJcblx0XHRcdFx0bGV0IHBhZCA9IG11bHRpcGFkZGluZyA/IGdldEJveCh0cmFjZS5wYWRkaW5nLCBpLCBqKSA6IHRyYWNlLnBhZGRpbmdcclxuXHRcdFx0XHRpZiAodHJhY2UuZG9tYWluKSB7XHJcblx0XHRcdFx0XHRsZXQgW2xveCwgbG95LCBoaXgsIGhpeV0gPSBnZXRCb3godHJhY2UuZG9tYWluLCBpLCBqKVxyXG5cclxuXHRcdFx0XHRcdHBhc3Mudmlld3BvcnQgPSBbXHJcblx0XHRcdFx0XHRcdGxlZnQgKyBsb3ggKiB3ICsgcGFkWzBdLFxyXG5cdFx0XHRcdFx0XHR0b3AgKyBsb3kgKiBoICsgcGFkWzFdLFxyXG5cdFx0XHRcdFx0XHRsZWZ0ICsgaGl4ICogdyAtIHBhZFsyXSxcclxuXHRcdFx0XHRcdFx0dG9wICsgaGl5ICogaCAtIHBhZFszXVxyXG5cdFx0XHRcdFx0XVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHQvLyBjb25zaWRlciBhdXRvLWRvbWFpbiBlcXVpcGFydGlhbFxyXG5cdFx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdFx0cGFzcy52aWV3cG9ydCA9IFtcclxuXHRcdFx0XHRcdFx0bGVmdCArIGogKiBpdyArIGl3ICogcGFkWzBdLFxyXG5cdFx0XHRcdFx0XHR0b3AgKyBpICogaWggKyBpaCAqIHBhZFsxXSxcclxuXHRcdFx0XHRcdFx0bGVmdCArIChqICsgMSkgKiBpdyAtIGl3ICogcGFkWzJdLFxyXG5cdFx0XHRcdFx0XHR0b3AgKyAoaSArIDEpICogaWggLSBpaCAqIHBhZFszXVxyXG5cdFx0XHRcdFx0XVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKG8uY29sb3IpIHBhc3MuY29sb3IgPSB0cmFjZS5jb2xvclxyXG5cdFx0XHRpZiAoby5zaXplKSBwYXNzLnNpemUgPSB0cmFjZS5zaXplXHJcblx0XHRcdGlmIChvLm1hcmtlcikgcGFzcy5tYXJrZXIgPSB0cmFjZS5tYXJrZXJcclxuXHRcdFx0aWYgKG8uYm9yZGVyU2l6ZSkgcGFzcy5ib3JkZXJTaXplID0gdHJhY2UuYm9yZGVyU2l6ZVxyXG5cdFx0XHRpZiAoby5ib3JkZXJDb2xvcikgcGFzcy5ib3JkZXJDb2xvciA9IHRyYWNlLmJvcmRlckNvbG9yXHJcblx0XHRcdGlmIChvLm9wYWNpdHkpIHBhc3Mub3BhY2l0eSA9IHRyYWNlLm9wYWNpdHlcclxuXHJcblx0XHRcdGlmIChvLnJhbmdlKSB7XHJcblx0XHRcdFx0cGFzcy5yYW5nZSA9IG11bHRpcmFuZ2UgPyBnZXRCb3godHJhY2UucmFuZ2UsIGksIGopIDogdHJhY2UucmFuZ2UgfHwgcGFzcy5ib3VuZHNcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0dHJhY2UucGFzc2VzLnB1c2goa2V5KVxyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIHRoaXNcclxufVxyXG5cclxuXHJcbi8vIGRyYXcgYWxsIG9yIHBhc3NlZCBwYXNzZXNcclxuU1BMT00ucHJvdG90eXBlLmRyYXcgPSBmdW5jdGlvbiAoLi4uYXJncykge1xyXG5cdGlmICghYXJncy5sZW5ndGgpIHtcclxuXHRcdHRoaXMuc2NhdHRlci5kcmF3KClcclxuXHR9XHJcblx0ZWxzZSB7XHJcblx0XHRsZXQgaWR4ID0gW11cclxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHQvLyBkcmF3KDAsIDIsIDUpIC0gZHJhdyB0cmFjZXNcclxuXHRcdFx0aWYgKHR5cGVvZiBhcmdzW2ldID09PSAnbnVtYmVyJyApIHtcclxuXHRcdFx0XHRsZXQgeyBwYXNzZXMsIHBhc3NPZmZzZXQgfSA9IHRoaXMudHJhY2VzW2FyZ3NbaV1dXHJcblx0XHRcdFx0aWR4LnB1c2goLi4uYXJyUmFuZ2UocGFzc09mZnNldCwgcGFzc09mZnNldCArIHBhc3Nlcy5sZW5ndGgpKVxyXG5cdFx0XHR9XHJcblx0XHRcdC8vIGRyYXcoWzAsIDEsIDIgLi4uXSwgWzMsIDQsIDVdKSAtIGRyYXcgcG9pbnRzXHJcblx0XHRcdGVsc2UgaWYgKGFyZ3NbaV0ubGVuZ3RoKSB7XHJcblx0XHRcdFx0bGV0IGVscyA9IGFyZ3NbaV1cclxuXHRcdFx0XHRsZXQgeyBwYXNzZXMsIHBhc3NPZmZzZXQgfSA9IHRoaXMudHJhY2VzW2ldXHJcblx0XHRcdFx0cGFzc2VzID0gcGFzc2VzLm1hcCgocGFzc0lkLCBpKSA9PiB7XHJcblx0XHRcdFx0XHRpZHhbcGFzc09mZnNldCArIGldID0gZWxzXHJcblx0XHRcdFx0fSlcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0dGhpcy5zY2F0dGVyLmRyYXcoLi4uaWR4KVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIHRoaXNcclxufVxyXG5cclxuXHJcbi8vIGRpc3Bvc2UgcmVzb3VyY2VzXHJcblNQTE9NLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xyXG5cdHRoaXMudHJhY2VzLmZvckVhY2godHJhY2UgPT4ge1xyXG5cdFx0aWYgKHRyYWNlLmJ1ZmZlciAmJiB0cmFjZS5idWZmZXIuZGVzdHJveSkgdHJhY2UuYnVmZmVyLmRlc3Ryb3koKVxyXG5cdH0pXHJcblx0dGhpcy50cmFjZXMgPSBudWxsXHJcblx0dGhpcy5wYXNzZXMgPSBudWxsXHJcblxyXG5cdHRoaXMuc2NhdHRlci5kZXN0cm95KClcclxuXHJcblx0cmV0dXJuIHRoaXNcclxufVxyXG5cclxuXHJcbi8vIHJldHVybiBwYXNzIGNvcnJlc3BvbmRpbmcgdG8gdHJhY2UgaS0gai0gc3F1YXJlXHJcbmZ1bmN0aW9uIHBhc3NJZCAodHJhY2UsIGksIGopIHtcclxuXHRsZXQgaWQgPSAodHJhY2UuaWQgIT0gbnVsbCA/IHRyYWNlLmlkIDogdHJhY2UpXHJcblx0bGV0IG4gPSBpXHJcblx0bGV0IG0gPSBqXHJcblx0bGV0IGtleSA9IGlkIDw8IDE2IHwgKG4gJiAweGZmKSA8PCA4IHwgbSAmIDB4ZmZcclxuXHJcblx0cmV0dXJuIGtleVxyXG59XHJcblxyXG5cclxuLy8gcmV0dXJuIGJvdW5kaW5nIGJveCBjb3JyZXNwb25kaW5nIHRvIGEgcGFzc1xyXG5mdW5jdGlvbiBnZXRCb3ggKGl0ZW1zLCBpLCBqKSB7XHJcblx0bGV0IGlsb3gsIGlsb3ksIGloaXgsIGloaXksIGpsb3gsIGpsb3ksIGpoaXgsIGpoaXlcclxuXHRsZXQgaWl0ZW0gPSBpdGVtc1tpXSwgaml0ZW0gPSBpdGVtc1tqXVxyXG5cclxuXHRpZiAoaWl0ZW0ubGVuZ3RoID4gMikge1xyXG5cdFx0aWxveCA9IGlpdGVtWzBdXHJcblx0XHRpaGl4ID0gaWl0ZW1bMl1cclxuXHRcdGlsb3kgPSBpaXRlbVsxXVxyXG5cdFx0aWhpeSA9IGlpdGVtWzNdXHJcblx0fVxyXG5cdGVsc2UgaWYgKGlpdGVtLmxlbmd0aCkge1xyXG5cdFx0aWxveCA9IGlsb3kgPSBpaXRlbVswXVxyXG5cdFx0aWhpeCA9IGloaXkgPSBpaXRlbVsxXVxyXG5cdH1cclxuXHRlbHNlIHtcclxuXHRcdGlsb3ggPSBpaXRlbS54XHJcblx0XHRpbG95ID0gaWl0ZW0ueVxyXG5cdFx0aWhpeCA9IGlpdGVtLnggKyBpaXRlbS53aWR0aFxyXG5cdFx0aWhpeSA9IGlpdGVtLnkgKyBpaXRlbS5oZWlnaHRcclxuXHR9XHJcblxyXG5cdGlmIChqaXRlbS5sZW5ndGggPiAyKSB7XHJcblx0XHRqbG94ID0gaml0ZW1bMF1cclxuXHRcdGpoaXggPSBqaXRlbVsyXVxyXG5cdFx0amxveSA9IGppdGVtWzFdXHJcblx0XHRqaGl5ID0gaml0ZW1bM11cclxuXHR9XHJcblx0ZWxzZSBpZiAoaml0ZW0ubGVuZ3RoKSB7XHJcblx0XHRqbG94ID0gamxveSA9IGppdGVtWzBdXHJcblx0XHRqaGl4ID0gamhpeSA9IGppdGVtWzFdXHJcblx0fVxyXG5cdGVsc2Uge1xyXG5cdFx0amxveCA9IGppdGVtLnhcclxuXHRcdGpsb3kgPSBqaXRlbS55XHJcblx0XHRqaGl4ID0gaml0ZW0ueCArIGppdGVtLndpZHRoXHJcblx0XHRqaGl5ID0gaml0ZW0ueSArIGppdGVtLmhlaWdodFxyXG5cdH1cclxuXHJcblx0cmV0dXJuIFsgamxveCwgaWxveSwgamhpeCwgaWhpeSBdXHJcbn1cclxuXHJcblxyXG5mdW5jdGlvbiBnZXRQYWQgKGFyZykge1xyXG5cdGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykgcmV0dXJuIFthcmcsIGFyZywgYXJnLCBhcmddXHJcblx0ZWxzZSBpZiAoYXJnLmxlbmd0aCA9PT0gMikgcmV0dXJuIFthcmdbMF0sIGFyZ1sxXSwgYXJnWzBdLCBhcmdbMV1dXHJcblx0ZWxzZSB7XHJcblx0XHRsZXQgYm94ID0gcmVjdChhcmcpXHJcblx0XHRyZXR1cm4gW2JveC54LCBib3gueSwgYm94LnggKyBib3gud2lkdGgsIGJveC55ICsgYm94LmhlaWdodF1cclxuXHR9XHJcbn1cclxuIl0sIm5hbWVzIjpbImNvbnN0IiwidGhpcyIsImkiLCJsZXQiLCJwYXNzZXMiLCJwYXNzT2Zmc2V0Il0sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBQ1o7QUFDQTtBQUNBQSxHQUFLLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQztBQUMvQ0EsR0FBSyxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO0FBQ3JDQSxHQUFLLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxjQUFjLENBQUM7QUFDekNBLEdBQUssQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztBQUMxQkEsR0FBSyxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDO0FBQ3ZDQSxHQUFLLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUM7QUFDbENBLEdBQUssQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLHFCQUFxQixDQUFDO0FBQzlDO0FBQ0E7QUFDQSxNQUFNLENBQUMsT0FBTyxHQUFHLEtBQUs7QUFDdEI7QUFDQTtBQUNBO0FBQ0EsU0FBUyxLQUFLLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRTtBQUMvQixDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksWUFBWSxLQUFLLENBQUMsSUFBRSxPQUFPLElBQUksS0FBSyxDQUFDLElBQUksRUFBRSxPQUFPLEdBQUM7QUFDOUQ7QUFDQTtBQUNBLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFO0FBQ2pCO0FBQ0E7QUFDQSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRTtBQUNqQjtBQUNBLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJO0FBQ2pCO0FBQ0E7QUFDQSxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsYUFBYSxDQUFDLElBQUksQ0FBQztBQUNuQztBQUNBLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU07QUFDbEMsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLFVBQWlCLEVBQUU7Ozs7O2dEQUFDO0FBQzdDLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO0FBQ2xCLFNBQUUsS0FBSSxDQUFDLFlBQU0sTUFBSSxJQUFJLENBQUM7QUFDdEIsRUFBRTtBQUNGO0FBQ0EsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLHFCQUFxQixJQUFFLE9BQU8sSUFBSSxDQUFDLElBQUksSUFBRTtBQUNuRTtBQUNBO0FBQ0EsQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7QUFDakIsRUFBRSxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxFQUFFO0FBQzVCLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxHQUFHLFVBQUMsR0FBTTtBQUM1QixJQUFJQyxNQUFJLENBQUMsSUFBSSxFQUFFO0FBQ2YsSUFBSUEsTUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJO0FBQ3JCLElBQUlBLE1BQUksQ0FBQyxPQUFPLEdBQUcsSUFBSTtBQUN2QixJQUFJLENBQUM7QUFDTCxHQUFHO0FBQ0gsRUFBRTtBQUNGLE1BQU07QUFDTixFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUU7QUFDYixFQUFFLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSTtBQUNuQixFQUFFLEdBQUcsVUFBQyxHQUFNO0FBQ1osR0FBR0EsTUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLO0FBQ3JCLEdBQUcsQ0FBQztBQUNKLEVBQUU7QUFDRjtBQUNBLENBQUMsT0FBTyxJQUFJO0FBQ1osQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLFVBQWlCLEVBQUU7Ozs7Z0RBQUM7QUFDN0MsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBRSxRQUFNO0FBQ3pCO0FBQ0EsQ0FBQyxLQUFLRSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUN2QyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3QixFQUFFO0FBQ0Y7QUFDQTtBQUNBLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUM7QUFDMUM7QUFDQTtBQUNBLENBQUNBLEdBQUcsQ0FBQyxNQUFNLEdBQUcsRUFBRTtBQUNoQixDQUFDQSxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUM7QUFDZixDQUFDLEtBQUtBLEdBQUcsQ0FBQ0QsR0FBQyxHQUFHLENBQUMsRUFBRUEsR0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFQSxHQUFDLEVBQUUsRUFBRTtBQUM5QyxFQUFFQyxHQUFHLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUNELEdBQUMsQ0FBQztBQUM1QixFQUFFQyxHQUFHLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUNELEdBQUMsQ0FBQyxDQUFDLE1BQU07QUFDekMsRUFBRSxLQUFLQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUMvQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMzQyxHQUFHO0FBQ0g7QUFDQSxFQUFFLEtBQUssQ0FBQyxVQUFVLEdBQUcsTUFBTTtBQUMzQixFQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU07QUFDL0IsRUFBRTtBQUNGO0FBQ0EsUUFBQyxJQUFJLENBQUMsUUFBTyxDQUFDLFlBQU0sTUFBSSxNQUFNLENBQUM7QUFDL0I7QUFDQSxDQUFDLE9BQU8sSUFBSTtBQUNaLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQSxLQUFLLENBQUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUMsRUFBRSxPQUFPLEVBQUU7QUFDbkQsUUFBYSxHQUFHO0NBQVQsb0JBQWE7QUFDcEI7QUFDQTtBQUNBLENBQUMsSUFBSSxPQUFPLEtBQUssSUFBSSxFQUFFO0FBQ3ZCLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJO0FBQ3ZCLEVBQUUsT0FBTyxJQUFJO0FBQ2IsRUFBRTtBQUNGO0FBQ0EsQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFFLE9BQU8sTUFBSTtBQUMxQjtBQUNBLENBQUNBLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRTtBQUN2QixFQUFFLElBQUksRUFBRSxxREFBcUQ7QUFDN0QsRUFBRSxJQUFJLEVBQUUsY0FBYztBQUN0QixFQUFFLElBQUksRUFBRSxtQkFBbUI7QUFDM0IsRUFBRSxLQUFLLEVBQUUsd0NBQXdDO0FBQ2pELEVBQUUsT0FBTyxFQUFFLG1DQUFtQztBQUM5QyxFQUFFLFVBQVUsRUFBRSw4SUFBOEk7QUFDNUosRUFBRSxXQUFXLEVBQUUsc0VBQXNFO0FBQ3JGLEVBQUUsTUFBTSxFQUFFLHNCQUFzQjtBQUNoQyxFQUFFLEtBQUssRUFBRSw4QkFBOEI7QUFDdkMsRUFBRSxRQUFRLEVBQUUsMEJBQTBCO0FBQ3RDLEVBQUUsTUFBTSxFQUFFLDJCQUEyQjtBQUNyQyxFQUFFLE9BQU8sRUFBRSwwQ0FBMEM7QUFDckQsRUFBRSxTQUFTLEVBQUUsc0JBQXNCO0FBQ25DLEVBQUUsUUFBUSxFQUFFLDRCQUE0QjtBQUN4QyxFQUFFLEtBQUssRUFBRSx3RUFBd0U7QUFDakYsRUFBRSxLQUFLLEVBQUUsNEVBQTRFO0FBQ3JGLEVBQUUsQ0FBQztBQUNIO0FBQ0E7QUFDQSxDQUFDQSxHQUFHLENBQUMsS0FBSyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUc7QUFDbEQsRUFBRSxFQUFFLEVBQUUsQ0FBQztBQUNQLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUM7QUFDdEIsR0FBRyxLQUFLLEVBQUUsU0FBUztBQUNuQixHQUFHLElBQUksRUFBRSxPQUFPO0FBQ2hCLEdBQUcsSUFBSSxFQUFFLElBQUksVUFBVSxFQUFFO0FBQ3pCLEdBQUcsQ0FBQztBQUNKLEVBQUUsS0FBSyxFQUFFLE9BQU87QUFDaEIsRUFBRSxNQUFNLEVBQUUsSUFBSTtBQUNkLEVBQUUsSUFBSSxFQUFFLEVBQUU7QUFDVixFQUFFLFdBQVcsRUFBRSxhQUFhO0FBQzVCLEVBQUUsVUFBVSxFQUFFLENBQUM7QUFDZixFQUFFLFFBQVEsR0FBRyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUMsQ0FBQztBQUM5RSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUN2QixFQUFFLE9BQU8sRUFBRSxDQUFDO0FBQ1osRUFBRSxRQUFRLEVBQUUsSUFBSTtBQUNoQixFQUFFLEtBQUssRUFBRSxJQUFJO0FBQ2IsRUFBRSxLQUFLLEVBQUUsSUFBSTtBQUNiLEVBQUUsQ0FBQyxDQUFDO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxFQUFFO0FBQ3RCLEVBQUUsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsS0FBSztBQUN2QixFQUFFO0FBQ0YsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLElBQUksSUFBSSxFQUFFO0FBQ3JCLEVBQUUsS0FBSyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsSUFBSTtBQUNyQixFQUFFO0FBQ0YsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLElBQUksSUFBSSxFQUFFO0FBQ3ZCLEVBQUUsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsTUFBTTtBQUN6QixFQUFFO0FBQ0YsQ0FBQyxJQUFJLENBQUMsQ0FBQyxXQUFXLElBQUksSUFBSSxFQUFFO0FBQzVCLEVBQUUsS0FBSyxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsV0FBVztBQUNuQyxFQUFFO0FBQ0YsQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLElBQUksSUFBSSxFQUFFO0FBQzNCLEVBQUUsS0FBSyxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUMsVUFBVTtBQUNqQyxFQUFFO0FBQ0YsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLElBQUksSUFBSSxFQUFFO0FBQ3hCLEVBQUUsS0FBSyxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsT0FBTztBQUMzQixFQUFFO0FBQ0YsQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUU7QUFDakIsRUFBRSxLQUFLLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO0FBQ25DLEVBQUU7QUFDRixDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsSUFBSSxJQUFJLElBQUUsS0FBSyxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUMsVUFBUTtBQUNwRCxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLElBQUUsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsT0FBSztBQUMzQyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLElBQUUsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsT0FBSztBQUMzQztBQUNBO0FBQ0EsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUU7QUFDYixFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMvQixFQUFFLEtBQUssQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNO0FBQy9CLEVBQUUsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU07QUFDaEM7QUFDQTtBQUNBLEVBQUUsS0FBSyxDQUFDLE1BQU0sR0FBRyxFQUFFO0FBQ25CO0FBQ0EsRUFBRSxLQUFLQSxHQUFHLENBQUNELEdBQUMsR0FBRyxDQUFDLEVBQUVBLEdBQUMsR0FBRyxLQUFLLENBQUMsT0FBTyxFQUFFQSxHQUFDLEVBQUUsRUFBRTtBQUMxQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUNBLEdBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDQSxHQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDNUMsR0FBRztBQUNILEVBQUU7QUFDRjtBQUNBO0FBQ0EsQ0FBQ0MsR0FBRyxDQUFDLFVBQVU7QUFDZixDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRTtBQUNkLEVBQUUsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsS0FBSztBQUN2QixFQUFFLFVBQVUsR0FBRyxLQUFLLENBQUMsS0FBSyxJQUFJLE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRO0FBQ2hFLEVBQUU7QUFDRjtBQUNBLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFO0FBQ2YsRUFBRSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxNQUFNO0FBQ3pCLEVBQUU7QUFDRixDQUFDQSxHQUFHLENBQUMsWUFBWSxHQUFHLEtBQUs7QUFDekIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLElBQUksSUFBSSxFQUFFO0FBQ3hCO0FBQ0EsRUFBRSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLLFFBQVEsRUFBRTtBQUM3SCxHQUFHLEtBQUssQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDO0FBQ3hDLEdBQUcsWUFBWSxHQUFHLElBQUk7QUFDdEIsR0FBRztBQUNIO0FBQ0EsT0FBTztBQUNQLEdBQUcsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztBQUNwQyxHQUFHO0FBQ0gsRUFBRTtBQUNGO0FBQ0E7QUFDQSxDQUFDQSxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxPQUFPO0FBQ3RCLENBQUNBLEdBQUcsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLEtBQUs7QUFDcEI7QUFDQSxDQUFDQSxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSztBQUM3QixDQUFDQSxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTTtBQUM5QixDQUFDQSxHQUFHLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUM1QixDQUFDQSxHQUFHLENBQUMsR0FBRyxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUMzQixDQUFDQSxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDO0FBQ2YsQ0FBQ0EsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQztBQUNmO0FBQ0EsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLEVBQUU7QUFDbEI7QUFDQSxDQUFDLEtBQUtBLEdBQUcsQ0FBQ0QsR0FBQyxHQUFHLENBQUMsRUFBRUEsR0FBQyxHQUFHLENBQUMsRUFBRUEsR0FBQyxFQUFFLEVBQUU7QUFDN0IsRUFBRSxLQUFLQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQzlCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLElBQUksQ0FBQyxLQUFLRCxHQUFDLElBQUUsVUFBUTtBQUMzQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJQSxHQUFDLEdBQUcsQ0FBQyxJQUFFLFVBQVE7QUFDdEMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssSUFBSUEsR0FBQyxHQUFHLENBQUMsSUFBRSxVQUFRO0FBQ3RDO0FBQ0EsR0FBR0MsR0FBRyxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRUQsR0FBQyxFQUFFLENBQUMsQ0FBQztBQUNuQztBQUNBLEdBQUdDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ3pEO0FBQ0EsR0FBRyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUU7QUFDZixJQUFJLElBQUksQ0FBQyxDQUFDLFNBQVMsRUFBRTtBQUNyQixLQUFLLElBQUksQ0FBQyxTQUFTLEdBQUc7QUFDdEIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztBQUMvRCxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRUQsR0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztBQUMvRCxNQUFNO0FBQ04sS0FBSztBQUNMLFNBQVM7QUFDVCxLQUFLLElBQUksQ0FBQyxTQUFTLEdBQUc7QUFDdEIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0FBQ3hELE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFQSxHQUFDLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7QUFDeEQsTUFBTTtBQUNOLEtBQUs7QUFDTDtBQUNBLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRUEsR0FBQyxFQUFFLENBQUMsQ0FBQztBQUM1QyxJQUFJO0FBQ0o7QUFDQSxHQUFHLElBQUksQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUU7QUFDekMsSUFBSUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxZQUFZLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUVELEdBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsT0FBTztBQUN4RSxJQUFJLElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRTtBQUN0QixjQUE2QixHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFQSxHQUFDLEVBQUUsQ0FBQztLQUEvQztLQUFLO0tBQUs7S0FBSyxtQkFBaUM7QUFDMUQ7QUFDQSxLQUFLLElBQUksQ0FBQyxRQUFRLEdBQUc7QUFDckIsTUFBTSxJQUFJLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzdCLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUM1QixNQUFNLElBQUksR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDN0IsTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzVCLE1BQU07QUFDTixLQUFLO0FBQ0w7QUFDQSxTQUFTO0FBQ1QsS0FBSyxJQUFJLENBQUMsUUFBUSxHQUFHO0FBQ3JCLE1BQU0sSUFBSSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDakMsTUFBTSxHQUFHLEdBQUdBLEdBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDaEMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3ZDLE1BQU0sR0FBRyxHQUFHLENBQUNBLEdBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdEMsTUFBTTtBQUNOLEtBQUs7QUFDTCxJQUFJO0FBQ0o7QUFDQSxHQUFHLElBQUksQ0FBQyxDQUFDLEtBQUssSUFBRSxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxPQUFLO0FBQ3hDLEdBQUcsSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFFLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLE1BQUk7QUFDckMsR0FBRyxJQUFJLENBQUMsQ0FBQyxNQUFNLElBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsUUFBTTtBQUMzQyxHQUFHLElBQUksQ0FBQyxDQUFDLFVBQVUsSUFBRSxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQyxZQUFVO0FBQ3ZELEdBQUcsSUFBSSxDQUFDLENBQUMsV0FBVyxJQUFFLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDLGFBQVc7QUFDMUQsR0FBRyxJQUFJLENBQUMsQ0FBQyxPQUFPLElBQUUsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUMsU0FBTztBQUM5QztBQUNBLEdBQUcsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFO0FBQ2hCLElBQUksSUFBSSxDQUFDLEtBQUssR0FBRyxVQUFVLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUVBLEdBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxNQUFNO0FBQ3BGLElBQUk7QUFDSjtBQUNBLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO0FBQ3pCLEdBQUc7QUFDSCxFQUFFO0FBQ0Y7QUFDQSxDQUFDLE9BQU8sSUFBSTtBQUNaLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQSxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksR0FBRyxVQUFpQixFQUFFOzs7O2dEQUFDO0FBQzNDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7QUFDbkIsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTtBQUNyQixFQUFFO0FBQ0YsTUFBTTtBQUNOLEVBQUVDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsRUFBRTtBQUNkLEVBQUUsS0FBS0EsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDeEM7QUFDQSxHQUFHLElBQUksT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssUUFBUSxHQUFHO0FBQ3JDLFdBQThCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQTFDO0lBQVEsZ0NBQW1DO0FBQ3JELElBQUksR0FBRyxDQUFDLFVBQUksTUFBSSxRQUFRLENBQUMsVUFBVSxFQUFFLFVBQVUsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDakUsSUFBSTtBQUNKO0FBQ0EsUUFBUSxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUU7QUFDNUIsSUFBSUEsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3JCLGFBQThCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQXBDO0lBQVEsb0NBQTZCO0FBQy9DLElBQUlDLFFBQU0sR0FBR0EsUUFBTSxDQUFDLEdBQUcsVUFBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUs7QUFDdkMsS0FBSyxHQUFHLENBQUNDLFlBQVUsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHO0FBQzlCLEtBQUssQ0FBQztBQUNOLElBQUk7QUFDSixHQUFHO0FBQ0gsV0FBRSxJQUFJLENBQUMsUUFBTyxDQUFDLFVBQUksUUFBSSxHQUFHLENBQUM7QUFDM0IsRUFBRTtBQUNGO0FBQ0EsQ0FBQyxPQUFPLElBQUk7QUFDWixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsS0FBSyxDQUFDLFNBQVMsQ0FBQyxPQUFPLEdBQUcsWUFBWTtBQUN0QyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxXQUFDLE1BQUssQ0FBSTtBQUM5QixFQUFFLElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sSUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sSUFBRTtBQUNsRSxFQUFFLENBQUM7QUFDSCxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSTtBQUNuQixDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSTtBQUNuQjtBQUNBLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUU7QUFDdkI7QUFDQSxDQUFDLE9BQU8sSUFBSTtBQUNaLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQSxTQUFTLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUM5QixDQUFDRixHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFDLEVBQUUsR0FBRyxLQUFLLENBQUM7QUFDL0MsQ0FBQ0EsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDO0FBQ1YsQ0FBQ0EsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDO0FBQ1YsQ0FBQ0EsR0FBRyxDQUFDLEdBQUcsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSTtBQUNoRDtBQUNBLENBQUMsT0FBTyxHQUFHO0FBQ1gsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLFNBQVMsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQzlCLENBQUNBLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSTtBQUNuRCxDQUFDQSxHQUFHLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUN2QztBQUNBLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtBQUN2QixFQUFFLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDakIsRUFBRSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUU7QUFDRixNQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRTtBQUN4QixFQUFFLElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUN4QixFQUFFLElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUN4QixFQUFFO0FBQ0YsTUFBTTtBQUNOLEVBQUUsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDO0FBQ2hCLEVBQUUsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLEtBQUs7QUFDOUIsRUFBRSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTTtBQUMvQixFQUFFO0FBQ0Y7QUFDQSxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7QUFDdkIsRUFBRSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDakIsRUFBRSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNqQixFQUFFO0FBQ0YsTUFBTSxJQUFJLEtBQUssQ0FBQyxNQUFNLEVBQUU7QUFDeEIsRUFBRSxJQUFJLEdBQUcsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDeEIsRUFBRSxJQUFJLEdBQUcsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDeEIsRUFBRTtBQUNGLE1BQU07QUFDTixFQUFFLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQztBQUNoQixFQUFFLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQztBQUNoQixFQUFFLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLO0FBQzlCLEVBQUUsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU07QUFDL0IsRUFBRTtBQUNGO0FBQ0EsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFO0FBQ2xDLENBQUM7QUFDRDtBQUNBO0FBQ0EsU0FBUyxNQUFNLEVBQUUsR0FBRyxFQUFFO0FBQ3RCLENBQUMsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLElBQUUsT0FBTyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBQztBQUN6RCxNQUFNLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBQztBQUNuRSxNQUFNO0FBQ04sRUFBRUEsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO0FBQ3JCLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDO0FBQzlELEVBQUU7QUFDRixDQUFDOyJ9\n\n//# sourceURL=webpack:///./node_modules/regl-splom/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/regl/dist/regl.js":
-/*!****************************************!*\
- !*** ./node_modules/regl/dist/regl.js ***!
- \****************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-eval("(function(aa,ia){ true?module.exports=ia():undefined})(this,function(){function aa(a,b){this.id=Ab++;this.type=a;this.data=b}function ia(a){if(0===a.length)return[];var b=a.charAt(0),c=a.charAt(a.length-1);if(1>>=b;c=(255>>=c;b|=c;c=(15>>=c;b|=c;c=(3>>c>>1}function cb(){function a(a){a:{for(var b=16;268435456>=b;b*=16)if(a<=b){a=b;break a}a=0}b=c[bb(a)>>2];return 0>2].push(a)}var c=J(8,function(){return[]});return{alloc:a,free:b,allocType:function(b,c){var d=null;switch(b){case 5120:d=new Int8Array(a(c),0,c);break;case 5121:d=new Uint8Array(a(c),0,c);break;case 5122:d=new Int16Array(a(2*c),0,c);break;case 5123:d=new Uint16Array(a(2*c),0,c);break;case 5124:d=new Int32Array(a(4*c),0,c);break;case 5125:d=new Uint32Array(a(4*c),0,c);break;case 5126:d=new Float32Array(a(4*c),0,c);break;default:return null}return d.length!==\nc?d.subarray(0,c):d},freeType:function(a){b(a.buffer)}}}function ma(a){return!!a&&\"object\"===typeof a&&Array.isArray(a.shape)&&Array.isArray(a.stride)&&\"number\"===typeof a.offset&&a.shape.length===a.stride.length&&(Array.isArray(a.data)||M(a.data))}function db(a,b,c,e,g,d){for(var p=0;pd&&(d=e.buffer.byteLength,5123===f?d>>=1:5125===f&&(d>>=2));e.vertCount=d;d=h;0>h&&(d=4,h=e.buffer.dimension,1===h&&(d=0),2===h&&(d=1),3===h&&(d=4));e.primType=d}function p(a){e.elementsCount--;delete f[a.id];a.buffer.destroy();a.buffer=null}var f={},r=0,q={uint8:5121,\nuint16:5123};b.oes_element_index_uint&&(q.uint32=5125);g.prototype.bind=function(){this.buffer.bind()};var t=[];return{create:function(a,b){function k(a){if(a)if(\"number\"===typeof a)h(a),l.primType=4,l.vertCount=a|0,l.type=5121;else{var b=null,c=35044,e=-1,g=-1,f=0,m=0;if(Array.isArray(a)||M(a)||ma(a))b=a;else if(\"data\"in a&&(b=a.data),\"usage\"in a&&(c=jb[a.usage]),\"primitive\"in a&&(e=Sa[a.primitive]),\"count\"in a&&(g=a.count|0),\"type\"in a&&(m=q[a.type]),\"length\"in a)f=a.length|0;else if(f=g,5123===\nm||5122===m)f*=2;else if(5125===m||5124===m)f*=4;d(l,b,c,e,g,f,m)}else h(),l.primType=4,l.vertCount=0,l.type=5121;return k}var h=c.create(null,34963,!0),l=new g(h._buffer);e.elementsCount++;k(a);k._reglType=\"elements\";k._elements=l;k.subdata=function(a,b){h.subdata(a,b);return k};k.destroy=function(){p(l)};return k},createStream:function(a){var b=t.pop();b||(b=new g(c.create(null,34963,!0,!1)._buffer));d(b,a,35040,-1,-1,0,0);return b},destroyStream:function(a){t.push(a)},getElements:function(a){return\"function\"===\ntypeof a&&a._elements instanceof g?a._elements:null},clear:function(){S(f).forEach(p)}}}function kb(a){for(var b=x.allocType(5123,a.length),c=0;c>>31<<15,d=(e<<1>>>24)-127,e=e>>13&1023;b[c]=-24>d?g:-14>d?g+(e+1024>>-14-d):15>=e,c.height>>=e,C(c,d[e]),a.mipmask|=1<b;++b)a.images[b]=null;return a}function ib(a){for(var b=a.images,c=0;cb){for(var c=0;c=--this.refCount&&A(this)}});p.profile&&(d.getTotalTextureSize=function(){var a=0;Object.keys(X).forEach(function(b){a+=X[b].stats.size});return a});return{create2D:function(b,c){function e(a,b){var c=f.texInfo;z.call(c);var d=D();\"number\"===typeof a?\"number\"===typeof b?\nv(d,a|0,b|0):v(d,a|0,a|0):a?(O(c,a),N(d,a)):v(d,1,1);c.genMipmaps&&(d.mipmask=(d.width<<1)-1);f.mipmask=d.mipmask;r(f,d);f.internalformat=d.internalformat;e.width=d.width;e.height=d.height;T(f);B(d,3553);R(c,3553);Aa();ib(d);p.profile&&(f.stats.size=Ja(f.internalformat,f.type,d.width,d.height,c.genMipmaps,!1));e.format=J[f.internalformat];e.type=da[f.type];e.mag=oa[c.magFilter];e.min=za[c.minFilter];e.wrapS=ka[c.wrapS];e.wrapT=ka[c.wrapT];return e}var f=new F(3553);X[f.id]=f;d.textureCount++;e(b,\nc);e.subimage=function(a,b,c,d){b|=0;c|=0;d|=0;var n=h();r(n,f);n.width=0;n.height=0;C(n,a);n.width=n.width||(f.width>>d)-b;n.height=n.height||(f.height>>d)-c;T(f);k(n,3553,b,c,d);Aa();l(n);return e};e.resize=function(b,c){var d=b|0,h=c|0||d;if(d===f.width&&h===f.height)return e;e.width=f.width=d;e.height=f.height=h;T(f);for(var n,w=f.channels,y=f.type,I=0;f.mipmask>>I;++I){var fa=d>>I,ga=h>>I;if(!fa||!ga)break;n=x.zero.allocType(y,fa*ga*w);a.texImage2D(3553,I,f.format,fa,ga,0,f.format,f.type,n);\nn&&x.zero.freeType(n)}Aa();p.profile&&(f.stats.size=Ja(f.internalformat,f.type,d,h,!1,!1));return e};e._reglType=\"texture2d\";e._texture=f;p.profile&&(e.stats=f.stats);e.destroy=function(){f.decRef()};return e},createCube:function(b,c,e,f,g,ua){function A(a,b,c,d,e,f){var H,Y=m.texInfo;z.call(Y);for(H=0;6>H;++H)n[H]=D();if(\"number\"===typeof a||!a)for(a=a|0||1,H=0;6>H;++H)v(n[H],a,a);else if(\"object\"===typeof a)if(b)N(n[0],a),N(n[1],b),N(n[2],c),N(n[3],d),N(n[4],e),N(n[5],f);else if(O(Y,a),q(m,a),\"faces\"in\na)for(a=a.faces,H=0;6>H;++H)r(n[H],m),N(n[H],a[H]);else for(H=0;6>H;++H)N(n[H],a);r(m,n[0]);m.mipmask=Y.genMipmaps?(n[0].width<<1)-1:n[0].mipmask;m.internalformat=n[0].internalformat;A.width=n[0].width;A.height=n[0].height;T(m);for(H=0;6>H;++H)B(n[H],34069+H);R(Y,34067);Aa();p.profile&&(m.stats.size=Ja(m.internalformat,m.type,A.width,A.height,Y.genMipmaps,!0));A.format=J[m.internalformat];A.type=da[m.type];A.mag=oa[Y.magFilter];A.min=za[Y.minFilter];A.wrapS=ka[Y.wrapS];A.wrapT=ka[Y.wrapT];for(H=0;6>\nH;++H)ib(n[H]);return A}var m=new F(34067);X[m.id]=m;d.cubeCount++;var n=Array(6);A(b,c,e,f,g,ua);A.subimage=function(a,b,c,n,d){c|=0;n|=0;d|=0;var e=h();r(e,m);e.width=0;e.height=0;C(e,b);e.width=e.width||(m.width>>d)-c;e.height=e.height||(m.height>>d)-n;T(m);k(e,34069+a,c,n,d);Aa();l(e);return A};A.resize=function(b){b|=0;if(b!==m.width){A.width=m.width=b;A.height=m.height=b;T(m);for(var c=0;6>c;++c)for(var n=0;m.mipmask>>n;++n)a.texImage2D(34069+c,n,m.format,b>>n,b>>n,0,m.format,m.type,null);Aa();\np.profile&&(m.stats.size=Ja(m.internalformat,m.type,A.width,A.height,!1,!0));return A}};A._reglType=\"textureCube\";A._texture=m;p.profile&&(A.stats=m.stats);A.destroy=function(){m.decRef()};return A},clear:function(){for(var b=0;bc;++c)if(0!==(b.mipmask&1<>c,b.height>>c,0,b.internalformat,b.type,null);else for(var d=0;6>d;++d)a.texImage2D(34069+d,c,b.internalformat,b.width>>c,b.height>>c,0,b.internalformat,b.type,null);R(b.texInfo,b.target)})}}}function Ob(a,b,c,e,g,d){function p(a,b,c){this.target=a;this.texture=b;this.renderbuffer=c;var d=a=0;b?(a=b.width,d=b.height):c&&(a=c.width,d=c.height);\nthis.width=a;this.height=d}function f(a){a&&(a.texture&&a.texture._texture.decRef(),a.renderbuffer&&a.renderbuffer._renderbuffer.decRef())}function r(a,b,c){a&&(a.texture?a.texture._texture.refCount+=1:a.renderbuffer._renderbuffer.refCount+=1)}function q(b,c){c&&(c.texture?a.framebufferTexture2D(36160,b,c.target,c.texture._texture.texture,0):a.framebufferRenderbuffer(36160,b,36161,c.renderbuffer._renderbuffer.renderbuffer))}function t(a){var b=3553,c=null,d=null,e=a;\"object\"===typeof a&&(e=a.data,\n\"target\"in a&&(b=a.target|0));a=e._reglType;\"texture2d\"===a?c=e:\"textureCube\"===a?c=e:\"renderbuffer\"===a&&(d=e,b=36161);return new p(b,c,d)}function m(a,b,c,d,f){if(c)return a=e.create2D({width:a,height:b,format:d,type:f}),a._texture.refCount=0,new p(3553,a,null);a=g.create({width:a,height:b,format:d});a._renderbuffer.refCount=0;return new p(36161,null,a)}function C(a){return a&&(a.texture||a.renderbuffer)}function k(a,b,c){a&&(a.texture?a.texture.resize(b,c):a.renderbuffer&&a.renderbuffer.resize(b,\nc),a.width=b,a.height=c)}function h(){this.id=O++;R[this.id]=this;this.framebuffer=a.createFramebuffer();this.height=this.width=0;this.colorAttachments=[];this.depthStencilAttachment=this.stencilAttachment=this.depthAttachment=null}function l(a){a.colorAttachments.forEach(f);f(a.depthAttachment);f(a.stencilAttachment);f(a.depthStencilAttachment)}function u(b){a.deleteFramebuffer(b.framebuffer);b.framebuffer=null;d.framebufferCount--;delete R[b.id]}function v(b){var d;a.bindFramebuffer(36160,b.framebuffer);\nvar e=b.colorAttachments;for(d=0;dd;++d){for(m=0;ma;++a)c[a].resize(d);b.width=b.height=d;return b},_reglType:\"framebufferCube\",destroy:function(){c.forEach(function(a){a.destroy()})}})},\nclear:function(){S(R).forEach(u)},restore:function(){B.cur=null;B.next=null;B.dirty=!0;S(R).forEach(function(b){b.framebuffer=a.createFramebuffer();v(b)})}})}function ub(){this.w=this.z=this.y=this.x=this.state=0;this.buffer=null;this.size=0;this.normalized=!1;this.type=5126;this.divisor=this.stride=this.offset=0}function Pb(a,b,c,e){a=c.maxAttributes;b=Array(a);for(c=0;ca&&(a=b.stats.uniformsCount)});return a},c.getMaxAttributesCount=function(){var a=0;C.forEach(function(b){b.stats.attributesCount>a&&(a=b.stats.attributesCount)});return a});return{clear:function(){var b=a.deleteShader.bind(a);S(q).forEach(b);q={};S(t).forEach(b);t={};C.forEach(function(b){a.deleteProgram(b.program)});\nC.length=0;m={};c.shaderCount=0},program:function(a,b,d){var e=m[b];e||(e=m[b]={});var g=e[a];g||(g=new f(b,a),c.shaderCount++,r(g,d),e[a]=g,C.push(g));return g},restore:function(){q={};t={};for(var a=0;a\"+b+\"?\"+e+\".constant[\"+b+\"]:0;\"}).join(\"\"),\"}}else{\",\"if(\",g,\"(\",e,\".buffer)){\",y,\"=\",n,\".createStream(\",34962,\",\",e,\".buffer);\",\"}else{\",y,\"=\",n,\".getBuffer(\",e,\".buffer);\",\"}\",k,'=\"type\" in ',e,\"?\",f.glTypes,\"[\",e,\".type]:\",y,\".dtype;\",\nw.normalized,\"=!!\",e,\".normalized;\");d(\"size\");d(\"offset\");d(\"stride\");d(\"divisor\");c(\"}}\");c.exit(\"if(\",w.isStream,\"){\",n,\".destroyStream(\",y,\");\",\"}\");return w})});return f}function M(a){var b=a[\"static\"],c=a.dynamic,d={};Object.keys(b).forEach(function(a){var c=b[a];d[a]=D(function(a,b){return\"number\"===typeof c||\"boolean\"===typeof c?\"\"+c:a.link(c)})});Object.keys(c).forEach(function(a){var b=c[a];d[a]=P(b,function(a,c){return a.invoke(c,b)})});return d}function A(a,b,c,d,e){var f=z(a,e),g=x(a,\nf,e),h=O(a,e),k=R(a,e),m=E(a,e),ba=g.viewport;ba&&(k.viewport=ba);ba=l(\"scissor.box\");(g=g[ba])&&(k[ba]=g);g=0>1)\",v],\");\")}function b(){c(u,\".drawArraysInstancedANGLE(\",[q,r,t,v],\");\")}p?da?a():(c(\"if(\",p,\"){\"),a(),c(\"}else{\"),b(),c(\"}\")):b()}function g(){function a(){c(k+\".drawElements(\"+[q,t,C,r+\"<<((\"+C+\"-5121)>>1)\"]+\");\")}function b(){c(k+\".drawArrays(\"+[q,r,t]+\");\")}p?da?a():(c(\"if(\",p,\"){\"),a(),c(\"}else{\"),b(),c(\"}\")):b()}var h=a.shared,k=h.gl,m=h.draw,l=d.draw,p=function(){var e=l.elements,f=b;if(e){if(e.contextDep&&d.contextDynamic||e.propDep)f=c;e=e.append(a,f)}else e=f.def(m,\n\".\",\"elements\");e&&f(\"if(\"+e+\")\"+k+\".bindBuffer(34963,\"+e+\".buffer.buffer);\");return e}(),q=e(\"primitive\"),r=e(\"offset\"),t=function(){var e=l.count,f=b;if(e){if(e.contextDep&&d.contextDynamic||e.propDep)f=c;e=e.append(a,f)}else e=f.def(m,\".\",\"count\");return e}();if(\"number\"===typeof t){if(0===t)return}else c(\"if(\",t,\"){\"),c.exit(\"}\");var v,u;ea&&(v=e(\"instances\"),u=a.instancing);var C=p+\".type\",da=l.elements&&va(l.elements);ea&&(\"number\"!==typeof v||0<=v)?\"string\"===typeof v?(c(\"if(\",v,\">0){\"),f(),\nc(\"}else if(\",v,\"<0){\"),g(),c(\"}\")):f():g()}function ca(a,b,c,d,e){b=N();e=b.proc(\"body\",e);ea&&(b.instancing=e.def(b.shared.extensions,\".angle_instanced_arrays\"));a(b,e,c,d);return b.compile().body}function L(a,b,c,d){wa(a,b);U(a,b,c,d.attributes,function(){return!0});W(a,b,c,d.uniforms,function(){return!0});S(a,b,b,c)}function da(a,b){var c=a.proc(\"draw\",1);wa(a,c);ua(a,c,b.context);K(a,c,b.framebuffer);V(a,c,b);Q(a,c,b.state);G(a,c,b,!1,!0);var d=b.shader.progVar.append(a,c);c(a.shared.gl,\".useProgram(\",\nd,\".program);\");if(b.shader.program)L(a,c,b,b.shader.program);else{var e=a.global.def(\"{}\"),f=c.def(d,\".id\"),g=c.def(e,\"[\",f,\"]\");c(a.cond(g).then(g,\".call(this,a0);\")[\"else\"](g,\"=\",e,\"[\",f,\"]=\",a.link(function(c){return ca(L,a,b,c,1)}),\"(\",d,\");\",g,\".call(this,a0);\"))}0=--this.refCount&&p(this)};g.profile&&(e.getTotalRenderbufferSize=function(){var a=0;Object.keys(t).forEach(function(b){a+=t[b].stats.size});return a});return{create:function(b,c){function k(b,c){var d=0,e=0,m=32854;\"object\"===typeof b&&b?(\"shape\"in b?(e=b.shape,d=e[0]|0,e=e[1]|0):(\"radius\"in b&&(d=e=b.radius|0),\"width\"in b&&(d=b.width|0),\"height\"in b&&(e=b.height|0)),\"format\"in b&&(m=f[b.format])):\"number\"===\ntypeof b?(d=b|0,e=\"number\"===typeof c?c|0:d):b||(d=e=1);if(d!==h.width||e!==h.height||m!==h.format)return k.width=h.width=d,k.height=h.height=e,h.format=m,a.bindRenderbuffer(36161,h.renderbuffer),a.renderbufferStorage(36161,m,d,e),g.profile&&(h.stats.size=Q[h.format]*h.width*h.height),k.format=r[h.format],k}var h=new d(a.createRenderbuffer());t[h.id]=h;e.renderbufferCount++;k(b,c);k.resize=function(b,c){var d=b|0,e=c|0||d;if(d===h.width&&e===h.height)return k;k.width=h.width=d;k.height=h.height=e;\na.bindRenderbuffer(36161,h.renderbuffer);a.renderbufferStorage(36161,h.format,d,e);g.profile&&(h.stats.size=Q[h.format]*h.width*h.height);return k};k._reglType=\"renderbuffer\";k._renderbuffer=h;g.profile&&(k.stats=h.stats);k.destroy=function(){h.decRef()};return k},clear:function(){S(t).forEach(p)},restore:function(){S(t).forEach(function(b){b.renderbuffer=a.createRenderbuffer();a.bindRenderbuffer(36161,b.renderbuffer);a.renderbufferStorage(36161,b.format,b.width,b.height)});a.bindRenderbuffer(36161,\nnull)}}},Wa=[];Wa[6408]=4;Wa[6407]=3;var Na=[];Na[5121]=1;Na[5126]=4;Na[36193]=2;var Da=[\"x\",\"y\",\"z\",\"w\"],Ub=\"blend.func blend.equation stencil.func stencil.opFront stencil.opBack sample.coverage viewport scissor.box polygonOffset.offset\".split(\" \"),Ga={0:0,1:1,zero:0,one:1,\"src color\":768,\"one minus src color\":769,\"src alpha\":770,\"one minus src alpha\":771,\"dst color\":774,\"one minus dst color\":775,\"dst alpha\":772,\"one minus dst alpha\":773,\"constant color\":32769,\"one minus constant color\":32770,\"constant alpha\":32771,\n\"one minus constant alpha\":32772,\"src alpha saturate\":776},Xa={never:512,less:513,\"<\":513,equal:514,\"=\":514,\"==\":514,\"===\":514,lequal:515,\"<=\":515,greater:516,\">\":516,notequal:517,\"!=\":517,\"!==\":517,gequal:518,\">=\":518,always:519},Pa={0:0,zero:0,keep:7680,replace:7681,increment:7682,decrement:7683,\"increment wrap\":34055,\"decrement wrap\":34056,invert:5386},wb={cw:2304,ccw:2305},xb=new Z(!1,!1,!1,function(){}),Xb=function(a,b){function c(){this.endQueryIndex=this.startQueryIndex=-1;this.sum=0;this.stats=\nnull}function e(a,b,d){var e=p.pop()||new c;e.startQueryIndex=a;e.endQueryIndex=b;e.sum=0;e.stats=d;f.push(e)}if(!b.ext_disjoint_timer_query)return null;var g=[],d=[],p=[],f=[],r=[],q=[];return{beginQuery:function(a){var c=g.pop()||b.ext_disjoint_timer_query.createQueryEXT();b.ext_disjoint_timer_query.beginQueryEXT(35007,c);d.push(c);e(d.length-1,d.length,a)},endQuery:function(){b.ext_disjoint_timer_query.endQueryEXT(35007)},pushScopeStats:e,update:function(){var a,c;a=d.length;if(0!==a){q.length=\nMath.max(q.length,a+1);r.length=Math.max(r.length,a+1);r[0]=0;var e=q[0]=0;for(c=a=0;c=G.length&&e()}var c=yb(G,a);G[c]=b}}}function q(){var a=S.viewport,b=S.scissor_box;a[0]=a[1]=b[0]=b[1]=0;O.viewportWidth=O.framebufferWidth=O.drawingBufferWidth=a[2]=b[2]=k.drawingBufferWidth;O.viewportHeight=O.framebufferHeight=O.drawingBufferHeight=a[3]=b[3]=k.drawingBufferHeight}function t(){O.tick+=1;O.time=z();\nq();V.procs.poll()}function m(){q();V.procs.refresh();B&&B.update()}function z(){return(zb()-D)/1E3}a=Eb(a);if(!a)return null;var k=a.gl,h=k.getContextAttributes();k.isContextLost();var l=Fb(k,a);if(!l)return null;var u=Bb(),v={bufferCount:0,elementsCount:0,framebufferCount:0,shaderCount:0,textureCount:0,cubeCount:0,renderbufferCount:0,maxTextureUnits:0},x=l.extensions,B=Xb(k,x),D=zb(),J=k.drawingBufferWidth,P=k.drawingBufferHeight,O={tick:0,time:0,viewportWidth:J,viewportHeight:P,framebufferWidth:J,\nframebufferHeight:P,drawingBufferWidth:J,drawingBufferHeight:P,pixelRatio:a.pixelRatio},R=Vb(k,x),J=Pb(k,x,R,u),F=Gb(k,v,a,J),T=Hb(k,x,F,v),Q=Qb(k,u,v,a),A=Kb(k,x,R,function(){V.procs.poll()},O,v,a),M=Wb(k,x,R,v,a),K=Ob(k,x,R,A,M,v),V=Tb(k,u,x,R,F,T,A,K,{},J,Q,{elements:null,primitive:4,count:-1,offset:0,instances:-1},O,B,a),u=Rb(k,K,V.procs.poll,O,h,x,R),S=V.next,L=k.canvas,G=[],U=[],W=[],Z=[a.onDestroy],ca=null;L&&(L.addEventListener(\"webglcontextlost\",g,!1),L.addEventListener(\"webglcontextrestored\",\nd,!1));var aa=K.setFBO=p({framebuffer:la.define.call(null,1,\"framebuffer\")});m();h=E(p,{clear:function(a){if(\"framebuffer\"in a)if(a.framebuffer&&\"framebufferCube\"===a.framebuffer_reglType)for(var b=0;6>b;++b)aa(E({framebuffer:a.framebuffer.faces[b]},a),f);else aa(a,f);else f(null,a)},prop:la.define.bind(null,1),context:la.define.bind(null,2),\"this\":la.define.bind(null,3),draw:p({}),buffer:function(a){return F.create(a,34962,!1,!1)},elements:function(a){return T.create(a,!1)},texture:A.create2D,cube:A.createCube,\nrenderbuffer:M.create,framebuffer:K.create,framebufferCube:K.createCube,attributes:h,frame:r,on:function(a,b){var c;switch(a){case \"frame\":return r(b);case \"lost\":c=U;break;case \"restore\":c=W;break;case \"destroy\":c=Z}c.push(b);return{cancel:function(){for(var a=0;a\n *\n * Copyright (c) 2014-2015, Jon Schlinkert.\n * Licensed under the MIT License.\n */\n\n\n\n/**\n * Results cache\n */\n\nvar res = '';\nvar cache;\n\n/**\n * Expose `repeat`\n */\n\nmodule.exports = repeat;\n\n/**\n * Repeat the given `string` the specified `number`\n * of times.\n *\n * **Example:**\n *\n * ```js\n * var repeat = require('repeat-string');\n * repeat('A', 5);\n * //=> AAAAA\n * ```\n *\n * @param {String} `string` The string to repeat\n * @param {Number} `number` The number of times to repeat the string\n * @return {String} Repeated string\n * @api public\n */\n\nfunction repeat(str, num) {\n if (typeof str !== 'string') {\n throw new TypeError('expected a string');\n }\n\n // cover common, quick use cases\n if (num === 1) return str;\n if (num === 2) return str + str;\n\n var max = str.length * num;\n if (cache !== str || typeof cache === 'undefined') {\n cache = str;\n res = '';\n } else if (res.length >= max) {\n return res.substr(0, max);\n }\n\n while (max > res.length && num > 1) {\n if (num & 1) {\n res += str;\n }\n\n num >>= 1;\n str += str;\n }\n\n res += str;\n res = res.substr(0, max);\n return res;\n}\n\n\n//# sourceURL=webpack:///./node_modules/repeat-string/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/right-now/browser.js":
-/*!*******************************************!*\
- !*** ./node_modules/right-now/browser.js ***!
- \*******************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-eval("/* WEBPACK VAR INJECTION */(function(global) {module.exports =\n global.performance &&\n global.performance.now ? function now() {\n return performance.now()\n } : Date.now || function now() {\n return +new Date\n }\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n//# sourceURL=webpack:///./node_modules/right-now/browser.js?");
-
-/***/ }),
-
-/***/ "./node_modules/robust-compress/compress.js":
-/*!**************************************************!*\
- !*** ./node_modules/robust-compress/compress.js ***!
- \**************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nmodule.exports = compressExpansion\n\nfunction compressExpansion(e) {\n var m = e.length\n var Q = e[e.length-1]\n var bottom = m\n for(var i=m-2; i>=0; --i) {\n var a = Q\n var b = e[i]\n Q = a + b\n var bv = Q - a\n var q = b - bv\n if(q) {\n e[--bottom] = Q\n Q = q\n }\n }\n var top = 0\n for(var i=bottom; i>1\n return [\"sum(\", generateSum(expr.slice(0, m)), \",\", generateSum(expr.slice(m)), \")\"].join(\"\")\n }\n}\n\nfunction determinant(m) {\n if(m.length === 2) {\n return [\"sum(prod(\", m[0][0], \",\", m[1][1], \"),prod(-\", m[0][1], \",\", m[1][0], \"))\"].join(\"\")\n } else {\n var expr = []\n for(var i=0; i>1\n return [\"sum(\", generateSum(expr.slice(0, m)), \",\", generateSum(expr.slice(m)), \")\"].join(\"\")\n }\n}\n\nfunction makeProduct(a, b) {\n if(a.charAt(0) === \"m\") {\n if(b.charAt(0) === \"w\") {\n var toks = a.split(\"[\")\n return [\"w\", b.substr(1), \"m\", toks[0].substr(1)].join(\"\")\n } else {\n return [\"prod(\", a, \",\", b, \")\"].join(\"\")\n }\n } else {\n return makeProduct(b, a)\n }\n}\n\nfunction sign(s) {\n if(s & 1 !== 0) {\n return \"-\"\n }\n return \"\"\n}\n\nfunction determinant(m) {\n if(m.length === 2) {\n return [[\"diff(\", makeProduct(m[0][0], m[1][1]), \",\", makeProduct(m[1][0], m[0][1]), \")\"].join(\"\")]\n } else {\n var expr = []\n for(var i=0; i 0) {\n code.push(\",\")\n }\n code.push(\"[\")\n for(var k=0; k 0) {\n code.push(\",\")\n }\n if(k === i) {\n code.push(\"+b[\", j, \"]\")\n } else {\n code.push(\"+A[\", j, \"][\", k, \"]\")\n }\n }\n code.push(\"]\")\n }\n code.push(\"]),\")\n }\n code.push(\"det(A)]}return \", funcName)\n var proc = new Function(\"det\", code.join(\"\"))\n if(n < 6) {\n return proc(determinant[n])\n }\n return proc(determinant)\n}\n\nfunction robustLinearSolve0d() {\n return [ 0 ]\n}\n\nfunction robustLinearSolve1d(A, b) {\n return [ [ b[0] ], [ A[0][0] ] ]\n}\n\nvar CACHE = [\n robustLinearSolve0d,\n robustLinearSolve1d\n]\n\nfunction generateDispatch() {\n while(CACHE.length < NUM_EXPAND) {\n CACHE.push(generateSolver(CACHE.length))\n }\n var procArgs = []\n var code = [\"function dispatchLinearSolve(A,b){switch(A.length){\"]\n for(var i=0; i>1\n return [\"sum(\", generateSum(expr.slice(0, m)), \",\", generateSum(expr.slice(m)), \")\"].join(\"\")\n }\n}\n\nfunction determinant(m) {\n if(m.length === 2) {\n return [[\"sum(prod(\", m[0][0], \",\", m[1][1], \"),prod(-\", m[0][1], \",\", m[1][0], \"))\"].join(\"\")]\n } else {\n var expr = []\n for(var i=0; i 0) {\n if(r <= 0) {\n return det\n } else {\n s = l + r\n }\n } else if(l < 0) {\n if(r >= 0) {\n return det\n } else {\n s = -(l + r)\n }\n } else {\n return det\n }\n var tol = ERRBOUND3 * s\n if(det >= tol || det <= -tol) {\n return det\n }\n return orientation3Exact(a, b, c)\n },\n function orientation4(a,b,c,d) {\n var adx = a[0] - d[0]\n var bdx = b[0] - d[0]\n var cdx = c[0] - d[0]\n var ady = a[1] - d[1]\n var bdy = b[1] - d[1]\n var cdy = c[1] - d[1]\n var adz = a[2] - d[2]\n var bdz = b[2] - d[2]\n var cdz = c[2] - d[2]\n var bdxcdy = bdx * cdy\n var cdxbdy = cdx * bdy\n var cdxady = cdx * ady\n var adxcdy = adx * cdy\n var adxbdy = adx * bdy\n var bdxady = bdx * ady\n var det = adz * (bdxcdy - cdxbdy) \n + bdz * (cdxady - adxcdy)\n + cdz * (adxbdy - bdxady)\n var permanent = (Math.abs(bdxcdy) + Math.abs(cdxbdy)) * Math.abs(adz)\n + (Math.abs(cdxady) + Math.abs(adxcdy)) * Math.abs(bdz)\n + (Math.abs(adxbdy) + Math.abs(bdxady)) * Math.abs(cdz)\n var tol = ERRBOUND4 * permanent\n if ((det > tol) || (-det > tol)) {\n return det\n }\n return orientation4Exact(a,b,c,d)\n }\n]\n\nfunction slowOrient(args) {\n var proc = CACHED[args.length]\n if(!proc) {\n proc = CACHED[args.length] = orientation(args.length)\n }\n return proc.apply(undefined, args)\n}\n\nfunction generateOrientationProc() {\n while(CACHED.length <= NUM_EXPAND) {\n CACHED.push(orientation(CACHED.length))\n }\n var args = []\n var procArgs = [\"slow\"]\n for(var i=0; i<=NUM_EXPAND; ++i) {\n args.push(\"a\" + i)\n procArgs.push(\"o\" + i)\n }\n var code = [\n \"function getOrientation(\", args.join(), \"){switch(arguments.length){case 0:case 1:return 0;\"\n ]\n for(var i=2; i<=NUM_EXPAND; ++i) {\n code.push(\"case \", i, \":return o\", i, \"(\", args.slice(0, i).join(), \");\")\n }\n code.push(\"}var s=new Array(arguments.length);for(var i=0;i 0 && y0 > 0) || (x0 < 0 && y0 < 0)) {\n return false\n }\n\n var x1 = orient(b0, a0, a1)\n var y1 = orient(b1, a0, a1)\n if((x1 > 0 && y1 > 0) || (x1 < 0 && y1 < 0)) {\n return false\n }\n\n //Check for degenerate collinear case\n if(x0 === 0 && y0 === 0 && x1 === 0 && y1 === 0) {\n return checkCollinear(a0, a1, b0, b1)\n }\n\n return true\n}\n\n//# sourceURL=webpack:///./node_modules/robust-segment-intersect/segseg.js?");
-
-/***/ }),
-
-/***/ "./node_modules/robust-subtract/robust-diff.js":
-/*!*****************************************************!*\
- !*** ./node_modules/robust-subtract/robust-diff.js ***!
- \*****************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nmodule.exports = robustSubtract\n\n//Easy case: Add two scalars\nfunction scalarScalar(a, b) {\n var x = a + b\n var bv = x - a\n var av = x - bv\n var br = b - bv\n var ar = a - av\n var y = ar + br\n if(y) {\n return [y, x]\n }\n return [x]\n}\n\nfunction robustSubtract(e, f) {\n var ne = e.length|0\n var nf = f.length|0\n if(ne === 1 && nf === 1) {\n return scalarScalar(e[0], -f[0])\n }\n var n = ne + nf\n var g = new Array(n)\n var count = 0\n var eptr = 0\n var fptr = 0\n var abs = Math.abs\n var ei = e[eptr]\n var ea = abs(ei)\n var fi = -f[fptr]\n var fa = abs(fi)\n var a, b\n if(ea < fa) {\n b = ei\n eptr += 1\n if(eptr < ne) {\n ei = e[eptr]\n ea = abs(ei)\n }\n } else {\n b = fi\n fptr += 1\n if(fptr < nf) {\n fi = -f[fptr]\n fa = abs(fi)\n }\n }\n if((eptr < ne && ea < fa) || (fptr >= nf)) {\n a = ei\n eptr += 1\n if(eptr < ne) {\n ei = e[eptr]\n ea = abs(ei)\n }\n } else {\n a = fi\n fptr += 1\n if(fptr < nf) {\n fi = -f[fptr]\n fa = abs(fi)\n }\n }\n var x = a + b\n var bv = x - a\n var y = b - bv\n var q0 = y\n var q1 = x\n var _x, _bv, _av, _br, _ar\n while(eptr < ne && fptr < nf) {\n if(ea < fa) {\n a = ei\n eptr += 1\n if(eptr < ne) {\n ei = e[eptr]\n ea = abs(ei)\n }\n } else {\n a = fi\n fptr += 1\n if(fptr < nf) {\n fi = -f[fptr]\n fa = abs(fi)\n }\n }\n b = q0\n x = a + b\n bv = x - a\n y = b - bv\n if(y) {\n g[count++] = y\n }\n _x = q1 + x\n _bv = _x - q1\n _av = _x - _bv\n _br = x - _bv\n _ar = q1 - _av\n q0 = _ar + _br\n q1 = _x\n }\n while(eptr < ne) {\n a = ei\n b = q0\n x = a + b\n bv = x - a\n y = b - bv\n if(y) {\n g[count++] = y\n }\n _x = q1 + x\n _bv = _x - q1\n _av = _x - _bv\n _br = x - _bv\n _ar = q1 - _av\n q0 = _ar + _br\n q1 = _x\n eptr += 1\n if(eptr < ne) {\n ei = e[eptr]\n }\n }\n while(fptr < nf) {\n a = fi\n b = q0\n x = a + b\n bv = x - a\n y = b - bv\n if(y) {\n g[count++] = y\n } \n _x = q1 + x\n _bv = _x - q1\n _av = _x - _bv\n _br = x - _bv\n _ar = q1 - _av\n q0 = _ar + _br\n q1 = _x\n fptr += 1\n if(fptr < nf) {\n fi = -f[fptr]\n }\n }\n if(q0) {\n g[count++] = q0\n }\n if(q1) {\n g[count++] = q1\n }\n if(!count) {\n g[count++] = 0.0 \n }\n g.length = count\n return g\n}\n\n//# sourceURL=webpack:///./node_modules/robust-subtract/robust-diff.js?");
-
-/***/ }),
-
-/***/ "./node_modules/robust-sum/robust-sum.js":
-/*!***********************************************!*\
- !*** ./node_modules/robust-sum/robust-sum.js ***!
- \***********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nmodule.exports = linearExpansionSum\n\n//Easy case: Add two scalars\nfunction scalarScalar(a, b) {\n var x = a + b\n var bv = x - a\n var av = x - bv\n var br = b - bv\n var ar = a - av\n var y = ar + br\n if(y) {\n return [y, x]\n }\n return [x]\n}\n\nfunction linearExpansionSum(e, f) {\n var ne = e.length|0\n var nf = f.length|0\n if(ne === 1 && nf === 1) {\n return scalarScalar(e[0], f[0])\n }\n var n = ne + nf\n var g = new Array(n)\n var count = 0\n var eptr = 0\n var fptr = 0\n var abs = Math.abs\n var ei = e[eptr]\n var ea = abs(ei)\n var fi = f[fptr]\n var fa = abs(fi)\n var a, b\n if(ea < fa) {\n b = ei\n eptr += 1\n if(eptr < ne) {\n ei = e[eptr]\n ea = abs(ei)\n }\n } else {\n b = fi\n fptr += 1\n if(fptr < nf) {\n fi = f[fptr]\n fa = abs(fi)\n }\n }\n if((eptr < ne && ea < fa) || (fptr >= nf)) {\n a = ei\n eptr += 1\n if(eptr < ne) {\n ei = e[eptr]\n ea = abs(ei)\n }\n } else {\n a = fi\n fptr += 1\n if(fptr < nf) {\n fi = f[fptr]\n fa = abs(fi)\n }\n }\n var x = a + b\n var bv = x - a\n var y = b - bv\n var q0 = y\n var q1 = x\n var _x, _bv, _av, _br, _ar\n while(eptr < ne && fptr < nf) {\n if(ea < fa) {\n a = ei\n eptr += 1\n if(eptr < ne) {\n ei = e[eptr]\n ea = abs(ei)\n }\n } else {\n a = fi\n fptr += 1\n if(fptr < nf) {\n fi = f[fptr]\n fa = abs(fi)\n }\n }\n b = q0\n x = a + b\n bv = x - a\n y = b - bv\n if(y) {\n g[count++] = y\n }\n _x = q1 + x\n _bv = _x - q1\n _av = _x - _bv\n _br = x - _bv\n _ar = q1 - _av\n q0 = _ar + _br\n q1 = _x\n }\n while(eptr < ne) {\n a = ei\n b = q0\n x = a + b\n bv = x - a\n y = b - bv\n if(y) {\n g[count++] = y\n }\n _x = q1 + x\n _bv = _x - q1\n _av = _x - _bv\n _br = x - _bv\n _ar = q1 - _av\n q0 = _ar + _br\n q1 = _x\n eptr += 1\n if(eptr < ne) {\n ei = e[eptr]\n }\n }\n while(fptr < nf) {\n a = fi\n b = q0\n x = a + b\n bv = x - a\n y = b - bv\n if(y) {\n g[count++] = y\n } \n _x = q1 + x\n _bv = _x - q1\n _av = _x - _bv\n _br = x - _bv\n _ar = q1 - _av\n q0 = _ar + _br\n q1 = _x\n fptr += 1\n if(fptr < nf) {\n fi = f[fptr]\n }\n }\n if(q0) {\n g[count++] = q0\n }\n if(q1) {\n g[count++] = q1\n }\n if(!count) {\n g[count++] = 0.0 \n }\n g.length = count\n return g\n}\n\n//# sourceURL=webpack:///./node_modules/robust-sum/robust-sum.js?");
-
-/***/ }),
-
-/***/ "./node_modules/signum/sgn.js":
-/*!************************************!*\
- !*** ./node_modules/signum/sgn.js ***!
- \************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nmodule.exports = function signum(x) {\n if(x < 0) { return -1 }\n if(x > 0) { return 1 }\n return 0.0\n}\n\n//# sourceURL=webpack:///./node_modules/signum/sgn.js?");
-
-/***/ }),
-
-/***/ "./node_modules/simplicial-complex-boundary/boundary.js":
-/*!**************************************************************!*\
- !*** ./node_modules/simplicial-complex-boundary/boundary.js ***!
- \**************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nmodule.exports = boundary\n\nvar bnd = __webpack_require__(/*! boundary-cells */ \"./node_modules/boundary-cells/boundary.js\")\nvar reduce = __webpack_require__(/*! reduce-simplicial-complex */ \"./node_modules/reduce-simplicial-complex/reduce.js\")\n\nfunction boundary(cells) {\n return reduce(bnd(cells))\n}\n\n\n//# sourceURL=webpack:///./node_modules/simplicial-complex-boundary/boundary.js?");
-
-/***/ }),
-
-/***/ "./node_modules/simplicial-complex-contour/contour.js":
-/*!************************************************************!*\
- !*** ./node_modules/simplicial-complex-contour/contour.js ***!
- \************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nmodule.exports = extractContour\n\nvar ndarray = __webpack_require__(/*! ndarray */ \"./node_modules/ndarray/ndarray.js\")\nvar pool = __webpack_require__(/*! typedarray-pool */ \"./node_modules/typedarray-pool/pool.js\")\nvar ndsort = __webpack_require__(/*! ndarray-sort */ \"./node_modules/ndarray-sort/sort.js\")\n\nvar contourAlgorithm = __webpack_require__(/*! ./lib/codegen */ \"./node_modules/simplicial-complex-contour/lib/codegen.js\")\n\nfunction getDimension(cells) {\n var numCells = cells.length\n var d = 0\n for(var i=0; i>1,v=E[2*m+1];',\n 'if(v===b){return m}',\n 'if(b 0) {\n code.push(',')\n }\n code.push('[')\n for(var j=0; j 0) {\n code.push(',')\n }\n code.push('B(C,E,c[', f[0], '],c[', f[1], '])')\n }\n code.push(']')\n }\n code.push(');')\n }\n\n for(var i=d+1; i>1; --i) {\n if(i < d+1) {\n code.push('else ')\n }\n code.push('if(l===', i, '){')\n\n //Generate mask\n var maskStr = []\n for(var j=0; j> 1\n , s = compareCells(cells[mid], c)\n if(s <= 0) {\n if(s === 0) {\n r = mid\n }\n lo = mid + 1\n } else if(s > 0) {\n hi = mid - 1\n }\n }\n return r\n}\nexports.findCell = findCell;\n\n//Builds an index for an n-cell. This is more general than dual, but less efficient\nfunction incidence(from_cells, to_cells) {\n var index = new Array(from_cells.length)\n for(var i=0, il=index.length; i= from_cells.length || compareCells(from_cells[idx], b) !== 0) {\n break\n }\n }\n }\n }\n return index\n}\nexports.incidence = incidence\n\n//Computes the dual of the mesh. This is basically an optimized version of buildIndex for the situation where from_cells is just the list of vertices\nfunction dual(cells, vertex_count) {\n if(!vertex_count) {\n return incidence(unique(skeleton(cells, 0)), cells, 0)\n }\n var res = new Array(vertex_count)\n for(var i=0; i>> k) & 1) {\n b.push(c[k])\n }\n }\n result.push(b)\n }\n }\n return normalize(result)\n}\nexports.explode = explode\n\n//Enumerates all of the n-cells of a cell complex\nfunction skeleton(cells, n) {\n if(n < 0) {\n return []\n }\n var result = []\n , k0 = (1<<(n+1))-1\n for(var i=0; i 0) - (v < 0);\n}\n\n//Computes absolute value of integer\nexports.abs = function(v) {\n var mask = v >> (INT_BITS-1);\n return (v ^ mask) - mask;\n}\n\n//Computes minimum of integers x and y\nexports.min = function(x, y) {\n return y ^ ((x ^ y) & -(x < y));\n}\n\n//Computes maximum of integers x and y\nexports.max = function(x, y) {\n return x ^ ((x ^ y) & -(x < y));\n}\n\n//Checks if a number is a power of two\nexports.isPow2 = function(v) {\n return !(v & (v-1)) && (!!v);\n}\n\n//Computes log base 2 of v\nexports.log2 = function(v) {\n var r, shift;\n r = (v > 0xFFFF) << 4; v >>>= r;\n shift = (v > 0xFF ) << 3; v >>>= shift; r |= shift;\n shift = (v > 0xF ) << 2; v >>>= shift; r |= shift;\n shift = (v > 0x3 ) << 1; v >>>= shift; r |= shift;\n return r | (v >> 1);\n}\n\n//Computes log base 10 of v\nexports.log10 = function(v) {\n return (v >= 1000000000) ? 9 : (v >= 100000000) ? 8 : (v >= 10000000) ? 7 :\n (v >= 1000000) ? 6 : (v >= 100000) ? 5 : (v >= 10000) ? 4 :\n (v >= 1000) ? 3 : (v >= 100) ? 2 : (v >= 10) ? 1 : 0;\n}\n\n//Counts number of bits\nexports.popCount = function(v) {\n v = v - ((v >>> 1) & 0x55555555);\n v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);\n return ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24;\n}\n\n//Counts number of trailing zeros\nfunction countTrailingZeros(v) {\n var c = 32;\n v &= -v;\n if (v) c--;\n if (v & 0x0000FFFF) c -= 16;\n if (v & 0x00FF00FF) c -= 8;\n if (v & 0x0F0F0F0F) c -= 4;\n if (v & 0x33333333) c -= 2;\n if (v & 0x55555555) c -= 1;\n return c;\n}\nexports.countTrailingZeros = countTrailingZeros;\n\n//Rounds to next power of 2\nexports.nextPow2 = function(v) {\n v += v === 0;\n --v;\n v |= v >>> 1;\n v |= v >>> 2;\n v |= v >>> 4;\n v |= v >>> 8;\n v |= v >>> 16;\n return v + 1;\n}\n\n//Rounds down to previous power of 2\nexports.prevPow2 = function(v) {\n v |= v >>> 1;\n v |= v >>> 2;\n v |= v >>> 4;\n v |= v >>> 8;\n v |= v >>> 16;\n return v - (v>>>1);\n}\n\n//Computes parity of word\nexports.parity = function(v) {\n v ^= v >>> 16;\n v ^= v >>> 8;\n v ^= v >>> 4;\n v &= 0xf;\n return (0x6996 >>> v) & 1;\n}\n\nvar REVERSE_TABLE = new Array(256);\n\n(function(tab) {\n for(var i=0; i<256; ++i) {\n var v = i, r = i, s = 7;\n for (v >>>= 1; v; v >>>= 1) {\n r <<= 1;\n r |= v & 1;\n --s;\n }\n tab[i] = (r << s) & 0xff;\n }\n})(REVERSE_TABLE);\n\n//Reverse bits in a 32 bit word\nexports.reverse = function(v) {\n return (REVERSE_TABLE[ v & 0xff] << 24) |\n (REVERSE_TABLE[(v >>> 8) & 0xff] << 16) |\n (REVERSE_TABLE[(v >>> 16) & 0xff] << 8) |\n REVERSE_TABLE[(v >>> 24) & 0xff];\n}\n\n//Interleave bits of 2 coordinates with 16 bits. Useful for fast quadtree codes\nexports.interleave2 = function(x, y) {\n x &= 0xFFFF;\n x = (x | (x << 8)) & 0x00FF00FF;\n x = (x | (x << 4)) & 0x0F0F0F0F;\n x = (x | (x << 2)) & 0x33333333;\n x = (x | (x << 1)) & 0x55555555;\n\n y &= 0xFFFF;\n y = (y | (y << 8)) & 0x00FF00FF;\n y = (y | (y << 4)) & 0x0F0F0F0F;\n y = (y | (y << 2)) & 0x33333333;\n y = (y | (y << 1)) & 0x55555555;\n\n return x | (y << 1);\n}\n\n//Extracts the nth interleaved component\nexports.deinterleave2 = function(v, n) {\n v = (v >>> n) & 0x55555555;\n v = (v | (v >>> 1)) & 0x33333333;\n v = (v | (v >>> 2)) & 0x0F0F0F0F;\n v = (v | (v >>> 4)) & 0x00FF00FF;\n v = (v | (v >>> 16)) & 0x000FFFF;\n return (v << 16) >> 16;\n}\n\n\n//Interleave bits of 3 coordinates, each with 10 bits. Useful for fast octree codes\nexports.interleave3 = function(x, y, z) {\n x &= 0x3FF;\n x = (x | (x<<16)) & 4278190335;\n x = (x | (x<<8)) & 251719695;\n x = (x | (x<<4)) & 3272356035;\n x = (x | (x<<2)) & 1227133513;\n\n y &= 0x3FF;\n y = (y | (y<<16)) & 4278190335;\n y = (y | (y<<8)) & 251719695;\n y = (y | (y<<4)) & 3272356035;\n y = (y | (y<<2)) & 1227133513;\n x |= (y << 1);\n \n z &= 0x3FF;\n z = (z | (z<<16)) & 4278190335;\n z = (z | (z<<8)) & 251719695;\n z = (z | (z<<4)) & 3272356035;\n z = (z | (z<<2)) & 1227133513;\n \n return x | (z << 2);\n}\n\n//Extracts nth interleaved component of a 3-tuple\nexports.deinterleave3 = function(v, n) {\n v = (v >>> n) & 1227133513;\n v = (v | (v>>>2)) & 3272356035;\n v = (v | (v>>>4)) & 251719695;\n v = (v | (v>>>8)) & 4278190335;\n v = (v | (v>>>16)) & 0x3FF;\n return (v<<22)>>22;\n}\n\n//Computes next combination in colexicographic order (this is mistakenly called nextPermutation on the bit twiddling hacks page)\nexports.nextCombination = function(v) {\n var t = v | (v - 1);\n return (t + 1) | (((~t & -~t) - 1) >>> (countTrailingZeros(v) + 1));\n}\n\n\n\n//# sourceURL=webpack:///./node_modules/simplify-planar-graph/node_modules/bit-twiddle/twiddle.js?");
-
-/***/ }),
-
-/***/ "./node_modules/simplify-planar-graph/node_modules/simplicial-complex/topology.js":
-/*!****************************************************************************************!*\
- !*** ./node_modules/simplify-planar-graph/node_modules/simplicial-complex/topology.js ***!
- \****************************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval(" \"use restrict\";\n\nvar bits = __webpack_require__(/*! bit-twiddle */ \"./node_modules/simplify-planar-graph/node_modules/bit-twiddle/twiddle.js\")\n , UnionFind = __webpack_require__(/*! union-find */ \"./node_modules/simplify-planar-graph/node_modules/union-find/index.js\")\n\n//Returns the dimension of a cell complex\nfunction dimension(cells) {\n var d = 0\n , max = Math.max\n for(var i=0, il=cells.length; i> 1\n , s = compareCells(cells[mid], c)\n if(s <= 0) {\n if(s === 0) {\n r = mid\n }\n lo = mid + 1\n } else if(s > 0) {\n hi = mid - 1\n }\n }\n return r\n}\nexports.findCell = findCell;\n\n//Builds an index for an n-cell. This is more general than dual, but less efficient\nfunction incidence(from_cells, to_cells) {\n var index = new Array(from_cells.length)\n for(var i=0, il=index.length; i= from_cells.length || compareCells(from_cells[idx], b) !== 0) {\n break\n }\n }\n }\n }\n return index\n}\nexports.incidence = incidence\n\n//Computes the dual of the mesh. This is basically an optimized version of buildIndex for the situation where from_cells is just the list of vertices\nfunction dual(cells, vertex_count) {\n if(!vertex_count) {\n return incidence(unique(skeleton(cells, 0)), cells, 0)\n }\n var res = new Array(vertex_count)\n for(var i=0; i>> k) & 1) {\n b.push(c[k])\n }\n }\n result.push(b)\n }\n }\n return normalize(result)\n}\nexports.explode = explode\n\n//Enumerates all of the n-cells of a cell complex\nfunction skeleton(cells, n) {\n if(n < 0) {\n return []\n }\n var result = []\n , k0 = (1<<(n+1))-1\n for(var i=0; i> 1\n }\n return (i >> 1) - 1\n }\n\n //Bubble element i down the heap\n function heapDown(i) {\n var w = heapWeight(i)\n while(true) {\n var tw = w\n var left = 2*i + 1\n var right = 2*(i + 1)\n var next = i\n if(left < heapCount) {\n var lw = heapWeight(left)\n if(lw < tw) {\n next = left\n tw = lw\n }\n }\n if(right < heapCount) {\n var rw = heapWeight(right)\n if(rw < tw) {\n next = right\n }\n }\n if(next === i) {\n return i\n }\n heapSwap(i, next)\n i = next \n }\n }\n\n //Bubbles element i up the heap\n function heapUp(i) {\n var w = heapWeight(i)\n while(i > 0) {\n var parent = heapParent(i)\n if(parent >= 0) {\n var pw = heapWeight(parent)\n if(w < pw) {\n heapSwap(i, parent)\n i = parent\n continue\n }\n }\n return i\n }\n }\n\n //Pop minimum element\n function heapPop() {\n if(heapCount > 0) {\n var head = heap[0]\n heapSwap(0, heapCount-1)\n heapCount -= 1\n heapDown(0)\n return head\n }\n return -1\n }\n\n //Update heap item i\n function heapUpdate(i, w) {\n var a = heap[i]\n if(weights[a] === w) {\n return i\n }\n weights[a] = -Infinity\n heapUp(i)\n heapPop()\n weights[a] = w\n heapCount += 1\n return heapUp(heapCount-1)\n }\n\n //Kills a vertex (assume vertex already removed from heap)\n function kill(i) {\n if(dead[i]) {\n return\n }\n //Kill vertex\n dead[i] = true\n //Fixup topology\n var s = inv[i]\n var t = outv[i]\n if(inv[t] >= 0) {\n inv[t] = s\n }\n if(outv[s] >= 0) {\n outv[s] = t\n }\n\n //Update weights on s and t\n if(index[s] >= 0) {\n heapUpdate(index[s], computeWeight(s))\n }\n if(index[t] >= 0) {\n heapUpdate(index[t], computeWeight(t))\n }\n }\n\n //Initialize weights and heap\n var heap = []\n var index = new Array(n)\n for(var i=0; i>1; i>=0; --i) {\n heapDown(i)\n }\n \n //Kill vertices\n while(true) {\n var hmin = heapPop()\n if((hmin < 0) || (weights[hmin] > minArea)) {\n break\n }\n kill(hmin)\n }\n\n //Build collapsed vertex table\n var npositions = []\n for(var i=0; i= 0 && tout >= 0 && tin !== tout) {\n var cin = index[tin]\n var cout = index[tout]\n if(cin !== cout) {\n ncells.push([ cin, cout ])\n }\n }\n })\n\n //Normalize result\n sc.unique(sc.normalize(ncells))\n\n //Return final list of cells\n return {\n positions: npositions,\n edges: ncells\n }\n}\n\n//# sourceURL=webpack:///./node_modules/simplify-planar-graph/simplify.js?");
-
-/***/ }),
-
-/***/ "./node_modules/slab-decomposition/lib/order-segments.js":
-/*!***************************************************************!*\
- !*** ./node_modules/slab-decomposition/lib/order-segments.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nmodule.exports = orderSegments\n\nvar orient = __webpack_require__(/*! robust-orientation */ \"./node_modules/robust-orientation/orientation.js\")\n\nfunction horizontalOrder(a, b) {\n var bl, br\n if(b[0][0] < b[1][0]) {\n bl = b[0]\n br = b[1]\n } else if(b[0][0] > b[1][0]) {\n bl = b[1]\n br = b[0]\n } else {\n var alo = Math.min(a[0][1], a[1][1])\n var ahi = Math.max(a[0][1], a[1][1])\n var blo = Math.min(b[0][1], b[1][1])\n var bhi = Math.max(b[0][1], b[1][1])\n if(ahi < blo) {\n return ahi - blo\n }\n if(alo > bhi) {\n return alo - bhi\n }\n return ahi - bhi\n }\n var al, ar\n if(a[0][1] < a[1][1]) {\n al = a[0]\n ar = a[1]\n } else {\n al = a[1]\n ar = a[0]\n }\n var d = orient(br, bl, al)\n if(d) {\n return d\n }\n d = orient(br, bl, ar)\n if(d) {\n return d\n }\n return ar - br\n}\n\nfunction orderSegments(b, a) {\n var al, ar\n if(a[0][0] < a[1][0]) {\n al = a[0]\n ar = a[1]\n } else if(a[0][0] > a[1][0]) {\n al = a[1]\n ar = a[0]\n } else {\n return horizontalOrder(a, b)\n }\n var bl, br\n if(b[0][0] < b[1][0]) {\n bl = b[0]\n br = b[1]\n } else if(b[0][0] > b[1][0]) {\n bl = b[1]\n br = b[0]\n } else {\n return -horizontalOrder(b, a)\n }\n var d1 = orient(al, ar, br)\n var d2 = orient(al, ar, bl)\n if(d1 < 0) {\n if(d2 <= 0) {\n return d1\n }\n } else if(d1 > 0) {\n if(d2 >= 0) {\n return d1\n }\n } else if(d2) {\n return d2\n }\n d1 = orient(br, bl, ar)\n d2 = orient(br, bl, al)\n if(d1 < 0) {\n if(d2 <= 0) {\n return d1\n }\n } else if(d1 > 0) {\n if(d2 >= 0) {\n return d1\n }\n } else if(d2) {\n return d2\n }\n return ar[0] - br[0]\n}\n\n//# sourceURL=webpack:///./node_modules/slab-decomposition/lib/order-segments.js?");
-
-/***/ }),
-
-/***/ "./node_modules/slab-decomposition/node_modules/binary-search-bounds/search-bounds.js":
-/*!********************************************************************************************!*\
- !*** ./node_modules/slab-decomposition/node_modules/binary-search-bounds/search-bounds.js ***!
- \********************************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nfunction compileSearch(funcName, predicate, reversed, extraArgs, useNdarray, earlyOut) {\n var code = [\n \"function \", funcName, \"(a,l,h,\", extraArgs.join(\",\"), \"){\",\nearlyOut ? \"\" : \"var i=\", (reversed ? \"l-1\" : \"h+1\"),\n\";while(l<=h){\\\nvar m=(l+h)>>>1,x=a\", useNdarray ? \".get(m)\" : \"[m]\"]\n if(earlyOut) {\n if(predicate.indexOf(\"c\") < 0) {\n code.push(\";if(x===y){return m}else if(x<=y){\")\n } else {\n code.push(\";var p=c(x,y);if(p===0){return m}else if(p<=0){\")\n }\n } else {\n code.push(\";if(\", predicate, \"){i=m;\")\n }\n if(reversed) {\n code.push(\"l=m+1}else{h=m-1}\")\n } else {\n code.push(\"h=m-1}else{l=m+1}\")\n }\n code.push(\"}\")\n if(earlyOut) {\n code.push(\"return -1};\")\n } else {\n code.push(\"return i};\")\n }\n return code.join(\"\")\n}\n\nfunction compileBoundsSearch(predicate, reversed, suffix, earlyOut) {\n var result = new Function([\n compileSearch(\"A\", \"x\" + predicate + \"y\", reversed, [\"y\"], false, earlyOut),\n compileSearch(\"B\", \"x\" + predicate + \"y\", reversed, [\"y\"], true, earlyOut),\n compileSearch(\"P\", \"c(x,y)\" + predicate + \"0\", reversed, [\"y\", \"c\"], false, earlyOut),\n compileSearch(\"Q\", \"c(x,y)\" + predicate + \"0\", reversed, [\"y\", \"c\"], true, earlyOut),\n\"function dispatchBsearch\", suffix, \"(a,y,c,l,h){\\\nif(a.shape){\\\nif(typeof(c)==='function'){\\\nreturn Q(a,(l===undefined)?0:l|0,(h===undefined)?a.shape[0]-1:h|0,y,c)\\\n}else{\\\nreturn B(a,(c===undefined)?0:c|0,(l===undefined)?a.shape[0]-1:l|0,y)\\\n}}else{\\\nif(typeof(c)==='function'){\\\nreturn P(a,(l===undefined)?0:l|0,(h===undefined)?a.length-1:h|0,y,c)\\\n}else{\\\nreturn A(a,(c===undefined)?0:c|0,(l===undefined)?a.length-1:l|0,y)\\\n}}}\\\nreturn dispatchBsearch\", suffix].join(\"\"))\n return result()\n}\n\nmodule.exports = {\n ge: compileBoundsSearch(\">=\", false, \"GE\"),\n gt: compileBoundsSearch(\">\", false, \"GT\"),\n lt: compileBoundsSearch(\"<\", true, \"LT\"),\n le: compileBoundsSearch(\"<=\", true, \"LE\"),\n eq: compileBoundsSearch(\"-\", true, \"EQ\", true)\n}\n\n\n//# sourceURL=webpack:///./node_modules/slab-decomposition/node_modules/binary-search-bounds/search-bounds.js?");
-
-/***/ }),
-
-/***/ "./node_modules/slab-decomposition/slabs.js":
-/*!**************************************************!*\
- !*** ./node_modules/slab-decomposition/slabs.js ***!
- \**************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nmodule.exports = createSlabDecomposition\n\nvar bounds = __webpack_require__(/*! binary-search-bounds */ \"./node_modules/slab-decomposition/node_modules/binary-search-bounds/search-bounds.js\")\nvar createRBTree = __webpack_require__(/*! functional-red-black-tree */ \"./node_modules/functional-red-black-tree/rbtree.js\")\nvar orient = __webpack_require__(/*! robust-orientation */ \"./node_modules/robust-orientation/orientation.js\")\nvar orderSegments = __webpack_require__(/*! ./lib/order-segments */ \"./node_modules/slab-decomposition/lib/order-segments.js\")\n\nfunction SlabDecomposition(slabs, coordinates, horizontal) {\n this.slabs = slabs\n this.coordinates = coordinates\n this.horizontal = horizontal\n}\n\nvar proto = SlabDecomposition.prototype\n\nfunction compareHorizontal(e, y) {\n return e.y - y\n}\n\nfunction searchBucket(root, p) {\n var lastNode = null\n while(root) {\n var seg = root.key\n var l, r\n if(seg[0][0] < seg[1][0]) {\n l = seg[0]\n r = seg[1]\n } else {\n l = seg[1]\n r = seg[0]\n }\n var o = orient(l, r, p)\n if(o < 0) {\n root = root.left\n } else if(o > 0) {\n if(p[0] !== seg[1][0]) {\n lastNode = root\n root = root.right\n } else {\n var val = searchBucket(root.right, p)\n if(val) {\n return val\n }\n root = root.left\n }\n } else {\n if(p[0] !== seg[1][0]) {\n return root\n } else {\n var val = searchBucket(root.right, p)\n if(val) {\n return val\n }\n root = root.left\n }\n }\n }\n return lastNode\n}\n\nproto.castUp = function(p) {\n var bucket = bounds.le(this.coordinates, p[0])\n if(bucket < 0) {\n return -1\n }\n var root = this.slabs[bucket]\n var hitNode = searchBucket(this.slabs[bucket], p)\n var lastHit = -1\n if(hitNode) {\n lastHit = hitNode.value\n }\n //Edge case: need to handle horizontal segments (sucks)\n if(this.coordinates[bucket] === p[0]) {\n var lastSegment = null\n if(hitNode) {\n lastSegment = hitNode.key\n }\n if(bucket > 0) {\n var otherHitNode = searchBucket(this.slabs[bucket-1], p)\n if(otherHitNode) {\n if(lastSegment) {\n if(orderSegments(otherHitNode.key, lastSegment) > 0) {\n lastSegment = otherHitNode.key\n lastHit = otherHitNode.value\n }\n } else {\n lastHit = otherHitNode.value\n lastSegment = otherHitNode.key\n }\n }\n }\n var horiz = this.horizontal[bucket]\n if(horiz.length > 0) {\n var hbucket = bounds.ge(horiz, p[1], compareHorizontal)\n if(hbucket < horiz.length) {\n var e = horiz[hbucket]\n if(p[1] === e.y) {\n if(e.closed) {\n return e.index\n } else {\n while(hbucket < horiz.length-1 && horiz[hbucket+1].y === p[1]) {\n hbucket = hbucket+1\n e = horiz[hbucket]\n if(e.closed) {\n return e.index\n }\n }\n if(e.y === p[1] && !e.start) {\n hbucket = hbucket+1\n if(hbucket >= horiz.length) {\n return lastHit\n }\n e = horiz[hbucket]\n }\n }\n }\n //Check if e is above/below last segment\n if(e.start) {\n if(lastSegment) {\n var o = orient(lastSegment[0], lastSegment[1], [p[0], e.y])\n if(lastSegment[0][0] > lastSegment[1][0]) {\n o = -o\n }\n if(o > 0) {\n lastHit = e.index\n }\n } else {\n lastHit = e.index\n }\n } else if(e.y !== p[1]) {\n lastHit = e.index\n }\n }\n }\n }\n return lastHit\n}\n\nfunction IntervalSegment(y, index, start, closed) {\n this.y = y\n this.index = index\n this.start = start\n this.closed = closed\n}\n\nfunction Event(x, segment, create, index) {\n this.x = x\n this.segment = segment\n this.create = create\n this.index = index\n}\n\n\nfunction createSlabDecomposition(segments) {\n var numSegments = segments.length\n var numEvents = 2 * numSegments\n var events = new Array(numEvents)\n for(var i=0; i 1.0) {\n t = 1.0\n }\n var ti = 1.0 - t\n var n = a.length\n var r = new Array(n)\n for(var i=0; i 0) || (a > 0 && b < 0)) {\n var p = lerpW(s, b, t, a)\n pos.push(p)\n neg.push(p.slice())\n }\n if(b < 0) {\n neg.push(t.slice())\n } else if(b > 0) {\n pos.push(t.slice())\n } else {\n pos.push(t.slice())\n neg.push(t.slice())\n }\n a = b\n }\n return { positive: pos, negative: neg }\n}\n\nfunction positive(points, plane) {\n var pos = []\n var a = planeT(points[points.length-1], plane)\n for(var s=points[points.length-1], t=points[0], i=0; i 0) || (a > 0 && b < 0)) {\n pos.push(lerpW(s, b, t, a))\n }\n if(b >= 0) {\n pos.push(t.slice())\n }\n a = b\n }\n return pos\n}\n\nfunction negative(points, plane) {\n var neg = []\n var a = planeT(points[points.length-1], plane)\n for(var s=points[points.length-1], t=points[0], i=0; i 0) || (a > 0 && b < 0)) {\n neg.push(lerpW(s, b, t, a))\n }\n if(b <= 0) {\n neg.push(t.slice())\n }\n a = b\n }\n return neg\n}\n\n//# sourceURL=webpack:///./node_modules/split-polygon/clip-poly.js?");
-
-/***/ }),
-
-/***/ "./node_modules/sprintf-js/src/sprintf.js":
-/*!************************************************!*\
- !*** ./node_modules/sprintf-js/src/sprintf.js ***!
- \************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-eval("var __WEBPACK_AMD_DEFINE_RESULT__;/* global window, exports, define */\n\n!function() {\n 'use strict'\n\n var re = {\n not_string: /[^s]/,\n not_bool: /[^t]/,\n not_type: /[^T]/,\n not_primitive: /[^v]/,\n number: /[diefg]/,\n numeric_arg: /[bcdiefguxX]/,\n json: /[j]/,\n not_json: /[^j]/,\n text: /^[^\\x25]+/,\n modulo: /^\\x25{2}/,\n placeholder: /^\\x25(?:([1-9]\\d*)\\$|\\(([^)]+)\\))?(\\+)?(0|'[^$])?(-)?(\\d+)?(?:\\.(\\d+))?([b-gijostTuvxX])/,\n key: /^([a-z_][a-z_\\d]*)/i,\n key_access: /^\\.([a-z_][a-z_\\d]*)/i,\n index_access: /^\\[(\\d+)\\]/,\n sign: /^[+-]/\n }\n\n function sprintf(key) {\n // `arguments` is not an array, but should be fine for this call\n return sprintf_format(sprintf_parse(key), arguments)\n }\n\n function vsprintf(fmt, argv) {\n return sprintf.apply(null, [fmt].concat(argv || []))\n }\n\n function sprintf_format(parse_tree, argv) {\n var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign\n for (i = 0; i < tree_length; i++) {\n if (typeof parse_tree[i] === 'string') {\n output += parse_tree[i]\n }\n else if (typeof parse_tree[i] === 'object') {\n ph = parse_tree[i] // convenience purposes only\n if (ph.keys) { // keyword argument\n arg = argv[cursor]\n for (k = 0; k < ph.keys.length; k++) {\n if (arg == undefined) {\n throw new Error(sprintf('[sprintf] Cannot access property \"%s\" of undefined value \"%s\"', ph.keys[k], ph.keys[k-1]))\n }\n arg = arg[ph.keys[k]]\n }\n }\n else if (ph.param_no) { // positional argument (explicit)\n arg = argv[ph.param_no]\n }\n else { // positional argument (implicit)\n arg = argv[cursor++]\n }\n\n if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {\n arg = arg()\n }\n\n if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {\n throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg))\n }\n\n if (re.number.test(ph.type)) {\n is_positive = arg >= 0\n }\n\n switch (ph.type) {\n case 'b':\n arg = parseInt(arg, 10).toString(2)\n break\n case 'c':\n arg = String.fromCharCode(parseInt(arg, 10))\n break\n case 'd':\n case 'i':\n arg = parseInt(arg, 10)\n break\n case 'j':\n arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0)\n break\n case 'e':\n arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential()\n break\n case 'f':\n arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg)\n break\n case 'g':\n arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg)\n break\n case 'o':\n arg = (parseInt(arg, 10) >>> 0).toString(8)\n break\n case 's':\n arg = String(arg)\n arg = (ph.precision ? arg.substring(0, ph.precision) : arg)\n break\n case 't':\n arg = String(!!arg)\n arg = (ph.precision ? arg.substring(0, ph.precision) : arg)\n break\n case 'T':\n arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase()\n arg = (ph.precision ? arg.substring(0, ph.precision) : arg)\n break\n case 'u':\n arg = parseInt(arg, 10) >>> 0\n break\n case 'v':\n arg = arg.valueOf()\n arg = (ph.precision ? arg.substring(0, ph.precision) : arg)\n break\n case 'x':\n arg = (parseInt(arg, 10) >>> 0).toString(16)\n break\n case 'X':\n arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase()\n break\n }\n if (re.json.test(ph.type)) {\n output += arg\n }\n else {\n if (re.number.test(ph.type) && (!is_positive || ph.sign)) {\n sign = is_positive ? '+' : '-'\n arg = arg.toString().replace(re.sign, '')\n }\n else {\n sign = ''\n }\n pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' '\n pad_length = ph.width - (sign + arg).length\n pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : ''\n output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)\n }\n }\n }\n return output\n }\n\n var sprintf_cache = Object.create(null)\n\n function sprintf_parse(fmt) {\n if (sprintf_cache[fmt]) {\n return sprintf_cache[fmt]\n }\n\n var _fmt = fmt, match, parse_tree = [], arg_names = 0\n while (_fmt) {\n if ((match = re.text.exec(_fmt)) !== null) {\n parse_tree.push(match[0])\n }\n else if ((match = re.modulo.exec(_fmt)) !== null) {\n parse_tree.push('%')\n }\n else if ((match = re.placeholder.exec(_fmt)) !== null) {\n if (match[2]) {\n arg_names |= 1\n var field_list = [], replacement_field = match[2], field_match = []\n if ((field_match = re.key.exec(replacement_field)) !== null) {\n field_list.push(field_match[1])\n while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {\n if ((field_match = re.key_access.exec(replacement_field)) !== null) {\n field_list.push(field_match[1])\n }\n else if ((field_match = re.index_access.exec(replacement_field)) !== null) {\n field_list.push(field_match[1])\n }\n else {\n throw new SyntaxError('[sprintf] failed to parse named argument key')\n }\n }\n }\n else {\n throw new SyntaxError('[sprintf] failed to parse named argument key')\n }\n match[2] = field_list\n }\n else {\n arg_names |= 2\n }\n if (arg_names === 3) {\n throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported')\n }\n\n parse_tree.push(\n {\n placeholder: match[0],\n param_no: match[1],\n keys: match[2],\n sign: match[3],\n pad_char: match[4],\n align: match[5],\n width: match[6],\n precision: match[7],\n type: match[8]\n }\n )\n }\n else {\n throw new SyntaxError('[sprintf] unexpected placeholder')\n }\n _fmt = _fmt.substring(match[0].length)\n }\n return sprintf_cache[fmt] = parse_tree\n }\n\n /**\n * export to either browser or node.js\n */\n /* eslint-disable quote-props */\n if (true) {\n exports['sprintf'] = sprintf\n exports['vsprintf'] = vsprintf\n }\n if (typeof window !== 'undefined') {\n window['sprintf'] = sprintf\n window['vsprintf'] = vsprintf\n\n if (true) {\n !(__WEBPACK_AMD_DEFINE_RESULT__ = (function() {\n return {\n 'sprintf': sprintf,\n 'vsprintf': vsprintf\n }\n }).call(exports, __webpack_require__, exports, module),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))\n }\n }\n /* eslint-enable quote-props */\n}(); // eslint-disable-line\n\n\n//# sourceURL=webpack:///./node_modules/sprintf-js/src/sprintf.js?");
-
-/***/ }),
-
-/***/ "./node_modules/string-split-by/index.js":
-/*!***********************************************!*\
- !*** ./node_modules/string-split-by/index.js ***!
- \***********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\r\n\r\nvar paren = __webpack_require__(/*! parenthesis */ \"./node_modules/parenthesis/index.js\")\r\n\r\nmodule.exports = function splitBy (string, separator, o) {\r\n\tif (string == null) throw Error('First argument should be a string')\r\n\tif (separator == null) throw Error('Separator should be a string or a RegExp')\r\n\r\n\tif (!o) o = {}\r\n\telse if (typeof o === 'string' || Array.isArray(o)) {\r\n\t\to = {ignore: o}\r\n\t}\r\n\r\n\tif (o.escape == null) o.escape = true\r\n\tif (o.ignore == null) o.ignore = ['[]', '()', '{}', '<>', '\"\"', \"''\", '``', '“”', '«»']\r\n\telse {\r\n\t\tif (typeof o.ignore === 'string') {o.ignore = [o.ignore]}\r\n\r\n\t\to.ignore = o.ignore.map(function (pair) {\r\n\t\t\t// '\"' → '\"\"'\r\n\t\t\tif (pair.length === 1) pair = pair + pair\r\n\t\t\treturn pair\r\n\t\t})\r\n\t}\r\n\r\n\tvar tokens = paren.parse(string, {flat: true, brackets: o.ignore})\r\n\tvar str = tokens[0]\r\n\r\n\tvar parts = str.split(separator)\r\n\r\n\t// join parts separated by escape\r\n\tif (o.escape) {\r\n\t\tvar cleanParts = []\r\n\t\tfor (var i = 0; i < parts.length; i++) {\r\n\t\t\tvar prev = parts[i]\r\n\t\t\tvar part = parts[i + 1]\r\n\r\n\t\t\tif (prev[prev.length - 1] === '\\\\' && prev[prev.length - 2] !== '\\\\') {\r\n\t\t\t\tcleanParts.push(prev + separator + part)\r\n\t\t\t\ti++\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tcleanParts.push(prev)\r\n\t\t\t}\r\n\t\t}\r\n\t\tparts = cleanParts\r\n\t}\r\n\r\n\t// open parens pack & apply unquotes, if any\r\n\tfor (var i = 0; i < parts.length; i++) {\r\n\t\ttokens[0] = parts[i]\r\n\t\tparts[i] = paren.stringify(tokens, {flat: true})\r\n\t}\r\n\r\n\treturn parts\r\n}\r\n\n\n//# sourceURL=webpack:///./node_modules/string-split-by/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/strip-indent/index.js":
-/*!********************************************!*\
- !*** ./node_modules/strip-indent/index.js ***!
- \********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\nmodule.exports = str => {\n\tconst match = str.match(/^[ \\t]*(?=\\S)/gm);\n\n\tif (!match) {\n\t\treturn str;\n\t}\n\n\t// TODO: use spread operator when targeting Node.js 6\n\tconst indent = Math.min.apply(Math, match.map(x => x.length)); // eslint-disable-line\n\tconst re = new RegExp(`^[ \\\\t]{${indent}}`, 'gm');\n\n\treturn indent > 0 ? str.replace(re, '') : str;\n};\n\n\n//# sourceURL=webpack:///./node_modules/strip-indent/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/strongly-connected-components/scc.js":
-/*!***********************************************************!*\
- !*** ./node_modules/strongly-connected-components/scc.js ***!
- \***********************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nmodule.exports = stronglyConnectedComponents\n\nfunction stronglyConnectedComponents(adjList) {\n var numVertices = adjList.length;\n var index = new Array(numVertices)\n var lowValue = new Array(numVertices)\n var active = new Array(numVertices)\n var child = new Array(numVertices)\n var scc = new Array(numVertices)\n var sccLinks = new Array(numVertices)\n \n //Initialize tables\n for(var i=0; i 0) {\n v = T[T.length-1]\n var e = adjList[v]\n if (child[v] < e.length) { // If we're not done iterating over the children, first try finishing that.\n for(var i=child[v]; i= 0) {\n // Node v is not yet assigned an scc, but once it is that scc can apparently reach scc[u].\n sccLinks[v].push(scc[u])\n }\n }\n child[v] = i // Remember where we left off.\n } else { // If we're done iterating over the children, check whether we have an scc.\n if(lowValue[v] === index[v]) { // TODO: It /might/ be true that T is always a prefix of S (at this point!!!), and if so, this could be used here.\n var component = []\n var links = [], linkCount = 0\n for(var i=S.length-1; i>=0; --i) {\n var w = S[i]\n active[w] = false\n component.push(w)\n links.push(sccLinks[w])\n linkCount += sccLinks[w].length\n scc[w] = components.length\n if(w === v) {\n S.length = i\n break\n }\n }\n components.push(component)\n var allLinks = new Array(linkCount)\n for(var i=0; i c)|0 },\")\n if(dtype === \"generic\") {\n code.push(\"getters:[0],\")\n }\n\n //Generate vertex function\n var cubeArgs = []\n var extraArgs = []\n for(var i=0; i>>7){\")\n }\n for(var i=0; i<1<<(1< 128) {\n if((i%128)===0) {\n if(extraFuncs.length > 0) {\n currentFunc.push(\"}}\")\n }\n var efName = \"vExtra\" + extraFuncs.length\n code.push(\"case \", (i>>>7), \":\", efName, \"(m&0x7f,\", extraArgs.join(), \");break;\")\n currentFunc = [\n \"function \", efName, \"(m,\", extraArgs.join(), \"){switch(m){\"\n ]\n extraFuncs.push(currentFunc)\n } \n }\n currentFunc.push(\"case \", (i&0x7f), \":\")\n var crossings = new Array(dimension)\n var denoms = new Array(dimension)\n var crossingCount = new Array(dimension)\n var bias = new Array(dimension)\n var totalCrossings = 0\n for(var j=0; j j) {\n continue\n }\n if(!(i&(1< 0) {\n cStr = \"+\" + crossingCount[k] + \"*c\"\n }\n var weight = 0.5 * (crossings[k].length / totalCrossings)\n var shift = 0.5 + 0.5 * (bias[k] / totalCrossings)\n vertexStr.push(\"d\" + k + \"-\" + shift + \"-\" + weight + \"*(\" + crossings[k].join(\"+\") + cStr + \")/(\" + denoms[k].join(\"+\") + \")\")\n \n }\n }\n currentFunc.push(\"a.push([\", vertexStr.join(), \"]);\",\n \"break;\")\n }\n code.push(\"}},\")\n if(extraFuncs.length > 0) {\n currentFunc.push(\"}}\")\n }\n\n //Create face function\n var faceArgs = []\n for(var i=0; i<(1<<(dimension-1)); ++i) {\n faceArgs.push(\"v\" + i)\n }\n faceArgs.push(\"c0\", \"c1\", \"p0\", \"p1\", \"a\", \"b\", \"c\")\n code.push(\"cell:function cellFunc(\", faceArgs.join(), \"){\")\n\n var facets = triangulateCube(dimension-1)\n code.push(\"if(p0){b.push(\",\n facets.map(function(f) {\n return \"[\" + f.map(function(v) {\n return \"v\" + v\n }) + \"]\"\n }).join(), \")}else{b.push(\",\n facets.map(function(f) {\n var e = f.slice()\n e.reverse()\n return \"[\" + e.map(function(v) {\n return \"v\" + v\n }) + \"]\"\n }).join(),\n \")}}});function \", funcName, \"(array,level){var verts=[],cells=[];contour(array,verts,cells,level);return {positions:verts,cells:cells};} return \", funcName, \";\")\n\n for(var i=0; i 1) {\n dot = 1;\n }\n\n if (dot < -1) {\n dot = -1;\n }\n\n return sign * Math.acos(dot);\n};\n\nvar getArcCenter = function getArcCenter(px, py, cx, cy, rx, ry, largeArcFlag, sweepFlag, sinphi, cosphi, pxp, pyp) {\n var rxsq = Math.pow(rx, 2);\n var rysq = Math.pow(ry, 2);\n var pxpsq = Math.pow(pxp, 2);\n var pypsq = Math.pow(pyp, 2);\n\n var radicant = rxsq * rysq - rxsq * pypsq - rysq * pxpsq;\n\n if (radicant < 0) {\n radicant = 0;\n }\n\n radicant /= rxsq * pypsq + rysq * pxpsq;\n radicant = Math.sqrt(radicant) * (largeArcFlag === sweepFlag ? -1 : 1);\n\n var centerxp = radicant * rx / ry * pyp;\n var centeryp = radicant * -ry / rx * pxp;\n\n var centerx = cosphi * centerxp - sinphi * centeryp + (px + cx) / 2;\n var centery = sinphi * centerxp + cosphi * centeryp + (py + cy) / 2;\n\n var vx1 = (pxp - centerxp) / rx;\n var vy1 = (pyp - centeryp) / ry;\n var vx2 = (-pxp - centerxp) / rx;\n var vy2 = (-pyp - centeryp) / ry;\n\n var ang1 = vectorAngle(1, 0, vx1, vy1);\n var ang2 = vectorAngle(vx1, vy1, vx2, vy2);\n\n if (sweepFlag === 0 && ang2 > 0) {\n ang2 -= TAU;\n }\n\n if (sweepFlag === 1 && ang2 < 0) {\n ang2 += TAU;\n }\n\n return [centerx, centery, ang1, ang2];\n};\n\nvar arcToBezier = function arcToBezier(_ref2) {\n var px = _ref2.px,\n py = _ref2.py,\n cx = _ref2.cx,\n cy = _ref2.cy,\n rx = _ref2.rx,\n ry = _ref2.ry,\n _ref2$xAxisRotation = _ref2.xAxisRotation,\n xAxisRotation = _ref2$xAxisRotation === undefined ? 0 : _ref2$xAxisRotation,\n _ref2$largeArcFlag = _ref2.largeArcFlag,\n largeArcFlag = _ref2$largeArcFlag === undefined ? 0 : _ref2$largeArcFlag,\n _ref2$sweepFlag = _ref2.sweepFlag,\n sweepFlag = _ref2$sweepFlag === undefined ? 0 : _ref2$sweepFlag;\n\n var curves = [];\n\n if (rx === 0 || ry === 0) {\n return [];\n }\n\n var sinphi = Math.sin(xAxisRotation * TAU / 360);\n var cosphi = Math.cos(xAxisRotation * TAU / 360);\n\n var pxp = cosphi * (px - cx) / 2 + sinphi * (py - cy) / 2;\n var pyp = -sinphi * (px - cx) / 2 + cosphi * (py - cy) / 2;\n\n if (pxp === 0 && pyp === 0) {\n return [];\n }\n\n rx = Math.abs(rx);\n ry = Math.abs(ry);\n\n var lambda = Math.pow(pxp, 2) / Math.pow(rx, 2) + Math.pow(pyp, 2) / Math.pow(ry, 2);\n\n if (lambda > 1) {\n rx *= Math.sqrt(lambda);\n ry *= Math.sqrt(lambda);\n }\n\n var _getArcCenter = getArcCenter(px, py, cx, cy, rx, ry, largeArcFlag, sweepFlag, sinphi, cosphi, pxp, pyp),\n _getArcCenter2 = _slicedToArray(_getArcCenter, 4),\n centerx = _getArcCenter2[0],\n centery = _getArcCenter2[1],\n ang1 = _getArcCenter2[2],\n ang2 = _getArcCenter2[3];\n\n // If 'ang2' == 90.0000000001, then `ratio` will evaluate to\n // 1.0000000001. This causes `segments` to be greater than one, which is an\n // unecessary split, and adds extra points to the bezier curve. To alleviate\n // this issue, we round to 1.0 when the ratio is close to 1.0.\n\n\n var ratio = Math.abs(ang2) / (TAU / 4);\n if (Math.abs(1.0 - ratio) < 0.0000001) {\n ratio = 1.0;\n }\n\n var segments = Math.max(Math.ceil(ratio), 1);\n\n ang2 /= segments;\n\n for (var i = 0; i < segments; i++) {\n curves.push(approxUnitArc(ang1, ang2));\n ang1 += ang2;\n }\n\n return curves.map(function (curve) {\n var _mapToEllipse = mapToEllipse(curve[0], rx, ry, cosphi, sinphi, centerx, centery),\n x1 = _mapToEllipse.x,\n y1 = _mapToEllipse.y;\n\n var _mapToEllipse2 = mapToEllipse(curve[1], rx, ry, cosphi, sinphi, centerx, centery),\n x2 = _mapToEllipse2.x,\n y2 = _mapToEllipse2.y;\n\n var _mapToEllipse3 = mapToEllipse(curve[2], rx, ry, cosphi, sinphi, centerx, centery),\n x = _mapToEllipse3.x,\n y = _mapToEllipse3.y;\n\n return { x1: x1, y1: y1, x2: x2, y2: y2, x: x, y: y };\n });\n};\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (arcToBezier);\n\n//# sourceURL=webpack:///./node_modules/svg-arc-to-cubic-bezier/modules/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/svg-path-bounds/index.js":
-/*!***********************************************!*\
- !*** ./node_modules/svg-path-bounds/index.js ***!
- \***********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\r\n\r\nvar parse = __webpack_require__(/*! parse-svg-path */ \"./node_modules/parse-svg-path/index.js\")\r\nvar abs = __webpack_require__(/*! abs-svg-path */ \"./node_modules/abs-svg-path/index.js\")\r\nvar normalize = __webpack_require__(/*! normalize-svg-path */ \"./node_modules/svg-path-bounds/node_modules/normalize-svg-path/index.js\")\r\nvar isSvgPath = __webpack_require__(/*! is-svg-path */ \"./node_modules/is-svg-path/index.js\")\r\nvar assert = __webpack_require__(/*! assert */ \"./node_modules/assert/assert.js\")\r\n\r\nmodule.exports = pathBounds\r\n\r\n\r\nfunction pathBounds(path) {\r\n // ES6 string tpl call\r\n if (Array.isArray(path) && path.length === 1 && typeof path[0] === 'string') path = path[0]\r\n\r\n // svg path string\r\n if (typeof path === 'string') {\r\n assert(isSvgPath(path), 'String is not an SVG path.')\r\n path = parse(path)\r\n }\r\n\r\n assert(Array.isArray(path), 'Argument should be a string or an array of path segments.')\r\n\r\n path = abs(path)\r\n path = normalize(path)\r\n\r\n if (!path.length) return [0, 0, 0, 0]\r\n\r\n var bounds = [Infinity, Infinity, -Infinity, -Infinity]\r\n\r\n for (var i = 0, l = path.length; i < l; i++) {\r\n var points = path[i].slice(1)\r\n\r\n for (var j = 0; j < points.length; j += 2) {\r\n if (points[j + 0] < bounds[0]) bounds[0] = points[j + 0]\r\n if (points[j + 1] < bounds[1]) bounds[1] = points[j + 1]\r\n if (points[j + 0] > bounds[2]) bounds[2] = points[j + 0]\r\n if (points[j + 1] > bounds[3]) bounds[3] = points[j + 1]\r\n }\r\n }\r\n\r\n return bounds\r\n}\r\n\n\n//# sourceURL=webpack:///./node_modules/svg-path-bounds/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/svg-path-bounds/node_modules/normalize-svg-path/index.js":
-/*!*******************************************************************************!*\
- !*** ./node_modules/svg-path-bounds/node_modules/normalize-svg-path/index.js ***!
- \*******************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\r\n\r\nmodule.exports = normalize\r\n\r\nvar arcToCurve = __webpack_require__(/*! svg-arc-to-cubic-bezier */ \"./node_modules/svg-arc-to-cubic-bezier/modules/index.js\")\r\n\r\nfunction normalize(path){\r\n // init state\r\n var prev\r\n var result = []\r\n var bezierX = 0\r\n var bezierY = 0\r\n var startX = 0\r\n var startY = 0\r\n var quadX = null\r\n var quadY = null\r\n var x = 0\r\n var y = 0\r\n\r\n for (var i = 0, len = path.length; i < len; i++) {\r\n var seg = path[i]\r\n var command = seg[0]\r\n\r\n switch (command) {\r\n case 'M':\r\n startX = seg[1]\r\n startY = seg[2]\r\n break\r\n case 'A':\r\n var curves = arcToCurve({\r\n px: x,\r\n py: y,\r\n cx: seg[6],\r\n cy: seg[7],\r\n rx: seg[1],\r\n ry: seg[2],\r\n xAxisRotation: seg[3],\r\n largeArcFlag: seg[4],\r\n sweepFlag: seg[5]\r\n })\r\n\r\n // null-curves\r\n if (!curves.length) continue\r\n\r\n for (var j = 0, c; j < curves.length; j++) {\r\n c = curves[j]\r\n seg = ['C', c.x1, c.y1, c.x2, c.y2, c.x, c.y]\r\n if (j < curves.length - 1) result.push(seg)\r\n }\r\n\r\n break\r\n case 'S':\r\n // default control point\r\n var cx = x\r\n var cy = y\r\n if (prev == 'C' || prev == 'S') {\r\n cx += cx - bezierX // reflect the previous command's control\r\n cy += cy - bezierY // point relative to the current point\r\n }\r\n seg = ['C', cx, cy, seg[1], seg[2], seg[3], seg[4]]\r\n break\r\n case 'T':\r\n if (prev == 'Q' || prev == 'T') {\r\n quadX = x * 2 - quadX // as with 'S' reflect previous control point\r\n quadY = y * 2 - quadY\r\n } else {\r\n quadX = x\r\n quadY = y\r\n }\r\n seg = quadratic(x, y, quadX, quadY, seg[1], seg[2])\r\n break\r\n case 'Q':\r\n quadX = seg[1]\r\n quadY = seg[2]\r\n seg = quadratic(x, y, seg[1], seg[2], seg[3], seg[4])\r\n break\r\n case 'L':\r\n seg = line(x, y, seg[1], seg[2])\r\n break\r\n case 'H':\r\n seg = line(x, y, seg[1], y)\r\n break\r\n case 'V':\r\n seg = line(x, y, x, seg[1])\r\n break\r\n case 'Z':\r\n seg = line(x, y, startX, startY)\r\n break\r\n }\r\n\r\n // update state\r\n prev = command\r\n x = seg[seg.length - 2]\r\n y = seg[seg.length - 1]\r\n if (seg.length > 4) {\r\n bezierX = seg[seg.length - 4]\r\n bezierY = seg[seg.length - 3]\r\n } else {\r\n bezierX = x\r\n bezierY = y\r\n }\r\n result.push(seg)\r\n }\r\n\r\n return result\r\n}\r\n\r\nfunction line(x1, y1, x2, y2){\r\n return ['C', x1, y1, x2, y2, x2, y2]\r\n}\r\n\r\nfunction quadratic(x1, y1, cx, cy, x2, y2){\r\n return [\r\n 'C',\r\n x1/3 + (2/3) * cx,\r\n y1/3 + (2/3) * cy,\r\n x2/3 + (2/3) * cx,\r\n y2/3 + (2/3) * cy,\r\n x2,\r\n y2\r\n ]\r\n}\r\n\n\n//# sourceURL=webpack:///./node_modules/svg-path-bounds/node_modules/normalize-svg-path/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/svg-path-sdf/index.js":
-/*!********************************************!*\
- !*** ./node_modules/svg-path-sdf/index.js ***!
- \********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\r\n\r\nvar pathBounds = __webpack_require__(/*! svg-path-bounds */ \"./node_modules/svg-path-bounds/index.js\")\r\nvar parsePath = __webpack_require__(/*! parse-svg-path */ \"./node_modules/parse-svg-path/index.js\")\r\nvar drawPath = __webpack_require__(/*! draw-svg-path */ \"./node_modules/draw-svg-path/index.js\")\r\nvar isSvgPath = __webpack_require__(/*! is-svg-path */ \"./node_modules/is-svg-path/index.js\")\r\nvar bitmapSdf = __webpack_require__(/*! bitmap-sdf */ \"./node_modules/bitmap-sdf/index.js\")\r\n\r\nvar canvas = document.createElement('canvas')\r\nvar ctx = canvas.getContext('2d')\r\n\r\n\r\nmodule.exports = pathSdf\r\n\r\n\r\nfunction pathSdf (path, options) {\r\n\tif (!isSvgPath(path)) throw Error('Argument should be valid svg path string')\r\n\r\n\tif (!options) options = {}\r\n\r\n\tvar w, h\r\n\tif (options.shape) {\r\n\t\tw = options.shape[0]\r\n\t\th = options.shape[1]\r\n\t}\r\n\telse {\r\n\t\tw = canvas.width = options.w || options.width || 200\r\n\t\th = canvas.height = options.h || options.height || 200\r\n\t}\r\n\tvar size = Math.min(w, h)\r\n\r\n\tvar stroke = options.stroke || 0\r\n\r\n\tvar viewbox = options.viewbox || options.viewBox || pathBounds(path)\r\n\tvar scale = [w / (viewbox[2] - viewbox[0]), h / (viewbox[3] - viewbox[1])]\r\n\tvar maxScale = Math.min(scale[0] || 0, scale[1] || 0) / 2\r\n\r\n\t//clear ctx\r\n\tctx.fillStyle = 'black'\r\n\tctx.fillRect(0, 0, w, h)\r\n\r\n\tctx.fillStyle = 'white'\r\n\r\n\tif (stroke)\t{\r\n\t\tif (typeof stroke != 'number') stroke = 1\r\n\t\tif (stroke > 0) {\r\n\t\t\tctx.strokeStyle = 'white'\r\n\t\t}\r\n\t\telse {\r\n\t\t\tctx.strokeStyle = 'black'\r\n\t\t}\r\n\r\n\t\tctx.lineWidth = Math.abs(stroke)\r\n\t}\r\n\r\n\tctx.translate(w * .5, h * .5)\r\n\tctx.scale(maxScale, maxScale)\r\n\r\n\t//if canvas svg paths api is available\r\n\tif (isPath2DSupported()) {\r\n\t\tvar path2d = new Path2D(path)\r\n\t\tctx.fill(path2d)\r\n\t\tstroke && ctx.stroke(path2d)\r\n\t}\r\n\t//fallback to bezier-curves\r\n\telse {\r\n\t\tvar segments = parsePath(path)\r\n\t\tdrawPath(ctx, segments)\r\n\t\tctx.fill()\r\n\t\tstroke && ctx.stroke()\r\n\t}\r\n\r\n\tctx.setTransform(1, 0, 0, 1, 0, 0);\r\n\r\n\tvar data = bitmapSdf(ctx, {\r\n\t\tcutoff: options.cutoff != null ? options.cutoff : .5,\r\n\t\tradius: options.radius != null ? options.radius : size * .5\r\n\t})\r\n\r\n\treturn data\r\n}\r\n\r\nvar path2DSupported\r\n\r\nfunction isPath2DSupported () {\r\n\tif (path2DSupported != null) return path2DSupported\r\n\r\n\tvar ctx = document.createElement('canvas').getContext('2d')\r\n\tctx.canvas.width = ctx.canvas.height = 1\r\n\r\n\tif (!window.Path2D) return path2DSupported = false\r\n\r\n\tvar path = new Path2D('M0,0h1v1h-1v-1Z')\r\n\r\n\tctx.fillStyle = 'black'\r\n\tctx.fill(path)\r\n\r\n\tvar idata = ctx.getImageData(0,0,1,1)\r\n\r\n\treturn path2DSupported = idata && idata.data && idata.data[3] === 255\r\n}\r\n\n\n//# sourceURL=webpack:///./node_modules/svg-path-sdf/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/text-cache/textcache.js":
-/*!**********************************************!*\
- !*** ./node_modules/text-cache/textcache.js ***!
- \**********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(process) {\n\nmodule.exports = textGet\n\nvar vectorizeText = __webpack_require__(/*! vectorize-text */ \"./node_modules/vectorize-text/index.js\")\n\nvar globals = window || process.global || {}\nvar __TEXT_CACHE = globals.__TEXT_CACHE || {}\nglobals.__TEXT_CACHE = {}\n\nfunction unwrap(mesh) {\n var cells = mesh.cells\n var positions = mesh.positions\n var data = new Float32Array(cells.length * 6)\n var ptr = 0\n var shapeX = 0\n for(var i=0; i0) {\n shapeX += 0.02\n }\n }\n\n var data = new Float32Array(bufferSize)\n var ptr = 0\n var xOffset = -0.5 * shapeX\n for(var i=0; i= 0;\n var needsAlphaFormat = !formatSet && hasAlpha && (format === \"hex\" || format === \"hex6\" || format === \"hex3\" || format === \"hex4\" || format === \"hex8\" || format === \"name\");\n\n if (needsAlphaFormat) {\n // Special case for \"transparent\", all other non-alpha formats\n // will return rgba when there is transparency.\n if (format === \"name\" && this._a === 0) {\n return this.toName();\n }\n return this.toRgbString();\n }\n if (format === \"rgb\") {\n formattedString = this.toRgbString();\n }\n if (format === \"prgb\") {\n formattedString = this.toPercentageRgbString();\n }\n if (format === \"hex\" || format === \"hex6\") {\n formattedString = this.toHexString();\n }\n if (format === \"hex3\") {\n formattedString = this.toHexString(true);\n }\n if (format === \"hex4\") {\n formattedString = this.toHex8String(true);\n }\n if (format === \"hex8\") {\n formattedString = this.toHex8String();\n }\n if (format === \"name\") {\n formattedString = this.toName();\n }\n if (format === \"hsl\") {\n formattedString = this.toHslString();\n }\n if (format === \"hsv\") {\n formattedString = this.toHsvString();\n }\n\n return formattedString || this.toHexString();\n },\n clone: function() {\n return tinycolor(this.toString());\n },\n\n _applyModification: function(fn, args) {\n var color = fn.apply(null, [this].concat([].slice.call(args)));\n this._r = color._r;\n this._g = color._g;\n this._b = color._b;\n this.setAlpha(color._a);\n return this;\n },\n lighten: function() {\n return this._applyModification(lighten, arguments);\n },\n brighten: function() {\n return this._applyModification(brighten, arguments);\n },\n darken: function() {\n return this._applyModification(darken, arguments);\n },\n desaturate: function() {\n return this._applyModification(desaturate, arguments);\n },\n saturate: function() {\n return this._applyModification(saturate, arguments);\n },\n greyscale: function() {\n return this._applyModification(greyscale, arguments);\n },\n spin: function() {\n return this._applyModification(spin, arguments);\n },\n\n _applyCombination: function(fn, args) {\n return fn.apply(null, [this].concat([].slice.call(args)));\n },\n analogous: function() {\n return this._applyCombination(analogous, arguments);\n },\n complement: function() {\n return this._applyCombination(complement, arguments);\n },\n monochromatic: function() {\n return this._applyCombination(monochromatic, arguments);\n },\n splitcomplement: function() {\n return this._applyCombination(splitcomplement, arguments);\n },\n triad: function() {\n return this._applyCombination(triad, arguments);\n },\n tetrad: function() {\n return this._applyCombination(tetrad, arguments);\n }\n};\n\n// If input is an object, force 1 into \"1.0\" to handle ratios properly\n// String input requires \"1.0\" as input, so 1 will be treated as 1\ntinycolor.fromRatio = function(color, opts) {\n if (typeof color == \"object\") {\n var newColor = {};\n for (var i in color) {\n if (color.hasOwnProperty(i)) {\n if (i === \"a\") {\n newColor[i] = color[i];\n }\n else {\n newColor[i] = convertToPercentage(color[i]);\n }\n }\n }\n color = newColor;\n }\n\n return tinycolor(color, opts);\n};\n\n// Given a string or object, convert that input to RGB\n// Possible string inputs:\n//\n// \"red\"\n// \"#f00\" or \"f00\"\n// \"#ff0000\" or \"ff0000\"\n// \"#ff000000\" or \"ff000000\"\n// \"rgb 255 0 0\" or \"rgb (255, 0, 0)\"\n// \"rgb 1.0 0 0\" or \"rgb (1, 0, 0)\"\n// \"rgba (255, 0, 0, 1)\" or \"rgba 255, 0, 0, 1\"\n// \"rgba (1.0, 0, 0, 1)\" or \"rgba 1.0, 0, 0, 1\"\n// \"hsl(0, 100%, 50%)\" or \"hsl 0 100% 50%\"\n// \"hsla(0, 100%, 50%, 1)\" or \"hsla 0 100% 50%, 1\"\n// \"hsv(0, 100%, 100%)\" or \"hsv 0 100% 100%\"\n//\nfunction inputToRGB(color) {\n\n var rgb = { r: 0, g: 0, b: 0 };\n var a = 1;\n var s = null;\n var v = null;\n var l = null;\n var ok = false;\n var format = false;\n\n if (typeof color == \"string\") {\n color = stringInputToObject(color);\n }\n\n if (typeof color == \"object\") {\n if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) {\n rgb = rgbToRgb(color.r, color.g, color.b);\n ok = true;\n format = String(color.r).substr(-1) === \"%\" ? \"prgb\" : \"rgb\";\n }\n else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) {\n s = convertToPercentage(color.s);\n v = convertToPercentage(color.v);\n rgb = hsvToRgb(color.h, s, v);\n ok = true;\n format = \"hsv\";\n }\n else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) {\n s = convertToPercentage(color.s);\n l = convertToPercentage(color.l);\n rgb = hslToRgb(color.h, s, l);\n ok = true;\n format = \"hsl\";\n }\n\n if (color.hasOwnProperty(\"a\")) {\n a = color.a;\n }\n }\n\n a = boundAlpha(a);\n\n return {\n ok: ok,\n format: color.format || format,\n r: mathMin(255, mathMax(rgb.r, 0)),\n g: mathMin(255, mathMax(rgb.g, 0)),\n b: mathMin(255, mathMax(rgb.b, 0)),\n a: a\n };\n}\n\n\n// Conversion Functions\n// --------------------\n\n// `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:\n// \n\n// `rgbToRgb`\n// Handle bounds / percentage checking to conform to CSS color spec\n// \n// *Assumes:* r, g, b in [0, 255] or [0, 1]\n// *Returns:* { r, g, b } in [0, 255]\nfunction rgbToRgb(r, g, b){\n return {\n r: bound01(r, 255) * 255,\n g: bound01(g, 255) * 255,\n b: bound01(b, 255) * 255\n };\n}\n\n// `rgbToHsl`\n// Converts an RGB color value to HSL.\n// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]\n// *Returns:* { h, s, l } in [0,1]\nfunction rgbToHsl(r, g, b) {\n\n r = bound01(r, 255);\n g = bound01(g, 255);\n b = bound01(b, 255);\n\n var max = mathMax(r, g, b), min = mathMin(r, g, b);\n var h, s, l = (max + min) / 2;\n\n if(max == min) {\n h = s = 0; // achromatic\n }\n else {\n var d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch(max) {\n case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n case g: h = (b - r) / d + 2; break;\n case b: h = (r - g) / d + 4; break;\n }\n\n h /= 6;\n }\n\n return { h: h, s: s, l: l };\n}\n\n// `hslToRgb`\n// Converts an HSL color value to RGB.\n// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]\n// *Returns:* { r, g, b } in the set [0, 255]\nfunction hslToRgb(h, s, l) {\n var r, g, b;\n\n h = bound01(h, 360);\n s = bound01(s, 100);\n l = bound01(l, 100);\n\n function hue2rgb(p, q, t) {\n if(t < 0) t += 1;\n if(t > 1) t -= 1;\n if(t < 1/6) return p + (q - p) * 6 * t;\n if(t < 1/2) return q;\n if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;\n return p;\n }\n\n if(s === 0) {\n r = g = b = l; // achromatic\n }\n else {\n var q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n var p = 2 * l - q;\n r = hue2rgb(p, q, h + 1/3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1/3);\n }\n\n return { r: r * 255, g: g * 255, b: b * 255 };\n}\n\n// `rgbToHsv`\n// Converts an RGB color value to HSV\n// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]\n// *Returns:* { h, s, v } in [0,1]\nfunction rgbToHsv(r, g, b) {\n\n r = bound01(r, 255);\n g = bound01(g, 255);\n b = bound01(b, 255);\n\n var max = mathMax(r, g, b), min = mathMin(r, g, b);\n var h, s, v = max;\n\n var d = max - min;\n s = max === 0 ? 0 : d / max;\n\n if(max == min) {\n h = 0; // achromatic\n }\n else {\n switch(max) {\n case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n case g: h = (b - r) / d + 2; break;\n case b: h = (r - g) / d + 4; break;\n }\n h /= 6;\n }\n return { h: h, s: s, v: v };\n}\n\n// `hsvToRgb`\n// Converts an HSV color value to RGB.\n// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]\n// *Returns:* { r, g, b } in the set [0, 255]\n function hsvToRgb(h, s, v) {\n\n h = bound01(h, 360) * 6;\n s = bound01(s, 100);\n v = bound01(v, 100);\n\n var i = Math.floor(h),\n f = h - i,\n p = v * (1 - s),\n q = v * (1 - f * s),\n t = v * (1 - (1 - f) * s),\n mod = i % 6,\n r = [v, q, p, p, t, v][mod],\n g = [t, v, v, q, p, p][mod],\n b = [p, p, t, v, v, q][mod];\n\n return { r: r * 255, g: g * 255, b: b * 255 };\n}\n\n// `rgbToHex`\n// Converts an RGB color to hex\n// Assumes r, g, and b are contained in the set [0, 255]\n// Returns a 3 or 6 character hex\nfunction rgbToHex(r, g, b, allow3Char) {\n\n var hex = [\n pad2(mathRound(r).toString(16)),\n pad2(mathRound(g).toString(16)),\n pad2(mathRound(b).toString(16))\n ];\n\n // Return a 3 character hex if possible\n if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {\n return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);\n }\n\n return hex.join(\"\");\n}\n\n// `rgbaToHex`\n// Converts an RGBA color plus alpha transparency to hex\n// Assumes r, g, b are contained in the set [0, 255] and\n// a in [0, 1]. Returns a 4 or 8 character rgba hex\nfunction rgbaToHex(r, g, b, a, allow4Char) {\n\n var hex = [\n pad2(mathRound(r).toString(16)),\n pad2(mathRound(g).toString(16)),\n pad2(mathRound(b).toString(16)),\n pad2(convertDecimalToHex(a))\n ];\n\n // Return a 4 character hex if possible\n if (allow4Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1) && hex[3].charAt(0) == hex[3].charAt(1)) {\n return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0);\n }\n\n return hex.join(\"\");\n}\n\n// `rgbaToArgbHex`\n// Converts an RGBA color to an ARGB Hex8 string\n// Rarely used, but required for \"toFilter()\"\nfunction rgbaToArgbHex(r, g, b, a) {\n\n var hex = [\n pad2(convertDecimalToHex(a)),\n pad2(mathRound(r).toString(16)),\n pad2(mathRound(g).toString(16)),\n pad2(mathRound(b).toString(16))\n ];\n\n return hex.join(\"\");\n}\n\n// `equals`\n// Can be called with any tinycolor input\ntinycolor.equals = function (color1, color2) {\n if (!color1 || !color2) { return false; }\n return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();\n};\n\ntinycolor.random = function() {\n return tinycolor.fromRatio({\n r: mathRandom(),\n g: mathRandom(),\n b: mathRandom()\n });\n};\n\n\n// Modification Functions\n// ----------------------\n// Thanks to less.js for some of the basics here\n// \n\nfunction desaturate(color, amount) {\n amount = (amount === 0) ? 0 : (amount || 10);\n var hsl = tinycolor(color).toHsl();\n hsl.s -= amount / 100;\n hsl.s = clamp01(hsl.s);\n return tinycolor(hsl);\n}\n\nfunction saturate(color, amount) {\n amount = (amount === 0) ? 0 : (amount || 10);\n var hsl = tinycolor(color).toHsl();\n hsl.s += amount / 100;\n hsl.s = clamp01(hsl.s);\n return tinycolor(hsl);\n}\n\nfunction greyscale(color) {\n return tinycolor(color).desaturate(100);\n}\n\nfunction lighten (color, amount) {\n amount = (amount === 0) ? 0 : (amount || 10);\n var hsl = tinycolor(color).toHsl();\n hsl.l += amount / 100;\n hsl.l = clamp01(hsl.l);\n return tinycolor(hsl);\n}\n\nfunction brighten(color, amount) {\n amount = (amount === 0) ? 0 : (amount || 10);\n var rgb = tinycolor(color).toRgb();\n rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));\n rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));\n rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));\n return tinycolor(rgb);\n}\n\nfunction darken (color, amount) {\n amount = (amount === 0) ? 0 : (amount || 10);\n var hsl = tinycolor(color).toHsl();\n hsl.l -= amount / 100;\n hsl.l = clamp01(hsl.l);\n return tinycolor(hsl);\n}\n\n// Spin takes a positive or negative amount within [-360, 360] indicating the change of hue.\n// Values outside of this range will be wrapped into this range.\nfunction spin(color, amount) {\n var hsl = tinycolor(color).toHsl();\n var hue = (hsl.h + amount) % 360;\n hsl.h = hue < 0 ? 360 + hue : hue;\n return tinycolor(hsl);\n}\n\n// Combination Functions\n// ---------------------\n// Thanks to jQuery xColor for some of the ideas behind these\n// \n\nfunction complement(color) {\n var hsl = tinycolor(color).toHsl();\n hsl.h = (hsl.h + 180) % 360;\n return tinycolor(hsl);\n}\n\nfunction triad(color) {\n var hsl = tinycolor(color).toHsl();\n var h = hsl.h;\n return [\n tinycolor(color),\n tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),\n tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })\n ];\n}\n\nfunction tetrad(color) {\n var hsl = tinycolor(color).toHsl();\n var h = hsl.h;\n return [\n tinycolor(color),\n tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),\n tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),\n tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })\n ];\n}\n\nfunction splitcomplement(color) {\n var hsl = tinycolor(color).toHsl();\n var h = hsl.h;\n return [\n tinycolor(color),\n tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),\n tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})\n ];\n}\n\nfunction analogous(color, results, slices) {\n results = results || 6;\n slices = slices || 30;\n\n var hsl = tinycolor(color).toHsl();\n var part = 360 / slices;\n var ret = [tinycolor(color)];\n\n for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {\n hsl.h = (hsl.h + part) % 360;\n ret.push(tinycolor(hsl));\n }\n return ret;\n}\n\nfunction monochromatic(color, results) {\n results = results || 6;\n var hsv = tinycolor(color).toHsv();\n var h = hsv.h, s = hsv.s, v = hsv.v;\n var ret = [];\n var modification = 1 / results;\n\n while (results--) {\n ret.push(tinycolor({ h: h, s: s, v: v}));\n v = (v + modification) % 1;\n }\n\n return ret;\n}\n\n// Utility Functions\n// ---------------------\n\ntinycolor.mix = function(color1, color2, amount) {\n amount = (amount === 0) ? 0 : (amount || 50);\n\n var rgb1 = tinycolor(color1).toRgb();\n var rgb2 = tinycolor(color2).toRgb();\n\n var p = amount / 100;\n\n var rgba = {\n r: ((rgb2.r - rgb1.r) * p) + rgb1.r,\n g: ((rgb2.g - rgb1.g) * p) + rgb1.g,\n b: ((rgb2.b - rgb1.b) * p) + rgb1.b,\n a: ((rgb2.a - rgb1.a) * p) + rgb1.a\n };\n\n return tinycolor(rgba);\n};\n\n\n// Readability Functions\n// ---------------------\n// false\n// tinycolor.isReadable(\"#000\", \"#111\",{level:\"AA\",size:\"large\"}) => false\ntinycolor.isReadable = function(color1, color2, wcag2) {\n var readability = tinycolor.readability(color1, color2);\n var wcag2Parms, out;\n\n out = false;\n\n wcag2Parms = validateWCAG2Parms(wcag2);\n switch (wcag2Parms.level + wcag2Parms.size) {\n case \"AAsmall\":\n case \"AAAlarge\":\n out = readability >= 4.5;\n break;\n case \"AAlarge\":\n out = readability >= 3;\n break;\n case \"AAAsmall\":\n out = readability >= 7;\n break;\n }\n return out;\n\n};\n\n// `mostReadable`\n// Given a base color and a list of possible foreground or background\n// colors for that base, returns the most readable color.\n// Optionally returns Black or White if the most readable color is unreadable.\n// *Example*\n// tinycolor.mostReadable(tinycolor.mostReadable(\"#123\", [\"#124\", \"#125\"],{includeFallbackColors:false}).toHexString(); // \"#112255\"\n// tinycolor.mostReadable(tinycolor.mostReadable(\"#123\", [\"#124\", \"#125\"],{includeFallbackColors:true}).toHexString(); // \"#ffffff\"\n// tinycolor.mostReadable(\"#a8015a\", [\"#faf3f3\"],{includeFallbackColors:true,level:\"AAA\",size:\"large\"}).toHexString(); // \"#faf3f3\"\n// tinycolor.mostReadable(\"#a8015a\", [\"#faf3f3\"],{includeFallbackColors:true,level:\"AAA\",size:\"small\"}).toHexString(); // \"#ffffff\"\ntinycolor.mostReadable = function(baseColor, colorList, args) {\n var bestColor = null;\n var bestScore = 0;\n var readability;\n var includeFallbackColors, level, size ;\n args = args || {};\n includeFallbackColors = args.includeFallbackColors ;\n level = args.level;\n size = args.size;\n\n for (var i= 0; i < colorList.length ; i++) {\n readability = tinycolor.readability(baseColor, colorList[i]);\n if (readability > bestScore) {\n bestScore = readability;\n bestColor = tinycolor(colorList[i]);\n }\n }\n\n if (tinycolor.isReadable(baseColor, bestColor, {\"level\":level,\"size\":size}) || !includeFallbackColors) {\n return bestColor;\n }\n else {\n args.includeFallbackColors=false;\n return tinycolor.mostReadable(baseColor,[\"#fff\", \"#000\"],args);\n }\n};\n\n\n// Big List of Colors\n// ------------------\n// \nvar names = tinycolor.names = {\n aliceblue: \"f0f8ff\",\n antiquewhite: \"faebd7\",\n aqua: \"0ff\",\n aquamarine: \"7fffd4\",\n azure: \"f0ffff\",\n beige: \"f5f5dc\",\n bisque: \"ffe4c4\",\n black: \"000\",\n blanchedalmond: \"ffebcd\",\n blue: \"00f\",\n blueviolet: \"8a2be2\",\n brown: \"a52a2a\",\n burlywood: \"deb887\",\n burntsienna: \"ea7e5d\",\n cadetblue: \"5f9ea0\",\n chartreuse: \"7fff00\",\n chocolate: \"d2691e\",\n coral: \"ff7f50\",\n cornflowerblue: \"6495ed\",\n cornsilk: \"fff8dc\",\n crimson: \"dc143c\",\n cyan: \"0ff\",\n darkblue: \"00008b\",\n darkcyan: \"008b8b\",\n darkgoldenrod: \"b8860b\",\n darkgray: \"a9a9a9\",\n darkgreen: \"006400\",\n darkgrey: \"a9a9a9\",\n darkkhaki: \"bdb76b\",\n darkmagenta: \"8b008b\",\n darkolivegreen: \"556b2f\",\n darkorange: \"ff8c00\",\n darkorchid: \"9932cc\",\n darkred: \"8b0000\",\n darksalmon: \"e9967a\",\n darkseagreen: \"8fbc8f\",\n darkslateblue: \"483d8b\",\n darkslategray: \"2f4f4f\",\n darkslategrey: \"2f4f4f\",\n darkturquoise: \"00ced1\",\n darkviolet: \"9400d3\",\n deeppink: \"ff1493\",\n deepskyblue: \"00bfff\",\n dimgray: \"696969\",\n dimgrey: \"696969\",\n dodgerblue: \"1e90ff\",\n firebrick: \"b22222\",\n floralwhite: \"fffaf0\",\n forestgreen: \"228b22\",\n fuchsia: \"f0f\",\n gainsboro: \"dcdcdc\",\n ghostwhite: \"f8f8ff\",\n gold: \"ffd700\",\n goldenrod: \"daa520\",\n gray: \"808080\",\n green: \"008000\",\n greenyellow: \"adff2f\",\n grey: \"808080\",\n honeydew: \"f0fff0\",\n hotpink: \"ff69b4\",\n indianred: \"cd5c5c\",\n indigo: \"4b0082\",\n ivory: \"fffff0\",\n khaki: \"f0e68c\",\n lavender: \"e6e6fa\",\n lavenderblush: \"fff0f5\",\n lawngreen: \"7cfc00\",\n lemonchiffon: \"fffacd\",\n lightblue: \"add8e6\",\n lightcoral: \"f08080\",\n lightcyan: \"e0ffff\",\n lightgoldenrodyellow: \"fafad2\",\n lightgray: \"d3d3d3\",\n lightgreen: \"90ee90\",\n lightgrey: \"d3d3d3\",\n lightpink: \"ffb6c1\",\n lightsalmon: \"ffa07a\",\n lightseagreen: \"20b2aa\",\n lightskyblue: \"87cefa\",\n lightslategray: \"789\",\n lightslategrey: \"789\",\n lightsteelblue: \"b0c4de\",\n lightyellow: \"ffffe0\",\n lime: \"0f0\",\n limegreen: \"32cd32\",\n linen: \"faf0e6\",\n magenta: \"f0f\",\n maroon: \"800000\",\n mediumaquamarine: \"66cdaa\",\n mediumblue: \"0000cd\",\n mediumorchid: \"ba55d3\",\n mediumpurple: \"9370db\",\n mediumseagreen: \"3cb371\",\n mediumslateblue: \"7b68ee\",\n mediumspringgreen: \"00fa9a\",\n mediumturquoise: \"48d1cc\",\n mediumvioletred: \"c71585\",\n midnightblue: \"191970\",\n mintcream: \"f5fffa\",\n mistyrose: \"ffe4e1\",\n moccasin: \"ffe4b5\",\n navajowhite: \"ffdead\",\n navy: \"000080\",\n oldlace: \"fdf5e6\",\n olive: \"808000\",\n olivedrab: \"6b8e23\",\n orange: \"ffa500\",\n orangered: \"ff4500\",\n orchid: \"da70d6\",\n palegoldenrod: \"eee8aa\",\n palegreen: \"98fb98\",\n paleturquoise: \"afeeee\",\n palevioletred: \"db7093\",\n papayawhip: \"ffefd5\",\n peachpuff: \"ffdab9\",\n peru: \"cd853f\",\n pink: \"ffc0cb\",\n plum: \"dda0dd\",\n powderblue: \"b0e0e6\",\n purple: \"800080\",\n rebeccapurple: \"663399\",\n red: \"f00\",\n rosybrown: \"bc8f8f\",\n royalblue: \"4169e1\",\n saddlebrown: \"8b4513\",\n salmon: \"fa8072\",\n sandybrown: \"f4a460\",\n seagreen: \"2e8b57\",\n seashell: \"fff5ee\",\n sienna: \"a0522d\",\n silver: \"c0c0c0\",\n skyblue: \"87ceeb\",\n slateblue: \"6a5acd\",\n slategray: \"708090\",\n slategrey: \"708090\",\n snow: \"fffafa\",\n springgreen: \"00ff7f\",\n steelblue: \"4682b4\",\n tan: \"d2b48c\",\n teal: \"008080\",\n thistle: \"d8bfd8\",\n tomato: \"ff6347\",\n turquoise: \"40e0d0\",\n violet: \"ee82ee\",\n wheat: \"f5deb3\",\n white: \"fff\",\n whitesmoke: \"f5f5f5\",\n yellow: \"ff0\",\n yellowgreen: \"9acd32\"\n};\n\n// Make it easy to access colors via `hexNames[hex]`\nvar hexNames = tinycolor.hexNames = flip(names);\n\n\n// Utilities\n// ---------\n\n// `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`\nfunction flip(o) {\n var flipped = { };\n for (var i in o) {\n if (o.hasOwnProperty(i)) {\n flipped[o[i]] = i;\n }\n }\n return flipped;\n}\n\n// Return a valid alpha value [0,1] with all invalid values being set to 1\nfunction boundAlpha(a) {\n a = parseFloat(a);\n\n if (isNaN(a) || a < 0 || a > 1) {\n a = 1;\n }\n\n return a;\n}\n\n// Take input from [0, n] and return it as [0, 1]\nfunction bound01(n, max) {\n if (isOnePointZero(n)) { n = \"100%\"; }\n\n var processPercent = isPercentage(n);\n n = mathMin(max, mathMax(0, parseFloat(n)));\n\n // Automatically convert percentage into number\n if (processPercent) {\n n = parseInt(n * max, 10) / 100;\n }\n\n // Handle floating point rounding errors\n if ((Math.abs(n - max) < 0.000001)) {\n return 1;\n }\n\n // Convert into [0, 1] range if it isn't already\n return (n % max) / parseFloat(max);\n}\n\n// Force a number between 0 and 1\nfunction clamp01(val) {\n return mathMin(1, mathMax(0, val));\n}\n\n// Parse a base-16 hex value into a base-10 integer\nfunction parseIntFromHex(val) {\n return parseInt(val, 16);\n}\n\n// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1\n// \nfunction isOnePointZero(n) {\n return typeof n == \"string\" && n.indexOf('.') != -1 && parseFloat(n) === 1;\n}\n\n// Check to see if string passed in is a percentage\nfunction isPercentage(n) {\n return typeof n === \"string\" && n.indexOf('%') != -1;\n}\n\n// Force a hex value to have 2 characters\nfunction pad2(c) {\n return c.length == 1 ? '0' + c : '' + c;\n}\n\n// Replace a decimal with it's percentage value\nfunction convertToPercentage(n) {\n if (n <= 1) {\n n = (n * 100) + \"%\";\n }\n\n return n;\n}\n\n// Converts a decimal to a hex value\nfunction convertDecimalToHex(d) {\n return Math.round(parseFloat(d) * 255).toString(16);\n}\n// Converts a hex value to a decimal\nfunction convertHexToDecimal(h) {\n return (parseIntFromHex(h) / 255);\n}\n\nvar matchers = (function() {\n\n // \n var CSS_INTEGER = \"[-\\\\+]?\\\\d+%?\";\n\n // \n var CSS_NUMBER = \"[-\\\\+]?\\\\d*\\\\.\\\\d+%?\";\n\n // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.\n var CSS_UNIT = \"(?:\" + CSS_NUMBER + \")|(?:\" + CSS_INTEGER + \")\";\n\n // Actual matching.\n // Parentheses and commas are optional, but not required.\n // Whitespace can take the place of commas or opening paren\n var PERMISSIVE_MATCH3 = \"[\\\\s|\\\\(]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")\\\\s*\\\\)?\";\n var PERMISSIVE_MATCH4 = \"[\\\\s|\\\\(]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")\\\\s*\\\\)?\";\n\n return {\n CSS_UNIT: new RegExp(CSS_UNIT),\n rgb: new RegExp(\"rgb\" + PERMISSIVE_MATCH3),\n rgba: new RegExp(\"rgba\" + PERMISSIVE_MATCH4),\n hsl: new RegExp(\"hsl\" + PERMISSIVE_MATCH3),\n hsla: new RegExp(\"hsla\" + PERMISSIVE_MATCH4),\n hsv: new RegExp(\"hsv\" + PERMISSIVE_MATCH3),\n hsva: new RegExp(\"hsva\" + PERMISSIVE_MATCH4),\n hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,\n hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,\n hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,\n hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/\n };\n})();\n\n// `isValidCSSUnit`\n// Take in a single string / number and check to see if it looks like a CSS unit\n// (see `matchers` above for definition).\nfunction isValidCSSUnit(color) {\n return !!matchers.CSS_UNIT.exec(color);\n}\n\n// `stringInputToObject`\n// Permissive string parsing. Take in a number of formats, and output an object\n// based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`\nfunction stringInputToObject(color) {\n\n color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();\n var named = false;\n if (names[color]) {\n color = names[color];\n named = true;\n }\n else if (color == 'transparent') {\n return { r: 0, g: 0, b: 0, a: 0, format: \"name\" };\n }\n\n // Try to match string input using regular expressions.\n // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]\n // Just return an object and let the conversion functions handle that.\n // This way the result will be the same whether the tinycolor is initialized with string or object.\n var match;\n if ((match = matchers.rgb.exec(color))) {\n return { r: match[1], g: match[2], b: match[3] };\n }\n if ((match = matchers.rgba.exec(color))) {\n return { r: match[1], g: match[2], b: match[3], a: match[4] };\n }\n if ((match = matchers.hsl.exec(color))) {\n return { h: match[1], s: match[2], l: match[3] };\n }\n if ((match = matchers.hsla.exec(color))) {\n return { h: match[1], s: match[2], l: match[3], a: match[4] };\n }\n if ((match = matchers.hsv.exec(color))) {\n return { h: match[1], s: match[2], v: match[3] };\n }\n if ((match = matchers.hsva.exec(color))) {\n return { h: match[1], s: match[2], v: match[3], a: match[4] };\n }\n if ((match = matchers.hex8.exec(color))) {\n return {\n r: parseIntFromHex(match[1]),\n g: parseIntFromHex(match[2]),\n b: parseIntFromHex(match[3]),\n a: convertHexToDecimal(match[4]),\n format: named ? \"name\" : \"hex8\"\n };\n }\n if ((match = matchers.hex6.exec(color))) {\n return {\n r: parseIntFromHex(match[1]),\n g: parseIntFromHex(match[2]),\n b: parseIntFromHex(match[3]),\n format: named ? \"name\" : \"hex\"\n };\n }\n if ((match = matchers.hex4.exec(color))) {\n return {\n r: parseIntFromHex(match[1] + '' + match[1]),\n g: parseIntFromHex(match[2] + '' + match[2]),\n b: parseIntFromHex(match[3] + '' + match[3]),\n a: convertHexToDecimal(match[4] + '' + match[4]),\n format: named ? \"name\" : \"hex8\"\n };\n }\n if ((match = matchers.hex3.exec(color))) {\n return {\n r: parseIntFromHex(match[1] + '' + match[1]),\n g: parseIntFromHex(match[2] + '' + match[2]),\n b: parseIntFromHex(match[3] + '' + match[3]),\n format: named ? \"name\" : \"hex\"\n };\n }\n\n return false;\n}\n\nfunction validateWCAG2Parms(parms) {\n // return valid WCAG2 parms for isReadable.\n // If input parms are invalid, return {\"level\":\"AA\", \"size\":\"small\"}\n var level, size;\n parms = parms || {\"level\":\"AA\", \"size\":\"small\"};\n level = (parms.level || \"AA\").toUpperCase();\n size = (parms.size || \"small\").toLowerCase();\n if (level !== \"AA\" && level !== \"AAA\") {\n level = \"AA\";\n }\n if (size !== \"small\" && size !== \"large\") {\n size = \"small\";\n }\n return {\"level\":level, \"size\":size};\n}\n\n// Node: Export function\nif ( true && module.exports) {\n module.exports = tinycolor;\n}\n// AMD/requirejs: Define the module\nelse if (true) {\n !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {return tinycolor;}).call(exports, __webpack_require__, exports, module),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n}\n// Browser: Expose to window\nelse {}\n\n})(Math);\n\n\n//# sourceURL=webpack:///./node_modules/tinycolor2/tinycolor.js?");
-
-/***/ }),
-
-/***/ "./node_modules/to-float32/index.js":
-/*!******************************************!*\
- !*** ./node_modules/to-float32/index.js ***!
- \******************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/* @module to-float32 */\r\n\r\n\r\n\r\nmodule.exports = float32\r\nmodule.exports.float32 =\r\nmodule.exports.float = float32\r\nmodule.exports.fract32 =\r\nmodule.exports.fract = fract32\r\n\r\nvar narr = new Float32Array(1)\r\n\r\n// return fractional part of float32 array\r\nfunction fract32 (arr) {\r\n\tif (arr.length) {\r\n\t\tvar fract = float32(arr)\r\n\t\tfor (var i = 0, l = fract.length; i < l; i++) {\r\n\t\t\tfract[i] = arr[i] - fract[i]\r\n\t\t}\r\n\t\treturn fract\r\n\t}\r\n\r\n\t// number\r\n\treturn float32(arr - float32(arr))\r\n}\r\n\r\n// make sure data is float32 array\r\nfunction float32 (arr) {\r\n\tif (arr.length) {\r\n\t\tif (arr instanceof Float32Array) return arr\r\n\t\tvar float = new Float32Array(arr)\r\n\t\tfloat.set(arr)\r\n\t\treturn float\r\n\t}\r\n\r\n\t// number\r\n\tnarr[0] = arr\r\n\treturn narr[0]\r\n}\r\n\n\n//# sourceURL=webpack:///./node_modules/to-float32/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/to-px/browser.js":
-/*!***************************************!*\
- !*** ./node_modules/to-px/browser.js ***!
- \***************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nvar parseUnit = __webpack_require__(/*! parse-unit */ \"./node_modules/parse-unit/index.js\")\n\nmodule.exports = toPX\n\nvar PIXELS_PER_INCH = getSizeBrutal('in', document.body) // 96\n\n\nfunction getPropertyInPX(element, prop) {\n var parts = parseUnit(getComputedStyle(element).getPropertyValue(prop))\n return parts[0] * toPX(parts[1], element)\n}\n\n//This brutal hack is needed\nfunction getSizeBrutal(unit, element) {\n var testDIV = document.createElement('div')\n testDIV.style['height'] = '128' + unit\n element.appendChild(testDIV)\n var size = getPropertyInPX(testDIV, 'height') / 128\n element.removeChild(testDIV)\n return size\n}\n\nfunction toPX(str, element) {\n if (!str) return null\n\n element = element || document.body\n str = (str + '' || 'px').trim().toLowerCase()\n if(element === window || element === document) {\n element = document.body\n }\n\n switch(str) {\n case '%': //Ambiguous, not sure if we should use width or height\n return element.clientHeight / 100.0\n case 'ch':\n case 'ex':\n return getSizeBrutal(str, element)\n case 'em':\n return getPropertyInPX(element, 'font-size')\n case 'rem':\n return getPropertyInPX(document.body, 'font-size')\n case 'vw':\n return window.innerWidth/100\n case 'vh':\n return window.innerHeight/100\n case 'vmin':\n return Math.min(window.innerWidth, window.innerHeight) / 100\n case 'vmax':\n return Math.max(window.innerWidth, window.innerHeight) / 100\n case 'in':\n return PIXELS_PER_INCH\n case 'cm':\n return PIXELS_PER_INCH / 2.54\n case 'mm':\n return PIXELS_PER_INCH / 25.4\n case 'pt':\n return PIXELS_PER_INCH / 72\n case 'pc':\n return PIXELS_PER_INCH / 6\n case 'px':\n return 1\n }\n\n // detect number of units\n var parts = parseUnit(str)\n if (!isNaN(parts[0]) && parts[1]) {\n var px = toPX(parts[1], element)\n return typeof px === 'number' ? parts[0] * px : null\n }\n\n return null\n}\n\n\n//# sourceURL=webpack:///./node_modules/to-px/browser.js?");
-
-/***/ }),
-
-/***/ "./node_modules/topojson-client/index.js":
-/*!***********************************************!*\
- !*** ./node_modules/topojson-client/index.js ***!
- \***********************************************/
-/*! exports provided: bbox, feature, mesh, meshArcs, merge, mergeArcs, neighbors, quantize, transform, untransform */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _src_bbox__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/bbox */ \"./node_modules/topojson-client/src/bbox.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"bbox\", function() { return _src_bbox__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; });\n\n/* harmony import */ var _src_feature__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./src/feature */ \"./node_modules/topojson-client/src/feature.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"feature\", function() { return _src_feature__WEBPACK_IMPORTED_MODULE_1__[\"default\"]; });\n\n/* harmony import */ var _src_mesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./src/mesh */ \"./node_modules/topojson-client/src/mesh.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"mesh\", function() { return _src_mesh__WEBPACK_IMPORTED_MODULE_2__[\"default\"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"meshArcs\", function() { return _src_mesh__WEBPACK_IMPORTED_MODULE_2__[\"meshArcs\"]; });\n\n/* harmony import */ var _src_merge__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./src/merge */ \"./node_modules/topojson-client/src/merge.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"merge\", function() { return _src_merge__WEBPACK_IMPORTED_MODULE_3__[\"default\"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"mergeArcs\", function() { return _src_merge__WEBPACK_IMPORTED_MODULE_3__[\"mergeArcs\"]; });\n\n/* harmony import */ var _src_neighbors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./src/neighbors */ \"./node_modules/topojson-client/src/neighbors.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"neighbors\", function() { return _src_neighbors__WEBPACK_IMPORTED_MODULE_4__[\"default\"]; });\n\n/* harmony import */ var _src_quantize__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./src/quantize */ \"./node_modules/topojson-client/src/quantize.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"quantize\", function() { return _src_quantize__WEBPACK_IMPORTED_MODULE_5__[\"default\"]; });\n\n/* harmony import */ var _src_transform__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./src/transform */ \"./node_modules/topojson-client/src/transform.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"transform\", function() { return _src_transform__WEBPACK_IMPORTED_MODULE_6__[\"default\"]; });\n\n/* harmony import */ var _src_untransform__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./src/untransform */ \"./node_modules/topojson-client/src/untransform.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"untransform\", function() { return _src_untransform__WEBPACK_IMPORTED_MODULE_7__[\"default\"]; });\n\n\n\n\n\n\n\n\n\n\n\n//# sourceURL=webpack:///./node_modules/topojson-client/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/topojson-client/src/bbox.js":
-/*!**************************************************!*\
- !*** ./node_modules/topojson-client/src/bbox.js ***!
- \**************************************************/
-/*! exports provided: default */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _transform__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./transform */ \"./node_modules/topojson-client/src/transform.js\");\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (function(topology) {\n var bbox = topology.bbox;\n\n function bboxPoint(p0) {\n p1[0] = p0[0], p1[1] = p0[1], t(p1);\n if (p1[0] < x0) x0 = p1[0];\n if (p1[0] > x1) x1 = p1[0];\n if (p1[1] < y0) y0 = p1[1];\n if (p1[1] > y1) y1 = p1[1];\n }\n\n function bboxGeometry(o) {\n switch (o.type) {\n case \"GeometryCollection\": o.geometries.forEach(bboxGeometry); break;\n case \"Point\": bboxPoint(o.coordinates); break;\n case \"MultiPoint\": o.coordinates.forEach(bboxPoint); break;\n }\n }\n\n if (!bbox) {\n var t = Object(_transform__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(topology), p0, p1 = new Array(2), name,\n x0 = Infinity, y0 = x0, x1 = -x0, y1 = -x0;\n\n topology.arcs.forEach(function(arc) {\n var i = -1, n = arc.length;\n while (++i < n) {\n p0 = arc[i], p1[0] = p0[0], p1[1] = p0[1], t(p1, i);\n if (p1[0] < x0) x0 = p1[0];\n if (p1[0] > x1) x1 = p1[0];\n if (p1[1] < y0) y0 = p1[1];\n if (p1[1] > y1) y1 = p1[1];\n }\n });\n\n for (name in topology.objects) {\n bboxGeometry(topology.objects[name]);\n }\n\n bbox = topology.bbox = [x0, y0, x1, y1];\n }\n\n return bbox;\n});\n\n\n//# sourceURL=webpack:///./node_modules/topojson-client/src/bbox.js?");
-
-/***/ }),
-
-/***/ "./node_modules/topojson-client/src/bisect.js":
-/*!****************************************************!*\
- !*** ./node_modules/topojson-client/src/bisect.js ***!
- \****************************************************/
-/*! exports provided: default */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (function(a, x) {\n var lo = 0, hi = a.length;\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (a[mid] < x) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n});\n\n\n//# sourceURL=webpack:///./node_modules/topojson-client/src/bisect.js?");
-
-/***/ }),
-
-/***/ "./node_modules/topojson-client/src/feature.js":
-/*!*****************************************************!*\
- !*** ./node_modules/topojson-client/src/feature.js ***!
- \*****************************************************/
-/*! exports provided: default, feature, object */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"feature\", function() { return feature; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"object\", function() { return object; });\n/* harmony import */ var _reverse__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./reverse */ \"./node_modules/topojson-client/src/reverse.js\");\n/* harmony import */ var _transform__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./transform */ \"./node_modules/topojson-client/src/transform.js\");\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (function(topology, o) {\n return o.type === \"GeometryCollection\"\n ? {type: \"FeatureCollection\", features: o.geometries.map(function(o) { return feature(topology, o); })}\n : feature(topology, o);\n});\n\nfunction feature(topology, o) {\n var id = o.id,\n bbox = o.bbox,\n properties = o.properties == null ? {} : o.properties,\n geometry = object(topology, o);\n return id == null && bbox == null ? {type: \"Feature\", properties: properties, geometry: geometry}\n : bbox == null ? {type: \"Feature\", id: id, properties: properties, geometry: geometry}\n : {type: \"Feature\", id: id, bbox: bbox, properties: properties, geometry: geometry};\n}\n\nfunction object(topology, o) {\n var transformPoint = Object(_transform__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(topology),\n arcs = topology.arcs;\n\n function arc(i, points) {\n if (points.length) points.pop();\n for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length; k < n; ++k) {\n points.push(transformPoint(a[k].slice(), k));\n }\n if (i < 0) Object(_reverse__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(points, n);\n }\n\n function point(p) {\n return transformPoint(p.slice());\n }\n\n function line(arcs) {\n var points = [];\n for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points);\n if (points.length < 2) points.push(points[0].slice());\n return points;\n }\n\n function ring(arcs) {\n var points = line(arcs);\n while (points.length < 4) points.push(points[0].slice());\n return points;\n }\n\n function polygon(arcs) {\n return arcs.map(ring);\n }\n\n function geometry(o) {\n var type = o.type, coordinates;\n switch (type) {\n case \"GeometryCollection\": return {type: type, geometries: o.geometries.map(geometry)};\n case \"Point\": coordinates = point(o.coordinates); break;\n case \"MultiPoint\": coordinates = o.coordinates.map(point); break;\n case \"LineString\": coordinates = line(o.arcs); break;\n case \"MultiLineString\": coordinates = o.arcs.map(line); break;\n case \"Polygon\": coordinates = polygon(o.arcs); break;\n case \"MultiPolygon\": coordinates = o.arcs.map(polygon); break;\n default: return null;\n }\n return {type: type, coordinates: coordinates};\n }\n\n return geometry(o);\n}\n\n\n//# sourceURL=webpack:///./node_modules/topojson-client/src/feature.js?");
-
-/***/ }),
-
-/***/ "./node_modules/topojson-client/src/identity.js":
-/*!******************************************************!*\
- !*** ./node_modules/topojson-client/src/identity.js ***!
- \******************************************************/
-/*! exports provided: default */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (function(x) {\n return x;\n});\n\n\n//# sourceURL=webpack:///./node_modules/topojson-client/src/identity.js?");
-
-/***/ }),
-
-/***/ "./node_modules/topojson-client/src/merge.js":
-/*!***************************************************!*\
- !*** ./node_modules/topojson-client/src/merge.js ***!
- \***************************************************/
-/*! exports provided: default, mergeArcs */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"mergeArcs\", function() { return mergeArcs; });\n/* harmony import */ var _feature__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./feature */ \"./node_modules/topojson-client/src/feature.js\");\n/* harmony import */ var _stitch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./stitch */ \"./node_modules/topojson-client/src/stitch.js\");\n\n\n\nfunction planarRingArea(ring) {\n var i = -1, n = ring.length, a, b = ring[n - 1], area = 0;\n while (++i < n) a = b, b = ring[i], area += a[0] * b[1] - a[1] * b[0];\n return Math.abs(area); // Note: doubled area!\n}\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (function(topology) {\n return Object(_feature__WEBPACK_IMPORTED_MODULE_0__[\"object\"])(topology, mergeArcs.apply(this, arguments));\n});\n\nfunction mergeArcs(topology, objects) {\n var polygonsByArc = {},\n polygons = [],\n groups = [];\n\n objects.forEach(geometry);\n\n function geometry(o) {\n switch (o.type) {\n case \"GeometryCollection\": o.geometries.forEach(geometry); break;\n case \"Polygon\": extract(o.arcs); break;\n case \"MultiPolygon\": o.arcs.forEach(extract); break;\n }\n }\n\n function extract(polygon) {\n polygon.forEach(function(ring) {\n ring.forEach(function(arc) {\n (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon);\n });\n });\n polygons.push(polygon);\n }\n\n function area(ring) {\n return planarRingArea(Object(_feature__WEBPACK_IMPORTED_MODULE_0__[\"object\"])(topology, {type: \"Polygon\", arcs: [ring]}).coordinates[0]);\n }\n\n polygons.forEach(function(polygon) {\n if (!polygon._) {\n var group = [],\n neighbors = [polygon];\n polygon._ = 1;\n groups.push(group);\n while (polygon = neighbors.pop()) {\n group.push(polygon);\n polygon.forEach(function(ring) {\n ring.forEach(function(arc) {\n polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) {\n if (!polygon._) {\n polygon._ = 1;\n neighbors.push(polygon);\n }\n });\n });\n });\n }\n }\n });\n\n polygons.forEach(function(polygon) {\n delete polygon._;\n });\n\n return {\n type: \"MultiPolygon\",\n arcs: groups.map(function(polygons) {\n var arcs = [], n;\n\n // Extract the exterior (unique) arcs.\n polygons.forEach(function(polygon) {\n polygon.forEach(function(ring) {\n ring.forEach(function(arc) {\n if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) {\n arcs.push(arc);\n }\n });\n });\n });\n\n // Stitch the arcs into one or more rings.\n arcs = Object(_stitch__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(topology, arcs);\n\n // If more than one ring is returned,\n // at most one of these rings can be the exterior;\n // choose the one with the greatest absolute area.\n if ((n = arcs.length) > 1) {\n for (var i = 1, k = area(arcs[0]), ki, t; i < n; ++i) {\n if ((ki = area(arcs[i])) > k) {\n t = arcs[0], arcs[0] = arcs[i], arcs[i] = t, k = ki;\n }\n }\n }\n\n return arcs;\n })\n };\n}\n\n\n//# sourceURL=webpack:///./node_modules/topojson-client/src/merge.js?");
-
-/***/ }),
-
-/***/ "./node_modules/topojson-client/src/mesh.js":
-/*!**************************************************!*\
- !*** ./node_modules/topojson-client/src/mesh.js ***!
- \**************************************************/
-/*! exports provided: default, meshArcs */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"meshArcs\", function() { return meshArcs; });\n/* harmony import */ var _feature__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./feature */ \"./node_modules/topojson-client/src/feature.js\");\n/* harmony import */ var _stitch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./stitch */ \"./node_modules/topojson-client/src/stitch.js\");\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (function(topology) {\n return Object(_feature__WEBPACK_IMPORTED_MODULE_0__[\"object\"])(topology, meshArcs.apply(this, arguments));\n});\n\nfunction meshArcs(topology, object, filter) {\n var arcs, i, n;\n if (arguments.length > 1) arcs = extractArcs(topology, object, filter);\n else for (i = 0, arcs = new Array(n = topology.arcs.length); i < n; ++i) arcs[i] = i;\n return {type: \"MultiLineString\", arcs: Object(_stitch__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(topology, arcs)};\n}\n\nfunction extractArcs(topology, object, filter) {\n var arcs = [],\n geomsByArc = [],\n geom;\n\n function extract0(i) {\n var j = i < 0 ? ~i : i;\n (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom});\n }\n\n function extract1(arcs) {\n arcs.forEach(extract0);\n }\n\n function extract2(arcs) {\n arcs.forEach(extract1);\n }\n\n function extract3(arcs) {\n arcs.forEach(extract2);\n }\n\n function geometry(o) {\n switch (geom = o, o.type) {\n case \"GeometryCollection\": o.geometries.forEach(geometry); break;\n case \"LineString\": extract1(o.arcs); break;\n case \"MultiLineString\": case \"Polygon\": extract2(o.arcs); break;\n case \"MultiPolygon\": extract3(o.arcs); break;\n }\n }\n\n geometry(object);\n\n geomsByArc.forEach(filter == null\n ? function(geoms) { arcs.push(geoms[0].i); }\n : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); });\n\n return arcs;\n}\n\n\n//# sourceURL=webpack:///./node_modules/topojson-client/src/mesh.js?");
-
-/***/ }),
-
-/***/ "./node_modules/topojson-client/src/neighbors.js":
-/*!*******************************************************!*\
- !*** ./node_modules/topojson-client/src/neighbors.js ***!
- \*******************************************************/
-/*! exports provided: default */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _bisect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./bisect */ \"./node_modules/topojson-client/src/bisect.js\");\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (function(objects) {\n var indexesByArc = {}, // arc index -> array of object indexes\n neighbors = objects.map(function() { return []; });\n\n function line(arcs, i) {\n arcs.forEach(function(a) {\n if (a < 0) a = ~a;\n var o = indexesByArc[a];\n if (o) o.push(i);\n else indexesByArc[a] = [i];\n });\n }\n\n function polygon(arcs, i) {\n arcs.forEach(function(arc) { line(arc, i); });\n }\n\n function geometry(o, i) {\n if (o.type === \"GeometryCollection\") o.geometries.forEach(function(o) { geometry(o, i); });\n else if (o.type in geometryType) geometryType[o.type](o.arcs, i);\n }\n\n var geometryType = {\n LineString: line,\n MultiLineString: polygon,\n Polygon: polygon,\n MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); }\n };\n\n objects.forEach(geometry);\n\n for (var i in indexesByArc) {\n for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) {\n for (var k = j + 1; k < m; ++k) {\n var ij = indexes[j], ik = indexes[k], n;\n if ((n = neighbors[ij])[i = Object(_bisect__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(n, ik)] !== ik) n.splice(i, 0, ik);\n if ((n = neighbors[ik])[i = Object(_bisect__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(n, ij)] !== ij) n.splice(i, 0, ij);\n }\n }\n }\n\n return neighbors;\n});\n\n\n//# sourceURL=webpack:///./node_modules/topojson-client/src/neighbors.js?");
-
-/***/ }),
-
-/***/ "./node_modules/topojson-client/src/quantize.js":
-/*!******************************************************!*\
- !*** ./node_modules/topojson-client/src/quantize.js ***!
- \******************************************************/
-/*! exports provided: default */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _bbox__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./bbox */ \"./node_modules/topojson-client/src/bbox.js\");\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (function(topology, n) {\n if (!((n = Math.floor(n)) >= 2)) throw new Error(\"n must be ≥2\");\n if (topology.transform) throw new Error(\"already quantized\");\n var bb = Object(_bbox__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(topology), name,\n dx = bb[0], kx = (bb[2] - dx) / (n - 1) || 1,\n dy = bb[1], ky = (bb[3] - dy) / (n - 1) || 1;\n\n function quantizePoint(p) {\n p[0] = Math.round((p[0] - dx) / kx);\n p[1] = Math.round((p[1] - dy) / ky);\n }\n\n function quantizeGeometry(o) {\n switch (o.type) {\n case \"GeometryCollection\": o.geometries.forEach(quantizeGeometry); break;\n case \"Point\": quantizePoint(o.coordinates); break;\n case \"MultiPoint\": o.coordinates.forEach(quantizePoint); break;\n }\n }\n\n topology.arcs.forEach(function(arc) {\n var i = 1,\n j = 1,\n n = arc.length,\n pi = arc[0],\n x0 = pi[0] = Math.round((pi[0] - dx) / kx),\n y0 = pi[1] = Math.round((pi[1] - dy) / ky),\n pj,\n x1,\n y1;\n\n for (; i < n; ++i) {\n pi = arc[i];\n x1 = Math.round((pi[0] - dx) / kx);\n y1 = Math.round((pi[1] - dy) / ky);\n if (x1 !== x0 || y1 !== y0) {\n pj = arc[j++];\n pj[0] = x1 - x0, x0 = x1;\n pj[1] = y1 - y0, y0 = y1;\n }\n }\n\n if (j < 2) {\n pj = arc[j++];\n pj[0] = 0;\n pj[1] = 0;\n }\n\n arc.length = j;\n });\n\n for (name in topology.objects) {\n quantizeGeometry(topology.objects[name]);\n }\n\n topology.transform = {\n scale: [kx, ky],\n translate: [dx, dy]\n };\n\n return topology;\n});\n\n\n//# sourceURL=webpack:///./node_modules/topojson-client/src/quantize.js?");
-
-/***/ }),
-
-/***/ "./node_modules/topojson-client/src/reverse.js":
-/*!*****************************************************!*\
- !*** ./node_modules/topojson-client/src/reverse.js ***!
- \*****************************************************/
-/*! exports provided: default */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (function(array, n) {\n var t, j = array.length, i = j - n;\n while (i < --j) t = array[i], array[i++] = array[j], array[j] = t;\n});\n\n\n//# sourceURL=webpack:///./node_modules/topojson-client/src/reverse.js?");
-
-/***/ }),
-
-/***/ "./node_modules/topojson-client/src/stitch.js":
-/*!****************************************************!*\
- !*** ./node_modules/topojson-client/src/stitch.js ***!
- \****************************************************/
-/*! exports provided: default */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (function(topology, arcs) {\n var stitchedArcs = {},\n fragmentByStart = {},\n fragmentByEnd = {},\n fragments = [],\n emptyIndex = -1;\n\n // Stitch empty arcs first, since they may be subsumed by other arcs.\n arcs.forEach(function(i, j) {\n var arc = topology.arcs[i < 0 ? ~i : i], t;\n if (arc.length < 3 && !arc[1][0] && !arc[1][1]) {\n t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t;\n }\n });\n\n arcs.forEach(function(i) {\n var e = ends(i),\n start = e[0],\n end = e[1],\n f, g;\n\n if (f = fragmentByEnd[start]) {\n delete fragmentByEnd[f.end];\n f.push(i);\n f.end = end;\n if (g = fragmentByStart[end]) {\n delete fragmentByStart[g.start];\n var fg = g === f ? f : f.concat(g);\n fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg;\n } else {\n fragmentByStart[f.start] = fragmentByEnd[f.end] = f;\n }\n } else if (f = fragmentByStart[end]) {\n delete fragmentByStart[f.start];\n f.unshift(i);\n f.start = start;\n if (g = fragmentByEnd[start]) {\n delete fragmentByEnd[g.end];\n var gf = g === f ? f : g.concat(f);\n fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf;\n } else {\n fragmentByStart[f.start] = fragmentByEnd[f.end] = f;\n }\n } else {\n f = [i];\n fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f;\n }\n });\n\n function ends(i) {\n var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1;\n if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; });\n else p1 = arc[arc.length - 1];\n return i < 0 ? [p1, p0] : [p0, p1];\n }\n\n function flush(fragmentByEnd, fragmentByStart) {\n for (var k in fragmentByEnd) {\n var f = fragmentByEnd[k];\n delete fragmentByStart[f.start];\n delete f.start;\n delete f.end;\n f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; });\n fragments.push(f);\n }\n }\n\n flush(fragmentByEnd, fragmentByStart);\n flush(fragmentByStart, fragmentByEnd);\n arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); });\n\n return fragments;\n});\n\n\n//# sourceURL=webpack:///./node_modules/topojson-client/src/stitch.js?");
-
-/***/ }),
-
-/***/ "./node_modules/topojson-client/src/transform.js":
-/*!*******************************************************!*\
- !*** ./node_modules/topojson-client/src/transform.js ***!
- \*******************************************************/
-/*! exports provided: default */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _identity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./identity */ \"./node_modules/topojson-client/src/identity.js\");\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (function(topology) {\n if ((transform = topology.transform) == null) return _identity__WEBPACK_IMPORTED_MODULE_0__[\"default\"];\n var transform,\n x0,\n y0,\n kx = transform.scale[0],\n ky = transform.scale[1],\n dx = transform.translate[0],\n dy = transform.translate[1];\n return function(point, i) {\n if (!i) x0 = y0 = 0;\n point[0] = (x0 += point[0]) * kx + dx;\n point[1] = (y0 += point[1]) * ky + dy;\n return point;\n };\n});\n\n\n//# sourceURL=webpack:///./node_modules/topojson-client/src/transform.js?");
-
-/***/ }),
-
-/***/ "./node_modules/topojson-client/src/untransform.js":
-/*!*********************************************************!*\
- !*** ./node_modules/topojson-client/src/untransform.js ***!
- \*********************************************************/
-/*! exports provided: default */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _identity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./identity */ \"./node_modules/topojson-client/src/identity.js\");\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (function(topology) {\n if ((transform = topology.transform) == null) return _identity__WEBPACK_IMPORTED_MODULE_0__[\"default\"];\n var transform,\n x0,\n y0,\n kx = transform.scale[0],\n ky = transform.scale[1],\n dx = transform.translate[0],\n dy = transform.translate[1];\n return function(point, i) {\n if (!i) x0 = y0 = 0;\n var x1 = Math.round((point[0] - dx) / kx),\n y1 = Math.round((point[1] - dy) / ky);\n point[0] = x1 - x0, x0 = x1;\n point[1] = y1 - y0, y0 = y1;\n return point;\n };\n});\n\n\n//# sourceURL=webpack:///./node_modules/topojson-client/src/untransform.js?");
-
-/***/ }),
-
-/***/ "./node_modules/triangulate-hypercube/triangulate-cube.js":
-/*!****************************************************************!*\
- !*** ./node_modules/triangulate-hypercube/triangulate-cube.js ***!
- \****************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nmodule.exports = triangulateCube\n\nvar perm = __webpack_require__(/*! permutation-rank */ \"./node_modules/permutation-rank/index.js\")\nvar sgn = __webpack_require__(/*! permutation-parity */ \"./node_modules/permutation-parity/permutation-sign.js\")\nvar gamma = __webpack_require__(/*! gamma */ \"./node_modules/gamma/index.js\")\n\nfunction triangulateCube(dimension) {\n if(dimension < 0) {\n return [ ]\n }\n if(dimension === 0) {\n return [ [0] ]\n }\n var dfactorial = Math.round(gamma(dimension+1))|0\n var result = []\n for(var i=0; i= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nfunction __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nfunction __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nfunction __awaiter(thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nfunction __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nfunction __exportStar(m, exports) {\r\n for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nfunction __values(o) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\r\n if (m) return m.call(o);\r\n return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n}\r\n\r\nfunction __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nfunction __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nfunction __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n};\r\n\r\nfunction __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nfunction __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nfunction __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nfunction __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nfunction __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nfunction __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nfunction __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\n\n//# sourceURL=webpack:///./node_modules/tslib/tslib.es6.js?");
-
-/***/ }),
-
-/***/ "./node_modules/turntable-camera-controller/turntable.js":
-/*!***************************************************************!*\
- !*** ./node_modules/turntable-camera-controller/turntable.js ***!
- \***************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nmodule.exports = createTurntableController\n\nvar filterVector = __webpack_require__(/*! filtered-vector */ \"./node_modules/filtered-vector/fvec.js\")\nvar invert44 = __webpack_require__(/*! gl-mat4/invert */ \"./node_modules/gl-mat4/invert.js\")\nvar rotateM = __webpack_require__(/*! gl-mat4/rotate */ \"./node_modules/gl-mat4/rotate.js\")\nvar cross = __webpack_require__(/*! gl-vec3/cross */ \"./node_modules/gl-vec3/cross.js\")\nvar normalize3 = __webpack_require__(/*! gl-vec3/normalize */ \"./node_modules/gl-vec3/normalize.js\")\nvar dot3 = __webpack_require__(/*! gl-vec3/dot */ \"./node_modules/gl-vec3/dot.js\")\n\nfunction len3(x, y, z) {\n return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2))\n}\n\nfunction clamp1(x) {\n return Math.min(1.0, Math.max(-1.0, x))\n}\n\nfunction findOrthoPair(v) {\n var vx = Math.abs(v[0])\n var vy = Math.abs(v[1])\n var vz = Math.abs(v[2])\n\n var u = [0,0,0]\n if(vx > Math.max(vy, vz)) {\n u[2] = 1\n } else if(vy > Math.max(vx, vz)) {\n u[0] = 1\n } else {\n u[1] = 1\n }\n\n var vv = 0\n var uv = 0\n for(var i=0; i<3; ++i ) {\n vv += v[i] * v[i]\n uv += u[i] * v[i]\n }\n for(var i=0; i<3; ++i) {\n u[i] -= (uv / vv) * v[i]\n }\n normalize3(u, u)\n return u\n}\n\nfunction TurntableController(zoomMin, zoomMax, center, up, right, radius, theta, phi) {\n this.center = filterVector(center)\n this.up = filterVector(up)\n this.right = filterVector(right)\n this.radius = filterVector([radius])\n this.angle = filterVector([theta, phi])\n this.angle.bounds = [[-Infinity,-Math.PI/2], [Infinity,Math.PI/2]]\n this.setDistanceLimits(zoomMin, zoomMax)\n\n this.computedCenter = this.center.curve(0)\n this.computedUp = this.up.curve(0)\n this.computedRight = this.right.curve(0)\n this.computedRadius = this.radius.curve(0)\n this.computedAngle = this.angle.curve(0)\n this.computedToward = [0,0,0]\n this.computedEye = [0,0,0]\n this.computedMatrix = new Array(16)\n for(var i=0; i<16; ++i) {\n this.computedMatrix[i] = 0.5\n }\n\n this.recalcMatrix(0)\n}\n\nvar proto = TurntableController.prototype\n\nproto.setDistanceLimits = function(minDist, maxDist) {\n if(minDist > 0) {\n minDist = Math.log(minDist)\n } else {\n minDist = -Infinity\n }\n if(maxDist > 0) {\n maxDist = Math.log(maxDist)\n } else {\n maxDist = Infinity\n }\n maxDist = Math.max(maxDist, minDist)\n this.radius.bounds[0][0] = minDist\n this.radius.bounds[1][0] = maxDist\n}\n\nproto.getDistanceLimits = function(out) {\n var bounds = this.radius.bounds[0]\n if(out) {\n out[0] = Math.exp(bounds[0][0])\n out[1] = Math.exp(bounds[1][0])\n return out\n }\n return [ Math.exp(bounds[0][0]), Math.exp(bounds[1][0]) ]\n}\n\nproto.recalcMatrix = function(t) {\n //Recompute curves\n this.center.curve(t)\n this.up.curve(t)\n this.right.curve(t)\n this.radius.curve(t)\n this.angle.curve(t)\n\n //Compute frame for camera matrix\n var up = this.computedUp\n var right = this.computedRight\n var uu = 0.0\n var ur = 0.0\n for(var i=0; i<3; ++i) {\n ur += up[i] * right[i]\n uu += up[i] * up[i]\n }\n var ul = Math.sqrt(uu)\n var rr = 0.0\n for(var i=0; i<3; ++i) {\n right[i] -= up[i] * ur / uu\n rr += right[i] * right[i]\n up[i] /= ul\n }\n var rl = Math.sqrt(rr)\n for(var i=0; i<3; ++i) {\n right[i] /= rl\n }\n\n //Compute toward vector\n var toward = this.computedToward\n cross(toward, up, right)\n normalize3(toward, toward)\n\n //Compute angular parameters\n var radius = Math.exp(this.computedRadius[0])\n var theta = this.computedAngle[0]\n var phi = this.computedAngle[1]\n\n var ctheta = Math.cos(theta)\n var stheta = Math.sin(theta)\n var cphi = Math.cos(phi)\n var sphi = Math.sin(phi)\n\n var center = this.computedCenter\n\n var wx = ctheta * cphi \n var wy = stheta * cphi\n var wz = sphi\n\n var sx = -ctheta * sphi\n var sy = -stheta * sphi\n var sz = cphi\n\n var eye = this.computedEye\n var mat = this.computedMatrix\n for(var i=0; i<3; ++i) {\n var x = wx * right[i] + wy * toward[i] + wz * up[i]\n mat[4*i+1] = sx * right[i] + sy * toward[i] + sz * up[i]\n mat[4*i+2] = x\n mat[4*i+3] = 0.0\n }\n\n var ax = mat[1]\n var ay = mat[5]\n var az = mat[9]\n var bx = mat[2]\n var by = mat[6]\n var bz = mat[10]\n var cx = ay * bz - az * by\n var cy = az * bx - ax * bz\n var cz = ax * by - ay * bx\n var cl = len3(cx, cy, cz)\n cx /= cl\n cy /= cl\n cz /= cl\n mat[0] = cx\n mat[4] = cy\n mat[8] = cz\n\n for(var i=0; i<3; ++i) {\n eye[i] = center[i] + mat[2+4*i]*radius\n }\n\n for(var i=0; i<3; ++i) {\n var rr = 0.0\n for(var j=0; j<3; ++j) {\n rr += mat[i+4*j] * eye[j]\n }\n mat[12+i] = -rr\n }\n mat[15] = 1.0\n}\n\nproto.getMatrix = function(t, result) {\n this.recalcMatrix(t)\n var mat = this.computedMatrix\n if(result) {\n for(var i=0; i<16; ++i) {\n result[i] = mat[i]\n }\n return result\n }\n return mat\n}\n\nvar zAxis = [0,0,0]\nproto.rotate = function(t, dtheta, dphi, droll) {\n this.angle.move(t, dtheta, dphi)\n if(droll) {\n this.recalcMatrix(t)\n\n var mat = this.computedMatrix\n zAxis[0] = mat[2]\n zAxis[1] = mat[6]\n zAxis[2] = mat[10]\n\n var up = this.computedUp\n var right = this.computedRight\n var toward = this.computedToward\n\n for(var i=0; i<3; ++i) {\n mat[4*i] = up[i]\n mat[4*i+1] = right[i]\n mat[4*i+2] = toward[i]\n }\n rotateM(mat, mat, droll, zAxis)\n for(var i=0; i<3; ++i) {\n up[i] = mat[4*i]\n right[i] = mat[4*i+1]\n }\n\n this.up.set(t, up[0], up[1], up[2])\n this.right.set(t, right[0], right[1], right[2])\n }\n}\n\nproto.pan = function(t, dx, dy, dz) {\n dx = dx || 0.0\n dy = dy || 0.0\n dz = dz || 0.0\n\n this.recalcMatrix(t)\n var mat = this.computedMatrix\n\n var dist = Math.exp(this.computedRadius[0])\n\n var ux = mat[1]\n var uy = mat[5]\n var uz = mat[9]\n var ul = len3(ux, uy, uz)\n ux /= ul\n uy /= ul\n uz /= ul\n\n var rx = mat[0]\n var ry = mat[4]\n var rz = mat[8]\n var ru = rx * ux + ry * uy + rz * uz\n rx -= ux * ru\n ry -= uy * ru\n rz -= uz * ru\n var rl = len3(rx, ry, rz)\n rx /= rl\n ry /= rl\n rz /= rl\n\n var vx = rx * dx + ux * dy\n var vy = ry * dx + uy * dy\n var vz = rz * dx + uz * dy\n this.center.move(t, vx, vy, vz)\n\n //Update z-component of radius\n var radius = Math.exp(this.computedRadius[0])\n radius = Math.max(1e-4, radius + dz)\n this.radius.set(t, Math.log(radius))\n}\n\nproto.translate = function(t, dx, dy, dz) {\n this.center.move(t,\n dx||0.0,\n dy||0.0,\n dz||0.0)\n}\n\n//Recenters the coordinate axes\nproto.setMatrix = function(t, mat, axes, noSnap) {\n \n //Get the axes for tare\n var ushift = 1\n if(typeof axes === 'number') {\n ushift = (axes)|0\n } \n if(ushift < 0 || ushift > 3) {\n ushift = 1\n }\n var vshift = (ushift + 2) % 3\n var fshift = (ushift + 1) % 3\n\n //Recompute state for new t value\n if(!mat) { \n this.recalcMatrix(t)\n mat = this.computedMatrix\n }\n\n //Get right and up vectors\n var ux = mat[ushift]\n var uy = mat[ushift+4]\n var uz = mat[ushift+8]\n if(!noSnap) {\n var ul = len3(ux, uy, uz)\n ux /= ul\n uy /= ul\n uz /= ul\n } else {\n var ax = Math.abs(ux)\n var ay = Math.abs(uy)\n var az = Math.abs(uz)\n var am = Math.max(ax,ay,az)\n if(ax === am) {\n ux = (ux < 0) ? -1 : 1\n uy = uz = 0\n } else if(az === am) {\n uz = (uz < 0) ? -1 : 1\n ux = uy = 0\n } else {\n uy = (uy < 0) ? -1 : 1\n ux = uz = 0\n }\n }\n\n var rx = mat[vshift]\n var ry = mat[vshift+4]\n var rz = mat[vshift+8]\n var ru = rx * ux + ry * uy + rz * uz\n rx -= ux * ru\n ry -= uy * ru\n rz -= uz * ru\n var rl = len3(rx, ry, rz)\n rx /= rl\n ry /= rl\n rz /= rl\n \n var fx = uy * rz - uz * ry\n var fy = uz * rx - ux * rz\n var fz = ux * ry - uy * rx\n var fl = len3(fx, fy, fz)\n fx /= fl\n fy /= fl\n fz /= fl\n\n this.center.jump(t, ex, ey, ez)\n this.radius.idle(t)\n this.up.jump(t, ux, uy, uz)\n this.right.jump(t, rx, ry, rz)\n\n var phi, theta\n if(ushift === 2) {\n var cx = mat[1]\n var cy = mat[5]\n var cz = mat[9]\n var cr = cx * rx + cy * ry + cz * rz\n var cf = cx * fx + cy * fy + cz * fz\n if(tu < 0) {\n phi = -Math.PI/2\n } else {\n phi = Math.PI/2\n }\n theta = Math.atan2(cf, cr)\n } else {\n var tx = mat[2]\n var ty = mat[6]\n var tz = mat[10]\n var tu = tx * ux + ty * uy + tz * uz\n var tr = tx * rx + ty * ry + tz * rz\n var tf = tx * fx + ty * fy + tz * fz\n\n phi = Math.asin(clamp1(tu))\n theta = Math.atan2(tf, tr)\n }\n\n this.angle.jump(t, theta, phi)\n\n this.recalcMatrix(t)\n var dx = mat[2]\n var dy = mat[6]\n var dz = mat[10]\n\n var imat = this.computedMatrix\n invert44(imat, mat)\n var w = imat[15]\n var ex = imat[12] / w\n var ey = imat[13] / w\n var ez = imat[14] / w\n\n var gs = Math.exp(this.computedRadius[0])\n this.center.jump(t, ex-dx*gs, ey-dy*gs, ez-dz*gs)\n}\n\nproto.lastT = function() {\n return Math.max(\n this.center.lastT(),\n this.up.lastT(),\n this.right.lastT(),\n this.radius.lastT(),\n this.angle.lastT())\n}\n\nproto.idle = function(t) {\n this.center.idle(t)\n this.up.idle(t)\n this.right.idle(t)\n this.radius.idle(t)\n this.angle.idle(t)\n}\n\nproto.flush = function(t) {\n this.center.flush(t)\n this.up.flush(t)\n this.right.flush(t)\n this.radius.flush(t)\n this.angle.flush(t)\n}\n\nproto.setDistance = function(t, d) {\n if(d > 0) {\n this.radius.set(t, Math.log(d))\n }\n}\n\nproto.lookAt = function(t, eye, center, up) {\n this.recalcMatrix(t)\n\n eye = eye || this.computedEye\n center = center || this.computedCenter\n up = up || this.computedUp\n\n var ux = up[0]\n var uy = up[1]\n var uz = up[2]\n var ul = len3(ux, uy, uz)\n if(ul < 1e-6) {\n return\n }\n ux /= ul\n uy /= ul\n uz /= ul\n\n var tx = eye[0] - center[0]\n var ty = eye[1] - center[1]\n var tz = eye[2] - center[2]\n var tl = len3(tx, ty, tz)\n if(tl < 1e-6) {\n return\n }\n tx /= tl\n ty /= tl\n tz /= tl\n\n var right = this.computedRight\n var rx = right[0]\n var ry = right[1]\n var rz = right[2]\n var ru = ux*rx + uy*ry + uz*rz\n rx -= ru * ux\n ry -= ru * uy\n rz -= ru * uz\n var rl = len3(rx, ry, rz)\n\n if(rl < 0.01) {\n rx = uy * tz - uz * ty\n ry = uz * tx - ux * tz\n rz = ux * ty - uy * tx\n rl = len3(rx, ry, rz)\n if(rl < 1e-6) {\n return\n }\n }\n rx /= rl\n ry /= rl\n rz /= rl\n\n this.up.set(t, ux, uy, uz)\n this.right.set(t, rx, ry, rz)\n this.center.set(t, center[0], center[1], center[2])\n this.radius.set(t, Math.log(tl))\n\n var fx = uy * rz - uz * ry\n var fy = uz * rx - ux * rz\n var fz = ux * ry - uy * rx\n var fl = len3(fx, fy, fz)\n fx /= fl\n fy /= fl\n fz /= fl\n\n var tu = ux*tx + uy*ty + uz*tz\n var tr = rx*tx + ry*ty + rz*tz\n var tf = fx*tx + fy*ty + fz*tz\n\n var phi = Math.asin(clamp1(tu))\n var theta = Math.atan2(tf, tr)\n\n var angleState = this.angle._state\n var lastTheta = angleState[angleState.length-1]\n var lastPhi = angleState[angleState.length-2]\n lastTheta = lastTheta % (2.0 * Math.PI)\n var dp = Math.abs(lastTheta + 2.0 * Math.PI - theta)\n var d0 = Math.abs(lastTheta - theta)\n var dn = Math.abs(lastTheta - 2.0 * Math.PI - theta)\n if(dp < d0) {\n lastTheta += 2.0 * Math.PI\n }\n if(dn < d0) {\n lastTheta -= 2.0 * Math.PI\n }\n\n this.angle.jump(this.angle.lastT(), lastTheta, lastPhi)\n this.angle.set(t, theta, phi)\n}\n\nfunction createTurntableController(options) {\n options = options || {}\n\n var center = options.center || [0,0,0]\n var up = options.up || [0,1,0]\n var right = options.right || findOrthoPair(up)\n var radius = options.radius || 1.0\n var theta = options.theta || 0.0\n var phi = options.phi || 0.0\n\n center = [].slice.call(center, 0, 3)\n\n up = [].slice.call(up, 0, 3)\n normalize3(up, up)\n\n right = [].slice.call(right, 0, 3)\n normalize3(right, right)\n\n if('eye' in options) {\n var eye = options.eye\n var toward = [\n eye[0]-center[0],\n eye[1]-center[1],\n eye[2]-center[2]\n ]\n cross(right, toward, up)\n if(len3(right[0], right[1], right[2]) < 1e-6) {\n right = findOrthoPair(up)\n } else {\n normalize3(right, right)\n }\n\n radius = len3(toward[0], toward[1], toward[2])\n\n var ut = dot3(up, toward) / radius\n var rt = dot3(right, toward) / radius\n phi = Math.acos(ut)\n theta = Math.acos(rt)\n }\n\n //Use logarithmic coordinates for radius\n radius = Math.log(radius)\n\n //Return the controller\n return new TurntableController(\n options.zoomMin,\n options.zoomMax,\n center,\n up,\n right,\n radius,\n theta,\n phi)\n}\n\n//# sourceURL=webpack:///./node_modules/turntable-camera-controller/turntable.js?");
-
-/***/ }),
-
-/***/ "./node_modules/two-product/two-product.js":
-/*!*************************************************!*\
- !*** ./node_modules/two-product/two-product.js ***!
- \*************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nmodule.exports = twoProduct\n\nvar SPLITTER = +(Math.pow(2, 27) + 1.0)\n\nfunction twoProduct(a, b, result) {\n var x = a * b\n\n var c = SPLITTER * a\n var abig = c - a\n var ahi = c - abig\n var alo = a - ahi\n\n var d = SPLITTER * b\n var bbig = d - b\n var bhi = d - bbig\n var blo = b - bhi\n\n var err1 = x - (ahi * bhi)\n var err2 = err1 - (alo * bhi)\n var err3 = err2 - (ahi * blo)\n\n var y = alo * blo - err3\n\n if(result) {\n result[0] = y\n result[1] = x\n return result\n }\n\n return [ y, x ]\n}\n\n//# sourceURL=webpack:///./node_modules/two-product/two-product.js?");
-
-/***/ }),
-
-/***/ "./node_modules/two-sum/two-sum.js":
-/*!*****************************************!*\
- !*** ./node_modules/two-sum/two-sum.js ***!
- \*****************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nmodule.exports = fastTwoSum\n\nfunction fastTwoSum(a, b, result) {\n\tvar x = a + b\n\tvar bv = x - a\n\tvar av = x - bv\n\tvar br = b - bv\n\tvar ar = a - av\n\tif(result) {\n\t\tresult[0] = ar + br\n\t\tresult[1] = x\n\t\treturn result\n\t}\n\treturn [ar+br, x]\n}\n\n//# sourceURL=webpack:///./node_modules/two-sum/two-sum.js?");
-
-/***/ }),
-
-/***/ "./node_modules/type/function/is.js":
-/*!******************************************!*\
- !*** ./node_modules/type/function/is.js ***!
- \******************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nvar isPrototype = __webpack_require__(/*! ../prototype/is */ \"./node_modules/type/prototype/is.js\");\n\nmodule.exports = function (value) {\n\tif (typeof value !== \"function\") return false;\n\n\tif (!hasOwnProperty.call(value, \"length\")) return false;\n\n\ttry {\n\t\tif (typeof value.length !== \"number\") return false;\n\t\tif (typeof value.call !== \"function\") return false;\n\t\tif (typeof value.apply !== \"function\") return false;\n\t} catch (error) {\n\t\treturn false;\n\t}\n\n\treturn !isPrototype(value);\n};\n\n\n//# sourceURL=webpack:///./node_modules/type/function/is.js?");
-
-/***/ }),
-
-/***/ "./node_modules/type/lib/resolve-exception.js":
-/*!****************************************************!*\
- !*** ./node_modules/type/lib/resolve-exception.js ***!
- \****************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nvar isValue = __webpack_require__(/*! ../value/is */ \"./node_modules/type/value/is.js\")\n , isObject = __webpack_require__(/*! ../object/is */ \"./node_modules/type/object/is.js\")\n , stringCoerce = __webpack_require__(/*! ../string/coerce */ \"./node_modules/type/string/coerce.js\")\n , toShortString = __webpack_require__(/*! ./to-short-string */ \"./node_modules/type/lib/to-short-string.js\");\n\nvar resolveMessage = function (message, value) {\n\treturn message.replace(\"%v\", toShortString(value));\n};\n\nmodule.exports = function (value, defaultMessage, inputOptions) {\n\tif (!isObject(inputOptions)) throw new TypeError(resolveMessage(defaultMessage, value));\n\tif (!isValue(value)) {\n\t\tif (\"default\" in inputOptions) return inputOptions[\"default\"];\n\t\tif (inputOptions.isOptional) return null;\n\t}\n\tvar errorMessage = stringCoerce(inputOptions.errorMessage);\n\tif (!isValue(errorMessage)) errorMessage = defaultMessage;\n\tthrow new TypeError(resolveMessage(errorMessage, value));\n};\n\n\n//# sourceURL=webpack:///./node_modules/type/lib/resolve-exception.js?");
-
-/***/ }),
-
-/***/ "./node_modules/type/lib/safe-to-string.js":
-/*!*************************************************!*\
- !*** ./node_modules/type/lib/safe-to-string.js ***!
- \*************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nmodule.exports = function (value) {\n\ttry {\n\t\treturn value.toString();\n\t} catch (error) {\n\t\ttry { return String(value); }\n\t\tcatch (error2) { return null; }\n\t}\n};\n\n\n//# sourceURL=webpack:///./node_modules/type/lib/safe-to-string.js?");
-
-/***/ }),
-
-/***/ "./node_modules/type/lib/to-short-string.js":
-/*!**************************************************!*\
- !*** ./node_modules/type/lib/to-short-string.js ***!
- \**************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nvar safeToString = __webpack_require__(/*! ./safe-to-string */ \"./node_modules/type/lib/safe-to-string.js\");\n\nvar reNewLine = /[\\n\\r\\u2028\\u2029]/g;\n\nmodule.exports = function (value) {\n\tvar string = safeToString(value);\n\tif (string === null) return \"\";\n\t// Trim if too long\n\tif (string.length > 100) string = string.slice(0, 99) + \"…\";\n\t// Replace eventual new lines\n\tstring = string.replace(reNewLine, function (char) {\n\t\tswitch (char) {\n\t\t\tcase \"\\n\":\n\t\t\t\treturn \"\\\\n\";\n\t\t\tcase \"\\r\":\n\t\t\t\treturn \"\\\\r\";\n\t\t\tcase \"\\u2028\":\n\t\t\t\treturn \"\\\\u2028\";\n\t\t\tcase \"\\u2029\":\n\t\t\t\treturn \"\\\\u2029\";\n\t\t\t/* istanbul ignore next */\n\t\t\tdefault:\n\t\t\t\tthrow new Error(\"Unexpected character\");\n\t\t}\n\t});\n\treturn string;\n};\n\n\n//# sourceURL=webpack:///./node_modules/type/lib/to-short-string.js?");
-
-/***/ }),
-
-/***/ "./node_modules/type/object/is.js":
-/*!****************************************!*\
- !*** ./node_modules/type/object/is.js ***!
- \****************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nvar isValue = __webpack_require__(/*! ../value/is */ \"./node_modules/type/value/is.js\");\n\n// prettier-ignore\nvar possibleTypes = { \"object\": true, \"function\": true, \"undefined\": true /* document.all */ };\n\nmodule.exports = function (value) {\n\tif (!isValue(value)) return false;\n\treturn hasOwnProperty.call(possibleTypes, typeof value);\n};\n\n\n//# sourceURL=webpack:///./node_modules/type/object/is.js?");
-
-/***/ }),
-
-/***/ "./node_modules/type/plain-function/ensure.js":
-/*!****************************************************!*\
- !*** ./node_modules/type/plain-function/ensure.js ***!
- \****************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nvar resolveException = __webpack_require__(/*! ../lib/resolve-exception */ \"./node_modules/type/lib/resolve-exception.js\")\n , is = __webpack_require__(/*! ./is */ \"./node_modules/type/plain-function/is.js\");\n\nmodule.exports = function (value/*, options*/) {\n\tif (is(value)) return value;\n\treturn resolveException(value, \"%v is not a plain function\", arguments[1]);\n};\n\n\n//# sourceURL=webpack:///./node_modules/type/plain-function/ensure.js?");
-
-/***/ }),
-
-/***/ "./node_modules/type/plain-function/is.js":
-/*!************************************************!*\
- !*** ./node_modules/type/plain-function/is.js ***!
- \************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nvar isFunction = __webpack_require__(/*! ../function/is */ \"./node_modules/type/function/is.js\");\n\nvar classRe = /^\\s*class[\\s{/}]/, functionToString = Function.prototype.toString;\n\nmodule.exports = function (value) {\n\tif (!isFunction(value)) return false;\n\tif (classRe.test(functionToString.call(value))) return false;\n\treturn true;\n};\n\n\n//# sourceURL=webpack:///./node_modules/type/plain-function/is.js?");
-
-/***/ }),
-
-/***/ "./node_modules/type/prototype/is.js":
-/*!*******************************************!*\
- !*** ./node_modules/type/prototype/is.js ***!
- \*******************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nvar isObject = __webpack_require__(/*! ../object/is */ \"./node_modules/type/object/is.js\");\n\nmodule.exports = function (value) {\n\tif (!isObject(value)) return false;\n\ttry {\n\t\tif (!value.constructor) return false;\n\t\treturn value.constructor.prototype === value;\n\t} catch (error) {\n\t\treturn false;\n\t}\n};\n\n\n//# sourceURL=webpack:///./node_modules/type/prototype/is.js?");
-
-/***/ }),
-
-/***/ "./node_modules/type/string/coerce.js":
-/*!********************************************!*\
- !*** ./node_modules/type/string/coerce.js ***!
- \********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nvar isValue = __webpack_require__(/*! ../value/is */ \"./node_modules/type/value/is.js\")\n , isObject = __webpack_require__(/*! ../object/is */ \"./node_modules/type/object/is.js\");\n\nvar objectToString = Object.prototype.toString;\n\nmodule.exports = function (value) {\n\tif (!isValue(value)) return null;\n\tif (isObject(value)) {\n\t\t// Reject Object.prototype.toString coercion\n\t\tvar valueToString = value.toString;\n\t\tif (typeof valueToString !== \"function\") return null;\n\t\tif (valueToString === objectToString) return null;\n\t\t// Note: It can be object coming from other realm, still as there's no ES3 and CSP compliant\n\t\t// way to resolve its realm's Object.prototype.toString it's left as not addressed edge case\n\t}\n\ttry {\n\t\treturn \"\" + value; // Ensure implicit coercion\n\t} catch (error) {\n\t\treturn null;\n\t}\n};\n\n\n//# sourceURL=webpack:///./node_modules/type/string/coerce.js?");
-
-/***/ }),
-
-/***/ "./node_modules/type/value/ensure.js":
-/*!*******************************************!*\
- !*** ./node_modules/type/value/ensure.js ***!
- \*******************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nvar resolveException = __webpack_require__(/*! ../lib/resolve-exception */ \"./node_modules/type/lib/resolve-exception.js\")\n , is = __webpack_require__(/*! ./is */ \"./node_modules/type/value/is.js\");\n\nmodule.exports = function (value/*, options*/) {\n\tif (is(value)) return value;\n\treturn resolveException(value, \"Cannot use %v\", arguments[1]);\n};\n\n\n//# sourceURL=webpack:///./node_modules/type/value/ensure.js?");
-
-/***/ }),
-
-/***/ "./node_modules/type/value/is.js":
-/*!***************************************!*\
- !*** ./node_modules/type/value/is.js ***!
- \***************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\n// ES3 safe\nvar _undefined = void 0;\n\nmodule.exports = function (value) { return value !== _undefined && value !== null; };\n\n\n//# sourceURL=webpack:///./node_modules/type/value/is.js?");
-
-/***/ }),
-
-/***/ "./node_modules/typedarray-pool/pool.js":
-/*!**********************************************!*\
- !*** ./node_modules/typedarray-pool/pool.js ***!
- \**********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(global) {\n\nvar bits = __webpack_require__(/*! bit-twiddle */ \"./node_modules/bit-twiddle/twiddle.js\")\nvar dup = __webpack_require__(/*! dup */ \"./node_modules/dup/dup.js\")\nvar Buffer = __webpack_require__(/*! buffer */ \"./node_modules/buffer/index.js\").Buffer\n\n//Legacy pool support\nif(!global.__TYPEDARRAY_POOL) {\n global.__TYPEDARRAY_POOL = {\n UINT8 : dup([32, 0])\n , UINT16 : dup([32, 0])\n , UINT32 : dup([32, 0])\n , BIGUINT64 : dup([32, 0])\n , INT8 : dup([32, 0])\n , INT16 : dup([32, 0])\n , INT32 : dup([32, 0])\n , BIGINT64 : dup([32, 0])\n , FLOAT : dup([32, 0])\n , DOUBLE : dup([32, 0])\n , DATA : dup([32, 0])\n , UINT8C : dup([32, 0])\n , BUFFER : dup([32, 0])\n }\n}\n\nvar hasUint8C = (typeof Uint8ClampedArray) !== 'undefined'\nvar hasBigUint64 = (typeof BigUint64Array) !== 'undefined'\nvar hasBigInt64 = (typeof BigInt64Array) !== 'undefined'\nvar POOL = global.__TYPEDARRAY_POOL\n\n//Upgrade pool\nif(!POOL.UINT8C) {\n POOL.UINT8C = dup([32, 0])\n}\nif(!POOL.BIGUINT64) {\n POOL.BIGUINT64 = dup([32, 0])\n}\nif(!POOL.BIGINT64) {\n POOL.BIGINT64 = dup([32, 0])\n}\nif(!POOL.BUFFER) {\n POOL.BUFFER = dup([32, 0])\n}\n\n//New technique: Only allocate from ArrayBufferView and Buffer\nvar DATA = POOL.DATA\n , BUFFER = POOL.BUFFER\n\nexports.free = function free(array) {\n if(Buffer.isBuffer(array)) {\n BUFFER[bits.log2(array.length)].push(array)\n } else {\n if(Object.prototype.toString.call(array) !== '[object ArrayBuffer]') {\n array = array.buffer\n }\n if(!array) {\n return\n }\n var n = array.length || array.byteLength\n var log_n = bits.log2(n)|0\n DATA[log_n].push(array)\n }\n}\n\nfunction freeArrayBuffer(buffer) {\n if(!buffer) {\n return\n }\n var n = buffer.length || buffer.byteLength\n var log_n = bits.log2(n)\n DATA[log_n].push(buffer)\n}\n\nfunction freeTypedArray(array) {\n freeArrayBuffer(array.buffer)\n}\n\nexports.freeUint8 =\nexports.freeUint16 =\nexports.freeUint32 =\nexports.freeBigUint64 =\nexports.freeInt8 =\nexports.freeInt16 =\nexports.freeInt32 =\nexports.freeBigInt64 =\nexports.freeFloat32 = \nexports.freeFloat =\nexports.freeFloat64 = \nexports.freeDouble = \nexports.freeUint8Clamped = \nexports.freeDataView = freeTypedArray\n\nexports.freeArrayBuffer = freeArrayBuffer\n\nexports.freeBuffer = function freeBuffer(array) {\n BUFFER[bits.log2(array.length)].push(array)\n}\n\nexports.malloc = function malloc(n, dtype) {\n if(dtype === undefined || dtype === 'arraybuffer') {\n return mallocArrayBuffer(n)\n } else {\n switch(dtype) {\n case 'uint8':\n return mallocUint8(n)\n case 'uint16':\n return mallocUint16(n)\n case 'uint32':\n return mallocUint32(n)\n case 'int8':\n return mallocInt8(n)\n case 'int16':\n return mallocInt16(n)\n case 'int32':\n return mallocInt32(n)\n case 'float':\n case 'float32':\n return mallocFloat(n)\n case 'double':\n case 'float64':\n return mallocDouble(n)\n case 'uint8_clamped':\n return mallocUint8Clamped(n)\n case 'bigint64':\n return mallocBigInt64(n)\n case 'biguint64':\n return mallocBigUint64(n)\n case 'buffer':\n return mallocBuffer(n)\n case 'data':\n case 'dataview':\n return mallocDataView(n)\n\n default:\n return null\n }\n }\n return null\n}\n\nfunction mallocArrayBuffer(n) {\n var n = bits.nextPow2(n)\n var log_n = bits.log2(n)\n var d = DATA[log_n]\n if(d.length > 0) {\n return d.pop()\n }\n return new ArrayBuffer(n)\n}\nexports.mallocArrayBuffer = mallocArrayBuffer\n\nfunction mallocUint8(n) {\n return new Uint8Array(mallocArrayBuffer(n), 0, n)\n}\nexports.mallocUint8 = mallocUint8\n\nfunction mallocUint16(n) {\n return new Uint16Array(mallocArrayBuffer(2*n), 0, n)\n}\nexports.mallocUint16 = mallocUint16\n\nfunction mallocUint32(n) {\n return new Uint32Array(mallocArrayBuffer(4*n), 0, n)\n}\nexports.mallocUint32 = mallocUint32\n\nfunction mallocInt8(n) {\n return new Int8Array(mallocArrayBuffer(n), 0, n)\n}\nexports.mallocInt8 = mallocInt8\n\nfunction mallocInt16(n) {\n return new Int16Array(mallocArrayBuffer(2*n), 0, n)\n}\nexports.mallocInt16 = mallocInt16\n\nfunction mallocInt32(n) {\n return new Int32Array(mallocArrayBuffer(4*n), 0, n)\n}\nexports.mallocInt32 = mallocInt32\n\nfunction mallocFloat(n) {\n return new Float32Array(mallocArrayBuffer(4*n), 0, n)\n}\nexports.mallocFloat32 = exports.mallocFloat = mallocFloat\n\nfunction mallocDouble(n) {\n return new Float64Array(mallocArrayBuffer(8*n), 0, n)\n}\nexports.mallocFloat64 = exports.mallocDouble = mallocDouble\n\nfunction mallocUint8Clamped(n) {\n if(hasUint8C) {\n return new Uint8ClampedArray(mallocArrayBuffer(n), 0, n)\n } else {\n return mallocUint8(n)\n }\n}\nexports.mallocUint8Clamped = mallocUint8Clamped\n\nfunction mallocBigUint64(n) {\n if(hasBigUint64) {\n return new BigUint64Array(mallocArrayBuffer(8*n), 0, n)\n } else {\n return null;\n }\n}\nexports.mallocBigUint64 = mallocBigUint64\n\nfunction mallocBigInt64(n) {\n if (hasBigInt64) {\n return new BigInt64Array(mallocArrayBuffer(8*n), 0, n)\n } else {\n return null;\n }\n}\nexports.mallocBigInt64 = mallocBigInt64\n\nfunction mallocDataView(n) {\n return new DataView(mallocArrayBuffer(n), 0, n)\n}\nexports.mallocDataView = mallocDataView\n\nfunction mallocBuffer(n) {\n n = bits.nextPow2(n)\n var log_n = bits.log2(n)\n var cache = BUFFER[log_n]\n if(cache.length > 0) {\n return cache.pop()\n }\n return new Buffer(n)\n}\nexports.mallocBuffer = mallocBuffer\n\nexports.clearCache = function clearCache() {\n for(var i=0; i<32; ++i) {\n POOL.UINT8[i].length = 0\n POOL.UINT16[i].length = 0\n POOL.UINT32[i].length = 0\n POOL.INT8[i].length = 0\n POOL.INT16[i].length = 0\n POOL.INT32[i].length = 0\n POOL.FLOAT[i].length = 0\n POOL.DOUBLE[i].length = 0\n POOL.BIGUINT64[i].length = 0\n POOL.BIGINT64[i].length = 0\n POOL.UINT8C[i].length = 0\n DATA[i].length = 0\n BUFFER[i].length = 0\n }\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n//# sourceURL=webpack:///./node_modules/typedarray-pool/pool.js?");
-
-/***/ }),
-
-/***/ "./node_modules/union-find/index.js":
-/*!******************************************!*\
- !*** ./node_modules/union-find/index.js ***!
- \******************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval(" \"use restrict\";\n\nmodule.exports = UnionFind;\n\nfunction UnionFind(count) {\n this.roots = new Array(count);\n this.ranks = new Array(count);\n \n for(var i=0; i= len) return x;\n switch (x) {\n case '%s': return String(args[i++]);\n case '%d': return Number(args[i++]);\n case '%j':\n try {\n return JSON.stringify(args[i++]);\n } catch (_) {\n return '[Circular]';\n }\n default:\n return x;\n }\n });\n for (var x = args[i]; i < len; x = args[++i]) {\n if (isNull(x) || !isObject(x)) {\n str += ' ' + x;\n } else {\n str += ' ' + inspect(x);\n }\n }\n return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n if (typeof process !== 'undefined' && process.noDeprecation === true) {\n return fn;\n }\n\n // Allow for deprecating things in the process of starting up.\n if (typeof process === 'undefined') {\n return function() {\n return exports.deprecate(fn, msg).apply(this, arguments);\n };\n }\n\n var warned = false;\n function deprecated() {\n if (!warned) {\n if (process.throwDeprecation) {\n throw new Error(msg);\n } else if (process.traceDeprecation) {\n console.trace(msg);\n } else {\n console.error(msg);\n }\n warned = true;\n }\n return fn.apply(this, arguments);\n }\n\n return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n if (isUndefined(debugEnviron))\n debugEnviron = Object({\"NODE_ENV\":\"development\",\"BASE_URL\":\"\"}).NODE_DEBUG || '';\n set = set.toUpperCase();\n if (!debugs[set]) {\n if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n var pid = process.pid;\n debugs[set] = function() {\n var msg = exports.format.apply(exports, arguments);\n console.error('%s %d: %s', set, pid, msg);\n };\n } else {\n debugs[set] = function() {};\n }\n }\n return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n // default options\n var ctx = {\n seen: [],\n stylize: stylizeNoColor\n };\n // legacy...\n if (arguments.length >= 3) ctx.depth = arguments[2];\n if (arguments.length >= 4) ctx.colors = arguments[3];\n if (isBoolean(opts)) {\n // legacy...\n ctx.showHidden = opts;\n } else if (opts) {\n // got an \"options\" object\n exports._extend(ctx, opts);\n }\n // set default options\n if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n if (isUndefined(ctx.depth)) ctx.depth = 2;\n if (isUndefined(ctx.colors)) ctx.colors = false;\n if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n if (ctx.colors) ctx.stylize = stylizeWithColor;\n return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n 'bold' : [1, 22],\n 'italic' : [3, 23],\n 'underline' : [4, 24],\n 'inverse' : [7, 27],\n 'white' : [37, 39],\n 'grey' : [90, 39],\n 'black' : [30, 39],\n 'blue' : [34, 39],\n 'cyan' : [36, 39],\n 'green' : [32, 39],\n 'magenta' : [35, 39],\n 'red' : [31, 39],\n 'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n 'special': 'cyan',\n 'number': 'yellow',\n 'boolean': 'yellow',\n 'undefined': 'grey',\n 'null': 'bold',\n 'string': 'green',\n 'date': 'magenta',\n // \"name\": intentionally not styling\n 'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n var style = inspect.styles[styleType];\n\n if (style) {\n return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n '\\u001b[' + inspect.colors[style][1] + 'm';\n } else {\n return str;\n }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n return str;\n}\n\n\nfunction arrayToHash(array) {\n var hash = {};\n\n array.forEach(function(val, idx) {\n hash[val] = true;\n });\n\n return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (ctx.customInspect &&\n value &&\n isFunction(value.inspect) &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes, ctx);\n if (!isString(ret)) {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // Look up the keys of the object.\n var keys = Object.keys(value);\n var visibleKeys = arrayToHash(keys);\n\n if (ctx.showHidden) {\n keys = Object.getOwnPropertyNames(value);\n }\n\n // IE doesn't make error fields non-enumerable\n // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n if (isError(value)\n && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n return formatError(value);\n }\n\n // Some type of object without properties can be shortcutted.\n if (keys.length === 0) {\n if (isFunction(value)) {\n var name = value.name ? ': ' + value.name : '';\n return ctx.stylize('[Function' + name + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (isFunction(value)) {\n var n = value.name ? ': ' + value.name : '';\n base = ' [Function' + n + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n base = ' ' + formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n if (isUndefined(value))\n return ctx.stylize('undefined', 'undefined');\n if (isString(value)) {\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n }\n if (isNumber(value))\n return ctx.stylize('' + value, 'number');\n if (isBoolean(value))\n return ctx.stylize('' + value, 'boolean');\n // For some reason typeof null is \"object\", so special case here.\n if (isNull(value))\n return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (hasOwnProperty(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str, desc;\n desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n if (desc.get) {\n if (desc.set) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (desc.set) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n if (!hasOwnProperty(visibleKeys, key)) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(desc.value) < 0) {\n if (isNull(recurseTimes)) {\n str = formatValue(ctx, desc.value, null);\n } else {\n str = formatValue(ctx, desc.value, recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (isUndefined(name)) {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n return isObject(e) &&\n (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n return arg === null ||\n typeof arg === 'boolean' ||\n typeof arg === 'number' ||\n typeof arg === 'string' ||\n typeof arg === 'symbol' || // ES6 symbol\n typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = __webpack_require__(/*! ./support/isBuffer */ \"./node_modules/util/support/isBufferBrowser.js\");\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n 'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n var d = new Date();\n var time = [pad(d.getHours()),\n pad(d.getMinutes()),\n pad(d.getSeconds())].join(':');\n return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n * prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = __webpack_require__(/*! inherits */ \"./node_modules/util/node_modules/inherits/inherits_browser.js\");\n\nexports._extend = function(origin, add) {\n // Don't do anything if add isn't an object\n if (!add || !isObject(add)) return origin;\n\n var keys = Object.keys(add);\n var i = keys.length;\n while (i--) {\n origin[keys[i]] = add[keys[i]];\n }\n return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\nvar kCustomPromisifiedSymbol = typeof Symbol !== 'undefined' ? Symbol('util.promisify.custom') : undefined;\n\nexports.promisify = function promisify(original) {\n if (typeof original !== 'function')\n throw new TypeError('The \"original\" argument must be of type Function');\n\n if (kCustomPromisifiedSymbol && original[kCustomPromisifiedSymbol]) {\n var fn = original[kCustomPromisifiedSymbol];\n if (typeof fn !== 'function') {\n throw new TypeError('The \"util.promisify.custom\" argument must be of type Function');\n }\n Object.defineProperty(fn, kCustomPromisifiedSymbol, {\n value: fn, enumerable: false, writable: false, configurable: true\n });\n return fn;\n }\n\n function fn() {\n var promiseResolve, promiseReject;\n var promise = new Promise(function (resolve, reject) {\n promiseResolve = resolve;\n promiseReject = reject;\n });\n\n var args = [];\n for (var i = 0; i < arguments.length; i++) {\n args.push(arguments[i]);\n }\n args.push(function (err, value) {\n if (err) {\n promiseReject(err);\n } else {\n promiseResolve(value);\n }\n });\n\n try {\n original.apply(this, args);\n } catch (err) {\n promiseReject(err);\n }\n\n return promise;\n }\n\n Object.setPrototypeOf(fn, Object.getPrototypeOf(original));\n\n if (kCustomPromisifiedSymbol) Object.defineProperty(fn, kCustomPromisifiedSymbol, {\n value: fn, enumerable: false, writable: false, configurable: true\n });\n return Object.defineProperties(\n fn,\n getOwnPropertyDescriptors(original)\n );\n}\n\nexports.promisify.custom = kCustomPromisifiedSymbol\n\nfunction callbackifyOnRejected(reason, cb) {\n // `!reason` guard inspired by bluebird (Ref: https://goo.gl/t5IS6M).\n // Because `null` is a special error value in callbacks which means \"no error\n // occurred\", we error-wrap so the callback consumer can distinguish between\n // \"the promise rejected with null\" or \"the promise fulfilled with undefined\".\n if (!reason) {\n var newReason = new Error('Promise was rejected with a falsy value');\n newReason.reason = reason;\n reason = newReason;\n }\n return cb(reason);\n}\n\nfunction callbackify(original) {\n if (typeof original !== 'function') {\n throw new TypeError('The \"original\" argument must be of type Function');\n }\n\n // We DO NOT return the promise as it gives the user a false sense that\n // the promise is actually somehow related to the callback's execution\n // and that the callback throwing will reject the promise.\n function callbackified() {\n var args = [];\n for (var i = 0; i < arguments.length; i++) {\n args.push(arguments[i]);\n }\n\n var maybeCb = args.pop();\n if (typeof maybeCb !== 'function') {\n throw new TypeError('The last argument must be of type Function');\n }\n var self = this;\n var cb = function() {\n return maybeCb.apply(self, arguments);\n };\n // In true node style we process the callback on `nextTick` with all the\n // implications (stack, `uncaughtException`, `async_hooks`)\n original.apply(this, args)\n .then(function(ret) { process.nextTick(cb, null, ret) },\n function(rej) { process.nextTick(callbackifyOnRejected, rej, cb) });\n }\n\n Object.setPrototypeOf(callbackified, Object.getPrototypeOf(original));\n Object.defineProperties(callbackified,\n getOwnPropertyDescriptors(original));\n return callbackified;\n}\nexports.callbackify = callbackify;\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../node-libs-browser/mock/process.js */ \"./node_modules/node-libs-browser/mock/process.js\")))\n\n//# sourceURL=webpack:///./node_modules/util/util.js?");
-
-/***/ }),
-
-/***/ "./node_modules/vectorize-text/index.js":
-/*!**********************************************!*\
- !*** ./node_modules/vectorize-text/index.js ***!
- \**********************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-eval("\n\nmodule.exports = createText\n\nvar vectorizeText = __webpack_require__(/*! ./lib/vtext */ \"./node_modules/vectorize-text/lib/vtext.js\")\nvar defaultCanvas = null\nvar defaultContext = null\n\nif(typeof document !== 'undefined') {\n defaultCanvas = document.createElement('canvas')\n defaultCanvas.width = 8192\n defaultCanvas.height = 1024\n defaultContext = defaultCanvas.getContext(\"2d\")\n}\n\nfunction createText(str, options) {\n if((typeof options !== \"object\") || (options === null)) {\n options = {}\n }\n return vectorizeText(\n str,\n options.canvas || defaultCanvas,\n options.context || defaultContext,\n options)\n}\n\n\n//# sourceURL=webpack:///./node_modules/vectorize-text/index.js?");
-
-/***/ }),
-
-/***/ "./node_modules/vectorize-text/lib/vtext.js":
-/*!**************************************************!*\
- !*** ./node_modules/vectorize-text/lib/vtext.js ***!
- \**************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-eval("module.exports = vectorizeText\nmodule.exports.processPixels = processPixels\n\nvar surfaceNets = __webpack_require__(/*! surface-nets */ \"./node_modules/surface-nets/surfacenets.js\")\nvar ndarray = __webpack_require__(/*! ndarray */ \"./node_modules/ndarray/ndarray.js\")\nvar simplify = __webpack_require__(/*! simplify-planar-graph */ \"./node_modules/simplify-planar-graph/simplify.js\")\nvar cleanPSLG = __webpack_require__(/*! clean-pslg */ \"./node_modules/clean-pslg/clean-pslg.js\")\nvar cdt2d = __webpack_require__(/*! cdt2d */ \"./node_modules/cdt2d/cdt2d.js\")\nvar toPolygonCrappy = __webpack_require__(/*! planar-graph-to-polyline */ \"./node_modules/planar-graph-to-polyline/pg2pl.js\")\n\nvar TAG_bold = \"b\"\nvar CHR_bold = 'b|'\n\nvar TAG_italic = \"i\"\nvar CHR_italic = 'i|'\n\nvar TAG_super = \"sup\"\nvar CHR_super0 = '+'\nvar CHR_super = '+1'\n\nvar TAG_sub = \"sub\"\nvar CHR_sub0 = '-'\nvar CHR_sub = '-1'\n\nfunction parseTag(tag, TAG_CHR, str, map) {\n\n var opnTag = \"<\" + tag + \">\"\n var clsTag = \"\" + tag + \">\"\n\n var nOPN = opnTag.length\n var nCLS = clsTag.length\n\n var isRecursive = (TAG_CHR[0] === CHR_super0) ||\n (TAG_CHR[0] === CHR_sub0);\n\n var a = 0\n var b = -nCLS\n while (a > -1) {\n a = str.indexOf(opnTag, a)\n if(a === -1) break\n\n b = str.indexOf(clsTag, a + nOPN)\n if(b === -1) break\n\n if(b <= a) break\n\n for(var i = a; i < b + nCLS; ++i){\n if((i < a + nOPN) || (i >= b)) {\n map[i] = null\n str = str.substr(0, i) + \" \" + str.substr(i + 1)\n } else {\n if(map[i] !== null) {\n var pos = map[i].indexOf(TAG_CHR[0])\n if(pos === -1) {\n map[i] += TAG_CHR\n } else { // i.e. to handle multiple sub/super-scripts\n if(isRecursive) {\n // i.e to increase the sub/sup number\n map[i] = map[i].substr(0, pos + 1) + (1 + parseInt(map[i][pos + 1])) + map[i].substr(pos + 2)\n }\n }\n }\n }\n }\n\n var start = a + nOPN\n var remainingStr = str.substr(start, b - start)\n\n var c = remainingStr.indexOf(opnTag)\n if(c !== -1) a = c\n else a = b + nCLS\n }\n\n return map\n}\n\nfunction transformPositions(positions, options, size) {\n var align = options.textAlign || \"start\"\n var baseline = options.textBaseline || \"alphabetic\"\n\n var lo = [1<<30, 1<<30]\n var hi = [0,0]\n var n = positions.length\n for(var i=0; i/g, '\\n') // replace
tags with \\n in the string\n } else {\n rawString = rawString.replace(/\\
/g, ' ') // don't accept
tags in the input and replace with space in this case\n }\n\n var activeStyle = \"\"\n var map = []\n for(j = 0; j < rawString.length; ++j) {\n map[j] = activeStyle\n }\n\n if(styletags.bolds === true) map = parseTag(TAG_bold, CHR_bold, rawString, map)\n if(styletags.italics === true) map = parseTag(TAG_italic, CHR_italic, rawString, map)\n if(styletags.superscripts === true) map = parseTag(TAG_super, CHR_super, rawString, map)\n if(styletags.subscripts === true) map = parseTag(TAG_sub, CHR_sub, rawString, map)\n\n var allStyles = []\n var plainText = \"\"\n for(j = 0; j < rawString.length; ++j) {\n if(map[j] !== null) {\n plainText += rawString[j]\n allStyles.push(map[j])\n }\n }\n\n var allTexts = plainText.split('\\n')\n\n var numberOfLines = allTexts.length\n var lineHeight = Math.round(lineSpacing * fontSize)\n var offsetX = fontSize\n var offsetY = fontSize * 2\n var maxWidth = 0\n var minHeight = numberOfLines * lineHeight + offsetY\n\n if(canvas.height < minHeight) {\n canvas.height = minHeight\n }\n\n context.fillStyle = \"#000\"\n context.fillRect(0, 0, canvas.width, canvas.height)\n\n context.fillStyle = \"#fff\"\n var i, j, xPos, yPos, zPos\n var nDone = 0\n\n var buffer = \"\"\n function writeBuffer() {\n if(buffer !== \"\") {\n var delta = context.measureText(buffer).width\n\n context.fillText(buffer, offsetX + xPos, offsetY + yPos)\n xPos += delta\n }\n }\n\n function getTextFontSize() {\n return \"\" + Math.round(zPos) + \"px \";\n }\n\n function changeStyle(oldStyle, newStyle) {\n var ctxFont = \"\" + context.font;\n\n if(styletags.subscripts === true) {\n var oldIndex_Sub = oldStyle.indexOf(CHR_sub0);\n var newIndex_Sub = newStyle.indexOf(CHR_sub0);\n\n var oldSub = (oldIndex_Sub > -1) ? parseInt(oldStyle[1 + oldIndex_Sub]) : 0;\n var newSub = (newIndex_Sub > -1) ? parseInt(newStyle[1 + newIndex_Sub]) : 0;\n\n if(oldSub !== newSub) {\n ctxFont = ctxFont.replace(getTextFontSize(), \"?px \")\n zPos *= Math.pow(0.75, (newSub - oldSub))\n ctxFont = ctxFont.replace(\"?px \", getTextFontSize())\n }\n yPos += 0.25 * lineHeight * (newSub - oldSub);\n }\n\n if(styletags.superscripts === true) {\n var oldIndex_Super = oldStyle.indexOf(CHR_super0);\n var newIndex_Super = newStyle.indexOf(CHR_super0);\n\n var oldSuper = (oldIndex_Super > -1) ? parseInt(oldStyle[1 + oldIndex_Super]) : 0;\n var newSuper = (newIndex_Super > -1) ? parseInt(newStyle[1 + newIndex_Super]) : 0;\n\n if(oldSuper !== newSuper) {\n ctxFont = ctxFont.replace(getTextFontSize(), \"?px \")\n zPos *= Math.pow(0.75, (newSuper - oldSuper))\n ctxFont = ctxFont.replace(\"?px \", getTextFontSize())\n }\n yPos -= 0.25 * lineHeight * (newSuper - oldSuper);\n }\n\n if(styletags.bolds === true) {\n var wasBold = (oldStyle.indexOf(CHR_bold) > -1)\n var is_Bold = (newStyle.indexOf(CHR_bold) > -1)\n\n if(!wasBold && is_Bold) {\n if(wasItalic) {\n ctxFont = ctxFont.replace(\"italic \", \"italic bold \")\n } else {\n ctxFont = \"bold \" + ctxFont\n }\n }\n if(wasBold && !is_Bold) {\n ctxFont = ctxFont.replace(\"bold \", '')\n }\n }\n\n if(styletags.italics === true) {\n var wasItalic = (oldStyle.indexOf(CHR_italic) > -1)\n var is_Italic = (newStyle.indexOf(CHR_italic) > -1)\n\n if(!wasItalic && is_Italic) {\n ctxFont = \"italic \" + ctxFont\n }\n if(wasItalic && !is_Italic) {\n ctxFont = ctxFont.replace(\"italic \", '')\n }\n }\n context.font = ctxFont\n }\n\n for(i = 0; i < numberOfLines; ++i) {\n var txt = allTexts[i] + '\\n'\n xPos = 0\n yPos = i * lineHeight\n zPos = fontSize\n\n buffer = \"\"\n \n for(j = 0; j < txt.length; ++j) {\n var style = (j + nDone < allStyles.length) ? allStyles[j + nDone] : allStyles[allStyles.length - 1]\n if(activeStyle === style) {\n buffer += txt[j]\n } else {\n writeBuffer()\n buffer = txt[j]\n\n if(style !== undefined) {\n changeStyle(activeStyle, style)\n activeStyle = style\n }\n }\n }\n writeBuffer()\n\n nDone += txt.length\n\n var width = Math.round(xPos + 2 * offsetX) | 0\n if(maxWidth < width) maxWidth = width\n }\n\n //Cut pixels from image\n var xCut = maxWidth\n var yCut = offsetY + lineHeight * numberOfLines\n var pixels = ndarray(context.getImageData(0, 0, xCut, yCut).data, [yCut, xCut, 4])\n return pixels.pick(-1, -1, 0).transpose(1, 0)\n}\n\nfunction getContour(pixels, doSimplify) {\n var contour = surfaceNets(pixels, 128)\n if(doSimplify) {\n return simplify(contour.cells, contour.positions, 0.25)\n }\n return {\n edges: contour.cells,\n positions: contour.positions\n }\n}\n\nfunction processPixelsImpl(pixels, options, size, simplify) {\n //Extract contour\n var contour = getContour(pixels, simplify)\n\n //Apply warp to positions\n var positions = transformPositions(contour.positions, options, size)\n var edges = contour.edges\n var flip = \"ccw\" === options.orientation\n\n //Clean up the PSLG, resolve self intersections, etc.\n cleanPSLG(positions, edges)\n\n //If triangulate flag passed, triangulate the result\n if(options.polygons || options.polygon || options.polyline) {\n var result = toPolygonCrappy(edges, positions)\n var nresult = new Array(result.length)\n for(var i=0; i 0) size =\n options.size\n\n if(options.lineSpacing &&\n options.lineSpacing > 0) lineSpacing =\n options.lineSpacing\n\n if(options.styletags &&\n options.styletags.breaklines) styletags.breaklines =\n options.styletags.breaklines ? true : false\n\n if(options.styletags &&\n options.styletags.bolds) styletags.bolds =\n options.styletags.bolds ? true : false\n\n if(options.styletags &&\n options.styletags.italics) styletags.italics =\n options.styletags.italics ? true : false\n\n if(options.styletags &&\n options.styletags.subscripts) styletags.subscripts =\n options.styletags.subscripts ? true : false\n\n if(options.styletags &&\n options.styletags.superscripts) styletags.superscripts =\n options.styletags.superscripts ? true : false\n }\n\n context.font = [\n options.fontStyle,\n options.fontVariant,\n options.fontWeight,\n size + \"px\",\n options.font\n ].filter(function(d) {return d}).join(\" \")\n context.textAlign = \"start\"\n context.textBaseline = \"alphabetic\"\n context.direction = \"ltr\"\n\n var pixels = getPixels(canvas, context, str, size, lineSpacing, styletags)\n\n return processPixels(pixels, options, size)\n}\n\n\n//# sourceURL=webpack:///./node_modules/vectorize-text/lib/vtext.js?");
-
-/***/ }),
-
-/***/ "./node_modules/vue-draggable-resizable/dist/VueDraggableResizable.css":
-/*!*****************************************************************************!*\
- !*** ./node_modules/vue-draggable-resizable/dist/VueDraggableResizable.css ***!
- \*****************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-eval("// style-loader: Adds some css to the DOM by adding a