From d4d4c342560f18e92fafb3c2bfd9d5c4b709e509 Mon Sep 17 00:00:00 2001 From: Klu002 <66345463+Klu002@users.noreply.github.com> Date: Fri, 8 Jan 2021 16:22:20 -0600 Subject: [PATCH 01/29] Update chart.arr --- src/web/arr/trove/chart.arr | 55 +++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/src/web/arr/trove/chart.arr b/src/web/arr/trove/chart.arr index 5c7c64aa4..8e40ecba4 100644 --- a/src/web/arr/trove/chart.arr +++ b/src/web/arr/trove/chart.arr @@ -249,6 +249,12 @@ default-function-plot-series = { legend: '', } +type GeoChartSeries = { + tab :: TableIntern, +} + +default-geochart-series = {} + ########### type ChartWindowObject = { @@ -351,6 +357,15 @@ default-plot-chart-window-object :: PlotChartWindowObject = default-chart-window num-samples: 1000, } +type GeoChartWindowObject = { + title :: String, + width :: Number, + height :: Number, + render :: ( -> IM.Image), +} + +default-geo-chart-window-object :: GeoChartWindowObject = default-chart-window-object + ################################################################################ # DATA DEFINITIONS ################################################################################ @@ -403,10 +418,13 @@ data DataSeries: end, method num-bins(self, num-bins :: Number): histogram-series(self.obj.{ - min-num-bins: some(num-bins), - max-num-bins: some(num-bins) - }) - end, + min-num-bins: some(num-bins), + max-num-bins: some(num-bins) + }) + end + | geochart-series(obj :: GeoChartSeries) with: + is-single: true, + contr: {(): geochart-series}, sharing: method _output(self): get-vs-from-img("DataSeries", render-chart(self).get-image()) @@ -454,7 +472,9 @@ data ChartWindow: raise('num-samples: value must be an ineger between 1 and 100000') end plot-chart-window(self.obj.{num-samples: num-samples}) - end, + end + | geochart-window(obj :: GeoChartWindowObject) with: + constr: {(): geochart-window}, sharing: method display(self): _ = check-chart-window(self.obj) @@ -478,6 +498,7 @@ sharing: end end + ################################################################################ # FUNCTIONS ################################################################################ @@ -752,6 +773,22 @@ fun labeled-histogram-from-list(labels :: List, values :: List) } ^ histogram-series end +fun geochart-from-list( + region-labels :: List, + values :: List) -> DataSeries block: + region-length = region-labels.length() + values-length = values.length() + when region-length <> values-length: + raise("geochart: region-labels and values should have the same length") + end + values.each(check-num) + region-labels.each(check-string) + default-geochart-series.{ + tab: to-table2(region-labels, values) + } ^ geochart-series +end + + ################################################################################ # PLOTS ################################################################################ @@ -820,6 +857,11 @@ fun render-chart(s :: DataSeries) -> ChartWindow: P.histogram(self, obj) end } ^ histogram-chart-window + |geochart-series(obj) => + default-geo-chart-window-object.{ + method render(self): + geo-map(self, obj) end + } ^ geochart-window end where: render-now = {(x): render-chart(x).get-image()} @@ -859,9 +901,10 @@ where: [list: 2, 3.1, 1, 3, 6, 5])) does-not-raise render-now(from-list.box-plot( [list: [list: 1, 2, 3, 4], [list: 1, 2, 3, 4, 5], [list: 10, 11]] - )) does-not-raise + )) does-not-raise end + fun generate-xy( p :: FunctionPlotSeries, x-min :: Number, From 574f7ed96c590e28a85cede16cd940657201c86f Mon Sep 17 00:00:00 2001 From: Klu002 <66345463+Klu002@users.noreply.github.com> Date: Fri, 8 Jan 2021 16:26:46 -0600 Subject: [PATCH 02/29] Update plot-list.arr --- src/web/arr/trove/plot-list.arr | 44 +++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/web/arr/trove/plot-list.arr b/src/web/arr/trove/plot-list.arr index d3c3250b5..436b82dff 100644 --- a/src/web/arr/trove/plot-list.arr +++ b/src/web/arr/trove/plot-list.arr @@ -68,6 +68,8 @@ data Series: typ: 'bar-chart' | histogram-series(values :: List, n :: Number) with: typ: 'histogram' + | geo-map-series(labels :: List, values :: List, threshold :: List) + with: typ: 'geo-map' sharing: method _output(self :: Series) -> VS.ValueSkeleton: VS.vs-constr(self.typ + "-like-series", [list: VS.vs-str("...")]) @@ -378,6 +380,38 @@ end end |# +fun adjustable-geo-map(labels :: List, values :: List, radiuses :: List) + -> Series block: + label-length = labels.length() + value-length = values.length() + when label-length <> value-length: + raise('adjustable-geo-chart: labels and values should have the same length') + end + radius-length = radiuses.length() + when label-length <> radius-length: + raise('adjustable-geo-chart: labels and radiuses should have the same length') + end + when label-length == 0: + raise('adjustable-geo-chart: need at least one data') + end + geo-map-series(labels, values, radiuses) +end + +fun geo-map-s(labels :: List, values :: List) -> Series block: + doc: ``` + Consume labels, a list of string, and values, a list of numbers + and construct a geo chart ``` + label-length = labels.length() + value-length = values.length() + when label-length <> value-length: + raise('geo-chart: labels and values should have the same length') + end + when label-length == 0: + raise('geo-chart: need at least one data') + end + geo-map-series(labels, values, repeat(label-length, 1)) +end + fun plot(s :: Series) -> PlotObject: cases (Series) s: | line-plot-series(_, _, _) => plots([list: s]) @@ -413,6 +447,16 @@ fun plot(s :: Series) -> PlotObject: P.histogram(self, builtins.raw-array-from-list(values), n) end } + | geo-map-series(labels, values, threshold) => + plot-object-base.{ + method _render(self): + geo-map-s(self, map3( + {(l :: String, v :: Number, t :: Number): [raw-array: l, v, t]}, + labels, + values, + threshold) ^ builtins.raw-array-from-list) + end + } end where: plot-now = {(x): plot(x).get-image()} From 9ab929e7dc981cdfbfaaaa0b568212e34bff3e9a Mon Sep 17 00:00:00 2001 From: Klu002 <66345463+Klu002@users.noreply.github.com> Date: Fri, 8 Jan 2021 16:28:36 -0600 Subject: [PATCH 03/29] Update plot.arr --- src/web/arr/trove/plot.arr | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/web/arr/trove/plot.arr b/src/web/arr/trove/plot.arr index 84cef28a1..99b977816 100644 --- a/src/web/arr/trove/plot.arr +++ b/src/web/arr/trove/plot.arr @@ -118,6 +118,9 @@ box-chart-window-options :: BoxChartWindowOptions = axis-window-options type HistogramWindowOptions = AxisWindowOptions histogram-window-options :: HistogramWindowOptions = axis-window-options +type GeoChartWindowOptions = BaseWindowOptions +geo-chart-window-option :: GeoChartWindowOptions = base-window-options + type PlotOptions = { color :: I.Color } @@ -133,6 +136,7 @@ type WrappedPieChartWindowOptions = (PieChartWindowOptions -> PieChartWindowOpti type WrappedHistogramWindowOptions = (HistogramWindowOptions -> HistogramWindowOptions) type WrappedDotChartWindowOptions = (DotChartWindowOptions -> DotChartWindowOptions) type WrappedBoxChartWindowOptions = (BoxChartWindowOptions -> BoxChartWindowOptions) +type WrappedGeoChartWindowOptions = (GeoChartWindowOptions -> GeoChartWindowOptions) type PlottableFunction = (Number -> Number) type Posn = RawArray type TableInt = RawArray @@ -547,6 +551,19 @@ fun render-plots( render-multi-plot(new-plots, options) end +fun geo-map(tab :: Table, options-generator :: WrappedGeoChartWindowOptions) -> IM.Image block: + doc: 'Consume a table with two columns: `region` and `value`, and show a geo-map' + when not(tab._header-raw-array =~ [raw-array: 'region', 'value']): + raise('geo-map: expect a table with columns named `region` and `value`') + end + when raw-array-length(tab._rows-raw-array) == 0: + raise('geo-map: expect the table to have at least one row') + end + options = options-generator(geo-chart-window-option) + _ = check-base-window-options(options) + P.geo-map(options, tab._rows-raw-array) +end + make-function-plot = function-plot(_, _.{color: I.blue}) make-line-plot = line-plot(_, _.{color: I.blue}) make-scatter-plot = scatter-plot(_, _.{color: I.blue}) From 68a10e4fd3491e50e5a4eec5e3c151cae6a275ee Mon Sep 17 00:00:00 2001 From: Klu002 <66345463+Klu002@users.noreply.github.com> Date: Fri, 8 Jan 2021 16:34:57 -0600 Subject: [PATCH 04/29] Update chart-lib.js --- src/web/js/trove/chart-lib.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/web/js/trove/chart-lib.js b/src/web/js/trove/chart-lib.js index 1b914d0ac..af13110e5 100644 --- a/src/web/js/trove/chart-lib.js +++ b/src/web/js/trove/chart-lib.js @@ -464,7 +464,24 @@ mutators: [axesNameMutator, yAxisRangeMutator, xAxisRangeMutator], }; } - + + function geoChart(globalOptions, rawData) { + const table = get(rawData, 'tab'); + const data = new google.visualization.GeoMap; + return { + data: data, + options: { + slices: table.map(row => ({offset: toFixnum(row[2])})), + legend: { + alignment: 'end' + } + }, + chartType: google.visualization.GeoMap, + onExit: defaultImageReturn, + } + } + + function plot(globalOptions, rawData) { const scatters = get(rawData, 'scatters'); const lines = get(rawData, 'lines'); From e0da7b17faec1bedc98aaa34b6efe0cdeed19232 Mon Sep 17 00:00:00 2001 From: Klu002 <66345463+Klu002@users.noreply.github.com> Date: Mon, 18 Jan 2021 14:58:31 -0500 Subject: [PATCH 05/29] Add files via upload --- src/web/arr/trove/chart.arr | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/web/arr/trove/chart.arr b/src/web/arr/trove/chart.arr index 8e40ecba4..a194c3ed3 100644 --- a/src/web/arr/trove/chart.arr +++ b/src/web/arr/trove/chart.arr @@ -860,7 +860,7 @@ fun render-chart(s :: DataSeries) -> ChartWindow: |geochart-series(obj) => default-geo-chart-window-object.{ method render(self): - geo-map(self, obj) end + P.geo-map(self, obj) end } ^ geochart-window end where: @@ -1242,4 +1242,5 @@ from-list = { freq-bar-chart: freq-bar-chart-from-list, labeled-box-plot: labeled-box-plot-from-list, box-plot: box-plot-from-list, + geochart: geochart-from-list, } From 36fb2566364ed8370b588cb17b01a213e87c0593 Mon Sep 17 00:00:00 2001 From: Klu002 <66345463+Klu002@users.noreply.github.com> Date: Mon, 18 Jan 2021 15:00:10 -0500 Subject: [PATCH 06/29] Add files via upload --- src/web/js/trove/chart-lib.js | 1 + src/web/js/trove/plot-lib-list.js | 91 ++++++++++++++++++++++++++++++- src/web/js/trove/plot-lib.js | 91 ++++++++++++++++++++++++++++++- 3 files changed, 181 insertions(+), 2 deletions(-) diff --git a/src/web/js/trove/chart-lib.js b/src/web/js/trove/chart-lib.js index af13110e5..bcbd96153 100644 --- a/src/web/js/trove/chart-lib.js +++ b/src/web/js/trove/chart-lib.js @@ -831,6 +831,7 @@ ${labelRow}`; 'histogram': makeFunction(histogram), 'box-plot': makeFunction(boxPlot), 'plot': makeFunction(plot), + 'geo-map': makeFunction(geoChart), }) }) }); diff --git a/src/web/js/trove/plot-lib-list.js b/src/web/js/trove/plot-lib-list.js index c285c11a1..0860ebf1a 100644 --- a/src/web/js/trove/plot-lib-list.js +++ b/src/web/js/trove/plot-lib-list.js @@ -14,7 +14,8 @@ 'plot-multi': "tany", 'bar-chart': "tany", 'dot-chart': "tany", - 'box-chart': "tany" + 'box-chart': "tany", + 'geo-map': "tany" } }, theModule: function (RUNTIME, NAMESPACE, uri, CLIB, jsnums, d3, D3TIP) { @@ -1290,6 +1291,93 @@ return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null); } + function geoChart(restart, windowOptions, tab) { + + function resizer(restarter, windowOptions) { + geoChart(restarter, windowOptions, tab); + } + + var sum = tab.map(function (row) { + return row[1]; + }) + .reduce(function (a, b) { + return jsnums.add(a, b, RUNTIME.NumberErrbacks); + }); + var valueScaler = libNum.scaler(0, sum, 0, 100, true); + + var dimension = getDimension({ + minWindowWidth: 700, + minWindowHeight: 550, + outerMarginLeft: 10, + outerMarginRight: 10, + marginLeft: 120, + marginRight: 120, + marginTop: 90, + marginBottom: 40, + mode: 'center', + }, windowOptions), + width = dimension.width, + height = dimension.height, + detached = createDiv(), + canvas = createCanvas(detached, dimension); + + //d3.json("world.geojson", createMap) + var proj = d3.geoMercator() + .scale(100) + .translate([250, 250]) + .center([0, 5]) + var geo = d3.geoPath().projection(proj) + var color = d3.scale.category20(); + + d3.select("svg").selectAll("path").data(countries.features) + .enter + .append("path") + .attr("d", geo) + .attr("class", "countries"); + + d3.selectAll("path.countries") + .on("mouseover", centerBounds) + .on("mouseout", clearCenterBounds) + + function centerBounds(d) { + var thisBounds = geoPath.bounds(d); + var thisCenter = geoPath.centroid(d); + d3.select("svg") + .append("rect") + .attr("class", "bbox") + .attr("x", thisBounds[0][0]) + .attr("y", thisBounds[0][1]) + .attr("width", thisBounds[1][0] - thisBounds[0][0]) + .attr("height", thisBounds[1][1] - thisBounds[0][1]) + d3.select("svg") + .append("circle") + .attr("class", "centroid") + .attr("r", 5) + .attr("cx", thisCenter[0]).attr("cy", thisCenter[1]) + } + + function clearCenterBounds() { + d3.selectAll("circle.centroid").remove(); + d3.selectAll("rect.bbox").remove(); + } + + var prettyNumToStringDigits9 = libNum.getPrettyNumToStringDigits(9); + var tip = d3tip(detached) + .attr('class', 'd3-tip') + .direction('e') + .offset([0, 20]) + .html(function (d) { + return 'value:
' + prettyNumToStringDigits9(d.data[1]) + '
' + + 'percent:
' + prettyNumToStringDigits9(valueScaler(d.data[1])) + '%'; + }); + + canvas.call(tip); + + stylizeTip(tip) + + return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null) +} + function boxChart(restarter, windowOptions, table) { /* * Box Chart @@ -1418,6 +1506,7 @@ 'bar-chart': makeFunction(barChart), 'dot-chart': makeFunction(dotChart), 'box-chart': makeFunction(boxChart), + 'geo-map': makeFunction(geoChart), }) }) }); diff --git a/src/web/js/trove/plot-lib.js b/src/web/js/trove/plot-lib.js index 458168d36..86c493233 100644 --- a/src/web/js/trove/plot-lib.js +++ b/src/web/js/trove/plot-lib.js @@ -14,7 +14,8 @@ 'plot-multi': "tany", 'bar-chart': "tany", 'dot-chart': "tany", - 'box-chart': "tany" + 'box-chart': "tany", + 'geo-map': "tany" } }, theModule: function (RUNTIME, NAMESPACE, uri, CLIB, jsnums, d3, D3TIP) { @@ -1009,6 +1010,93 @@ return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null); } + function geoChart(restart, windowOptions, tab) { + + function resizer(restarter, windowOptions) { + geoChart(restarter, windowOptions, tab); + } + + var sum = tab.map(function (row) { + return row[1]; + }) + .reduce(function (a, b) { + return jsnums.add(a, b, RUNTIME.NumberErrbacks); + }); + var valueScaler = libNum.scaler(0, sum, 0, 100, true); + + var dimension = getDimension({ + minWindowWidth: 700, + minWindowHeight: 550, + outerMarginLeft: 10, + outerMarginRight: 10, + marginLeft: 120, + marginRight: 120, + marginTop: 90, + marginBottom: 40, + mode: 'center', + }, windowOptions), + width = dimension.width, + height = dimension.height, + detached = createDiv(), + canvas = createCanvas(detached, dimension); + + //d3.json("world.geojson", createMap) + var proj = d3.geoMercator() + .scale(100) + .translate([250, 250]) + .center([0, 5]) + var geo = d3.geoPath().projection(proj) + var color = d3.scale.category20(); + + d3.select("svg").selectAll("path").data(countries.features) + .enter + .append("path") + .attr("d", geo) + .attr("class", "countries"); + + d3.selectAll("path.countries") + .on("mouseover", centerBounds) + .on("mouseout", clearCenterBounds) + + function centerBounds(d) { + var thisBounds = geoPath.bounds(d); + var thisCenter = geoPath.centroid(d); + d3.select("svg") + .append("rect") + .attr("class", "bbox") + .attr("x", thisBounds[0][0]) + .attr("y", thisBounds[0][1]) + .attr("width", thisBounds[1][0] - thisBounds[0][0]) + .attr("height", thisBounds[1][1] - thisBounds[0][1]) + d3.select("svg") + .append("circle") + .attr("class", "centroid") + .attr("r", 5) + .attr("cx", thisCenter[0]).attr("cy", thisCenter[1]) + } + + function clearCenterBounds() { + d3.selectAll("circle.centroid").remove(); + d3.selectAll("rect.bbox").remove(); + } + + var prettyNumToStringDigits9 = libNum.getPrettyNumToStringDigits(9); + var tip = d3tip(detached) + .attr('class', 'd3-tip') + .direction('e') + .offset([0, 20]) + .html(function (d) { + return 'value:
' + prettyNumToStringDigits9(d.data[1]) + '
' + + 'percent:
' + prettyNumToStringDigits9(valueScaler(d.data[1])) + '%'; + }); + + canvas.call(tip); + + stylizeTip(tip) + + return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null) +} + function barChart(restarter, windowOptions, table, legend, showLegend) { /* * Bar Chart @@ -1418,6 +1506,7 @@ 'bar-chart': makeFunction(barChart), 'dot-chart': makeFunction(dotChart), 'box-chart': makeFunction(boxChart), + 'geo-map': makeFunction(geoChart), }) }) }); From 47f0848d9a6c0fa2adac14938b81e19face67f11 Mon Sep 17 00:00:00 2001 From: youming lu Date: Mon, 18 Jan 2021 15:19:18 -0500 Subject: [PATCH 07/29] First commit --- package-lock.json | 170 ++++++++-------------------------- src/web/js/trove/chart-lib.js | 3 +- 2 files changed, 42 insertions(+), 131 deletions(-) diff --git a/package-lock.json b/package-lock.json index f92ad260b..e129f763a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3955,15 +3955,6 @@ "ip-address": "^5.8.8" } }, - "@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - } - }, "@nodelib/fs.scandir": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", @@ -7347,6 +7338,14 @@ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" }, + "bufferutil": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", + "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", + "requires": { + "node-gyp-build": "^4.2.0" + } + }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", @@ -7446,11 +7445,6 @@ "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==" }, - "call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=" - }, "callsite": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", @@ -9560,9 +9554,9 @@ }, "dependencies": { "type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", - "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", + "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==" } } }, @@ -11013,11 +11007,6 @@ } } }, - "glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=" - }, "global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -12680,51 +12669,12 @@ } }, "jasmine": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.6.1.tgz", - "integrity": "sha512-Jqp8P6ZWkTVFGmJwBK46p+kJNrZCdqkQ4GL+PGuBXZwK1fM4ST9BizkYgIwCFqYYqnTizAy6+XG2Ej5dFrej9Q==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.6.3.tgz", + "integrity": "sha512-Th91zHsbsALWjDUIiU5d/W5zaYQsZFMPTdeNmi8GivZPmAaUAK8MblSG3yQI4VMGC/abF2us7ex60NH1AAIMTA==", "requires": { - "fast-glob": "^2.2.6", + "glob": "^7.1.6", "jasmine-core": "~3.6.0" - }, - "dependencies": { - "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" - }, - "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "requires": { - "is-extglob": "^2.1.0" - } - } - } - } } }, "jasmine-core": { @@ -14217,7 +14167,8 @@ "nan": { "version": "2.14.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "optional": true }, "nanomatch": { "version": "1.2.13", @@ -14320,6 +14271,11 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.1.tgz", "integrity": "sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ==" }, + "node-gyp-build": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" + }, "node-libs-browser": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", @@ -15293,8 +15249,8 @@ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" }, "pyret-codemirror-mode": { - "version": "git://github.com/brownplt/pyret-codemirror-mode.git#2c5def8044f34abfa32ca6a40c8a3c4551f8bdb9", - "from": "git://github.com/brownplt/pyret-codemirror-mode.git#horizon", + "version": "git://github.com/brownplt/pyret-codemirror-mode.git#465bda4d5ae28ad99f4249bccafd8dc5d67a0850", + "from": "git://github.com/brownplt/pyret-codemirror-mode.git#master", "requires": { "codemirror": "^5.x" } @@ -15380,8 +15336,8 @@ } }, "pyret-lang": { - "version": "git://github.com/brownplt/pyret-lang.git#5c7dc402fe453edca8acc01df5afe68f9d0a6c4f", - "from": "git://github.com/brownplt/pyret-lang.git#horizon", + "version": "git://github.com/brownplt/pyret-lang.git#6b80dd68a92c73db5fa255e164c51a84de40bcc8", + "from": "git://github.com/brownplt/pyret-lang.git#master", "requires": { "ascii-table": "~0.0.9", "benchmark": "^2.1.4", @@ -15399,8 +15355,7 @@ "seedrandom": "~2.3.10", "sha.js": "^2.4.8", "source-map": "^0.5.6", - "stacktrace-js": "^1.3.1", - "websocket": "^1.0.23" + "websocket": "^1.0.32" }, "dependencies": { "q": { @@ -17040,65 +16995,11 @@ "figgy-pudding": "^3.5.1" } }, - "stack-generator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-1.1.0.tgz", - "integrity": "sha1-NvapIHUabBD0maE8Msu19RoLiyU=", - "requires": { - "stackframe": "^1.0.2" - } - }, "stackframe": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==" }, - "stacktrace-gps": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-2.4.4.tgz", - "integrity": "sha1-acgn6dbW9Bz0ONfxleLjy/zyjEQ=", - "requires": { - "source-map": "0.5.6", - "stackframe": "~0.3" - }, - "dependencies": { - "source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" - }, - "stackframe": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-0.3.1.tgz", - "integrity": "sha1-M6qE8Rd6VUjIk1Uzy/6zQgl19aQ=" - } - } - }, - "stacktrace-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-1.3.1.tgz", - "integrity": "sha1-Z8qyWJr1xBe5Yvc2mUAne7O2oYs=", - "requires": { - "error-stack-parser": "^1.3.6", - "stack-generator": "^1.0.7", - "stacktrace-gps": "^2.4.3" - }, - "dependencies": { - "error-stack-parser": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-1.3.6.tgz", - "integrity": "sha1-4Oc7k+QXE40c18C3RrGkoUhUwpI=", - "requires": { - "stackframe": "^0.3.1" - } - }, - "stackframe": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-0.3.1.tgz", - "integrity": "sha1-M6qE8Rd6VUjIk1Uzy/6zQgl19aQ=" - } - } - }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -18325,6 +18226,14 @@ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, + "utf-8-validate": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz", + "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==", + "requires": { + "node-gyp-build": "^4.2.0" + } + }, "util": { "version": "0.10.4", "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", @@ -19007,14 +18916,15 @@ } }, "websocket": { - "version": "1.0.31", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.31.tgz", - "integrity": "sha512-VAouplvGKPiKFDTeCCO65vYHsyay8DqoBSlzIO3fayrfOgU94lQN5a1uWVnFrMLceTJw/+fQXR5PGbUVRaHshQ==", + "version": "1.0.33", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.33.tgz", + "integrity": "sha512-XwNqM2rN5eh3G2CUQE3OHZj+0xfdH42+OFK6LdC2yqiC0YU8e5UK0nYre220T0IyyN031V/XOvtHvXozvJYFWA==", "requires": { + "bufferutil": "^4.0.1", "debug": "^2.2.0", "es5-ext": "^0.10.50", - "nan": "^2.14.0", "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", "yaeti": "^0.0.6" } }, diff --git a/src/web/js/trove/chart-lib.js b/src/web/js/trove/chart-lib.js index bcbd96153..952b3e7d4 100644 --- a/src/web/js/trove/chart-lib.js +++ b/src/web/js/trove/chart-lib.js @@ -12,7 +12,8 @@ 'bar-chart': "tany", 'histogram': "tany", 'box-plot': "tany", - 'plot': "tany" + 'plot': "tany", + 'geo-map': "tany" } }, theModule: function (RUNTIME, NAMESPACE, uri, IMAGELIB, jsnums , google) { From 44456d894f22ecfca842524a2984afd7495c6743 Mon Sep 17 00:00:00 2001 From: Klu002 <66345463+Klu002@users.noreply.github.com> Date: Tue, 19 Jan 2021 15:35:51 -0500 Subject: [PATCH 08/29] Update chart-lib.js --- src/web/js/trove/chart-lib.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/web/js/trove/chart-lib.js b/src/web/js/trove/chart-lib.js index 952b3e7d4..054eea370 100644 --- a/src/web/js/trove/chart-lib.js +++ b/src/web/js/trove/chart-lib.js @@ -468,11 +468,11 @@ function geoChart(globalOptions, rawData) { const table = get(rawData, 'tab'); - const data = new google.visualization.GeoMap; + const data = new google.visualization.DataTable(); return { data: data, options: { - slices: table.map(row => ({offset: toFixnum(row[2])})), + slices: table.map(row => ({offset: toFixnum(row[1])})), legend: { alignment: 'end' } From ac9fe04a969ca016e75d17861e46a9e2078a124a Mon Sep 17 00:00:00 2001 From: Klu002 <66345463+Klu002@users.noreply.github.com> Date: Tue, 19 Jan 2021 16:17:46 -0500 Subject: [PATCH 09/29] Update plot-lib.js --- src/web/js/trove/plot-lib.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/web/js/trove/plot-lib.js b/src/web/js/trove/plot-lib.js index 86c493233..47441c9e3 100644 --- a/src/web/js/trove/plot-lib.js +++ b/src/web/js/trove/plot-lib.js @@ -1047,8 +1047,8 @@ .center([0, 5]) var geo = d3.geoPath().projection(proj) var color = d3.scale.category20(); - - d3.select("svg").selectAll("path").data(countries.features) + + d3.select("svg").selectAll("path").data(tab.map(function (f): return row[2])) .enter .append("path") .attr("d", geo) From 1c80a164d692360e1953054ed0de68f6ee119fa6 Mon Sep 17 00:00:00 2001 From: schornb <55115049+schornb@users.noreply.github.com> Date: Wed, 28 Apr 2021 16:42:21 -0400 Subject: [PATCH 10/29] added geochart to values, changing all names to geochart --- package-lock.json | 1358 +++++++++++------------------ package.json | 2 +- src/web/arr/trove/chart.arr | 56 +- src/web/js/trove/chart-lib.js | 23 +- src/web/js/trove/plot-lib-list.js | 76 +- 5 files changed, 643 insertions(+), 872 deletions(-) diff --git a/package-lock.json b/package-lock.json index f92ad260b..86a3633c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -840,6 +840,11 @@ "requires": { "has-flag": "^3.0.0" } + }, + "urijs": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.2.tgz", + "integrity": "sha512-s/UIq9ap4JPZ7H1EB5ULo/aOUbWqfDi7FKzMC2Nz+0Si8GiT1rIEaprt8hy3Vy2Ex2aJPpOQv4P4DuOZ+K1c6w==" } } }, @@ -1428,11 +1433,9 @@ "integrity": "sha512-2N7AmszH/WPPpl5Z3XMw1HAP+8d+xugnKQAeKvxFZ/04dbT/CAznqwbl+7eSr3HkwdepNwtb2yx3CAMQWvG01Q==", "requires": { "clone-response": "^1.0.2", - "get-stream": "^4.0.0", "http-cache-semantics": "^4.0.0", "keyv": "^3.0.0", "lowercase-keys": "^1.0.1", - "normalize-url": "^3.1.0", "responselike": "^1.0.2" } }, @@ -1455,11 +1458,11 @@ } }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "doctrine": { @@ -1613,14 +1616,6 @@ "write": "1.0.3" } }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, "globals": { "version": "12.3.0", "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz", @@ -1639,7 +1634,6 @@ "cacheable-request": "^6.0.0", "decompress-response": "^3.3.0", "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", "lowercase-keys": "^1.0.1", "mimic-response": "^1.0.1", "p-cancelable": "^1.0.0", @@ -1797,11 +1791,6 @@ } } }, - "normalize-url": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==" - }, "onetime": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", @@ -3955,15 +3944,6 @@ "ip-address": "^5.8.8" } }, - "@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - } - }, "@nodelib/fs.scandir": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", @@ -5478,6 +5458,11 @@ "@types/node": "*" } }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==" + }, "@webassemblyjs/ast": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", @@ -5897,17 +5882,6 @@ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, - "array.prototype.map": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.2.tgz", - "integrity": "sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.4" - } - }, "arraybuffer.slice": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", @@ -6955,14 +6929,6 @@ "platform": "^1.3.3" } }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", - "requires": { - "callsite": "1.0.0" - } - }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -6988,9 +6954,9 @@ } }, "bl": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", "requires": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" @@ -7347,6 +7313,14 @@ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" }, + "bufferutil": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", + "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", + "requires": { + "node-gyp-build": "^4.2.0" + } + }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", @@ -7446,16 +7420,6 @@ "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==" }, - "call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=" - }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" - }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -8268,11 +8232,10 @@ } }, "create-react-class": { - "version": "15.6.3", - "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz", - "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==", + "version": "15.7.0", + "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.7.0.tgz", + "integrity": "sha512-QZv4sFWG9S5RUvkTYWbflxeZX+JG7Cz0Tn33rQBJ+WFQTqTfUTjMjiv9tnfXazjsO5r0KhPs+AqCjyrQX6h2ng==", "requires": { - "fbjs": "^0.8.9", "loose-envify": "^1.3.1", "object-assign": "^4.1.1" } @@ -8701,9 +8664,9 @@ "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=" }, "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==" }, "diffie-hellman": { "version": "5.0.3", @@ -8879,17 +8842,29 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", + "bn.js": "^4.11.9", + "brorand": "^1.1.0", "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + } } }, "emoji-regex": { @@ -8923,80 +8898,6 @@ "once": "^1.4.0" } }, - "engine.io": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.2.tgz", - "integrity": "sha512-b4Q85dFkGw+TqgytGPrGgACRUhsdKc9S9ErRAXpPGy/CXKs4tYoHDkvIRdsseAF7NjfVwjRFIn6KTnbw7LwJZg==", - "requires": { - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "0.3.1", - "debug": "~4.1.0", - "engine.io-parser": "~2.2.0", - "ws": "^7.1.2" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "ws": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", - "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==" - } - } - }, - "engine.io-client": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.3.tgz", - "integrity": "sha512-0NGY+9hioejTEJCaSJZfWZLk4FPI9dN+1H1C4+wj2iuFba47UgZbJzfWs4aNFajnX/qAaYKbe2lLTfEEWzCmcw==", - "requires": { - "component-emitter": "~1.3.0", - "component-inherit": "0.0.3", - "debug": "~4.1.0", - "engine.io-parser": "~2.2.0", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "~6.1.0", - "xmlhttprequest-ssl": "~1.5.4", - "yeast": "0.1.2" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "ws": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", - "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", - "requires": { - "async-limiter": "~1.0.0" - } - } - } - }, "engine.io-parser": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz", @@ -9077,63 +8978,6 @@ "string.prototype.trimright": "^2.1.0" } }, - "es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" - }, - "es-get-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz", - "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==", - "requires": { - "es-abstract": "^1.17.4", - "has-symbols": "^1.0.1", - "is-arguments": "^1.0.4", - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-string": "^1.0.5", - "isarray": "^2.0.5" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "requires": { - "has-symbols": "^1.0.1" - } - }, - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - } - } - }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -9191,6 +9035,11 @@ "ext": "^1.1.2" } }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -9560,9 +9409,9 @@ }, "dependencies": { "type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", - "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", + "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==" } } }, @@ -10028,196 +9877,6 @@ "xtend": "^4.0.1" }, "dependencies": { - "jws": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.1.3.tgz", - "integrity": "sha512-KiwFJo7lfoVFV6AbEjZLvfY6dUnFVHliKdoEKtd0P+AN5wBGv8a25qYf0qgXrTzB6vArpnXi67reRpXo2EBUKw==", - "requires": { - "base64url": "~1.0.4", - "jwa": "^1.1.2" - }, - "dependencies": { - "base64url": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/base64url/-/base64url-1.0.6.tgz", - "integrity": "sha512-YJUNcKuU8Df1LhS3s9OzoYCAOZYHgAUGnDlPgXFCaJZwRzZLcnQ7uM9KRY6EFaJRvzxZqw2w+wCDigwpe+4XUw==", - "requires": { - "concat-stream": "~1.4.7", - "meow": "~2.0.0" - }, - "dependencies": { - "concat-stream": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.4.10.tgz", - "integrity": "sha512-hB2ZF9QT0ix27ojlJ97Fv7C/46tBKgRTGepOossaCmnXZU4dxnWcn55i5Xk0WTXwcZ1IUKqsWWottibqlYggUA==", - "requires": { - "inherits": "~2.0.1", - "readable-stream": "~1.1.9", - "typedarray": "~0.0.5" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==" - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" - } - } - }, - "meow": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-2.0.0.tgz", - "integrity": "sha512-X7rkdgy5Wxxp2MhCiAOkC3lqfkrJkt3iXvW4BY0rYQIn3GMvYvBTsAPEmHHTjTeVzBelrRcQa2F80rYfigz2+A==", - "requires": { - "camelcase-keys": "^1.0.0", - "indent-string": "^1.1.0", - "minimist": "^1.1.0", - "object-assign": "^1.0.0" - }, - "dependencies": { - "camelcase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-1.0.0.tgz", - "integrity": "sha512-hwNYKTjJTlDabjJp2xn0h8bRmOpObvXVgYbQmR+Xob/EeBDtYea3xttjr5hqiWqLWtI3/6xO7x1ZAktQ9up+ag==", - "requires": { - "camelcase": "^1.0.1", - "map-obj": "^1.0.0" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha512-wzLkDa4K/mzI1OSITC+DUyjgIl/ETNHE9QvYgy6J6Jvqyyz4C0Xfd+lQhb19sX2jMpZV4IssUn0VDVmglV+s4g==" - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==" - } - } - }, - "indent-string": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-1.2.2.tgz", - "integrity": "sha512-Z1vqf6lDC3f4N2mWqRywY6odjRatPNGDZgUr4DY9MLC14+Fp2/y+CI/RnNGlb8hD6ckscE/8DlZUwHUaiDBshg==", - "requires": { - "get-stdin": "^4.0.1", - "minimist": "^1.1.0", - "repeating": "^1.1.0" - }, - "dependencies": { - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==" - }, - "repeating": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz", - "integrity": "sha512-Nh30JLeMHdoI+AsQ5eblhZ7YlTsM9wiJQe/AHIunlK3KWzvXhXb36IJ7K1IOeRjIOtzMjdUHjwXUFxKJoPTSOg==", - "requires": { - "is-finite": "^1.0.0" - }, - "dependencies": { - "is-finite": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.1.tgz", - "integrity": "sha512-F/Vjbc68OaPWG9b+wfcG0egINwKP4CVT/Nah121WZ5e1v0OzJeqecnqXeyERJisyQ+42pgakX27WI9leMwsVlA==", - "requires": { - "number-is-nan": "^1.0.0" - }, - "dependencies": { - "number-is-nan": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz", - "integrity": "sha512-XMFr+QWyCsZjZRn9LXA0SkPqanwQmD59vzQp8ufguk8bVdHq4RteGh3kpQe/wrqVicacPgnGR5cPWvkGXmfSrw==" - } - } - } - } - } - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha512-7Wl+Jz+IGWuSdgsQEJ4JunV0si/iMhg42MnQQG6h1R6TNeVenp4U9x5CC5v/gYqz/fENLQITAWXidNtVL0NNbw==" - }, - "object-assign": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-1.0.0.tgz", - "integrity": "sha512-LpUkixU1BUMQ6bwUHbOue4IGGbdRbxi+IEZw7zHniw78erlxrKGHbhfLbHIsI35LGbGqys6QOrjVmLnD2ie+1A==" - } - } - } - } - }, - "jwa": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.3.tgz", - "integrity": "sha512-VUr8nmKQLWi3Gf0O6EU7M1/tBlxVMvScdKKMLGvCBYexNbFPVoCMnedScvB8hONjHPs2lTEonny6sLEpVOCduw==", - "requires": { - "base64url": "~1.0.4", - "buffer-equal-constant-time": "^1.0.1", - "ecdsa-sig-formatter": "^1.0.0" - }, - "dependencies": { - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" - }, - "ecdsa-sig-formatter": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.5.tgz", - "integrity": "sha512-+iTWaj9CQHnvYQ7keATosCbg6I60hVQoT3SGAva2dHwGuWe9enc3Irl60Bb6Mm9+eEZ9xukm1UMrEY1dSHC03A==", - "requires": { - "base64-url": "^1.2.1" - }, - "dependencies": { - "base64-url": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/base64-url/-/base64-url-1.2.2.tgz", - "integrity": "sha512-m1UfGF9P4pHtsRXXJ+yqtXQAYKU8gzvzRh9l0UDqFbGXfUP9DB4lcJUbE4Z6yeHDyVYi52FW31suA1OdycMNOw==" - } - } - } - } - } - } - }, "ms": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", @@ -10230,6 +9889,15 @@ } } }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "rsvp": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.2.1.tgz", @@ -10243,19 +9911,9 @@ } }, "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" - } - } + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" }, "flat-cache": { "version": "2.0.1", @@ -11013,11 +10671,6 @@ } } }, - "glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=" - }, "global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -11968,9 +11621,9 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, "inline-source-map": { @@ -12301,11 +11954,6 @@ "is-extglob": "^2.1.1" } }, - "is-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz", - "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==" - }, "is-negated-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", @@ -12394,21 +12042,11 @@ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==" }, - "is-set": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz", - "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==" - }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" - }, "is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", @@ -12656,20 +12294,6 @@ "is-object": "^1.0.1" } }, - "iterate-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/iterate-iterator/-/iterate-iterator-1.0.1.tgz", - "integrity": "sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw==" - }, - "iterate-value": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/iterate-value/-/iterate-value-1.0.2.tgz", - "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==", - "requires": { - "es-get-iterator": "^1.0.2", - "iterate-iterator": "^1.0.1" - } - }, "iterm2-version": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/iterm2-version/-/iterm2-version-4.2.0.tgz", @@ -12680,51 +12304,12 @@ } }, "jasmine": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.6.1.tgz", - "integrity": "sha512-Jqp8P6ZWkTVFGmJwBK46p+kJNrZCdqkQ4GL+PGuBXZwK1fM4ST9BizkYgIwCFqYYqnTizAy6+XG2Ej5dFrej9Q==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.6.3.tgz", + "integrity": "sha512-Th91zHsbsALWjDUIiU5d/W5zaYQsZFMPTdeNmi8GivZPmAaUAK8MblSG3yQI4VMGC/abF2us7ex60NH1AAIMTA==", "requires": { - "fast-glob": "^2.2.6", + "glob": "^7.1.6", "jasmine-core": "~3.6.0" - }, - "dependencies": { - "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" - }, - "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "requires": { - "is-extglob": "^2.1.0" - } - } - } - } } }, "jasmine-core": { @@ -13564,37 +13149,54 @@ "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==" }, "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", "requires": { - "chalk": "^2.4.2" + "chalk": "^4.0.0" }, "dependencies": { "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" } }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" } }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } } } @@ -13878,35 +13480,35 @@ } }, "mocha": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.0.1.tgz", - "integrity": "sha512-vefaXfdYI8+Yo8nPZQQi0QO2o+5q9UIMX1jZ1XMmK3+4+CQjc7+B0hPdUeglXiTlr8IHMVRo63IhO9Mzt6fxOg==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", + "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", "requires": { + "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.3.1", - "debug": "3.2.6", - "diff": "4.0.2", - "escape-string-regexp": "1.0.5", - "find-up": "4.1.0", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", "glob": "7.1.6", "growl": "1.10.5", "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", + "js-yaml": "4.0.0", + "log-symbols": "4.0.0", "minimatch": "3.0.4", - "ms": "2.1.2", - "object.assign": "4.1.0", - "promise.allsettled": "1.0.2", - "serialize-javascript": "3.0.0", - "strip-json-comments": "3.0.1", - "supports-color": "7.1.0", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", "which": "2.0.2", "wide-align": "1.1.3", - "workerpool": "6.0.0", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" }, "dependencies": { "ansi-colors": { @@ -13914,19 +13516,37 @@ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, "braces": { "version": "3.0.2", @@ -13937,28 +13557,63 @@ } }, "chokidar": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", - "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", - "fsevents": "~2.1.2", + "fsevents": "~2.3.1", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.3.0" + "readdirp": "~3.5.0" } }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "requires": { - "ms": "^2.1.1" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" } }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -13968,18 +13623,18 @@ } }, "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "requires": { - "locate-path": "^5.0.0", + "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "optional": true }, "has-flag": { @@ -14000,57 +13655,80 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, + "js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "requires": { + "argparse": "^2.0.1" + } + }, "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "requires": { - "p-locate": "^4.1.0" + "p-locate": "^5.0.0" } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "requires": { - "p-try": "^2.0.0" + "yocto-queue": "^0.1.0" } }, "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "requires": { - "p-limit": "^2.2.0" + "p-limit": "^3.0.2" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "readdirp": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", - "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", "requires": { - "picomatch": "^2.0.7" + "picomatch": "^2.2.1" + }, + "dependencies": { + "picomatch": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==" + } } }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "requires": { "has-flag": "^4.0.0" } @@ -14070,6 +13748,40 @@ "requires": { "isexe": "^2.0.0" } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" } } }, @@ -14217,7 +13929,13 @@ "nan": { "version": "2.14.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "optional": true + }, + "nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==" }, "nanomatch": { "version": "1.2.13", @@ -14311,15 +14029,20 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, "node-forge": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.1.tgz", "integrity": "sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ==" }, + "node-gyp-build": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" + }, "node-libs-browser": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", @@ -14521,11 +14244,6 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" - }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -14837,22 +14555,6 @@ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", "dev": true }, - "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", - "requires": { - "better-assert": "~1.0.0" - } - }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -15006,13 +14708,25 @@ "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==" }, "plist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", - "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.2.tgz", + "integrity": "sha512-MSrkwZBdQ6YapHy87/8hDU8MnIcyxBKjeF+McXnr5A9MtffPewTs7G3hlpodT5TacyfIyFTaJEhh3GGcmasTgQ==", "requires": { - "base64-js": "^1.2.3", + "base64-js": "^1.5.1", "xmlbuilder": "^9.0.7", - "xmldom": "0.1.x" + "xmldom": "^0.5.0" + }, + "dependencies": { + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "xmldom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz", + "integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==" + } } }, "popper.js": { @@ -15203,18 +14917,6 @@ "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" }, - "promise.allsettled": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.2.tgz", - "integrity": "sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg==", - "requires": { - "array.prototype.map": "^1.0.1", - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "iterate-value": "^1.0.0" - } - }, "prop-types": { "version": "15.7.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", @@ -15293,8 +14995,8 @@ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" }, "pyret-codemirror-mode": { - "version": "git://github.com/brownplt/pyret-codemirror-mode.git#2c5def8044f34abfa32ca6a40c8a3c4551f8bdb9", - "from": "git://github.com/brownplt/pyret-codemirror-mode.git#horizon", + "version": "git://github.com/brownplt/pyret-codemirror-mode.git#465bda4d5ae28ad99f4249bccafd8dc5d67a0850", + "from": "git://github.com/brownplt/pyret-codemirror-mode.git#master", "requires": { "codemirror": "^5.x" } @@ -15380,8 +15082,8 @@ } }, "pyret-lang": { - "version": "git://github.com/brownplt/pyret-lang.git#5c7dc402fe453edca8acc01df5afe68f9d0a6c4f", - "from": "git://github.com/brownplt/pyret-lang.git#horizon", + "version": "git://github.com/brownplt/pyret-lang.git#6b80dd68a92c73db5fa255e164c51a84de40bcc8", + "from": "git://github.com/brownplt/pyret-lang.git#master", "requires": { "ascii-table": "~0.0.9", "benchmark": "^2.1.4", @@ -15399,8 +15101,7 @@ "seedrandom": "~2.3.10", "sha.js": "^2.4.8", "source-map": "^0.5.6", - "stacktrace-js": "^1.3.1", - "websocket": "^1.0.23" + "websocket": "^1.0.32" }, "dependencies": { "q": { @@ -16267,17 +15968,17 @@ } }, "selfsigned": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", - "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz", + "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==", "requires": { - "node-forge": "0.9.0" + "node-forge": "^0.10.0" }, "dependencies": { "node-forge": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", - "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==" + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" } } }, @@ -16314,9 +16015,12 @@ } }, "serialize-javascript": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.0.0.tgz", - "integrity": "sha512-skZcHYw2vEX4bw90nAr2iTTsz6x2SrHEnfxgKYmZlvJYBEZrvbKtobJWlQ20zczKb3bsHHXXTYt48zBA7ni9cw==" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "requires": { + "randombytes": "^2.1.0" + } }, "serve-index": { "version": "1.9.1", @@ -16629,18 +16333,23 @@ } }, "socket.io": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz", - "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.4.1.tgz", + "integrity": "sha512-Si18v0mMXGAqLqCVpTxBa8MGqriHGQh8ccEOhmsmNS3thNCGBwO8WGrwMibANsWtQQ5NStdZwHqZR3naJVFc3w==", "requires": { "debug": "~4.1.0", - "engine.io": "~3.4.0", + "engine.io": "~3.5.0", "has-binary2": "~1.0.2", "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.3.0", + "socket.io-client": "2.4.0", "socket.io-parser": "~3.4.0" }, "dependencies": { + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -16649,50 +16358,50 @@ "ms": "^2.1.1" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "socket.io-adapter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", - "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==" - }, - "socket.io-client": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz", - "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==", - "requires": { - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "~4.1.0", - "engine.io-client": "~3.4.0", - "has-binary2": "~1.0.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "socket.io-parser": "~3.3.0", - "to-array": "0.1.4" - }, - "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + "engine.io": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.5.0.tgz", + "integrity": "sha512-21HlvPUKaitDGE4GXNtQ7PLP0Sz4aWLddMPw2VTyFz1FVZqu/kZsJUO8WNpKuE/OCL7nkfRaOui2ZCJloGznGA==", + "requires": { + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "ws": "~7.4.2" + } }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "engine.io-client": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.1.tgz", + "integrity": "sha512-oVu9kBkGbcggulyVF0kz6BV3ganqUeqXvD79WOFKa+11oK692w1NyFkuEj4xrkFRpZhn92QOqTk4RQq5LiBXbQ==", "requires": { - "ms": "^2.1.1" + "component-emitter": "~1.3.0", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~7.4.2", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, "isarray": { @@ -16701,18 +16410,36 @@ "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "parseqs": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" + }, + "parseuri": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" }, - "socket.io-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", - "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "socket.io-client": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.4.0.tgz", + "integrity": "sha512-M6xhnKQHuuZd4Ba9vltCLT9oa+YvTsP8j9NcEiLElfIg8KeYPyhWOes6x4t+LTAC8enQbE/995AdTem2uNyKKQ==", "requires": { - "component-emitter": "1.2.1", + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "~1.3.0", "debug": "~3.1.0", - "isarray": "2.0.1" + "engine.io-client": "~3.5.0", + "has-binary2": "~1.0.2", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" }, "dependencies": { "debug": { @@ -16727,11 +16454,31 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "socket.io-parser": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz", + "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==", + "requires": { + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "isarray": "2.0.1" + } } } + }, + "ws": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" } } }, + "socket.io-adapter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", + "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==" + }, "socket.io-parser": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz", @@ -17033,72 +16780,18 @@ } }, "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", + "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", "requires": { "figgy-pudding": "^3.5.1" } }, - "stack-generator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-1.1.0.tgz", - "integrity": "sha1-NvapIHUabBD0maE8Msu19RoLiyU=", - "requires": { - "stackframe": "^1.0.2" - } - }, "stackframe": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==" }, - "stacktrace-gps": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-2.4.4.tgz", - "integrity": "sha1-acgn6dbW9Bz0ONfxleLjy/zyjEQ=", - "requires": { - "source-map": "0.5.6", - "stackframe": "~0.3" - }, - "dependencies": { - "source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" - }, - "stackframe": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-0.3.1.tgz", - "integrity": "sha1-M6qE8Rd6VUjIk1Uzy/6zQgl19aQ=" - } - } - }, - "stacktrace-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-1.3.1.tgz", - "integrity": "sha1-Z8qyWJr1xBe5Yvc2mUAne7O2oYs=", - "requires": { - "error-stack-parser": "^1.3.6", - "stack-generator": "^1.0.7", - "stacktrace-gps": "^2.4.3" - }, - "dependencies": { - "error-stack-parser": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-1.3.6.tgz", - "integrity": "sha1-4Oc7k+QXE40c18C3RrGkoUhUwpI=", - "requires": { - "stackframe": "^0.3.1" - } - }, - "stackframe": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-0.3.1.tgz", - "integrity": "sha1-M6qE8Rd6VUjIk1Uzy/6zQgl19aQ=" - } - } - }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -17261,48 +16954,6 @@ } } }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "requires": { - "has-symbols": "^1.0.1" - } - } - } - }, "string.prototype.trimleft": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", @@ -17321,48 +16972,6 @@ "function-bind": "^1.1.1" } }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "requires": { - "has-symbols": "^1.0.1" - } - } - } - }, "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", @@ -18222,9 +17831,9 @@ } }, "urijs": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.2.tgz", - "integrity": "sha512-s/UIq9ap4JPZ7H1EB5ULo/aOUbWqfDi7FKzMC2Nz+0Si8GiT1rIEaprt8hy3Vy2Ex2aJPpOQv4P4DuOZ+K1c6w==" + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.6.tgz", + "integrity": "sha512-eSXsXZ2jLvGWeLYlQA3Gh36BcjF+0amo92+wHPyN1mdR8Nxf75fuEuYTd9c0a+m/vhCjRK0ESlE9YNLW+E1VEw==" }, "urix": { "version": "0.1.0", @@ -18325,6 +17934,14 @@ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, + "utf-8-validate": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz", + "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==", + "requires": { + "node-gyp-build": "^4.2.0" + } + }, "util": { "version": "0.10.4", "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", @@ -19007,14 +18624,15 @@ } }, "websocket": { - "version": "1.0.31", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.31.tgz", - "integrity": "sha512-VAouplvGKPiKFDTeCCO65vYHsyay8DqoBSlzIO3fayrfOgU94lQN5a1uWVnFrMLceTJw/+fQXR5PGbUVRaHshQ==", + "version": "1.0.33", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.33.tgz", + "integrity": "sha512-XwNqM2rN5eh3G2CUQE3OHZj+0xfdH42+OFK6LdC2yqiC0YU8e5UK0nYre220T0IyyN031V/XOvtHvXozvJYFWA==", "requires": { + "bufferutil": "^4.0.1", "debug": "^2.2.0", "es5-ext": "^0.10.50", - "nan": "^2.14.0", "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", "yaeti": "^0.0.6" } }, @@ -19137,9 +18755,9 @@ } }, "workerpool": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz", - "integrity": "sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA==" + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==" }, "wrap-ansi": { "version": "4.0.0", @@ -19232,11 +18850,6 @@ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" }, - "xmldom": { - "version": "0.1.31", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz", - "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==" - }, "xmlhttprequest-ssl": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", @@ -19256,9 +18869,9 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" }, "yaeti": { "version": "0.0.6", @@ -19365,13 +18978,31 @@ } }, "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==" + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" + } } }, "yarn": { @@ -19393,6 +19024,11 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" } } } diff --git a/package.json b/package.json index 83db86b98..eb7019b60 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "karma-webpack": "^4.0.2", "load-script": "^1.0.0", "lodash": "^4.17.19", - "mocha": "^8.0.1", + "mocha": "^8.3.2", "mousetrap": "^1.6.1", "mustache": "^2.2.1", "mustache-express": "^1.2.1", diff --git a/src/web/arr/trove/chart.arr b/src/web/arr/trove/chart.arr index 5c7c64aa4..a194c3ed3 100644 --- a/src/web/arr/trove/chart.arr +++ b/src/web/arr/trove/chart.arr @@ -249,6 +249,12 @@ default-function-plot-series = { legend: '', } +type GeoChartSeries = { + tab :: TableIntern, +} + +default-geochart-series = {} + ########### type ChartWindowObject = { @@ -351,6 +357,15 @@ default-plot-chart-window-object :: PlotChartWindowObject = default-chart-window num-samples: 1000, } +type GeoChartWindowObject = { + title :: String, + width :: Number, + height :: Number, + render :: ( -> IM.Image), +} + +default-geo-chart-window-object :: GeoChartWindowObject = default-chart-window-object + ################################################################################ # DATA DEFINITIONS ################################################################################ @@ -403,10 +418,13 @@ data DataSeries: end, method num-bins(self, num-bins :: Number): histogram-series(self.obj.{ - min-num-bins: some(num-bins), - max-num-bins: some(num-bins) - }) - end, + min-num-bins: some(num-bins), + max-num-bins: some(num-bins) + }) + end + | geochart-series(obj :: GeoChartSeries) with: + is-single: true, + contr: {(): geochart-series}, sharing: method _output(self): get-vs-from-img("DataSeries", render-chart(self).get-image()) @@ -454,7 +472,9 @@ data ChartWindow: raise('num-samples: value must be an ineger between 1 and 100000') end plot-chart-window(self.obj.{num-samples: num-samples}) - end, + end + | geochart-window(obj :: GeoChartWindowObject) with: + constr: {(): geochart-window}, sharing: method display(self): _ = check-chart-window(self.obj) @@ -478,6 +498,7 @@ sharing: end end + ################################################################################ # FUNCTIONS ################################################################################ @@ -752,6 +773,22 @@ fun labeled-histogram-from-list(labels :: List, values :: List) } ^ histogram-series end +fun geochart-from-list( + region-labels :: List, + values :: List) -> DataSeries block: + region-length = region-labels.length() + values-length = values.length() + when region-length <> values-length: + raise("geochart: region-labels and values should have the same length") + end + values.each(check-num) + region-labels.each(check-string) + default-geochart-series.{ + tab: to-table2(region-labels, values) + } ^ geochart-series +end + + ################################################################################ # PLOTS ################################################################################ @@ -820,6 +857,11 @@ fun render-chart(s :: DataSeries) -> ChartWindow: P.histogram(self, obj) end } ^ histogram-chart-window + |geochart-series(obj) => + default-geo-chart-window-object.{ + method render(self): + P.geo-map(self, obj) end + } ^ geochart-window end where: render-now = {(x): render-chart(x).get-image()} @@ -859,9 +901,10 @@ where: [list: 2, 3.1, 1, 3, 6, 5])) does-not-raise render-now(from-list.box-plot( [list: [list: 1, 2, 3, 4], [list: 1, 2, 3, 4, 5], [list: 10, 11]] - )) does-not-raise + )) does-not-raise end + fun generate-xy( p :: FunctionPlotSeries, x-min :: Number, @@ -1199,4 +1242,5 @@ from-list = { freq-bar-chart: freq-bar-chart-from-list, labeled-box-plot: labeled-box-plot-from-list, box-plot: box-plot-from-list, + geochart: geochart-from-list, } diff --git a/src/web/js/trove/chart-lib.js b/src/web/js/trove/chart-lib.js index 1b914d0ac..c2d3de8e8 100644 --- a/src/web/js/trove/chart-lib.js +++ b/src/web/js/trove/chart-lib.js @@ -12,7 +12,8 @@ 'bar-chart': "tany", 'histogram': "tany", 'box-plot': "tany", - 'plot': "tany" + 'plot': "tany", + 'geochart': "tany" } }, theModule: function (RUNTIME, NAMESPACE, uri, IMAGELIB, jsnums , google) { @@ -464,7 +465,24 @@ mutators: [axesNameMutator, yAxisRangeMutator, xAxisRangeMutator], }; } - + + function geoChart(globalOptions, rawData) { + const table = get(rawData, 'tab'); + const data = new google.visualization.GeoMap; + return { + data: data, + options: { + slices: table.map(row => ({offset: toFixnum(row[2])})), + legend: { + alignment: 'end' + } + }, + chartType: google.visualization.GeoMap, + onExit: defaultImageReturn, + } + } + + function plot(globalOptions, rawData) { const scatters = get(rawData, 'scatters'); const lines = get(rawData, 'lines'); @@ -814,6 +832,7 @@ ${labelRow}`; 'histogram': makeFunction(histogram), 'box-plot': makeFunction(boxPlot), 'plot': makeFunction(plot), + 'geo-map': makeFunction(geoChart), }) }) }); diff --git a/src/web/js/trove/plot-lib-list.js b/src/web/js/trove/plot-lib-list.js index c285c11a1..cbe612983 100644 --- a/src/web/js/trove/plot-lib-list.js +++ b/src/web/js/trove/plot-lib-list.js @@ -15,6 +15,7 @@ 'bar-chart': "tany", 'dot-chart': "tany", 'box-chart': "tany" + 'geo-map': "tany" } }, theModule: function (RUNTIME, NAMESPACE, uri, CLIB, jsnums, d3, D3TIP) { @@ -886,10 +887,10 @@ 'shape-rendering': 'crispEdges' }) .on('mouseover', function () { - d3.select(this).style('fill', 'black'); + d3.select(this).style('xfill', 'black'); }) .on('mouseout', function () { - d3.select(this).style('fill', 'steelblue'); + d3.select(this).xstyle('fill', 'steelblue'); }); @@ -897,6 +898,76 @@ return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null); } + function geoChart(restart, windowOptions, tab) { + + function resizer(restarter, windowOptions) { + geoChart(restarter, windowOptions, tab); + } + + var sum = tab.map(function (row) { return row[1]; }) + .reduce(function (a, b) { + return jsnums.add(a, b, RUNTIME.NumberErrbacks); + }); + var valueScaler = libNum.scaler(0, sum, 0, 100, true); + + var dimension = getDimension({ + minWindowWidth: 700, + minWindowHeight: 550, + outerMarginLeft: 10, + outerMarginRight: 10, + marginLeft: 120, + marginRight: 120, + marginTop: 90, + marginBottom: 40, + mode: 'center', + }, windowOptions), + width = dimension.width, + height = dimension.height, + detached = createDiv(), + canvas = createCanvas(detached, dimension); + + var proj = d3.geoMercator() + .scale(100) + .translate([250, 250]) + .center([0, 5]) + var geo = d3.geoPath().projection(proj) + var color = d3.scale.category20(); + + d3.select("svg").selectAll("path").data(countries.features) + .enter + .append("path") + .attr("d", geo) + .attr("class", "countries"); + + + + + + d3.selectAll("path.countries") + .on("mouseover", centerBounds) + .on("mouseout", clearCenterBounds) + + + var prettyNumToStringDigits9 = libNum.getPrettyNumToStringDigits(9); + var tip = d3tip(detached) + .attr('class', 'd3-tip') + .direction('e') + .offset([0, 20]) + .html(function (d) { + return 'value:
' + prettyNumToStringDigits9(d.data[1]) + '
' + + 'percent:
' + prettyNumToStringDigits9(valueScaler(d.data[1])) + '%'; + }); + + canvas.call(tip); + + stylizeTip(tip) + + + + + return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null) + + } function pieChart(restarter, windowOptions, tab) { /* * Pie Chart @@ -1418,6 +1489,7 @@ 'bar-chart': makeFunction(barChart), 'dot-chart': makeFunction(dotChart), 'box-chart': makeFunction(boxChart), + 'geo-map': makeFunction(geoChart) }) }) }); From b8e2ed7fa67dab5f8aa7c4efab6200cfca7fe003 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 28 Apr 2021 16:13:18 -0500 Subject: [PATCH 11/29] added missing return sttatement in render function --- src/web/js/trove/plot-lib-list.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/web/js/trove/plot-lib-list.js b/src/web/js/trove/plot-lib-list.js index 0860ebf1a..f35f5d40b 100644 --- a/src/web/js/trove/plot-lib-list.js +++ b/src/web/js/trove/plot-lib-list.js @@ -1291,10 +1291,10 @@ return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null); } - function geoChart(restart, windowOptions, tab) { + function geoChart(restart, windowOptions, tab) { function resizer(restarter, windowOptions) { - geoChart(restarter, windowOptions, tab); + return geoChart(restarter, windowOptions, tab); } var sum = tab.map(function (row) { From 0db881fcc8ced6b2a63d3d1e75158540eb329b25 Mon Sep 17 00:00:00 2001 From: schornb <55115049+schornb@users.noreply.github.com> Date: Wed, 28 Apr 2021 17:23:01 -0400 Subject: [PATCH 12/29] chart lib fixed --- src/web/js/trove/chart-lib.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/web/js/trove/chart-lib.js b/src/web/js/trove/chart-lib.js index c2d3de8e8..7a76d29d2 100644 --- a/src/web/js/trove/chart-lib.js +++ b/src/web/js/trove/chart-lib.js @@ -468,7 +468,9 @@ function geoChart(globalOptions, rawData) { const table = get(rawData, 'tab'); - const data = new google.visualization.GeoMap; + const data = new google.visualization.DataTable(); + data.addColumn('string', 'Region'); + data.addColumn('number', "Color"); return { data: data, options: { @@ -477,7 +479,7 @@ alignment: 'end' } }, - chartType: google.visualization.GeoMap, + chartType: google.visualization.GeoChart, onExit: defaultImageReturn, } } From f70bdc09219db0d2273598c7984a88b46187b2bd Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 29 Apr 2021 16:26:37 -0500 Subject: [PATCH 13/29] fixed merge conflicts --- src/web/js/trove/chart-lib.js | 33 +++++++++---------------------- src/web/js/trove/plot-lib-list.js | 8 -------- 2 files changed, 9 insertions(+), 32 deletions(-) diff --git a/src/web/js/trove/chart-lib.js b/src/web/js/trove/chart-lib.js index 88319cc63..fc7db371c 100644 --- a/src/web/js/trove/chart-lib.js +++ b/src/web/js/trove/chart-lib.js @@ -13,11 +13,7 @@ 'histogram': "tany", 'box-plot': "tany", 'plot': "tany", -<<<<<<< HEAD - 'geo-map': "tany" -======= 'geochart': "tany" ->>>>>>> 0db881fcc8ced6b2a63d3d1e75158540eb329b25 } }, theModule: function (RUNTIME, NAMESPACE, uri, IMAGELIB, jsnums , google) { @@ -351,7 +347,7 @@ // ONLY if we're showing outliers, add whiskers to the tooltip // (otherwise, the min/max ARE the bottom/top whiskers) if(table.length == 1 && showOutliers) { - tooltip += + tooltip += `

