first commit
This commit is contained in:
42
public/bower_components/c3/.bower.json
vendored
Executable file
42
public/bower_components/c3/.bower.json
vendored
Executable file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "c3",
|
||||
"main": [
|
||||
"c3.css",
|
||||
"c3.js"
|
||||
],
|
||||
"homepage": "https://github.com/masayuki0812/c3",
|
||||
"authors": [
|
||||
"Masayuki Tanaka <masayuki0812@mac.com>"
|
||||
],
|
||||
"description": "D3-based reusable chart library",
|
||||
"keywords": [
|
||||
"chart",
|
||||
"d3"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"htdocs",
|
||||
"spec",
|
||||
"src",
|
||||
"package.json",
|
||||
"component.json",
|
||||
"Gruntfile.*"
|
||||
],
|
||||
"dependencies": {
|
||||
"d3": "~3.5.0"
|
||||
},
|
||||
"version": "0.4.11",
|
||||
"_release": "0.4.11",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "0.4.11",
|
||||
"commit": "223404a79246c61d150d8a209dbdc81f6955083b"
|
||||
},
|
||||
"_source": "https://github.com/masayuki0812/c3.git",
|
||||
"_target": "^0.4.11",
|
||||
"_originalSource": "c3",
|
||||
"_direct": true
|
||||
}
|
||||
40
public/bower_components/c3/CONTRIBUTING.md
vendored
Executable file
40
public/bower_components/c3/CONTRIBUTING.md
vendored
Executable file
@@ -0,0 +1,40 @@
|
||||
## Filing an issue
|
||||
|
||||
Before filing an issue, please [search the queue](https://github.com/masayuki0812/c3/issues) to make sure it hasn't already been reported.
|
||||
|
||||
If a bug, please include the following —
|
||||
|
||||
1. What version of C3?
|
||||
1. What browsers have you confirmed it in?
|
||||
1. Can you isolate the issue by providing a jsFiddle demonstrating it in a minimalist capacity?
|
||||
|
||||
Please *do not* ask for support using the issue queue. For support, please ask [on chat](https://gitter.im/masayuki0812/c3) or [the mailing list](groups.google.com/forum/#!forum/c3js).
|
||||
|
||||
##Building C3 from sources
|
||||
|
||||
1. **Clone the repo from GitHub**
|
||||
|
||||
git clone https://github.com/masayuki0812/c3.git
|
||||
cd c3
|
||||
|
||||
2. **Acquire build dependencies.** Make sure you have [Node.js](http://nodejs.org/) installed on your workstation. This is only needed to _build_ C3 from sources. C3 itself has no dependency on Node.js once it is built. Now run:
|
||||
|
||||
npm install -g grunt-cli
|
||||
npm install
|
||||
|
||||
The first `npm` command sets up the popular [Grunt](http://gruntjs.com/) build tool. You might need to run this command with `sudo` if you're on Linux or Mac OS X, or in an Administrator command prompt on Windows. The second `npm` command fetches the remaining build dependencies.
|
||||
|
||||
3. **Run the build tool**
|
||||
|
||||
grunt
|
||||
|
||||
Now you'll find the built files in `c3.js`, `c3.min.js`, `c3.css` & `c3.min.css`.
|
||||
|
||||
## Running the tests
|
||||
The `grunt` script will automatically run the specification suite and report its results.
|
||||
|
||||
Or, if you want to run the specs in a browser (e.g., for debugging), simply open `spec/runner.html` in your browser.
|
||||
|
||||
## Contributing your changes
|
||||
|
||||
Add something about PRs here, indicate that PRs should not bump the version number & the build output files (`c3.js`, `c3.min.js`, `c3.css` & `c3.min.css`) should be excluded
|
||||
20
public/bower_components/c3/LICENSE
vendored
Executable file
20
public/bower_components/c3/LICENSE
vendored
Executable file
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Masayuki Tanaka
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
53
public/bower_components/c3/README.md
vendored
Executable file
53
public/bower_components/c3/README.md
vendored
Executable file
@@ -0,0 +1,53 @@
|
||||
c3 [](https://travis-ci.org/c3js/c3) [](https://david-dm.org/c3js/c3) [](https://david-dm.org/c3js/c3#info=devDependencies) [](https://github.com/c3js/c3/blob/master/LICENSE) [](https://codecov.io/github/c3js/c3?branch=master)
|
||||
==
|
||||
|
||||
c3 is a D3-based reusable chart library that enables deeper integration of charts into web applications.
|
||||
|
||||
Follow the link for more information: [http://c3js.org](http://c3js.org/)
|
||||
|
||||
## Tutorial and Examples
|
||||
|
||||
+ [Getting Started](http://c3js.org/gettingstarted.html)
|
||||
+ [Examples](http://c3js.org/examples.html)
|
||||
|
||||
Additional samples can be found in this repository:
|
||||
+ [https://github.com/c3js/c3/tree/master/htdocs/samples](https://github.com/c3js/c3/tree/master/htdocs/samples)
|
||||
|
||||
You can run these samples as:
|
||||
```
|
||||
$ cd c3/htdocs
|
||||
$ python -m SimpleHTTPServer 8080
|
||||
```
|
||||
|
||||
## Google Group
|
||||
For general C3.js-related discussion, please visit our [Google Group at https://groups.google.com/forum/#!forum/c3js](https://groups.google.com/forum/#!forum/c3js).
|
||||
|
||||
## Gitter
|
||||
[](https://gitter.im/c3js/c3?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
## Using the issue queue
|
||||
The [issue queue](https://github.com/c3js/c3/issues) is to be used for reporting defects and problems with C3.js, in addition to feature requests and ideas. It is **not** a catch-all support forum. **For general support enquiries, please use the [Google Group](https://groups.google.com/forum/#!forum/c3js) at https://groups.google.com/forum/#!forum/c3js.** All questions involving the interplay between C3.js and any other library (such as AngularJS) should be posted there first!
|
||||
|
||||
Before reporting an issue, please do the following:
|
||||
|
||||
1. [Search for existing issues](https://github.com/c3js/c3/issues) to ensure you're not posting a duplicate.
|
||||
|
||||
1. [Search the Google Group](https://groups.google.com/forum/#!forum/c3js) to ensure it hasn't been addressed there already.
|
||||
|
||||
1. Create a JSFiddle or Plunkr highlighting the issue. Please don't include any unnecessary dependencies so we can isolate that the issue is in fact with C3. *Please be advised that custom CSS can modify C3.js output!*
|
||||
|
||||
1. When posting the issue, please use a descriptive title and include the version of C3 (or, if cloning from Git, the commit hash — C3 is under active development and the master branch contains the latest dev commits!), along with any platform/browser/OS information that may be relevant.
|
||||
|
||||
## Pull requests
|
||||
Pull requests are welcome, though please post an issue first to see whether such a change is desirable.
|
||||
If you choose to submit a pull request, please do not bump the version number unless asked to, and please include test cases for any new features. Squash all your commits as well, please.
|
||||
|
||||
## Playground
|
||||
Please fork this fiddle:
|
||||
+ [http://jsfiddle.net/masayuki0812/7kYJu/](http://jsfiddle.net/masayuki0812/7kYJu/)
|
||||
|
||||
## Dependency
|
||||
+ [D3.js](https://github.com/mbostock/d3) `~3.5.0`
|
||||
|
||||
## License
|
||||
MIT
|
||||
31
public/bower_components/c3/bower.json
vendored
Executable file
31
public/bower_components/c3/bower.json
vendored
Executable file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "c3",
|
||||
"main": [
|
||||
"c3.css",
|
||||
"c3.js"
|
||||
],
|
||||
"homepage": "https://github.com/masayuki0812/c3",
|
||||
"authors": [
|
||||
"Masayuki Tanaka <masayuki0812@mac.com>"
|
||||
],
|
||||
"description": "D3-based reusable chart library",
|
||||
"keywords": [
|
||||
"chart",
|
||||
"d3"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"htdocs",
|
||||
"spec",
|
||||
"src",
|
||||
"package.json",
|
||||
"component.json",
|
||||
"Gruntfile.*"
|
||||
],
|
||||
"dependencies": {
|
||||
"d3": "~3.5.0"
|
||||
}
|
||||
}
|
||||
167
public/bower_components/c3/c3.css
vendored
Executable file
167
public/bower_components/c3/c3.css
vendored
Executable file
@@ -0,0 +1,167 @@
|
||||
/*-- Chart --*/
|
||||
.c3 svg {
|
||||
font: 10px sans-serif;
|
||||
-webkit-tap-highlight-color: transparent; }
|
||||
|
||||
.c3 path, .c3 line {
|
||||
fill: none;
|
||||
stroke: #000; }
|
||||
|
||||
.c3 text {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none; }
|
||||
|
||||
.c3-legend-item-tile,
|
||||
.c3-xgrid-focus,
|
||||
.c3-ygrid,
|
||||
.c3-event-rect,
|
||||
.c3-bars path {
|
||||
shape-rendering: crispEdges; }
|
||||
|
||||
.c3-chart-arc path {
|
||||
stroke: #fff; }
|
||||
|
||||
.c3-chart-arc text {
|
||||
fill: #fff;
|
||||
font-size: 13px; }
|
||||
|
||||
/*-- Axis --*/
|
||||
/*-- Grid --*/
|
||||
.c3-grid line {
|
||||
stroke: #aaa; }
|
||||
|
||||
.c3-grid text {
|
||||
fill: #aaa; }
|
||||
|
||||
.c3-xgrid, .c3-ygrid {
|
||||
stroke-dasharray: 3 3; }
|
||||
|
||||
/*-- Text on Chart --*/
|
||||
.c3-text.c3-empty {
|
||||
fill: #808080;
|
||||
font-size: 2em; }
|
||||
|
||||
/*-- Line --*/
|
||||
.c3-line {
|
||||
stroke-width: 1px; }
|
||||
|
||||
/*-- Point --*/
|
||||
.c3-circle._expanded_ {
|
||||
stroke-width: 1px;
|
||||
stroke: white; }
|
||||
|
||||
.c3-selected-circle {
|
||||
fill: white;
|
||||
stroke-width: 2px; }
|
||||
|
||||
/*-- Bar --*/
|
||||
.c3-bar {
|
||||
stroke-width: 0; }
|
||||
|
||||
.c3-bar._expanded_ {
|
||||
fill-opacity: 0.75; }
|
||||
|
||||
/*-- Focus --*/
|
||||
.c3-target.c3-focused {
|
||||
opacity: 1; }
|
||||
|
||||
.c3-target.c3-focused path.c3-line, .c3-target.c3-focused path.c3-step {
|
||||
stroke-width: 2px; }
|
||||
|
||||
.c3-target.c3-defocused {
|
||||
opacity: 0.3 !important; }
|
||||
|
||||
/*-- Region --*/
|
||||
.c3-region {
|
||||
fill: steelblue;
|
||||
fill-opacity: .1; }
|
||||
|
||||
/*-- Brush --*/
|
||||
.c3-brush .extent {
|
||||
fill-opacity: .1; }
|
||||
|
||||
/*-- Select - Drag --*/
|
||||
/*-- Legend --*/
|
||||
.c3-legend-item {
|
||||
font-size: 12px; }
|
||||
|
||||
.c3-legend-item-hidden {
|
||||
opacity: 0.15; }
|
||||
|
||||
.c3-legend-background {
|
||||
opacity: 0.75;
|
||||
fill: white;
|
||||
stroke: lightgray;
|
||||
stroke-width: 1; }
|
||||
|
||||
/*-- Title --*/
|
||||
.c3-title {
|
||||
font: 14px sans-serif; }
|
||||
|
||||
/*-- Tooltip --*/
|
||||
.c3-tooltip-container {
|
||||
z-index: 10; }
|
||||
|
||||
.c3-tooltip {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
background-color: #fff;
|
||||
empty-cells: show;
|
||||
-webkit-box-shadow: 7px 7px 12px -9px #777777;
|
||||
-moz-box-shadow: 7px 7px 12px -9px #777777;
|
||||
box-shadow: 7px 7px 12px -9px #777777;
|
||||
opacity: 0.9; }
|
||||
|
||||
.c3-tooltip tr {
|
||||
border: 1px solid #CCC; }
|
||||
|
||||
.c3-tooltip th {
|
||||
background-color: #aaa;
|
||||
font-size: 14px;
|
||||
padding: 2px 5px;
|
||||
text-align: left;
|
||||
color: #FFF; }
|
||||
|
||||
.c3-tooltip td {
|
||||
font-size: 13px;
|
||||
padding: 3px 6px;
|
||||
background-color: #fff;
|
||||
border-left: 1px dotted #999; }
|
||||
|
||||
.c3-tooltip td > span {
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin-right: 6px; }
|
||||
|
||||
.c3-tooltip td.value {
|
||||
text-align: right; }
|
||||
|
||||
/*-- Area --*/
|
||||
.c3-area {
|
||||
stroke-width: 0;
|
||||
opacity: 0.2; }
|
||||
|
||||
/*-- Arc --*/
|
||||
.c3-chart-arcs-title {
|
||||
dominant-baseline: middle;
|
||||
font-size: 1.3em; }
|
||||
|
||||
.c3-chart-arcs .c3-chart-arcs-background {
|
||||
fill: #e0e0e0;
|
||||
stroke: none; }
|
||||
|
||||
.c3-chart-arcs .c3-chart-arcs-gauge-unit {
|
||||
fill: #000;
|
||||
font-size: 16px; }
|
||||
|
||||
.c3-chart-arcs .c3-chart-arcs-gauge-max {
|
||||
fill: #777; }
|
||||
|
||||
.c3-chart-arcs .c3-chart-arcs-gauge-min {
|
||||
fill: #777; }
|
||||
|
||||
.c3-chart-arc .c3-gauge-value {
|
||||
fill: #000;
|
||||
/* font-size: 28px !important;*/ }
|
||||
8202
public/bower_components/c3/c3.js
vendored
Executable file
8202
public/bower_components/c3/c3.js
vendored
Executable file
File diff suppressed because it is too large
Load Diff
1
public/bower_components/c3/c3.min.css
vendored
Executable file
1
public/bower_components/c3/c3.min.css
vendored
Executable file
@@ -0,0 +1 @@
|
||||
.c3 svg{font:10px sans-serif;-webkit-tap-highlight-color:transparent}.c3 line,.c3 path{fill:none;stroke:#000}.c3 text{-webkit-user-select:none;-moz-user-select:none;user-select:none}.c3-bars path,.c3-event-rect,.c3-legend-item-tile,.c3-xgrid-focus,.c3-ygrid{shape-rendering:crispEdges}.c3-chart-arc path{stroke:#fff}.c3-chart-arc text{fill:#fff;font-size:13px}.c3-grid line{stroke:#aaa}.c3-grid text{fill:#aaa}.c3-xgrid,.c3-ygrid{stroke-dasharray:3 3}.c3-text.c3-empty{fill:gray;font-size:2em}.c3-line{stroke-width:1px}.c3-circle._expanded_{stroke-width:1px;stroke:#fff}.c3-selected-circle{fill:#fff;stroke-width:2px}.c3-bar{stroke-width:0}.c3-bar._expanded_{fill-opacity:.75}.c3-target.c3-focused{opacity:1}.c3-target.c3-focused path.c3-line,.c3-target.c3-focused path.c3-step{stroke-width:2px}.c3-target.c3-defocused{opacity:.3!important}.c3-region{fill:#4682b4;fill-opacity:.1}.c3-brush .extent{fill-opacity:.1}.c3-legend-item{font-size:12px}.c3-legend-item-hidden{opacity:.15}.c3-legend-background{opacity:.75;fill:#fff;stroke:#d3d3d3;stroke-width:1}.c3-title{font:14px sans-serif}.c3-tooltip-container{z-index:10}.c3-tooltip{border-collapse:collapse;border-spacing:0;background-color:#fff;empty-cells:show;-webkit-box-shadow:7px 7px 12px -9px #777;-moz-box-shadow:7px 7px 12px -9px #777;box-shadow:7px 7px 12px -9px #777;opacity:.9}.c3-tooltip tr{border:1px solid #CCC}.c3-tooltip th{background-color:#aaa;font-size:14px;padding:2px 5px;text-align:left;color:#FFF}.c3-tooltip td{font-size:13px;padding:3px 6px;background-color:#fff;border-left:1px dotted #999}.c3-tooltip td>span{display:inline-block;width:10px;height:10px;margin-right:6px}.c3-tooltip td.value{text-align:right}.c3-area{stroke-width:0;opacity:.2}.c3-chart-arcs-title{dominant-baseline:middle;font-size:1.3em}.c3-chart-arcs .c3-chart-arcs-background{fill:#e0e0e0;stroke:none}.c3-chart-arcs .c3-chart-arcs-gauge-unit{fill:#000;font-size:16px}.c3-chart-arcs .c3-chart-arcs-gauge-max,.c3-chart-arcs .c3-chart-arcs-gauge-min{fill:#777}.c3-chart-arc .c3-gauge-value{fill:#000}
|
||||
6
public/bower_components/c3/c3.min.js
vendored
Executable file
6
public/bower_components/c3/c3.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
116
public/bower_components/c3/extensions/chart-bubble/bubble.js
vendored
Executable file
116
public/bower_components/c3/extensions/chart-bubble/bubble.js
vendored
Executable file
@@ -0,0 +1,116 @@
|
||||
(function() {
|
||||
var extra = {};
|
||||
|
||||
c3.chart.internal.fn.additionalConfig = {
|
||||
data_pairs: [],
|
||||
};
|
||||
|
||||
c3.chart.internal.fn.beforeInit = function (config) {
|
||||
|
||||
var that = this;
|
||||
|
||||
// update internals only when chart type is "bubble"
|
||||
if (config.data.type !== 'bubble') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set extra to ba able to be used in other part
|
||||
this.extra = extra;
|
||||
|
||||
extra.getKey = function (x, y) {
|
||||
return x + '::' + y;
|
||||
};
|
||||
|
||||
this.config.data_type = 'scatter';
|
||||
|
||||
this.config.axis_x_padding = 0;
|
||||
this.config.axis_y_padding = 0;
|
||||
this.config.axis_x_tick_centered = true;
|
||||
this.config.axis_x_tick_format = function (d) {
|
||||
return extra.names[d];
|
||||
};
|
||||
this.config.axis_y_tick_format = function (d) {
|
||||
return extra.names[d];
|
||||
};
|
||||
|
||||
if (!config.color || !config.color.pattern) {
|
||||
this.config.color_pattern = ['#1f77b4'];
|
||||
}
|
||||
|
||||
this.config.point_r = function (d) {
|
||||
var names = extra.names, values = extra.values, base_length = extra.base_length,
|
||||
x = names[d.x], y = d.id,
|
||||
key = extra.getKey(x, y), value = !values[key] ? 0 : values[key],
|
||||
max, max_r, max_area, a, area, r;
|
||||
|
||||
if (!base_length) {
|
||||
base_length = extra.base_length = d3.min([
|
||||
that.svg.select('.c3-axis.c3-axis-y path').node().getTotalLength(),
|
||||
that.svg.select('.c3-axis.c3-axis-x path').node().getTotalLength(),
|
||||
]);
|
||||
}
|
||||
|
||||
max = d3.max(Object.keys(values).map(function (key) { return values[key]; }));
|
||||
max_r = (base_length / (names.length * 2));
|
||||
max_area = max_r * max_r * Math.PI;
|
||||
|
||||
a = max_area / max;
|
||||
|
||||
area = value * a;
|
||||
r = Math.sqrt(area / Math.PI);
|
||||
|
||||
return r;
|
||||
};
|
||||
this.config.point_sensitivity = 25;
|
||||
this.config.point_focus_expand_enabled = false;
|
||||
|
||||
this.config.legend_show = false;
|
||||
|
||||
if (!config.tooltip || !config.tooltip.contents) {
|
||||
this.config.tooltip_contents = function (d, defaultTitleFormat, defaultValueFormat, color) {
|
||||
var x = extra.names[d[0].x], y = d[0].name, v = extra.values[extra.getKey(x, y)], text;
|
||||
|
||||
text = "<table class='" + this.CLASS.tooltip + "'>";
|
||||
text += "<tr><th colspan='2'>" + x + " / " + y + "</th></tr>";
|
||||
text += "<tr><td class='value'>" + (!v ? 0 : v) + "</td></tr>";
|
||||
text += "</table>";
|
||||
|
||||
return text;
|
||||
};
|
||||
}
|
||||
|
||||
// construct bubble chart data and setup config based on the values
|
||||
|
||||
var xs = this.config.data_pairs.map(function (pair) { return pair.x; }),
|
||||
ys = this.config.data_pairs.map(function (pair) { return pair.y; });
|
||||
|
||||
extra.names = d3.set(xs.concat(ys)).values().sort();
|
||||
|
||||
this.config.axis_y_tick_values = extra.names.map(function (name, i) { return i; });
|
||||
|
||||
var data_xs = {};
|
||||
extra.names.forEach(function (name) {
|
||||
data_xs[name] = name + '_x';
|
||||
});
|
||||
var data_columns_xs = Object.keys(data_xs).map(function (key) {
|
||||
return [data_xs[key]].concat(extra.names.map(function (name, i) { return i; }));
|
||||
});
|
||||
var data_columns_values = extra.names.map(function (name, i) {
|
||||
return [name].concat(extra.names.map(function (name) { return i; }));
|
||||
});
|
||||
this.config.data_xs = data_xs;
|
||||
this.config.data_columns = data_columns_xs.concat(data_columns_values);
|
||||
|
||||
var values = {};
|
||||
this.config.data_pairs.forEach(function (pair) {
|
||||
if (!pair.x || !pair.y) {
|
||||
throw "x and y are required in data.";
|
||||
}
|
||||
values[extra.getKey(pair.x, pair.y)] = pair.value;
|
||||
});
|
||||
extra.values = values;
|
||||
|
||||
this.config.axis_x_min = this.config.axis_y_min = -0.5;
|
||||
this.config.axis_x_max = this.config.axis_y_max = extra.names.length - 0.5;
|
||||
};
|
||||
})(window);
|
||||
38
public/bower_components/c3/extensions/chart-bubble/index.html
vendored
Executable file
38
public/bower_components/c3/extensions/chart-bubble/index.html
vendored
Executable file
@@ -0,0 +1,38 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="c3.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="chart"></div>
|
||||
|
||||
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
|
||||
<script src="c3.min.js"></script>
|
||||
<script src="bubble.js"></script>
|
||||
<script>
|
||||
var chart = c3.generate({
|
||||
data: {
|
||||
type: 'bubble',
|
||||
pairs: [
|
||||
{ x: 'Name_0', y: 'Name_0', value: 10000 },
|
||||
{ x: 'Name_0', y: 'Name_1', value: 20000 },
|
||||
{ x: 'Name_0', y: 'Name_2', value: 39990 },
|
||||
// { x: 'Name_1', y: 'Name_0', value: 5000 },
|
||||
{ x: 'Name_1', y: 'Name_1', value: 6000 },
|
||||
{ x: 'Name_1', y: 'Name_2', value: 50000 },
|
||||
{ x: 'Name_2', y: 'Name_0', value: 1000 },
|
||||
{ x: 'Name_2', y: 'Name_1', value: 2000 },
|
||||
{ x: 'Name_2', y: 'Name_2', value: 3000 },
|
||||
]
|
||||
},
|
||||
grid: {
|
||||
x: {
|
||||
show: true
|
||||
},
|
||||
y: {
|
||||
show: true
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
11
public/bower_components/c3/extensions/exporter/config.json
vendored
Executable file
11
public/bower_components/c3/extensions/exporter/config.json
vendored
Executable file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"js": [
|
||||
"../../bower_components/d3/d3.min.js",
|
||||
"../../c3.min.js"
|
||||
],
|
||||
"css": [
|
||||
"../../c3.css"
|
||||
],
|
||||
|
||||
"template": "<html><head><meta charset=\"utf-8\"><style>{0}</style></head><body><div id=\"chart\"></div></body></html>"
|
||||
}
|
||||
140
public/bower_components/c3/extensions/exporter/phantom-exporter.js
vendored
Executable file
140
public/bower_components/c3/extensions/exporter/phantom-exporter.js
vendored
Executable file
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* PNG\JPEG exporter for C3.js, version 0.2
|
||||
* (c) 2014 Yuval Bar-On
|
||||
*
|
||||
* usage: path/to/phantomjs output options [WxH]
|
||||
*
|
||||
*/
|
||||
|
||||
// useful python-styled string formatting, "hello {0}! Javascript is {1}".format("world", "awesome");
|
||||
if (!String.prototype.format) {
|
||||
String.prototype.format = function() {
|
||||
var args = arguments;
|
||||
return this.replace(/{(\d+)}/g, function(match, number) {
|
||||
return typeof args[number] != 'undefined'
|
||||
? args[number]
|
||||
: match
|
||||
;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// defaults
|
||||
var page = require('webpage').create(),
|
||||
fs = require('fs'),
|
||||
system = require('system'),
|
||||
config = JSON.parse( fs.read('config.json') ),
|
||||
output, size;
|
||||
|
||||
if (system.args.length < 3 ) {
|
||||
console.log('Usage: phantasm.js filename html [WxH]');
|
||||
phantom.exit(1);
|
||||
} else {
|
||||
out = system.args[1];
|
||||
opts = JSON.parse( system.args[2] );
|
||||
|
||||
if (system.args[3]) {
|
||||
var dimensions = system.args[3].split('x'),
|
||||
width = dimensions[0],
|
||||
height = dimensions[1];
|
||||
|
||||
function checkNum(check) {
|
||||
check = parseInt(check);
|
||||
if (!isNaN(check))
|
||||
return check;
|
||||
return false;
|
||||
}
|
||||
|
||||
width = checkNum(width);
|
||||
height = checkNum(height);
|
||||
|
||||
if (width && height) {
|
||||
page.viewportSize = {
|
||||
height: height,
|
||||
width: width
|
||||
}
|
||||
}
|
||||
|
||||
// fit chart size to img size, if undefined
|
||||
if (!opts.size) {
|
||||
opts.size = {
|
||||
"height": height,
|
||||
"width": width
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// check if size is defined in chart,
|
||||
// else apply defaults
|
||||
page.viewportSize = {
|
||||
height: (opts.size && opts.size.height) ? opts.size.height : 320,
|
||||
width: (opts.size && opts.size.width ) ? opts.size.width : 710,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
page.onResourceRequested = function(requestData, request) {
|
||||
console.log('::loading resource ', requestData['url']);
|
||||
};
|
||||
|
||||
// helpful debug functions
|
||||
page.onConsoleMessage = function(msg){
|
||||
console.log(msg);
|
||||
};
|
||||
|
||||
page.onError = function(msg, trace) {
|
||||
var msgStack = ['ERROR: ' + msg];
|
||||
|
||||
if (trace && trace.length) {
|
||||
msgStack.push('TRACE:');
|
||||
trace.forEach(function(t) {
|
||||
msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function +'")' : ''));
|
||||
});
|
||||
}
|
||||
|
||||
console.error(msgStack.join('\n'));
|
||||
};
|
||||
|
||||
// render page
|
||||
function injectVerify(script) {
|
||||
var req = page.injectJs(script);
|
||||
if (!req) {
|
||||
console.log( '\nError!\n' + script + ' not found!\n' );
|
||||
phantom.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
page.onLoadFinished = function() {
|
||||
console.log('::rendering');
|
||||
|
||||
for (var j in config.js) {
|
||||
injectVerify(config.js[j]);
|
||||
}
|
||||
|
||||
page.evaluate(function(chartoptions) {
|
||||
// phantomjs doesn't know how to handle .bind, so we override
|
||||
Function.prototype.bind = Function.prototype.bind || function (thisp) {
|
||||
var fn = this;
|
||||
return function () {
|
||||
return fn.apply(thisp, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
// generate chart
|
||||
c3.generate(chartoptions);
|
||||
|
||||
}, opts);
|
||||
|
||||
// setting transition to 0 has proven not to work thus far, but 300ms isn't much
|
||||
// so this is acceptable for now
|
||||
setTimeout(function() {
|
||||
page.render(out);
|
||||
phantom.exit();
|
||||
}, 300);
|
||||
}
|
||||
|
||||
// apply css inline because that usually renders better
|
||||
var css = '';
|
||||
for (var i in config.css) {
|
||||
css += fs.read(config.css[i]);
|
||||
}
|
||||
page.content = config.template.format(css);
|
||||
BIN
public/bower_components/c3/extensions/exporter/test.png
vendored
Executable file
BIN
public/bower_components/c3/extensions/exporter/test.png
vendored
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
380
public/bower_components/c3/extensions/js/c3ext.js
vendored
Executable file
380
public/bower_components/c3/extensions/js/c3ext.js
vendored
Executable file
@@ -0,0 +1,380 @@
|
||||
var c3ext = {};
|
||||
c3ext.generate = function (options) {
|
||||
|
||||
if (options.zoom2 != null) {
|
||||
zoom2_reducers = options.zoom2.reducers || {};
|
||||
zoom2_enabled = options.zoom2.enabled;
|
||||
_zoom2_factor = options.zoom2.factor || 1;
|
||||
_zoom2_maxItems = options.zoom2.maxItems;
|
||||
}
|
||||
|
||||
if (!zoom2_enabled) {
|
||||
return c3.generate(options);
|
||||
}
|
||||
|
||||
|
||||
var originalData = Q.copy(options.data);
|
||||
var zoom2_reducers;
|
||||
var zoom2_enabled;
|
||||
var _zoom2_maxItems;
|
||||
|
||||
if (_zoom2_maxItems == null) {
|
||||
var el = d3.select(options.bindto)[0][0];
|
||||
if (el != null) {
|
||||
var availWidth = el.clientWidth;
|
||||
|
||||
var pointSize = 20;
|
||||
_zoom2_maxItems = Math.ceil(availWidth / pointSize);
|
||||
}
|
||||
if (_zoom2_maxItems == null || _zoom2_maxItems < 10) {
|
||||
_zoom2_maxItems = 10;
|
||||
}
|
||||
}
|
||||
|
||||
function onZoomChanged(e) {
|
||||
refresh();
|
||||
}
|
||||
|
||||
var zoom2 = c3ext.ZoomBehavior({ changed: onZoomChanged, bindto: options.bindto });
|
||||
|
||||
zoom2.enhance = function () {
|
||||
_zoom2_maxItems *= 2;
|
||||
var totalItems = zoom2.getZoom().totalItems;
|
||||
if (_zoom2_maxItems > totalItems)
|
||||
_zoom2_maxItems = totalItems;
|
||||
refresh();
|
||||
}
|
||||
zoom2.dehance = function () {
|
||||
_zoom2_maxItems = Math.ceil(_zoom2_maxItems / 2) + 1;
|
||||
refresh();
|
||||
}
|
||||
|
||||
zoom2.maxItems = function () { return _zoom2_maxItems; };
|
||||
function zoomAndReduceData(list, zoomRange, func, maxItems) {
|
||||
//var maxItems = 10;//Math.ceil(10 * zoomFactor);
|
||||
var list2 = list.slice(zoomRange[0], zoomRange[1]);
|
||||
var chunkSize = 1;
|
||||
var list3 = list2;
|
||||
if (list3.length > maxItems) {
|
||||
var chunkSize = Math.ceil(list2.length / maxItems);
|
||||
list3 = list3.splitIntoChunksOf(chunkSize).map(func);
|
||||
}
|
||||
//console.log("x" + getCurrentZoomLevel() + ", maxItems=" + maxItems + " chunkSize=" + chunkSize + " totalBefore=" + list2.length + ", totalAfter=" + list3.length);
|
||||
return list3;
|
||||
}
|
||||
|
||||
function first(t) { return t[0]; }
|
||||
|
||||
var getDataForZoom = function (data) {
|
||||
if (data.columns == null || data.columns.length == 0)
|
||||
return;
|
||||
|
||||
var zoomInfo = zoom2.getZoom();
|
||||
if (zoomInfo.totalItems != data.columns[0].length - 1) {
|
||||
zoom2.setOptions({ totalItems: data.columns[0].length - 1 });
|
||||
zoomInfo = zoom2.getZoom();
|
||||
}
|
||||
data.columns = originalData.columns.map(function (column) {
|
||||
var name = column[0];
|
||||
var reducer = zoom2_reducers[name] || first; //by default take the first
|
||||
|
||||
var values = column.slice(1);
|
||||
var newValues = zoomAndReduceData(values, zoomInfo.currentZoom, reducer, _zoom2_maxItems);
|
||||
return [name].concat(newValues);
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
getDataForZoom(options.data);
|
||||
var chart = c3.generate(options);
|
||||
var _chart_load_org = chart.load.bind(chart);
|
||||
chart.zoom2 = zoom2;
|
||||
chart.load = function (data) {
|
||||
if (data.unload) {
|
||||
unload(data.unload);
|
||||
delete data.unload;
|
||||
}
|
||||
Q.copy(data, originalData);
|
||||
refresh();
|
||||
}
|
||||
chart.unload = function (names) {
|
||||
unload(names);
|
||||
refresh();
|
||||
}
|
||||
|
||||
function unload(names) {
|
||||
originalData.columns.removeAll(function (t) { names.contains(t); });
|
||||
}
|
||||
|
||||
|
||||
function refresh() {
|
||||
var data = Q.copy(originalData)
|
||||
getDataForZoom(data);
|
||||
_chart_load_org(data);
|
||||
};
|
||||
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
c3ext.ZoomBehavior = function (options) {
|
||||
var zoom = { __type: "ZoomBehavior" };
|
||||
|
||||
var _zoom2_factor;
|
||||
var _left;
|
||||
var totalItems;
|
||||
var currentZoom;
|
||||
var bindto = options.bindto;
|
||||
var _zoomChanged = options.changed || function () { };
|
||||
var element;
|
||||
var mousewheelTimer;
|
||||
var deltaY = 0;
|
||||
var leftRatio = 0;
|
||||
|
||||
|
||||
zoom.setOptions = function (options) {
|
||||
if (options == null)
|
||||
options = {};
|
||||
_zoom2_factor = options.factor || 1;
|
||||
_left = 0;
|
||||
totalItems = options.totalItems || 0;
|
||||
currentZoom = [0, totalItems];
|
||||
_zoomChanged = options.changed || _zoomChanged;
|
||||
}
|
||||
|
||||
zoom.setOptions(options);
|
||||
|
||||
|
||||
function verifyZoom(newZoom) {
|
||||
//newZoom.sort();
|
||||
if (newZoom[1] > totalItems) {
|
||||
var diff = newZoom[1] - totalItems;
|
||||
newZoom[0] -= diff;
|
||||
newZoom[1] -= diff;
|
||||
}
|
||||
if (newZoom[0] < 0) {
|
||||
var diff = newZoom[0] * -1;
|
||||
newZoom[0] += diff;
|
||||
newZoom[1] += diff;
|
||||
}
|
||||
if (newZoom[1] > totalItems)
|
||||
newZoom[1] = totalItems;
|
||||
if (newZoom[0] < 0)
|
||||
newZoom[0] = 0;
|
||||
}
|
||||
|
||||
function zoomAndPan(zoomFactor, left) {
|
||||
var itemsToShow = Math.ceil(totalItems / zoomFactor);
|
||||
var newZoom = [left, left + itemsToShow];
|
||||
verifyZoom(newZoom);
|
||||
currentZoom = newZoom;
|
||||
onZoomChanged();
|
||||
}
|
||||
|
||||
function onZoomChanged() {
|
||||
if (_zoomChanged != null)
|
||||
_zoomChanged(zoom.getZoom());
|
||||
}
|
||||
function applyZoomAndPan() {
|
||||
zoomAndPan(_zoom2_factor, _left);
|
||||
}
|
||||
function getItemsToShow() {
|
||||
var itemsToShow = Math.ceil(totalItems / _zoom2_factor);
|
||||
return itemsToShow;
|
||||
}
|
||||
|
||||
|
||||
zoom.getZoom = function () {
|
||||
return { totalItems: totalItems, currentZoom: currentZoom.slice() };
|
||||
}
|
||||
|
||||
zoom.factor = function (factor, skipDraw) {
|
||||
if (arguments.length == 0)
|
||||
return _zoom2_factor;
|
||||
_zoom2_factor = factor;
|
||||
if (_zoom2_factor < 1)
|
||||
_zoom2_factor = 1;
|
||||
if (skipDraw)
|
||||
return;
|
||||
applyZoomAndPan();
|
||||
}
|
||||
zoom.left = function (left, skipDraw) {
|
||||
if (arguments.length == 0)
|
||||
return _left;
|
||||
_left = left;
|
||||
if (_left < 0)
|
||||
_left = 0;
|
||||
var pageSize = getItemsToShow();
|
||||
//_left += pageSize;
|
||||
if (_left + pageSize > totalItems)
|
||||
_left = totalItems - pageSize;
|
||||
console.log({ left: _left, pageSize: pageSize });
|
||||
if (skipDraw)
|
||||
return;
|
||||
applyZoomAndPan();
|
||||
}
|
||||
|
||||
zoom.zoomAndPanByRatio = function (zoomRatio, panRatio) {
|
||||
|
||||
var pageSize = getItemsToShow();
|
||||
var leftOffset = Math.round(pageSize * panRatio);
|
||||
var mouseLeft = _left + leftOffset;
|
||||
zoom.factor(zoom.factor() * zoomRatio, true);
|
||||
|
||||
var finalLeft = mouseLeft;
|
||||
if (zoomRatio != 1) {
|
||||
var pageSize2 = getItemsToShow();
|
||||
var leftOffset2 = Math.round(pageSize2 * panRatio);
|
||||
finalLeft = mouseLeft - leftOffset2;
|
||||
}
|
||||
zoom.left(finalLeft, true);
|
||||
applyZoomAndPan();
|
||||
}
|
||||
|
||||
zoom.zoomIn = function () {
|
||||
zoom.zoomAndPanByRatio(2, 0);
|
||||
}
|
||||
|
||||
zoom.zoomOut = function () {
|
||||
zoom.zoomAndPanByRatio(0.5, 0);
|
||||
}
|
||||
|
||||
zoom.panLeft = function () {
|
||||
zoom.zoomAndPanByRatio(1, -1);
|
||||
}
|
||||
zoom.panRight = function () {
|
||||
zoom.zoomAndPanByRatio(1, 1);
|
||||
}
|
||||
|
||||
zoom.reset = function () {
|
||||
_left = 0;
|
||||
_zoom2_factor = 1;
|
||||
applyZoomAndPan();
|
||||
}
|
||||
|
||||
function doZoom() {
|
||||
if (deltaY != 0) {
|
||||
var maxDelta = 10;
|
||||
var multiply = (maxDelta + deltaY) / maxDelta;
|
||||
//var factor = chart.zoom2.factor()*multiply;
|
||||
//factor= Math.ceil(factor*100) / 100;
|
||||
console.log({ deltaY: deltaY, multiply: multiply });
|
||||
zoom.zoomAndPanByRatio(multiply, leftRatio);//0.5);//leftRatio);
|
||||
deltaY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function element_mousewheel(e) {
|
||||
deltaY += e.deltaY;
|
||||
leftRatio = (e.offsetX - 70) / (e.currentTarget.offsetWidth - 70);
|
||||
//console.log({ "e.offsetX": e.offsetX, "e.currentTarget.offsetWidth": e.currentTarget.offsetWidth, leftRatio: leftRatio });
|
||||
mousewheelTimer.set(150);
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
if (bindto != null) {
|
||||
element = $(options.bindto);
|
||||
if (element.mousewheel) {
|
||||
mousewheelTimer = new Timer(doZoom);
|
||||
element.mousewheel(element_mousewheel);
|
||||
}
|
||||
}
|
||||
|
||||
return zoom;
|
||||
|
||||
}
|
||||
|
||||
if (typeof (Q) == "undefined") {
|
||||
var Q = function () {
|
||||
};
|
||||
|
||||
Q.copy = function (src, target, options, depth) {
|
||||
///<summary>Copies an object into a target object, recursively cloning any object or array in the way, overwrite=true will overwrite a primitive field value even if exists</summary>
|
||||
///<param name="src" />
|
||||
///<param name="target" />
|
||||
///<param name="options" type="Object">{ overwrite:false }</param>
|
||||
///<returns type="Object">The copied object</returns>
|
||||
if (depth == null)
|
||||
depth = 0;
|
||||
if (depth == 100) {
|
||||
console.warn("Q.copy is in depth of 100 - possible circular reference")
|
||||
}
|
||||
options = options || { overwrite: false };
|
||||
if (src == target || src == null)
|
||||
return target;
|
||||
if (typeof (src) != "object") {
|
||||
if (options.overwrite || target == null)
|
||||
return src;
|
||||
return target;
|
||||
}
|
||||
if (typeof (src.clone) == "function") {
|
||||
if (options.overwrite || target == null)
|
||||
return src.clone();
|
||||
return target;
|
||||
}
|
||||
if (target == null) {
|
||||
if (src instanceof Array)
|
||||
target = [];
|
||||
else
|
||||
target = {};
|
||||
}
|
||||
|
||||
if (src instanceof Array) {
|
||||
for (var i = 0; i < src.length; i++) {
|
||||
var item = src[i];
|
||||
var item2 = target[i];
|
||||
item2 = Q.copy(item, item2, options, depth + 1);
|
||||
target[i] = item2;
|
||||
}
|
||||
target.splice(src.length, target.length - src.length);
|
||||
return target;
|
||||
}
|
||||
for (var p in src) {
|
||||
var value = src[p];
|
||||
var value2 = target[p];
|
||||
value2 = Q.copy(value, value2, options, depth + 1);
|
||||
target[p] = value2;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
}
|
||||
if (typeof (Timer) == "undefined") {
|
||||
var Timer = function (action, ms) {
|
||||
this.action = action;
|
||||
if (ms != null)
|
||||
this.set(ms);
|
||||
}
|
||||
|
||||
Timer.prototype.set = function (ms) {
|
||||
if (ms == null)
|
||||
ms = this._ms;
|
||||
else
|
||||
this._ms = ms;
|
||||
this.clear();
|
||||
if (ms == null)
|
||||
return;
|
||||
this.timeout = window.setTimeout(this.onTick.bind(this), ms);
|
||||
}
|
||||
|
||||
Timer.prototype.onTick = function () {
|
||||
this.clear();
|
||||
this.action();
|
||||
}
|
||||
|
||||
Timer.prototype.clear = function (ms) {
|
||||
if (this.timeout == null)
|
||||
return;
|
||||
window.clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
}
|
||||
}
|
||||
if (typeof(Array.prototype.splitIntoChunksOf)=="undefined") {
|
||||
Array.prototype.splitIntoChunksOf = function (countInEachChunk) {
|
||||
var chunks = Math.ceil(this.length / countInEachChunk);
|
||||
var list = [];
|
||||
for (var i = 0; i < this.length; i += countInEachChunk) {
|
||||
list.push(this.slice(i, i + countInEachChunk));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
77
public/bower_components/c3/karma.conf.js
vendored
Executable file
77
public/bower_components/c3/karma.conf.js
vendored
Executable file
@@ -0,0 +1,77 @@
|
||||
// Karma configuration
|
||||
// Generated on Wed Sep 30 2015 22:01:48 GMT+0900 (KST)
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
|
||||
// base path that will be used to resolve all patterns (eg. files, exclude)
|
||||
basePath: '',
|
||||
|
||||
|
||||
// frameworks to use
|
||||
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
|
||||
frameworks: ['jasmine'],
|
||||
|
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
'node_modules/d3/d3.min.js',
|
||||
'c3.js',
|
||||
'c3.css',
|
||||
'spec/*-helper.js',
|
||||
'spec/*-spec.js'
|
||||
],
|
||||
|
||||
|
||||
// list of files to exclude
|
||||
exclude: [
|
||||
],
|
||||
|
||||
|
||||
// preprocess matching files before serving them to the browser
|
||||
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
|
||||
preprocessors: {
|
||||
'c3.js': ['coverage']
|
||||
},
|
||||
|
||||
|
||||
// test results reporter to use
|
||||
// possible values: 'dots', 'progress'
|
||||
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
|
||||
reporters: ['spec', 'coverage'],
|
||||
|
||||
|
||||
coverageReporter: {
|
||||
reporters: [{type: 'lcov'}]
|
||||
},
|
||||
|
||||
|
||||
// web server port
|
||||
port: 9876,
|
||||
|
||||
|
||||
// enable / disable colors in the output (reporters and logs)
|
||||
colors: true,
|
||||
|
||||
|
||||
// level of logging
|
||||
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
|
||||
logLevel: config.LOG_INFO,
|
||||
|
||||
|
||||
// enable / disable watching file and executing tests whenever any file changes
|
||||
autoWatch: true,
|
||||
|
||||
|
||||
// start these browsers
|
||||
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
|
||||
browsers: ['PhantomJS'],
|
||||
|
||||
|
||||
// Continuous Integration mode
|
||||
// if true, Karma captures browsers, runs the tests and exits
|
||||
singleRun: true,
|
||||
|
||||
browserNoActivityTimeout: 60000,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user