bottom whisker: ${summaryValues[4]}

top whisker: ${summaryValues[3]}

`; } @@ -400,7 +396,7 @@ data.addColumn('string', 'Label'); data.addColumn('number', ''); - + var max, min; var val = null; var hasAtLeastTwoValues = false; @@ -440,7 +436,7 @@ cases(RUNTIME.ffi.isOption, 'Option', get(rawData, 'min-num-bins'), { none: function () { if(options.histogram.bucketSize !== undefined) { - options.histogram.minNumBuckets = Math.floor((max - min) / options.histogram.bucketSize) + 1; + options.histogram.minNumBuckets = Math.floor((max - min) / options.histogram.bucketSize) + 1; } }, some: function (minNumBins) { @@ -469,37 +465,26 @@ mutators: [axesNameMutator, yAxisRangeMutator, xAxisRangeMutator], }; } - + function geoChart(globalOptions, rawData) { const table = get(rawData, 'tab'); const data = new google.visualization.DataTable(); -<<<<<<< HEAD - return { - data: data, - options: { - slices: table.map(row => ({offset: toFixnum(row[1])})), -======= data.addColumn('string', 'Region'); data.addColumn('number', "Color"); return { data: data, options: { slices: table.map(row => ({offset: toFixnum(row[2])})), ->>>>>>> 0db881fcc8ced6b2a63d3d1e75158540eb329b25 legend: { alignment: 'end' } }, -<<<<<<< HEAD - chartType: google.visualization.GeoMap, -======= chartType: google.visualization.GeoChart, ->>>>>>> 0db881fcc8ced6b2a63d3d1e75158540eb329b25 onExit: defaultImageReturn, } } - - + + function plot(globalOptions, rawData) { const scatters = get(rawData, 'scatters'); const lines = get(rawData, 'lines'); @@ -552,7 +537,7 @@ ${labelRow}`; series: combined.map((p, i) => { // are we using custom images instead of dots? const hasImage = get(p, 'ps').filter(p => p[3]).length > 0; - + // scatters and then lines const seriesOptions = {}; @@ -697,11 +682,11 @@ ${labelRow}`; // if custom images is defined, use the image at that location // and overlay it atop each dot google.visualization.events.addListener(chart, 'ready', function () { - // HACK(Emmanuel): + // HACK(Emmanuel): // The only way to hijack marker events is to walk the DOM here // If Google changes the DOM, these lines will likely break const svgRoot = chart.container.querySelector('svg'); - const markers = svgRoot.children[2].children[2].children; + const markers = svgRoot.children[2].children[2].children; const layout = chart.getChartLayoutInterface(); // remove any labels that have previously been drawn diff --git a/src/web/js/trove/plot-lib-list.js b/src/web/js/trove/plot-lib-list.js index 40989a980..9ccae9c68 100644 --- a/src/web/js/trove/plot-lib-list.js +++ b/src/web/js/trove/plot-lib-list.js @@ -14,11 +14,7 @@ 'plot-multi': "tany", 'bar-chart': "tany", 'dot-chart': "tany", -<<<<<<< HEAD 'box-chart': "tany", -======= - 'box-chart': "tany" ->>>>>>> 0db881fcc8ced6b2a63d3d1e75158540eb329b25 'geo-map': "tany" } }, @@ -1580,11 +1576,7 @@ 'bar-chart': makeFunction(barChart), 'dot-chart': makeFunction(dotChart), 'box-chart': makeFunction(boxChart), -<<<<<<< HEAD - 'geo-map': makeFunction(geoChart), -======= 'geo-map': makeFunction(geoChart) ->>>>>>> 0db881fcc8ced6b2a63d3d1e75158540eb329b25 }) }) }); From 25a950e30b664441d52b03dae509fc0c70d3a0ad Mon Sep 17 00:00:00 2001 From: schornb <55115049+schornb@users.noreply.github.com> Date: Thu, 29 Apr 2021 17:38:36 -0400 Subject: [PATCH 14/29] minor syntax fixes --- src/web/js/trove/plot-lib.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/web/js/trove/plot-lib.js b/src/web/js/trove/plot-lib.js index 47441c9e3..1a5bd30d3 100644 --- a/src/web/js/trove/plot-lib.js +++ b/src/web/js/trove/plot-lib.js @@ -15,7 +15,7 @@ 'bar-chart': "tany", 'dot-chart': "tany", 'box-chart': "tany", - 'geo-map': "tany" + 'geo-chart': "tany" } }, theModule: function (RUNTIME, NAMESPACE, uri, CLIB, jsnums, d3, D3TIP) { @@ -1092,9 +1092,9 @@ canvas.call(tip); - stylizeTip(tip) + stylizeTip(tip); - return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null) + return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null); } function barChart(restarter, windowOptions, table, legend, showLegend) { @@ -1506,7 +1506,7 @@ 'bar-chart': makeFunction(barChart), 'dot-chart': makeFunction(dotChart), 'box-chart': makeFunction(boxChart), - 'geo-map': makeFunction(geoChart), + 'geo-chart': makeFunction(geoChart), }) }) }); From 6897cafacc7c8f167af2762904bfc2bc858afcb9 Mon Sep 17 00:00:00 2001 From: schornb <55115049+schornb@users.noreply.github.com> Date: Tue, 4 May 2021 17:13:26 -0400 Subject: [PATCH 15/29] editing chart.arr render-chart function for geomap --- src/web/arr/trove/chart.arr | 4 +- src/web/js/trove/chart-lib.js | 2 +- src/web/js/trove/plot-lib.js | 143 +++++++++++++++++++--------------- 3 files changed, 83 insertions(+), 66 deletions(-) diff --git a/src/web/arr/trove/chart.arr b/src/web/arr/trove/chart.arr index a194c3ed3..7f6b32ae8 100644 --- a/src/web/arr/trove/chart.arr +++ b/src/web/arr/trove/chart.arr @@ -857,10 +857,10 @@ fun render-chart(s :: DataSeries) -> ChartWindow: P.histogram(self, obj) end } ^ histogram-chart-window - |geochart-series(obj) => + | geochart-series(obj) => default-geo-chart-window-object.{ method render(self): - P.geo-map(self, obj) end + P.geo-chart(self, obj) end } ^ geochart-window end where: diff --git a/src/web/js/trove/chart-lib.js b/src/web/js/trove/chart-lib.js index fc7db371c..f4521becd 100644 --- a/src/web/js/trove/chart-lib.js +++ b/src/web/js/trove/chart-lib.js @@ -834,7 +834,7 @@ ${labelRow}`; 'histogram': makeFunction(histogram), 'box-plot': makeFunction(boxPlot), 'plot': makeFunction(plot), - 'geo-map': makeFunction(geoChart), + 'geo-chart': makeFunction(geoChart), }) }) }); diff --git a/src/web/js/trove/plot-lib.js b/src/web/js/trove/plot-lib.js index 1a5bd30d3..d0b2ef4bd 100644 --- a/src/web/js/trove/plot-lib.js +++ b/src/web/js/trove/plot-lib.js @@ -1016,15 +1016,14 @@ geoChart(restarter, windowOptions, tab); } - var sum = tab.map(function (row) { - return row[1]; - }) - .reduce(function (a, b) { + var sum = tab.map(function (row) { return row[1]; }) + .reduce(function (a, b) { return jsnums.add(a, b, RUNTIME.NumberErrbacks); - }); - var valueScaler = libNum.scaler(0, sum, 0, 100, true); + }); + var valueScaler = libNum.scaler(0, sum, 0, 100, true); - var dimension = getDimension({ + + var dimension = getDimension({ minWindowWidth: 700, minWindowHeight: 550, outerMarginLeft: 10, @@ -1034,67 +1033,85 @@ marginTop: 90, marginBottom: 40, mode: 'center', - }, windowOptions), - width = dimension.width, - height = dimension.height, - detached = createDiv(), - canvas = createCanvas(detached, dimension); - - //d3.json("world.geojson", createMap) - var proj = d3.geoMercator() - .scale(100) - .translate([250, 250]) - .center([0, 5]) - var geo = d3.geoPath().projection(proj) - var color = d3.scale.category20(); - - d3.select("svg").selectAll("path").data(tab.map(function (f): return row[2])) - .enter - .append("path") - .attr("d", geo) - .attr("class", "countries"); - - d3.selectAll("path.countries") - .on("mouseover", centerBounds) - .on("mouseout", clearCenterBounds) - - function centerBounds(d) { - var thisBounds = geoPath.bounds(d); - var thisCenter = geoPath.centroid(d); - d3.select("svg") - .append("rect") - .attr("class", "bbox") - .attr("x", thisBounds[0][0]) - .attr("y", thisBounds[0][1]) - .attr("width", thisBounds[1][0] - thisBounds[0][0]) - .attr("height", thisBounds[1][1] - thisBounds[0][1]) - d3.select("svg") - .append("circle") - .attr("class", "centroid") - .attr("r", 5) - .attr("cx", thisCenter[0]).attr("cy", thisCenter[1]) - } - - function clearCenterBounds() { - d3.selectAll("circle.centroid").remove(); - d3.selectAll("rect.bbox").remove(); - } - - var prettyNumToStringDigits9 = libNum.getPrettyNumToStringDigits(9); - var tip = d3tip(detached) - .attr('class', 'd3-tip') - .direction('e') - .offset([0, 20]) - .html(function (d) { + }, windowOptions), + width = dimension.width, + height = dimension.height, + detached = createDiv(), + canvas = createCanvas(detached, dimension); + + var maxRadius = Math.min(width, height) / 2; + var maxRadiusValue = tab.map(function (row) { return row[2]; }) + .reduce(libNum.numMax); + var radiusScaler = libNum.scaler(0, maxRadiusValue, 0, maxRadius, true); + var color = d3.scale.category20(); + var arc = d3.svg.arc() + .outerRadius(function (row) { return radiusScaler(row.data[2]); }) + .innerRadius(0); + var pie = d3.layout.pie() + .sort(null) + .value(function (row) { return valueScaler(row[1]); }); + + var prettyNumToStringDigits9 = libNum.getPrettyNumToStringDigits(9); + var tip = d3tip(detached) + .attr('class', 'd3-tip') + .direction('e') + .offset([0, 20]) + .html(function (d) { return 'value:
' + prettyNumToStringDigits9(d.data[1]) + '
' + 'percent:
' + prettyNumToStringDigits9(valueScaler(d.data[1])) + '%'; - }); + }); - canvas.call(tip); + canvas.call(tip); - stylizeTip(tip); + var g = canvas.selectAll('.arc') + .data(pie(tab)) + .enter().append('g') + .attr('class', 'arc'); + + g.append('path').attr('class', 'path').attr('d', arc); + + const arc2 = d3.svg.arc(); + + g.append('path').attr('class', 'transparent').attr('d', arc); + + g.append('text') + .attr('transform', function (d) { + const r = radiusScaler(d.data[2]); + d.outerRadius = r + 15; + d.innerRadius = r + 10; + return svgTranslate(arc2.centroid(d)); + }) + .attr('dy', '.35em') + .style('text-anchor', function(d) { + const placement = arc2.centroid(d)[0]; + if (-10 <= placement && placement <= 10) { + return 'middle'; + } + return (placement >= 0) ? 'start' : 'end'; + }) + .text(function (d) { return d.data[0]; }); - return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null); + canvas.selectAll('.arc path') + .style({ + fill: function (d, i) { return color(i); } + }) + .on('mouseover', function (e) { + d3.select(this.parentNode) + .selectAll('.path') + .style('opacity', '0.4'); + tip.show(e); + }) + .on('mouseout', function (e) { + d3.select(this.parentNode) + .selectAll('.path') + .style('opacity', '0.9'); + tip.hide(e); + }); + canvas.selectAll('.transparent').style('opacity', '0'); + canvas.selectAll('text').style({'font-size': '15px'}); + + stylizeTip(detached); + return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null); } function barChart(restarter, windowOptions, table, legend, showLegend) { From f38ab61abce5a4df55cd48ee9fcc857c02ac2fd2 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 4 May 2021 16:16:36 -0500 Subject: [PATCH 16/29] reset plot js files --- src/web/js/trove/plot-lib-list.js | 165 +----------------------------- src/web/js/trove/plot-lib.js | 108 +------------------ 2 files changed, 4 insertions(+), 269 deletions(-) diff --git a/src/web/js/trove/plot-lib-list.js b/src/web/js/trove/plot-lib-list.js index 9ccae9c68..c285c11a1 100644 --- a/src/web/js/trove/plot-lib-list.js +++ b/src/web/js/trove/plot-lib-list.js @@ -14,8 +14,7 @@ 'plot-multi': "tany", 'bar-chart': "tany", 'dot-chart': "tany", - 'box-chart': "tany", - 'geo-map': "tany" + 'box-chart': "tany" } }, theModule: function (RUNTIME, NAMESPACE, uri, CLIB, jsnums, d3, D3TIP) { @@ -887,10 +886,10 @@ 'shape-rendering': 'crispEdges' }) .on('mouseover', function () { - d3.select(this).style('xfill', 'black'); + d3.select(this).style('fill', 'black'); }) .on('mouseout', function () { - d3.select(this).xstyle('fill', 'steelblue'); + d3.select(this).style('fill', 'steelblue'); }); @@ -898,76 +897,6 @@ return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null); } - function geoChart(restart, windowOptions, tab) { - - function resizer(restarter, windowOptions) { - geoChart(restarter, windowOptions, tab); - } - - var sum = tab.map(function (row) { return row[1]; }) - .reduce(function (a, b) { - return jsnums.add(a, b, RUNTIME.NumberErrbacks); - }); - var valueScaler = libNum.scaler(0, sum, 0, 100, true); - - var dimension = getDimension({ - minWindowWidth: 700, - minWindowHeight: 550, - outerMarginLeft: 10, - outerMarginRight: 10, - marginLeft: 120, - marginRight: 120, - marginTop: 90, - marginBottom: 40, - mode: 'center', - }, windowOptions), - width = dimension.width, - height = dimension.height, - detached = createDiv(), - canvas = createCanvas(detached, dimension); - - var proj = d3.geoMercator() - .scale(100) - .translate([250, 250]) - .center([0, 5]) - var geo = d3.geoPath().projection(proj) - var color = d3.scale.category20(); - - d3.select("svg").selectAll("path").data(countries.features) - .enter - .append("path") - .attr("d", geo) - .attr("class", "countries"); - - - - - - d3.selectAll("path.countries") - .on("mouseover", centerBounds) - .on("mouseout", clearCenterBounds) - - - var prettyNumToStringDigits9 = libNum.getPrettyNumToStringDigits(9); - var tip = d3tip(detached) - .attr('class', 'd3-tip') - .direction('e') - .offset([0, 20]) - .html(function (d) { - return 'value:
' + prettyNumToStringDigits9(d.data[1]) + '
' + - 'percent:
' + prettyNumToStringDigits9(valueScaler(d.data[1])) + '%'; - }); - - canvas.call(tip); - - stylizeTip(tip) - - - - - return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null) - - } function pieChart(restarter, windowOptions, tab) { /* * Pie Chart @@ -1361,93 +1290,6 @@ return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null); } - function geoChart(restart, windowOptions, tab) { - - function resizer(restarter, windowOptions) { - return geoChart(restarter, windowOptions, tab); - } - - var sum = tab.map(function (row) { - return row[1]; - }) - .reduce(function (a, b) { - return jsnums.add(a, b, RUNTIME.NumberErrbacks); - }); - var valueScaler = libNum.scaler(0, sum, 0, 100, true); - - var dimension = getDimension({ - minWindowWidth: 700, - minWindowHeight: 550, - outerMarginLeft: 10, - outerMarginRight: 10, - marginLeft: 120, - marginRight: 120, - marginTop: 90, - marginBottom: 40, - mode: 'center', - }, windowOptions), - width = dimension.width, - height = dimension.height, - detached = createDiv(), - canvas = createCanvas(detached, dimension); - - //d3.json("world.geojson", createMap) - var proj = d3.geoMercator() - .scale(100) - .translate([250, 250]) - .center([0, 5]) - var geo = d3.geoPath().projection(proj) - var color = d3.scale.category20(); - - d3.select("svg").selectAll("path").data(countries.features) - .enter - .append("path") - .attr("d", geo) - .attr("class", "countries"); - - d3.selectAll("path.countries") - .on("mouseover", centerBounds) - .on("mouseout", clearCenterBounds) - - function centerBounds(d) { - var thisBounds = geoPath.bounds(d); - var thisCenter = geoPath.centroid(d); - d3.select("svg") - .append("rect") - .attr("class", "bbox") - .attr("x", thisBounds[0][0]) - .attr("y", thisBounds[0][1]) - .attr("width", thisBounds[1][0] - thisBounds[0][0]) - .attr("height", thisBounds[1][1] - thisBounds[0][1]) - d3.select("svg") - .append("circle") - .attr("class", "centroid") - .attr("r", 5) - .attr("cx", thisCenter[0]).attr("cy", thisCenter[1]) - } - - function clearCenterBounds() { - d3.selectAll("circle.centroid").remove(); - d3.selectAll("rect.bbox").remove(); - } - - var prettyNumToStringDigits9 = libNum.getPrettyNumToStringDigits(9); - var tip = d3tip(detached) - .attr('class', 'd3-tip') - .direction('e') - .offset([0, 20]) - .html(function (d) { - return 'value:
' + prettyNumToStringDigits9(d.data[1]) + '
' + - 'percent:
' + prettyNumToStringDigits9(valueScaler(d.data[1])) + '%'; - }); - - canvas.call(tip); - - stylizeTip(tip) - - return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null) -} - function boxChart(restarter, windowOptions, table) { /* * Box Chart @@ -1576,7 +1418,6 @@ 'bar-chart': makeFunction(barChart), 'dot-chart': makeFunction(dotChart), 'box-chart': makeFunction(boxChart), - 'geo-map': makeFunction(geoChart) }) }) }); diff --git a/src/web/js/trove/plot-lib.js b/src/web/js/trove/plot-lib.js index d0b2ef4bd..458168d36 100644 --- a/src/web/js/trove/plot-lib.js +++ b/src/web/js/trove/plot-lib.js @@ -14,8 +14,7 @@ 'plot-multi': "tany", 'bar-chart': "tany", 'dot-chart': "tany", - 'box-chart': "tany", - 'geo-chart': "tany" + 'box-chart': "tany" } }, theModule: function (RUNTIME, NAMESPACE, uri, CLIB, jsnums, d3, D3TIP) { @@ -1010,110 +1009,6 @@ return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null); } - function geoChart(restart, windowOptions, tab) { - - function resizer(restarter, windowOptions) { - geoChart(restarter, windowOptions, tab); - } - - var sum = tab.map(function (row) { return row[1]; }) - .reduce(function (a, b) { - return jsnums.add(a, b, RUNTIME.NumberErrbacks); - }); - var valueScaler = libNum.scaler(0, sum, 0, 100, true); - - - var dimension = getDimension({ - minWindowWidth: 700, - minWindowHeight: 550, - outerMarginLeft: 10, - outerMarginRight: 10, - marginLeft: 120, - marginRight: 120, - marginTop: 90, - marginBottom: 40, - mode: 'center', - }, windowOptions), - width = dimension.width, - height = dimension.height, - detached = createDiv(), - canvas = createCanvas(detached, dimension); - - var maxRadius = Math.min(width, height) / 2; - var maxRadiusValue = tab.map(function (row) { return row[2]; }) - .reduce(libNum.numMax); - var radiusScaler = libNum.scaler(0, maxRadiusValue, 0, maxRadius, true); - var color = d3.scale.category20(); - var arc = d3.svg.arc() - .outerRadius(function (row) { return radiusScaler(row.data[2]); }) - .innerRadius(0); - var pie = d3.layout.pie() - .sort(null) - .value(function (row) { return valueScaler(row[1]); }); - - var prettyNumToStringDigits9 = libNum.getPrettyNumToStringDigits(9); - var tip = d3tip(detached) - .attr('class', 'd3-tip') - .direction('e') - .offset([0, 20]) - .html(function (d) { - return 'value:
' + prettyNumToStringDigits9(d.data[1]) + '
' + - 'percent:
' + prettyNumToStringDigits9(valueScaler(d.data[1])) + '%'; - }); - - canvas.call(tip); - - var g = canvas.selectAll('.arc') - .data(pie(tab)) - .enter().append('g') - .attr('class', 'arc'); - - g.append('path').attr('class', 'path').attr('d', arc); - - const arc2 = d3.svg.arc(); - - g.append('path').attr('class', 'transparent').attr('d', arc); - - g.append('text') - .attr('transform', function (d) { - const r = radiusScaler(d.data[2]); - d.outerRadius = r + 15; - d.innerRadius = r + 10; - return svgTranslate(arc2.centroid(d)); - }) - .attr('dy', '.35em') - .style('text-anchor', function(d) { - const placement = arc2.centroid(d)[0]; - if (-10 <= placement && placement <= 10) { - return 'middle'; - } - return (placement >= 0) ? 'start' : 'end'; - }) - .text(function (d) { return d.data[0]; }); - - canvas.selectAll('.arc path') - .style({ - fill: function (d, i) { return color(i); } - }) - .on('mouseover', function (e) { - d3.select(this.parentNode) - .selectAll('.path') - .style('opacity', '0.4'); - tip.show(e); - }) - .on('mouseout', function (e) { - d3.select(this.parentNode) - .selectAll('.path') - .style('opacity', '0.9'); - tip.hide(e); - }); - canvas.selectAll('.transparent').style('opacity', '0'); - canvas.selectAll('text').style({'font-size': '15px'}); - - stylizeTip(detached); - return callBigBang(detached, restarter, resizer, windowOptions, dimension, null, null); -} - function barChart(restarter, windowOptions, table, legend, showLegend) { /* * Bar Chart @@ -1523,7 +1418,6 @@ 'bar-chart': makeFunction(barChart), 'dot-chart': makeFunction(dotChart), 'box-chart': makeFunction(boxChart), - 'geo-chart': makeFunction(geoChart), }) }) }); From 731fae38ea138f66ec3fdcb2ad96bfcf4d97f125 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 4 May 2021 16:21:51 -0500 Subject: [PATCH 17/29] reset plot arr files --- src/web/arr/trove/plot-list.arr | 44 --------------------------------- src/web/arr/trove/plot.arr | 17 ------------- 2 files changed, 61 deletions(-) diff --git a/src/web/arr/trove/plot-list.arr b/src/web/arr/trove/plot-list.arr index 436b82dff..d3c3250b5 100644 --- a/src/web/arr/trove/plot-list.arr +++ b/src/web/arr/trove/plot-list.arr @@ -68,8 +68,6 @@ data Series: typ: 'bar-chart' | histogram-series(values :: List, n :: Number) with: typ: 'histogram' - | geo-map-series(labels :: List, values :: List, threshold :: List) - with: typ: 'geo-map' sharing: method _output(self :: Series) -> VS.ValueSkeleton: VS.vs-constr(self.typ + "-like-series", [list: VS.vs-str("...")]) @@ -380,38 +378,6 @@ end end |# -fun adjustable-geo-map(labels :: List, values :: List, radiuses :: List) - -> Series block: - label-length = labels.length() - value-length = values.length() - when label-length <> value-length: - raise('adjustable-geo-chart: labels and values should have the same length') - end - radius-length = radiuses.length() - when label-length <> radius-length: - raise('adjustable-geo-chart: labels and radiuses should have the same length') - end - when label-length == 0: - raise('adjustable-geo-chart: need at least one data') - end - geo-map-series(labels, values, radiuses) -end - -fun geo-map-s(labels :: List, values :: List) -> Series block: - doc: ``` - Consume labels, a list of string, and values, a list of numbers - and construct a geo chart ``` - label-length = labels.length() - value-length = values.length() - when label-length <> value-length: - raise('geo-chart: labels and values should have the same length') - end - when label-length == 0: - raise('geo-chart: need at least one data') - end - geo-map-series(labels, values, repeat(label-length, 1)) -end - fun plot(s :: Series) -> PlotObject: cases (Series) s: | line-plot-series(_, _, _) => plots([list: s]) @@ -447,16 +413,6 @@ fun plot(s :: Series) -> PlotObject: P.histogram(self, builtins.raw-array-from-list(values), n) end } - | geo-map-series(labels, values, threshold) => - plot-object-base.{ - method _render(self): - geo-map-s(self, map3( - {(l :: String, v :: Number, t :: Number): [raw-array: l, v, t]}, - labels, - values, - threshold) ^ builtins.raw-array-from-list) - end - } end where: plot-now = {(x): plot(x).get-image()} diff --git a/src/web/arr/trove/plot.arr b/src/web/arr/trove/plot.arr index 99b977816..84cef28a1 100644 --- a/src/web/arr/trove/plot.arr +++ b/src/web/arr/trove/plot.arr @@ -118,9 +118,6 @@ box-chart-window-options :: BoxChartWindowOptions = axis-window-options type HistogramWindowOptions = AxisWindowOptions histogram-window-options :: HistogramWindowOptions = axis-window-options -type GeoChartWindowOptions = BaseWindowOptions -geo-chart-window-option :: GeoChartWindowOptions = base-window-options - type PlotOptions = { color :: I.Color } @@ -136,7 +133,6 @@ type WrappedPieChartWindowOptions = (PieChartWindowOptions -> PieChartWindowOpti type WrappedHistogramWindowOptions = (HistogramWindowOptions -> HistogramWindowOptions) type WrappedDotChartWindowOptions = (DotChartWindowOptions -> DotChartWindowOptions) type WrappedBoxChartWindowOptions = (BoxChartWindowOptions -> BoxChartWindowOptions) -type WrappedGeoChartWindowOptions = (GeoChartWindowOptions -> GeoChartWindowOptions) type PlottableFunction = (Number -> Number) type Posn = RawArray type TableInt = RawArray @@ -551,19 +547,6 @@ fun render-plots( render-multi-plot(new-plots, options) end -fun geo-map(tab :: Table, options-generator :: WrappedGeoChartWindowOptions) -> IM.Image block: - doc: 'Consume a table with two columns: `region` and `value`, and show a geo-map' - when not(tab._header-raw-array =~ [raw-array: 'region', 'value']): - raise('geo-map: expect a table with columns named `region` and `value`') - end - when raw-array-length(tab._rows-raw-array) == 0: - raise('geo-map: expect the table to have at least one row') - end - options = options-generator(geo-chart-window-option) - _ = check-base-window-options(options) - P.geo-map(options, tab._rows-raw-array) -end - make-function-plot = function-plot(_, _.{color: I.blue}) make-line-plot = line-plot(_, _.{color: I.blue}) make-scatter-plot = scatter-plot(_, _.{color: I.blue}) From 173bf7e4e29baf091f6bec9c6646d28daab6a90d Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 4 May 2021 16:34:14 -0500 Subject: [PATCH 18/29] reset plot arr files --- src/web/arr/trove/chart.arr | 2 +- src/web/js/trove/chart-lib.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/web/arr/trove/chart.arr b/src/web/arr/trove/chart.arr index 7f6b32ae8..562d7c713 100644 --- a/src/web/arr/trove/chart.arr +++ b/src/web/arr/trove/chart.arr @@ -860,7 +860,7 @@ fun render-chart(s :: DataSeries) -> ChartWindow: | geochart-series(obj) => default-geo-chart-window-object.{ method render(self): - P.geo-chart(self, obj) end + P.geochart(self, obj) end } ^ geochart-window end where: diff --git a/src/web/js/trove/chart-lib.js b/src/web/js/trove/chart-lib.js index f4521becd..3ef18273a 100644 --- a/src/web/js/trove/chart-lib.js +++ b/src/web/js/trove/chart-lib.js @@ -834,7 +834,7 @@ ${labelRow}`; 'histogram': makeFunction(histogram), 'box-plot': makeFunction(boxPlot), 'plot': makeFunction(plot), - 'geo-chart': makeFunction(geoChart), + 'geochart': makeFunction(geoChart), }) }) }); From 2ee2def67ca8fd92f8f50b3a7921e6e914dde807 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 4 May 2021 17:00:03 -0500 Subject: [PATCH 19/29] reset plot arr files --- src/web/js/trove/chart-lib.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/js/trove/chart-lib.js b/src/web/js/trove/chart-lib.js index 3ef18273a..f4c4054dd 100644 --- a/src/web/js/trove/chart-lib.js +++ b/src/web/js/trove/chart-lib.js @@ -481,7 +481,7 @@ }, chartType: google.visualization.GeoChart, onExit: defaultImageReturn, - } + }; } From 110070012b5eb11868ce56a2c8d8a932a6045400 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 18 May 2021 18:31:38 -0400 Subject: [PATCH 20/29] basic functionality --- src/web/js/trove/chart-lib.js | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/web/js/trove/chart-lib.js b/src/web/js/trove/chart-lib.js index f4c4054dd..dda61d61f 100644 --- a/src/web/js/trove/chart-lib.js +++ b/src/web/js/trove/chart-lib.js @@ -29,7 +29,8 @@ var IMAGE = get(IMAGELIB, "internal"); - google.charts.load('current', {'packages' : ['corechart']}); + google.charts.load('current', {'packages' : ['corechart', 'geochart'], +'mapsApiKey': 'AIzaSyD-9tSrke72PouQMnMX-a7eZSW0jkFMBWY'}); ////////////////////////////////////////////////////////////////////////////// @@ -467,18 +468,26 @@ } function geoChart(globalOptions, rawData) { + console.log("test 123") const table = get(rawData, 'tab'); - const data = new google.visualization.DataTable(); - data.addColumn('string', 'Region'); - data.addColumn('number', "Color"); + //const data = new google.visualization.DataTable(); + //data.addColumn('string', 'Region'); + //data.addColumn('number', "Color"); + //data.addRows(table.map(row => [row[0], toFixnum(row[1])])); + const data = google.visualization.arrayToDataTable([ + ['Country', 'Popularity'], + ['Germany', 200], + ['United States', 300], + ['Brazil', 400], + ['Canada', 500], + ['France', 600], + ['RU', 700] + ]); + + return { data: data, - options: { - slices: table.map(row => ({offset: toFixnum(row[2])})), - legend: { - alignment: 'end' - } - }, + options: {}, chartType: google.visualization.GeoChart, onExit: defaultImageReturn, }; @@ -760,6 +769,7 @@ ${labelRow}`; However, somehow this event is never triggered, so we will just call it here to guarantee that it will return. */ + imageReturn(result.chart.getImageURI(), restarter, x => x); } From 83a372e27459e7ac88ed64e0f5f9c8fa0a9ead77 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 18 May 2021 18:51:12 -0400 Subject: [PATCH 21/29] geoChart now correctly uses data --- src/web/js/trove/chart-lib.js | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/src/web/js/trove/chart-lib.js b/src/web/js/trove/chart-lib.js index dda61d61f..459fc050f 100644 --- a/src/web/js/trove/chart-lib.js +++ b/src/web/js/trove/chart-lib.js @@ -468,23 +468,12 @@ } function geoChart(globalOptions, rawData) { - console.log("test 123") + //console.log("test 123") const table = get(rawData, 'tab'); - //const data = new google.visualization.DataTable(); - //data.addColumn('string', 'Region'); - //data.addColumn('number', "Color"); - //data.addRows(table.map(row => [row[0], toFixnum(row[1])])); - const data = google.visualization.arrayToDataTable([ - ['Country', 'Popularity'], - ['Germany', 200], - ['United States', 300], - ['Brazil', 400], - ['Canada', 500], - ['France', 600], - ['RU', 700] - ]); - - + const data = new google.visualization.DataTable(); + data.addColumn('string', 'Region'); + data.addColumn('number', "Color"); + data.addRows(table.map(row => [row[0], toFixnum(row[1])])); return { data: data, options: {}, From 5cddc4b3a7d5341b22c40c6b5854e306af89764c Mon Sep 17 00:00:00 2001 From: schornb <55115049+schornb@users.noreply.github.com> Date: Sat, 22 May 2021 22:19:31 -0400 Subject: [PATCH 22/29] added ability to change region --- src/web/js/trove/chart-lib.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/web/js/trove/chart-lib.js b/src/web/js/trove/chart-lib.js index 459fc050f..be03e0112 100644 --- a/src/web/js/trove/chart-lib.js +++ b/src/web/js/trove/chart-lib.js @@ -474,9 +474,19 @@ data.addColumn('string', 'Region'); data.addColumn('number', "Color"); data.addRows(table.map(row => [row[0], toFixnum(row[1])])); + + const options = {region: {}}; + + cases(RUNTIME.ffi.isOption, 'Option', get(rawData, 'region'), { + none: function () {}, + some: function (r) { + options.region = r; + } + }); + return { data: data, - options: {}, + options: options, chartType: google.visualization.GeoChart, onExit: defaultImageReturn, }; From 51fb03ec04ec6bad3f1b17b8571b2697b9ccf6ed Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 22 May 2021 22:51:27 -0400 Subject: [PATCH 23/29] changed type of region parameter --- src/web/arr/trove/chart.arr | 9 ++++++++- src/web/js/trove/chart-lib.js | 14 ++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/web/arr/trove/chart.arr b/src/web/arr/trove/chart.arr index 562d7c713..bc2edc8a5 100644 --- a/src/web/arr/trove/chart.arr +++ b/src/web/arr/trove/chart.arr @@ -118,6 +118,9 @@ y-max-method = method(self, y-max :: Number): self.constr()(self.obj.{y-max: some(y-max)}) end +region-method = method(self, region :: String): + self.constr()(self.obj.{region: region}) +end ################################################################################ # BOUNDING BOX ################################################################################ @@ -251,9 +254,12 @@ default-function-plot-series = { type GeoChartSeries = { tab :: TableIntern, + region :: String, } -default-geochart-series = {} +default-geochart-series = { + region: "world", +} ########### @@ -425,6 +431,7 @@ data DataSeries: | geochart-series(obj :: GeoChartSeries) with: is-single: true, contr: {(): geochart-series}, + region: region-method, sharing: method _output(self): get-vs-from-img("DataSeries", render-chart(self).get-image()) diff --git a/src/web/js/trove/chart-lib.js b/src/web/js/trove/chart-lib.js index be03e0112..8dbc657d1 100644 --- a/src/web/js/trove/chart-lib.js +++ b/src/web/js/trove/chart-lib.js @@ -468,21 +468,15 @@ } function geoChart(globalOptions, rawData) { - //console.log("test 123") const table = get(rawData, 'tab'); const data = new google.visualization.DataTable(); + const region = get(rawData, 'region'); data.addColumn('string', 'Region'); data.addColumn('number', "Color"); data.addRows(table.map(row => [row[0], toFixnum(row[1])])); - - const options = {region: {}}; - - cases(RUNTIME.ffi.isOption, 'Option', get(rawData, 'region'), { - none: function () {}, - some: function (r) { - options.region = r; - } - }); + console.log("test123"); + console.log(region); + const options = {region: region}; return { data: data, From 59462a282ec27c55d56d7072d7e32c89cbb3c069 Mon Sep 17 00:00:00 2001 From: schornb <55115049+schornb@users.noreply.github.com> Date: Sat, 22 May 2021 23:02:10 -0400 Subject: [PATCH 24/29] fixing change region --- src/web/arr/trove/chart.arr | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/web/arr/trove/chart.arr b/src/web/arr/trove/chart.arr index bc2edc8a5..1dcf87e07 100644 --- a/src/web/arr/trove/chart.arr +++ b/src/web/arr/trove/chart.arr @@ -431,7 +431,10 @@ data DataSeries: | geochart-series(obj :: GeoChartSeries) with: is-single: true, contr: {(): geochart-series}, - region: region-method, + method region(self, region :: String): + geochart-series(self.obj.{ + region: region}) + end sharing: method _output(self): get-vs-from-img("DataSeries", render-chart(self).get-image()) From 5c5b092479a1d4cbb508297f60e437f6dde5dc45 Mon Sep 17 00:00:00 2001 From: schornb <55115049+schornb@users.noreply.github.com> Date: Sun, 23 May 2021 11:09:25 -0400 Subject: [PATCH 25/29] change color to value --- src/web/js/trove/chart-lib.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/js/trove/chart-lib.js b/src/web/js/trove/chart-lib.js index 8dbc657d1..2ee4a4f73 100644 --- a/src/web/js/trove/chart-lib.js +++ b/src/web/js/trove/chart-lib.js @@ -472,7 +472,7 @@ const data = new google.visualization.DataTable(); const region = get(rawData, 'region'); data.addColumn('string', 'Region'); - data.addColumn('number', "Color"); + data.addColumn('number', "Value"); data.addRows(table.map(row => [row[0], toFixnum(row[1])])); console.log("test123"); console.log(region); From aef51580f0ee03df11495f4edce4ddf396e6c2f5 Mon Sep 17 00:00:00 2001 From: schornb <55115049+schornb@users.noreply.github.com> Date: Tue, 18 Jan 2022 22:00:46 -0500 Subject: [PATCH 26/29] changed only files that needed changes --- src/web/arr/trove/chart.arr | 8 +- src/web/js/trove/chart-lib.js | 1565 +++++++++++++++++---------------- 2 files changed, 830 insertions(+), 743 deletions(-) diff --git a/src/web/arr/trove/chart.arr b/src/web/arr/trove/chart.arr index 1dcf87e07..819a79677 100644 --- a/src/web/arr/trove/chart.arr +++ b/src/web/arr/trove/chart.arr @@ -784,15 +784,13 @@ fun labeled-histogram-from-list(labels :: List, values :: List) end fun geochart-from-list( - region-labels :: List, - values :: List) -> DataSeries block: + region-labels :: P.LoS, + values :: P.LoN) -> DataSeries block: region-length = region-labels.length() values-length = values.length() when region-length <> values-length: raise("geochart: region-labels and values should have the same length") end - values.each(check-num) - region-labels.each(check-string) default-geochart-series.{ tab: to-table2(region-labels, values) } ^ geochart-series @@ -1253,4 +1251,4 @@ from-list = { labeled-box-plot: labeled-box-plot-from-list, box-plot: box-plot-from-list, geochart: geochart-from-list, -} +} \ No newline at end of file diff --git a/src/web/js/trove/chart-lib.js b/src/web/js/trove/chart-lib.js index 2ee4a4f73..0ac1c6a65 100644 --- a/src/web/js/trove/chart-lib.js +++ b/src/web/js/trove/chart-lib.js @@ -1,451 +1,518 @@ ({ - requires: [ - { 'import-type': 'builtin', 'name': 'image-lib' }, - ], - nativeRequires: [ - 'pyret-base/js/js-numbers', - 'google-charts', - ], + requires: [{ "import-type": "builtin", name: "image-lib" }], + nativeRequires: ["pyret-base/js/js-numbers", "google-charts"], provides: { values: { - 'pie-chart': "tany", - 'bar-chart': "tany", - 'histogram': "tany", - 'box-plot': "tany", - 'plot': "tany", - 'geochart': "tany" - } + "pie-chart": "tany", + "bar-chart": "tany", + histogram: "tany", + "box-plot": "tany", + plot: "tany", + geochart: "tany", + }, }, - theModule: function (RUNTIME, NAMESPACE, uri, IMAGELIB, jsnums , google) { - 'use strict'; + theModule: function (RUNTIME, NAMESPACE, uri, IMAGELIB, jsnums, google) { + "use strict"; - // Load google library via editor.html to avoid loading issues + // Load google library via editor.html to avoid loading issues - //const google = _google.google; - const isTrue = RUNTIME.isPyretTrue; - const get = RUNTIME.getField; - const toFixnum = jsnums.toFixnum; - const cases = RUNTIME.ffi.cases; + //const google = _google.google; + const isTrue = RUNTIME.isPyretTrue; + const get = RUNTIME.getField; + const toFixnum = jsnums.toFixnum; + const cases = RUNTIME.ffi.cases; - var IMAGE = get(IMAGELIB, "internal"); + var IMAGE = get(IMAGELIB, "internal"); - google.charts.load('current', {'packages' : ['corechart', 'geochart'], -'mapsApiKey': 'AIzaSyD-9tSrke72PouQMnMX-a7eZSW0jkFMBWY'}); + google.charts.load("current", { + packages: ["corechart", "geochart"], + mapsApiKey: "AIzaSyD-9tSrke72PouQMnMX-a7eZSW0jkFMBWY", + }); - ////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// - function getPrettyNumToStringDigits(d) { - // this accepts Pyret num - return n => - jsnums.toStringDigits(n, d, RUNTIME.NumberErrbacks).replace(/\.?0*$/, ''); - } + function getPrettyNumToStringDigits(d) { + // this accepts Pyret num + return (n) => + jsnums + .toStringDigits(n, d, RUNTIME.NumberErrbacks) + .replace(/\.?0*$/, ""); + } - const prettyNumToStringDigits5 = getPrettyNumToStringDigits(5); + const prettyNumToStringDigits5 = getPrettyNumToStringDigits(5); - function convertColor(v) { - function p(pred, name) { - return val => { - RUNTIME.makeCheckType(pred, name)(val); - return val; + function convertColor(v) { + function p(pred, name) { + return (val) => { + RUNTIME.makeCheckType(pred, name)(val); + return val; }; - } + } - const colorDb = IMAGE.colorDb; - const _checkColor = p(IMAGE.isColorOrColorString, 'Color'); + const colorDb = IMAGE.colorDb; + const _checkColor = p(IMAGE.isColorOrColorString, "Color"); - function checkColor(val) { + function checkColor(val) { let aColor = _checkColor(val); if (colorDb.get(aColor)) { - aColor = colorDb.get(aColor); + aColor = colorDb.get(aColor); } return aColor; - } + } - function rgb2hex(rgb){ - // From http://jsfiddle.net/Mottie/xcqpF/1/light/ - rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i); - return (rgb && rgb.length === 4) ? "#" + - ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) + - ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) + - ("0" + parseInt(rgb[3],10).toString(16)).slice(-2) : ''; + function rgb2hex(rgb) { + // From http://jsfiddle.net/Mottie/xcqpF/1/light/ + rgb = rgb.match( + /^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i + ); + return rgb && rgb.length === 4 + ? "#" + + ("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) + + ("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) + + ("0" + parseInt(rgb[3], 10).toString(16)).slice(-2) + : ""; + } + return rgb2hex(IMAGE.colorString(checkColor(v))); } - return rgb2hex(IMAGE.colorString(checkColor(v))); - } - - ////////////////////////////////////////////////////////////////////////////// - - function getNewWindow(xMinC, xMaxC, yMinC, yMaxC, numSamplesC) { - return cases(RUNTIME.ffi.isOption, 'Option', - RUNTIME.string_to_number(xMinC.val()), { - none: function () { - xMinC.addClass('error-bg'); - xMinC.removeClass('ok-bg'); - return null; - }, - some: function (xMinVal) { - xMinC.removeClass('error-bg'); - xMinC.addClass('ok-bg'); - return cases(RUNTIME.ffi.isOption, 'Option', - RUNTIME.string_to_number(xMaxC.val()), { + + ////////////////////////////////////////////////////////////////////////////// + + function getNewWindow(xMinC, xMaxC, yMinC, yMaxC, numSamplesC) { + return cases( + RUNTIME.ffi.isOption, + "Option", + RUNTIME.string_to_number(xMinC.val()), + { none: function () { - xMaxC.addClass('error-bg'); - xMaxC.removeClass('ok-bg'); + xMinC.addClass("error-bg"); + xMinC.removeClass("ok-bg"); return null; }, - some: function (xMaxVal) { - xMaxC.removeClass('error-bg'); - xMaxC.addClass('ok-bg'); - - if (jsnums.greaterThanOrEqual(xMinVal, xMaxVal, - RUNTIME.NumberErrbacks)) { - xMinC.addClass('error-bg'); - xMaxC.addClass('error-bg'); - xMinC.removeClass('ok-bg'); - xMaxC.removeClass('ok-bg'); - return null; - } - - return cases(RUNTIME.ffi.isOption, 'Option', - RUNTIME.string_to_number(yMinC.val()), { - none: function () { - yMinC.addClass('error-bg'); - yMinC.removeClass('ok-bg'); - return null; - }, - some: function (yMinVal) { - yMinC.removeClass('error-bg'); - yMinC.addClass('ok-bg'); - - return cases(RUNTIME.ffi.isOption, 'Option', - RUNTIME.string_to_number(yMaxC.val()), { - none: function () { - yMaxC.addClass('error-bg'); - yMaxC.removeClass('ok-bg'); + some: function (xMinVal) { + xMinC.removeClass("error-bg"); + xMinC.addClass("ok-bg"); + return cases( + RUNTIME.ffi.isOption, + "Option", + RUNTIME.string_to_number(xMaxC.val()), + { + none: function () { + xMaxC.addClass("error-bg"); + xMaxC.removeClass("ok-bg"); + return null; + }, + some: function (xMaxVal) { + xMaxC.removeClass("error-bg"); + xMaxC.addClass("ok-bg"); + + if ( + jsnums.greaterThanOrEqual( + xMinVal, + xMaxVal, + RUNTIME.NumberErrbacks + ) + ) { + xMinC.addClass("error-bg"); + xMaxC.addClass("error-bg"); + xMinC.removeClass("ok-bg"); + xMaxC.removeClass("ok-bg"); return null; - }, - some: function (yMaxVal) { - yMaxC.removeClass('error-bg'); - yMaxC.addClass('ok-bg'); - - if (jsnums.greaterThanOrEqual(xMinVal, xMaxVal, - RUNTIME.NumberErrbacks)) { - yMinC.addClass('error-bg'); - yMaxC.addClass('error-bg'); - yMinC.removeClass('ok-bg'); - yMaxC.removeClass('ok-bg'); - return null; - } + } - return cases(RUNTIME.ffi.isOption, 'Option', - RUNTIME.string_to_number(numSamplesC.val()), { + return cases( + RUNTIME.ffi.isOption, + "Option", + RUNTIME.string_to_number(yMinC.val()), + { none: function () { - numSamplesC.addClass('error-bg'); - numSamplesC.removeClass('ok-bg'); + yMinC.addClass("error-bg"); + yMinC.removeClass("ok-bg"); return null; }, - some: function (numSamplesVal) { - numSamplesC.removeClass('error-bg'); - numSamplesC.addClass('ok-bg'); - - if (!isTrue(RUNTIME.num_is_integer(numSamplesVal)) || - jsnums.lessThanOrEqual(numSamplesVal, 1, - RUNTIME.NumberErrbacks)) { - numSamplesC.addClass('error-bg'); - numSamplesC.removeClass('ok-bg'); - return null; - } - - return { - 'x-min': RUNTIME.ffi.makeSome(xMinVal), - 'x-max': RUNTIME.ffi.makeSome(xMaxVal), - 'y-min': RUNTIME.ffi.makeSome(yMinVal), - 'y-max': RUNTIME.ffi.makeSome(yMaxVal), - 'num-samples': numSamplesVal - }; - } - }); - } - }); + some: function (yMinVal) { + yMinC.removeClass("error-bg"); + yMinC.addClass("ok-bg"); + + return cases( + RUNTIME.ffi.isOption, + "Option", + RUNTIME.string_to_number(yMaxC.val()), + { + none: function () { + yMaxC.addClass("error-bg"); + yMaxC.removeClass("ok-bg"); + return null; + }, + some: function (yMaxVal) { + yMaxC.removeClass("error-bg"); + yMaxC.addClass("ok-bg"); + + if ( + jsnums.greaterThanOrEqual( + xMinVal, + xMaxVal, + RUNTIME.NumberErrbacks + ) + ) { + yMinC.addClass("error-bg"); + yMaxC.addClass("error-bg"); + yMinC.removeClass("ok-bg"); + yMaxC.removeClass("ok-bg"); + return null; + } + + return cases( + RUNTIME.ffi.isOption, + "Option", + RUNTIME.string_to_number(numSamplesC.val()), + { + none: function () { + numSamplesC.addClass("error-bg"); + numSamplesC.removeClass("ok-bg"); + return null; + }, + some: function (numSamplesVal) { + numSamplesC.removeClass("error-bg"); + numSamplesC.addClass("ok-bg"); + + if ( + !isTrue( + RUNTIME.num_is_integer(numSamplesVal) + ) || + jsnums.lessThanOrEqual( + numSamplesVal, + 1, + RUNTIME.NumberErrbacks + ) + ) { + numSamplesC.addClass("error-bg"); + numSamplesC.removeClass("ok-bg"); + return null; + } + + return { + "x-min": RUNTIME.ffi.makeSome(xMinVal), + "x-max": RUNTIME.ffi.makeSome(xMaxVal), + "y-min": RUNTIME.ffi.makeSome(yMinVal), + "y-max": RUNTIME.ffi.makeSome(yMaxVal), + "num-samples": numSamplesVal, + }; + }, + } + ); + }, + } + ); + }, + } + ); + }, } - }); - } - }); - } - }); - } - - ////////////////////////////////////////////////////////////////////////////// - - function axesNameMutator(options, globalOptions, _) { - const hAxis = ('hAxis' in options) ? options.hAxis : {}; - const vAxis = ('vAxis' in options) ? options.vAxis : {}; - hAxis.title = get(globalOptions, 'x-axis'); - vAxis.title = get(globalOptions, 'y-axis'); - $.extend(options, {hAxis: hAxis, vAxis: vAxis}); - } - - function yAxisRangeMutator(options, globalOptions, _) { - const vAxis = ('vAxis' in options) ? options.vAxis : {}; - const viewWindow = ('viewWindow' in vAxis) ? vAxis.viewWindow : {}; - - cases(RUNTIME.ffi.isOption, 'Option', get(globalOptions, 'y-min'), { - none: function () {}, - some: function (minValue) { - const v = toFixnum(minValue); - vAxis.minValue = v; - viewWindow.min = v; - } - }); - cases(RUNTIME.ffi.isOption, 'Option', get(globalOptions, 'y-max'), { - none: function () {}, - some: function (maxValue) { - const v = toFixnum(maxValue); - vAxis.maxValue = v; - viewWindow.max = v; - } - }); - vAxis.viewWindow = viewWindow; - $.extend(options, {vAxis: vAxis}); - } - - function xAxisRangeMutator(options, globalOptions, _) { - const hAxis = ('hAxis' in options) ? options.hAxis : {}; - const viewWindow = ('viewWindow' in hAxis) ? hAxis.viewWindow : {}; - - const minValue = get(globalOptions, 'x-min'); - const maxValue = get(globalOptions, 'x-max'); - - cases(RUNTIME.ffi.isOption, 'Option', minValue, { - none: function () {}, - some: function (realMinValue) { - hAxis.minValue = toFixnum(realMinValue); - viewWindow.min = toFixnum(realMinValue); - } - }); - cases(RUNTIME.ffi.isOption, 'Option', maxValue, { - none: function () {}, - some: function (realMaxValue) { - hAxis.maxValue = toFixnum(realMaxValue); - viewWindow.max = toFixnum(realMaxValue); - } - }); - - hAxis.viewWindow = viewWindow; - $.extend(options, {hAxis: hAxis}); - } - - ////////////////////////////////////////////////////////////////////////////// - - function pieChart(globalOptions, rawData) { - const table = get(rawData, 'tab'); - const data = new google.visualization.DataTable(); - data.addColumn('string', 'Label'); - data.addColumn('number', 'Value'); - data.addRows(table.map(row => [row[0], toFixnum(row[1])])); - return { - data: data, - options: { - slices: table.map(row => ({offset: toFixnum(row[2])})), - legend: { - alignment: 'end' - } - }, - chartType: google.visualization.PieChart, - onExit: defaultImageReturn, - }; - } - - function barChart(globalOptions, rawData) { - const table = get(rawData, 'tab'); - const legends = get(rawData, 'legends'); - const data = new google.visualization.DataTable(); - data.addColumn('string', 'Label'); - legends.forEach(legend => data.addColumn('number', legend)); - data.addRows(table.map(row => [row[0]].concat(row[1].map(n => toFixnum(n))))); - return { - data: data, - options: { - legend: { - position: isTrue(get(rawData, 'has-legend')) ? 'right' : 'none' + ); + }, } - }, - chartType: google.visualization.ColumnChart, - onExit: defaultImageReturn, - mutators: [axesNameMutator, yAxisRangeMutator], - }; - } - - function boxPlot(globalOptions, rawData) { - var table = get(rawData, 'tab'); - const dimension = toFixnum(get(rawData, 'height')); - const horizontal = get(rawData, 'horizontal'); - const showOutliers = get(rawData, 'show-outliers'); - const axisName = horizontal ? 'hAxis' : 'vAxis'; - const chartType = horizontal ? google.visualization.BarChart : google.visualization.ColumnChart; - const data = new google.visualization.DataTable(); - - const intervalOptions = { - lowNonOutlier: { - style: 'bars', - fillOpacity: 1, - color: '#777' - }, - highNonOutlier: { - style: 'bars', - fillOpacity: 1, - color: '#777' - } - }; - - - data.addColumn('string', 'Label'); - data.addColumn('number', 'Total'); - data.addColumn({id: 'firstQuartile', type: 'number', role: 'interval'}); - data.addColumn({id: 'median', type: 'number', role: 'interval'}); - data.addColumn({id: 'thirdQuartile', type: 'number', role: 'interval'}); - data.addColumn({id: 'highNonOutlier', type: 'number', role: 'interval'}); - data.addColumn({id: 'lowNonOutlier', type: 'number', role: 'interval'}); - data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}}); - - // NOTE(joe & emmanuel, Aug 2019): With the current chart library, it seems - // like we can only get outliers to work as a variable-length row if we - // have a single row of data. It's an explicit error to mix row lengths. - // Since the main use case where outliers matter is for single-column - // box-plots, this maintains existing behavior (if anyone was relying on - // multiple series), while adding the ability to render outliers for BS:DS. - if(table.length === 1 && showOutliers) { - var extraCols = table[0][8].length + table[0][9].length; - for(var i = 0; i < extraCols; i += 1) { - data.addColumn({id: 'outlier', type: 'number', role: 'interval'}); - } - intervalOptions['outlier'] = { 'style':'points', 'color':'grey', 'pointSize': 10, 'lineWidth': 0, 'fillOpacity': 0.3 }; + ); + } + + ////////////////////////////////////////////////////////////////////////////// + + function axesNameMutator(options, globalOptions, _) { + const hAxis = "hAxis" in options ? options.hAxis : {}; + const vAxis = "vAxis" in options ? options.vAxis : {}; + hAxis.title = get(globalOptions, "x-axis"); + vAxis.title = get(globalOptions, "y-axis"); + $.extend(options, { hAxis: hAxis, vAxis: vAxis }); } - else { - // NOTE(joe & emmanuel, Aug 2019 cont.): This forces the low and high - // whiskers to be equal to the min/max when there are multiple rows since we - // won't be able to render the outliers, and the whiskers need to cover - // the whole span of data. - table = table.map(function(row) { - row = row.slice(0, row.length); - // force whisker to be max/min - row[7] = row[2]; - row[6] = row[1]; - // empty outliers - row[9] = []; - row[8] = []; - return row; + + function yAxisRangeMutator(options, globalOptions, _) { + const vAxis = "vAxis" in options ? options.vAxis : {}; + const viewWindow = "viewWindow" in vAxis ? vAxis.viewWindow : {}; + + cases(RUNTIME.ffi.isOption, "Option", get(globalOptions, "y-min"), { + none: function () {}, + some: function (minValue) { + const v = toFixnum(minValue); + vAxis.minValue = v; + viewWindow.min = v; + }, + }); + cases(RUNTIME.ffi.isOption, "Option", get(globalOptions, "y-max"), { + none: function () {}, + some: function (maxValue) { + const v = toFixnum(maxValue); + vAxis.maxValue = v; + viewWindow.max = v; + }, + }); + vAxis.viewWindow = viewWindow; + $.extend(options, { vAxis: vAxis }); + } + + function xAxisRangeMutator(options, globalOptions, _) { + const hAxis = "hAxis" in options ? options.hAxis : {}; + const viewWindow = "viewWindow" in hAxis ? hAxis.viewWindow : {}; + + const minValue = get(globalOptions, "x-min"); + const maxValue = get(globalOptions, "x-max"); + + cases(RUNTIME.ffi.isOption, "Option", minValue, { + none: function () {}, + some: function (realMinValue) { + hAxis.minValue = toFixnum(realMinValue); + viewWindow.min = toFixnum(realMinValue); + }, + }); + cases(RUNTIME.ffi.isOption, "Option", maxValue, { + none: function () {}, + some: function (realMaxValue) { + hAxis.maxValue = toFixnum(realMaxValue); + viewWindow.max = toFixnum(realMaxValue); + }, }); + + hAxis.viewWindow = viewWindow; + $.extend(options, { hAxis: hAxis }); + } + + ////////////////////////////////////////////////////////////////////////////// + + function pieChart(globalOptions, rawData) { + const table = get(rawData, "tab"); + const data = new google.visualization.DataTable(); + data.addColumn("string", "Label"); + data.addColumn("number", "Value"); + data.addRows(table.map((row) => [row[0], toFixnum(row[1])])); + return { + data: data, + options: { + slices: table.map((row) => ({ offset: toFixnum(row[2]) })), + legend: { + alignment: "end", + }, + }, + chartType: google.visualization.PieChart, + onExit: defaultImageReturn, + }; } - const rowsToAdd = table.map(row => { - const summaryValues = row.slice(3, 8).map(n => toFixnum(n)); - let tooltip = `

${row[0]}

+ function barChart(globalOptions, rawData) { + const table = get(rawData, "tab"); + const legends = get(rawData, "legends"); + const data = new google.visualization.DataTable(); + data.addColumn("string", "Label"); + legends.forEach((legend) => data.addColumn("number", legend)); + data.addRows( + table.map((row) => [row[0]].concat(row[1].map((n) => toFixnum(n)))) + ); + return { + data: data, + options: { + legend: { + position: isTrue(get(rawData, "has-legend")) ? "right" : "none", + }, + }, + chartType: google.visualization.ColumnChart, + onExit: defaultImageReturn, + mutators: [axesNameMutator, yAxisRangeMutator], + }; + } + + function boxPlot(globalOptions, rawData) { + var table = get(rawData, "tab"); + const dimension = toFixnum(get(rawData, "height")); + const horizontal = get(rawData, "horizontal"); + const showOutliers = get(rawData, "show-outliers"); + const axisName = horizontal ? "hAxis" : "vAxis"; + const chartType = horizontal + ? google.visualization.BarChart + : google.visualization.ColumnChart; + const data = new google.visualization.DataTable(); + + const intervalOptions = { + lowNonOutlier: { + style: "bars", + fillOpacity: 1, + color: "#777", + }, + highNonOutlier: { + style: "bars", + fillOpacity: 1, + color: "#777", + }, + }; + + data.addColumn("string", "Label"); + data.addColumn("number", "Total"); + data.addColumn({ id: "firstQuartile", type: "number", role: "interval" }); + data.addColumn({ id: "median", type: "number", role: "interval" }); + data.addColumn({ id: "thirdQuartile", type: "number", role: "interval" }); + data.addColumn({ + id: "highNonOutlier", + type: "number", + role: "interval", + }); + data.addColumn({ id: "lowNonOutlier", type: "number", role: "interval" }); + data.addColumn({ type: "string", role: "tooltip", p: { html: true } }); + + // NOTE(joe & emmanuel, Aug 2019): With the current chart library, it seems + // like we can only get outliers to work as a variable-length row if we + // have a single row of data. It's an explicit error to mix row lengths. + // Since the main use case where outliers matter is for single-column + // box-plots, this maintains existing behavior (if anyone was relying on + // multiple series), while adding the ability to render outliers for BS:DS. + if (table.length === 1 && showOutliers) { + var extraCols = table[0][8].length + table[0][9].length; + for (var i = 0; i < extraCols; i += 1) { + data.addColumn({ id: "outlier", type: "number", role: "interval" }); + } + intervalOptions["outlier"] = { + style: "points", + color: "grey", + pointSize: 10, + lineWidth: 0, + fillOpacity: 0.3, + }; + } else { + // NOTE(joe & emmanuel, Aug 2019 cont.): This forces the low and high + // whiskers to be equal to the min/max when there are multiple rows since we + // won't be able to render the outliers, and the whiskers need to cover + // the whole span of data. + table = table.map(function (row) { + row = row.slice(0, row.length); + // force whisker to be max/min + row[7] = row[2]; + row[6] = row[1]; + // empty outliers + row[9] = []; + row[8] = []; + return row; + }); + } + + const rowsToAdd = table.map((row) => { + const summaryValues = row.slice(3, 8).map((n) => toFixnum(n)); + let tooltip = `

${row[0]}

minimum: ${row[2]}

maximum: ${row[1]}

first quartile: ${summaryValues[0]}

median: ${summaryValues[1]}

third quartile: ${summaryValues[2]}

`; - // ONLY if we're showing outliers, add whiskers to the tooltip - // (otherwise, the min/max ARE the bottom/top whiskers) - if(table.length == 1 && showOutliers) { - tooltip += - `

bottom whisker: ${summaryValues[4]}

+ // ONLY if we're showing outliers, add whiskers to the tooltip + // (otherwise, the min/max ARE the bottom/top whiskers) + if (table.length == 1 && showOutliers) { + tooltip += `

bottom whisker: ${summaryValues[4]}

top whisker: ${summaryValues[3]}

`; - } - return [row[0], toFixnum(dimension)] - .concat(summaryValues) - .concat([tooltip]) - .concat(row[9]).concat(row[8]); - }); - - data.addRows(rowsToAdd); - const options = { - tooltip: {isHtml: true}, - legend: {position: 'none'}, - lineWidth: 0, - intervals: { - barWidth: 0.25, - boxWidth: 0.8, - lineWidth: 2, - style: 'boxes' - }, - interval: intervalOptions, - dataOpacity: 0 - }; - /* NOTE(Oak): manually set the max value to coincide with bar charts' height - * so that the bar charts are concealed (the automatic value from Google - * is likely to screw this up) - */ - options[axisName] = { - maxValue: dimension, - viewWindow: { - max: dimension - }, - }; - return { - data: data, - options: options, - chartType: chartType, - onExit: defaultImageReturn, - mutators: [axesNameMutator], - }; - } - - function histogram(globalOptions, rawData) { - const table = get(rawData, 'tab'); - const data = new google.visualization.DataTable(); - - data.addColumn('string', 'Label'); - data.addColumn('number', ''); - - var max, min; - var val = null; - var hasAtLeastTwoValues = false; - data.addRows(table.map(row => { - var valfix = toFixnum(row[1]); - if(val !== null && val !== valfix) { hasAtLeastTwoValues = true; } - if(val === null) { val = valfix; } - if(max === undefined) { max = valfix; } - if(min === undefined) { min = valfix; } - if(valfix > max) { max = valfix; } - if(valfix < min) { min = valfix; } - return [row[0], valfix]; - })); - - // set legend to none because there's only one data set - const options = {legend: {position: 'none'}, histogram: {}}; - - cases(RUNTIME.ffi.isOption, 'Option', get(rawData, 'bin-width'), { - none: function () {}, - some: function (binWidth) { - // NOTE(joe, aug 2019): The chart library has a bug for histograms with - // a single unique value (https://jsfiddle.net/L0y64fbo/2/), so thisi - // hackaround makes it so this case can't come up. - if(hasAtLeastTwoValues) { - options.histogram.bucketSize = toFixnum(binWidth); } - } - }); + return [row[0], toFixnum(dimension)] + .concat(summaryValues) + .concat([tooltip]) + .concat(row[9]) + .concat(row[8]); + }); - cases(RUNTIME.ffi.isOption, 'Option', get(rawData, 'max-num-bins'), { - none: function () {}, - some: function (maxNumBins) { - options.histogram.maxNumBuckets = toFixnum(maxNumBins); - } - }); + data.addRows(rowsToAdd); + const options = { + tooltip: { isHtml: true }, + legend: { position: "none" }, + lineWidth: 0, + intervals: { + barWidth: 0.25, + boxWidth: 0.8, + lineWidth: 2, + style: "boxes", + }, + interval: intervalOptions, + dataOpacity: 0, + }; + /* NOTE(Oak): manually set the max value to coincide with bar charts' height + * so that the bar charts are concealed (the automatic value from Google + * is likely to screw this up) + */ + options[axisName] = { + maxValue: dimension, + viewWindow: { + max: dimension, + }, + }; + return { + data: data, + options: options, + chartType: chartType, + onExit: defaultImageReturn, + mutators: [axesNameMutator], + }; + } - cases(RUNTIME.ffi.isOption, 'Option', get(rawData, 'min-num-bins'), { - none: function () { - if(options.histogram.bucketSize !== undefined) { - options.histogram.minNumBuckets = Math.floor((max - min) / options.histogram.bucketSize) + 1; - } - }, - some: function (minNumBins) { - options.histogram.minNumBuckets = toFixnum(minNumBins); - } - }); + function histogram(globalOptions, rawData) { + const table = get(rawData, "tab"); + const data = new google.visualization.DataTable(); + + data.addColumn("string", "Label"); + data.addColumn("number", ""); + + var max, min; + var val = null; + var hasAtLeastTwoValues = false; + data.addRows( + table.map((row) => { + var valfix = toFixnum(row[1]); + if (val !== null && val !== valfix) { + hasAtLeastTwoValues = true; + } + if (val === null) { + val = valfix; + } + if (max === undefined) { + max = valfix; + } + if (min === undefined) { + min = valfix; + } + if (valfix > max) { + max = valfix; + } + if (valfix < min) { + min = valfix; + } + return [row[0], valfix]; + }) + ); + + // set legend to none because there's only one data set + const options = { legend: { position: "none" }, histogram: {} }; + + cases(RUNTIME.ffi.isOption, "Option", get(rawData, "bin-width"), { + none: function () {}, + some: function (binWidth) { + // NOTE(joe, aug 2019): The chart library has a bug for histograms with + // a single unique value (https://jsfiddle.net/L0y64fbo/2/), so thisi + // hackaround makes it so this case can't come up. + if (hasAtLeastTwoValues) { + options.histogram.bucketSize = toFixnum(binWidth); + } + }, + }); + + cases(RUNTIME.ffi.isOption, "Option", get(rawData, "max-num-bins"), { + none: function () {}, + some: function (maxNumBins) { + options.histogram.maxNumBuckets = toFixnum(maxNumBins); + }, + }); - /* + cases(RUNTIME.ffi.isOption, "Option", get(rawData, "min-num-bins"), { + none: function () { + if (options.histogram.bucketSize !== undefined) { + options.histogram.minNumBuckets = + Math.floor((max - min) / options.histogram.bucketSize) + 1; + } + }, + some: function (minNumBins) { + options.histogram.minNumBuckets = toFixnum(minNumBins); + }, + }); + + /* The main reason to use `x-min`, `x-max` is so that students can compare different histogram agaisnt each other. Setting `x-min`, `x-max` on `hAxis` is more accurate than setting it to `histogram` @@ -458,301 +525,318 @@ } */ - return { - data: data, - options: options, - chartType: google.visualization.Histogram, - onExit: defaultImageReturn, - mutators: [axesNameMutator, yAxisRangeMutator, xAxisRangeMutator], - }; - } - - function geoChart(globalOptions, rawData) { - const table = get(rawData, 'tab'); + return { + data: data, + options: options, + chartType: google.visualization.Histogram, + onExit: defaultImageReturn, + mutators: [axesNameMutator, yAxisRangeMutator, xAxisRangeMutator], + }; + } + + function geoChart(globalOptions, rawData) { + const table = get(rawData, "tab"); const data = new google.visualization.DataTable(); - const region = get(rawData, 'region'); - data.addColumn('string', 'Region'); - data.addColumn('number', "Value"); - data.addRows(table.map(row => [row[0], toFixnum(row[1])])); - console.log("test123"); - console.log(region); - const options = {region: region}; + const region = get(rawData, "region"); + data.addColumn("string", "Region"); + data.addColumn("number", "Value"); + data.addRows(table.map((row) => [row[0], toFixnum(row[1])])); + const options = { region: region }; return { - data: data, - options: options, - chartType: google.visualization.GeoChart, - onExit: defaultImageReturn, + data: data, + options: options, + chartType: google.visualization.GeoChart, + onExit: defaultImageReturn, }; - } - - - function plot(globalOptions, rawData) { - const scatters = get(rawData, 'scatters'); - const lines = get(rawData, 'lines'); - const data = new google.visualization.DataTable(); - data.addColumn('number', 'X'); - const combined = scatters.concat(lines); - const legends = []; - let cnt = 1; - combined.forEach(p => { - let legend = get(p, 'legend'); - if (legend === '') { - legend = `Plot ${cnt}`; - cnt++; - } - legends.push(legend); - data.addColumn('number', legend); - data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}}); - }); + } - combined.forEach((p, i) => { - /* + function plot(globalOptions, rawData) { + const scatters = get(rawData, "scatters"); + const lines = get(rawData, "lines"); + const data = new google.visualization.DataTable(); + data.addColumn("number", "X"); + const combined = scatters.concat(lines); + const legends = []; + let cnt = 1; + combined.forEach((p) => { + let legend = get(p, "legend"); + if (legend === "") { + legend = `Plot ${cnt}`; + cnt++; + } + legends.push(legend); + data.addColumn("number", legend); + data.addColumn({ type: "string", role: "tooltip", p: { html: true } }); + }); + + combined.forEach((p, i) => { + /* x | n n n | y | n n n n n n n n n n n n i combined.length - i - 1 */ - const prefix = new Array(2 * i).fill(null); - const suffix = new Array(2 * (combined.length - i - 1)).fill(null); - const rowTemplate = [0].concat(prefix).concat([null, null]).concat(suffix); - data.addRows(get(p, 'ps').map(row => { - const currentRow = rowTemplate.slice(); - if (row.length != 0) { - currentRow[0] = toFixnum(row[0]); - currentRow[2*i + 1] = toFixnum(row[1]); - let labelRow = null; - if (row.length >= 3 && row[2] !== '') { - labelRow = `

label: ${row[2]}

`; - } else { - labelRow = ''; - } - currentRow[2*i + 2] = `

${legends[i]}

+ const prefix = new Array(2 * i).fill(null); + const suffix = new Array(2 * (combined.length - i - 1)).fill(null); + const rowTemplate = [0] + .concat(prefix) + .concat([null, null]) + .concat(suffix); + data.addRows( + get(p, "ps").map((row) => { + const currentRow = rowTemplate.slice(); + if (row.length != 0) { + currentRow[0] = toFixnum(row[0]); + currentRow[2 * i + 1] = toFixnum(row[1]); + let labelRow = null; + if (row.length >= 3 && row[2] !== "") { + labelRow = `

label: ${row[2]}

`; + } else { + labelRow = ""; + } + currentRow[2 * i + 2] = `

${legends[i]}

x: ${currentRow[0]}

-

y: ${currentRow[2*i + 1]}

+

y: ${currentRow[2 * i + 1]}

${labelRow}`; - } - return currentRow; - })); - }); + } + return currentRow; + }) + ); + }); - const options = { - tooltip: {isHtml: true}, - series: combined.map((p, i) => { - // are we using custom images instead of dots? - const hasImage = get(p, 'ps').filter(p => p[3]).length > 0; + const options = { + tooltip: { isHtml: true }, + series: combined.map((p, i) => { + // are we using custom images instead of dots? + const hasImage = get(p, "ps").filter((p) => p[3]).length > 0; - // scatters and then lines - const seriesOptions = {}; + // scatters and then lines + const seriesOptions = {}; - cases(RUNTIME.ffi.isOption, 'Option', get(p, 'color'), { - none: function () {}, - some: function (color) { - seriesOptions.color = convertColor(color); - } - }); - // If we have our own image, make the point small and transparent - if (i < scatters.length) { - $.extend(seriesOptions, { - pointSize: hasImage? 1 :toFixnum(get(p, 'point-size')), - lineWidth: 0, - dataOpacity: hasImage? 0 : 1, + cases(RUNTIME.ffi.isOption, "Option", get(p, "color"), { + none: function () {}, + some: function (color) { + seriesOptions.color = convertColor(color); + }, }); - } - return seriesOptions; - }), - legend: {position: 'bottom',}, - crosshair: {trigger: 'selection'} - }; - - if (isTrue(get(globalOptions, 'interact'))) { - $.extend(options, { - chartArea: { - left: '12%', - width: '56%', - } - }); - } + // If we have our own image, make the point small and transparent + if (i < scatters.length) { + $.extend(seriesOptions, { + pointSize: hasImage ? 1 : toFixnum(get(p, "point-size")), + lineWidth: 0, + dataOpacity: hasImage ? 0 : 1, + }); + } + return seriesOptions; + }), + legend: { position: "bottom" }, + crosshair: { trigger: "selection" }, + }; - return { - data: data, - options: options, - chartType: google.visualization.LineChart, - onExit: (restarter, result) => { - let svg = result.chart.container.querySelector('svg'); - let svg_xml = (new XMLSerializer()).serializeToString(svg); - let dataURI = "data:image/svg+xml;base64," + btoa(svg_xml); - imageReturn( - dataURI, - restarter, - RUNTIME.ffi.makeRight) - }, - mutators: [axesNameMutator, yAxisRangeMutator, xAxisRangeMutator], - overlay: (overlay, restarter, chart, container) => { - overlay.css({ - width: '30%', - position: 'absolute', - right: '0px', - top: '50%', - transform: 'translateY(-50%)', + if (isTrue(get(globalOptions, "interact"))) { + $.extend(options, { + chartArea: { + left: "12%", + width: "56%", + }, }); + } - const controller = $('
'); - - overlay.append(controller); - - const inputSize = 16; - - const xMinC = $('', { - 'class': 'controller', - type: 'text', - placeholder: 'x-min', - }).attr('size', inputSize); - const xMaxC = $('', { - 'class': 'controller', - type: 'text', - placeholder: 'x-max', - }).attr('size', inputSize); - const yMinC = $('', { - 'class': 'controller', - type: 'text', - placeholder: 'y-min', - }).attr('size', inputSize); - const yMaxC = $('', { - 'class': 'controller', - type: 'text', - placeholder: 'y-max', - }).attr('size', inputSize); - const numSamplesC = $('', { - 'class': 'controller', - type: 'text', - placeholder: '#samples', - }).attr('size', inputSize).val('2'); - // dummy value so that a new window can be constructed correctly - // when numSamplesC is not used. The value must be at least 2 - - const redrawC = $('