raain-model 1.10.28 → 1.11.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.travis.deploy.sh +41 -0
- package/.travis.yml +22 -0
- package/RELEASE.md +1 -0
- package/package.json +1 -1
- package/specs/cartesian/Cartesian.spec.ts +56 -0
- package/specs/gauge/Gauge.spec.ts +19 -0
- package/specs/organization/Organization.spec.ts +32 -0
- package/specs/polar/Polar.spec.ts +25 -0
- package/specs/quality/Position.spec.ts +18 -0
- package/specs/quality/QualityTools.spec.ts +120 -0
- package/specs/quality/SpeedMatrix.spec.ts +125 -0
- package/specs/radar/Radar.spec.ts +18 -0
- package/specs/rain/Rain.spec.ts +71 -0
- package/specs/tsconfig.json +12 -0
- package/{cartesian/CartesianMeasureValue.js → src/cartesian/CartesianMeasureValue.ts} +64 -34
- package/src/cartesian/CartesianValue.ts +17 -0
- package/src/cartesian/ICartesianMeasureValue.ts +27 -0
- package/src/cartesian/LatLng.ts +39 -0
- package/src/cartesian/RadarCartesianMeasureValue.ts +29 -0
- package/src/cartesian/RainCartesianMeasureValue.ts +33 -0
- package/src/gauge/GaugeMeasure.ts +36 -0
- package/src/gauge/GaugeNode.ts +46 -0
- package/src/gauge/GaugeNodeMap.ts +55 -0
- package/{index.d.ts → src/index.ts} +6 -0
- package/src/organization/EventNode.ts +44 -0
- package/{organization/Link.js → src/organization/Link.ts} +13 -13
- package/src/organization/Measure.ts +49 -0
- package/src/organization/PeopleNode.ts +36 -0
- package/{organization/RaainNode.js → src/organization/RaainNode.ts} +53 -29
- package/src/organization/TeamNode.ts +46 -0
- package/{polar/AbstractPolarMeasureValue.js → src/polar/AbstractPolarMeasureValue.ts} +53 -29
- package/src/polar/GaugePolarMeasureValue.ts +15 -0
- package/src/polar/IPolarMeasureValue.ts +21 -0
- package/src/polar/MeasureValuePolarContainer.ts +28 -0
- package/{polar/PolarMeasureValue.js → src/polar/PolarMeasureValue.ts} +46 -27
- package/src/polar/PolarValue.ts +16 -0
- package/src/polar/RadarPolarMeasureValue.ts +43 -0
- package/src/polar/RainPolarMeasureValue.ts +57 -0
- package/{quality/QualityPoint.js → src/quality/QualityPoint.ts} +48 -23
- package/{quality/SpeedMatrix.js → src/quality/SpeedMatrix.ts} +117 -75
- package/{quality/SpeedMatrixContainer.js → src/quality/SpeedMatrixContainer.ts} +178 -91
- package/src/quality/history/CartesianGaugeHistory.ts +23 -0
- package/src/quality/history/CartesianRainHistory.ts +18 -0
- package/src/quality/history/PositionHistory.ts +31 -0
- package/src/quality/position/Position.ts +60 -0
- package/src/quality/position/PositionValue.ts +15 -0
- package/{quality/tools/QualityTools.js → src/quality/tools/QualityTools.ts} +82 -49
- package/src/radar/RadarMeasure.ts +27 -0
- package/src/radar/RadarNode.ts +46 -0
- package/src/radar/RadarNodeMap.ts +65 -0
- package/src/rain/RainComputation.ts +82 -0
- package/src/rain/RainComputationAbstract.ts +137 -0
- package/src/rain/RainComputationMap.ts +68 -0
- package/{rain/RainComputationQuality.js → src/rain/RainComputationQuality.ts} +56 -20
- package/src/rain/RainMeasure.ts +27 -0
- package/{rain/RainNode.js → src/rain/RainNode.ts} +76 -48
- package/tsconfig.json +17 -0
- package/tslint.json +79 -0
- package/cartesian/CartesianMeasureValue.d.ts +0 -41
- package/cartesian/CartesianMeasureValue.js.map +0 -1
- package/cartesian/CartesianValue.d.ts +0 -9
- package/cartesian/CartesianValue.js +0 -12
- package/cartesian/CartesianValue.js.map +0 -1
- package/cartesian/ICartesianMeasureValue.d.ts +0 -29
- package/cartesian/ICartesianMeasureValue.js +0 -3
- package/cartesian/ICartesianMeasureValue.js.map +0 -1
- package/cartesian/LatLng.d.ts +0 -12
- package/cartesian/LatLng.js +0 -31
- package/cartesian/LatLng.js.map +0 -1
- package/cartesian/RadarCartesianMeasureValue.d.ts +0 -15
- package/cartesian/RadarCartesianMeasureValue.js +0 -22
- package/cartesian/RadarCartesianMeasureValue.js.map +0 -1
- package/cartesian/RainCartesianMeasureValue.d.ts +0 -17
- package/cartesian/RainCartesianMeasureValue.js +0 -25
- package/cartesian/RainCartesianMeasureValue.js.map +0 -1
- package/gauge/GaugeMeasure.d.ts +0 -20
- package/gauge/GaugeMeasure.js +0 -24
- package/gauge/GaugeMeasure.js.map +0 -1
- package/gauge/GaugeNode.d.ts +0 -24
- package/gauge/GaugeNode.js +0 -31
- package/gauge/GaugeNode.js.map +0 -1
- package/gauge/GaugeNodeMap.d.ts +0 -22
- package/gauge/GaugeNodeMap.js +0 -42
- package/gauge/GaugeNodeMap.js.map +0 -1
- package/index.js +0 -56
- package/index.js.map +0 -1
- package/organization/EventNode.d.ts +0 -22
- package/organization/EventNode.js +0 -30
- package/organization/EventNode.js.map +0 -1
- package/organization/IVersion.js +0 -3
- package/organization/IVersion.js.map +0 -1
- package/organization/Link.d.ts +0 -16
- package/organization/Link.js.map +0 -1
- package/organization/Measure.d.ts +0 -20
- package/organization/Measure.js +0 -35
- package/organization/Measure.js.map +0 -1
- package/organization/PeopleNode.d.ts +0 -18
- package/organization/PeopleNode.js +0 -26
- package/organization/PeopleNode.js.map +0 -1
- package/organization/RaainNode.d.ts +0 -23
- package/organization/RaainNode.js.map +0 -1
- package/organization/TeamNode.d.ts +0 -22
- package/organization/TeamNode.js +0 -32
- package/organization/TeamNode.js.map +0 -1
- package/polar/AbstractPolarMeasureValue.d.ts +0 -29
- package/polar/AbstractPolarMeasureValue.js.map +0 -1
- package/polar/GaugePolarMeasureValue.d.ts +0 -11
- package/polar/GaugePolarMeasureValue.js +0 -14
- package/polar/GaugePolarMeasureValue.js.map +0 -1
- package/polar/IPolarMeasureValue.d.ts +0 -19
- package/polar/IPolarMeasureValue.js +0 -3
- package/polar/IPolarMeasureValue.js.map +0 -1
- package/polar/MeasureValuePolarContainer.d.ts +0 -11
- package/polar/MeasureValuePolarContainer.js +0 -22
- package/polar/MeasureValuePolarContainer.js.map +0 -1
- package/polar/PolarMeasureValue.d.ts +0 -26
- package/polar/PolarMeasureValue.js.map +0 -1
- package/polar/PolarValue.d.ts +0 -10
- package/polar/PolarValue.js +0 -12
- package/polar/PolarValue.js.map +0 -1
- package/polar/RadarPolarMeasureValue.d.ts +0 -15
- package/polar/RadarPolarMeasureValue.js +0 -34
- package/polar/RadarPolarMeasureValue.js.map +0 -1
- package/polar/RainPolarMeasureValue.d.ts +0 -18
- package/polar/RainPolarMeasureValue.js +0 -42
- package/polar/RainPolarMeasureValue.js.map +0 -1
- package/quality/QualityPoint.d.ts +0 -35
- package/quality/QualityPoint.js.map +0 -1
- package/quality/SpeedMatrix.d.ts +0 -79
- package/quality/SpeedMatrix.js.map +0 -1
- package/quality/SpeedMatrixContainer.d.ts +0 -76
- package/quality/SpeedMatrixContainer.js.map +0 -1
- package/quality/history/CartesianGaugeHistory.d.ts +0 -15
- package/quality/history/CartesianGaugeHistory.js +0 -14
- package/quality/history/CartesianGaugeHistory.js.map +0 -1
- package/quality/history/CartesianRainHistory.d.ts +0 -11
- package/quality/history/CartesianRainHistory.js +0 -12
- package/quality/history/CartesianRainHistory.js.map +0 -1
- package/quality/history/PositionHistory.d.ts +0 -20
- package/quality/history/PositionHistory.js +0 -17
- package/quality/history/PositionHistory.js.map +0 -1
- package/quality/position/Position.d.ts +0 -22
- package/quality/position/Position.js +0 -50
- package/quality/position/Position.js.map +0 -1
- package/quality/position/PositionValue.d.ts +0 -9
- package/quality/position/PositionValue.js +0 -12
- package/quality/position/PositionValue.js.map +0 -1
- package/quality/tools/QualityTools.d.ts +0 -24
- package/quality/tools/QualityTools.js.map +0 -1
- package/radar/RadarMeasure.d.ts +0 -17
- package/radar/RadarMeasure.js +0 -18
- package/radar/RadarMeasure.js.map +0 -1
- package/radar/RadarNode.d.ts +0 -24
- package/radar/RadarNode.js +0 -31
- package/radar/RadarNode.js.map +0 -1
- package/radar/RadarNodeMap.d.ts +0 -28
- package/radar/RadarNodeMap.js +0 -46
- package/radar/RadarNodeMap.js.map +0 -1
- package/rain/RainComputation.d.ts +0 -34
- package/rain/RainComputation.js +0 -55
- package/rain/RainComputation.js.map +0 -1
- package/rain/RainComputationAbstract.d.ts +0 -41
- package/rain/RainComputationAbstract.js +0 -102
- package/rain/RainComputationAbstract.js.map +0 -1
- package/rain/RainComputationMap.d.ts +0 -32
- package/rain/RainComputationMap.js +0 -45
- package/rain/RainComputationMap.js.map +0 -1
- package/rain/RainComputationQuality.d.ts +0 -37
- package/rain/RainComputationQuality.js.map +0 -1
- package/rain/RainMeasure.d.ts +0 -18
- package/rain/RainMeasure.js +0 -19
- package/rain/RainMeasure.js.map +0 -1
- package/rain/RainNode.d.ts +0 -38
- package/rain/RainNode.js.map +0 -1
- /package/{organization/IVersion.d.ts → src/organization/IVersion.ts} +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -o errexit -o nounset
|
|
4
|
+
|
|
5
|
+
if [ "$TRAVIS_BRANCH" != "master" ]; then
|
|
6
|
+
echo "This commit was made against the $TRAVIS_BRANCH and not the master! No deploy."
|
|
7
|
+
exit 0
|
|
8
|
+
fi
|
|
9
|
+
|
|
10
|
+
setup_git() {
|
|
11
|
+
echo "> Setup Git."
|
|
12
|
+
git init
|
|
13
|
+
git config --global user.email "travis@travis-ci.com"
|
|
14
|
+
git config --global user.name "Travis CI"
|
|
15
|
+
git remote -v
|
|
16
|
+
git remote add upstream "https://${GH_TOKEN}@github.com/raainio/raain-model.git"
|
|
17
|
+
|
|
18
|
+
REVISION=$(git rev-parse --short HEAD)
|
|
19
|
+
PACKAGE_VERSION=$(cat package.json |
|
|
20
|
+
grep version |
|
|
21
|
+
head -1 |
|
|
22
|
+
awk -F: '{ print $2 }' |
|
|
23
|
+
sed 's/[", ]//g')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
push_git() {
|
|
27
|
+
echo "> Commit, tag and push on master."
|
|
28
|
+
NEXT_VERSION=$(npm version patch -m "[skip ci] travis is OK: v${PACKAGE_VERSION} - ${REVISION}")
|
|
29
|
+
echo "- ${NEXT_VERSION} : In progress... " >> RELEASE.md
|
|
30
|
+
git add .
|
|
31
|
+
git commit -m "[skip ci] ${NEXT_VERSION} : In progress..."
|
|
32
|
+
# no git tag -a "v${PACKAGE_VERSION}" -m "v${PACKAGE_VERSION}"
|
|
33
|
+
git push -q upstream HEAD:master --tags
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
###########
|
|
37
|
+
## Main
|
|
38
|
+
###########
|
|
39
|
+
|
|
40
|
+
setup_git
|
|
41
|
+
push_git
|
package/.travis.yml
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
language: node_js
|
|
2
|
+
node_js:
|
|
3
|
+
- 18
|
|
4
|
+
cache:
|
|
5
|
+
bundler: true
|
|
6
|
+
directories:
|
|
7
|
+
- node_modules
|
|
8
|
+
branches:
|
|
9
|
+
only:
|
|
10
|
+
- master
|
|
11
|
+
script:
|
|
12
|
+
- npm run build
|
|
13
|
+
- npm test
|
|
14
|
+
after_success:
|
|
15
|
+
- bash .travis.deploy.sh
|
|
16
|
+
before_deploy:
|
|
17
|
+
- cd dist
|
|
18
|
+
deploy:
|
|
19
|
+
provider: npm
|
|
20
|
+
email: $NPM_USER
|
|
21
|
+
api_key: $NPM_TOKEN
|
|
22
|
+
skip_cleanup: true
|
package/RELEASE.md
CHANGED
|
@@ -10,3 +10,4 @@
|
|
|
10
10
|
- v0.4.1 : Cartesian values, Folder reorg (renaming of Polar objects : XX-MeasureValue => XX-PolarMeasureValue )
|
|
11
11
|
- v1.9.x : Cartesian improvements
|
|
12
12
|
- v1.10.x : Object constructor based on json only. Specs added.
|
|
13
|
+
- v1.11.x : Change SpeedMatrixContainer's QualityPoints relation (1.N). Add a SpeedMatrix name.
|
package/package.json
CHANGED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {
|
|
3
|
+
CartesianMeasureValue,
|
|
4
|
+
CartesianValue,
|
|
5
|
+
GaugeMeasure,
|
|
6
|
+
GaugeNode,
|
|
7
|
+
ICartesianMeasureValue,
|
|
8
|
+
LatLng,
|
|
9
|
+
RadarCartesianMeasureValue
|
|
10
|
+
} from '../../src';
|
|
11
|
+
|
|
12
|
+
describe('Cartesian', () => {
|
|
13
|
+
|
|
14
|
+
it('should create ones', () => {
|
|
15
|
+
|
|
16
|
+
const cartesianValue = new CartesianValue({
|
|
17
|
+
value: 123,
|
|
18
|
+
lat: 10,
|
|
19
|
+
lng: 20
|
|
20
|
+
});
|
|
21
|
+
const cartesianMeasureValue = new CartesianMeasureValue({
|
|
22
|
+
cartesianValues: [cartesianValue, cartesianValue],
|
|
23
|
+
cartesianPixelWidth: {lat: 1.002, lng: 13.0024}
|
|
24
|
+
});
|
|
25
|
+
const radarCartesianMeasureValue = new RadarCartesianMeasureValue({
|
|
26
|
+
cartesianValues: [cartesianValue, cartesianValue],
|
|
27
|
+
cartesianPixelWidth: new LatLng({lat: 1, lng: 2}),
|
|
28
|
+
angle: 4
|
|
29
|
+
});
|
|
30
|
+
expect(radarCartesianMeasureValue.angle).eq(4);
|
|
31
|
+
expect(radarCartesianMeasureValue.getCartesianValues().length).eq(2);
|
|
32
|
+
expect(radarCartesianMeasureValue.getCartesianPixelWidth().lng).eq(2);
|
|
33
|
+
|
|
34
|
+
const gaugeNode = new GaugeNode({
|
|
35
|
+
id: 'GaugeNode looks OK.',
|
|
36
|
+
name: 'name',
|
|
37
|
+
links: [],
|
|
38
|
+
latitude: 1,
|
|
39
|
+
longitude: 1
|
|
40
|
+
});
|
|
41
|
+
expect(gaugeNode.id).eq('GaugeNode looks OK.');
|
|
42
|
+
|
|
43
|
+
const gaugeMeasure = new GaugeMeasure({
|
|
44
|
+
id: 'gaugeMeasure',
|
|
45
|
+
date: new Date(),
|
|
46
|
+
timeInSec: 300,
|
|
47
|
+
values: [cartesianMeasureValue],
|
|
48
|
+
validity: 1
|
|
49
|
+
});
|
|
50
|
+
expect(gaugeMeasure.timeInSec).eq(300);
|
|
51
|
+
expect((gaugeMeasure.values[0] as ICartesianMeasureValue).getCartesianValue({lat: 10, lng: 20}).value).eq(123);
|
|
52
|
+
expect((gaugeMeasure.values[0] as ICartesianMeasureValue).getCartesianValue({lat: 10.0001, lng: 20.00001})).eq(null);
|
|
53
|
+
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {GaugeMeasure, GaugeNode} from '../../src';
|
|
3
|
+
|
|
4
|
+
describe('Gauge', () => {
|
|
5
|
+
|
|
6
|
+
it('should create ones', () => {
|
|
7
|
+
|
|
8
|
+
const gaugeNode = new GaugeNode({
|
|
9
|
+
id: 'Node looks OK.', name: 'name', links: [], latitude: 1, longitude: 1
|
|
10
|
+
});
|
|
11
|
+
expect(gaugeNode.id).eq('Node looks OK.');
|
|
12
|
+
expect(JSON.stringify(gaugeNode.toJSON())).eq('{"id":"Node looks OK.","links":[],"latitude":1,"longitude":1,"name":"name"}');
|
|
13
|
+
|
|
14
|
+
const gaugeMeasure = new GaugeMeasure({id: 'measure', values: [10, 11], configurationAsJSON: {test: true}});
|
|
15
|
+
expect(JSON.stringify(gaugeMeasure.toJSON())).eq('{"id":"measure","links":[],"validity":-1,"configurationAsJSON":"{\\"test\\":true}","values":[10,11],"timeInSec":-1}');
|
|
16
|
+
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {EventNode, PeopleNode, TeamNode} from '../../src';
|
|
3
|
+
|
|
4
|
+
describe('Organization', () => {
|
|
5
|
+
|
|
6
|
+
it('should create ones', () => {
|
|
7
|
+
const user1 = new PeopleNode({
|
|
8
|
+
id: 'uid1', role: 'user', email: 'user1@null.com', name: 'user1', comments: 'extra info...'
|
|
9
|
+
});
|
|
10
|
+
const team1 = new TeamNode({
|
|
11
|
+
id: 'tid1',
|
|
12
|
+
name: 'team1',
|
|
13
|
+
description: 'team...',
|
|
14
|
+
contracts: ['basic'],
|
|
15
|
+
contacts: [user1]
|
|
16
|
+
});
|
|
17
|
+
expect(team1.contacts[0].email).eq('user1@null.com');
|
|
18
|
+
expect(team1.contracts[0]).eq('basic');
|
|
19
|
+
|
|
20
|
+
const eventNode = new EventNode({
|
|
21
|
+
id: 'event1',
|
|
22
|
+
title: 'EventNode looks OK.',
|
|
23
|
+
status: 0,
|
|
24
|
+
red: false,
|
|
25
|
+
description: 'need help on...',
|
|
26
|
+
created: new Date(),
|
|
27
|
+
modified: new Date()
|
|
28
|
+
});
|
|
29
|
+
expect(eventNode.title).eq('EventNode looks OK.');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {MeasureValuePolarContainer, PolarMeasureValue, PolarValue} from '../../src';
|
|
3
|
+
|
|
4
|
+
describe('Polar', () => {
|
|
5
|
+
|
|
6
|
+
it('should create ones', () => {
|
|
7
|
+
|
|
8
|
+
const polarValue = new PolarValue({value: 12, polarAzimuthInDegrees: 2, polarDistanceInMeters: 4});
|
|
9
|
+
expect(polarValue.value).eq(12);
|
|
10
|
+
expect(polarValue.polarAzimuthInDegrees).eq(2);
|
|
11
|
+
expect(polarValue.polarDistanceInMeters).eq(4);
|
|
12
|
+
|
|
13
|
+
const measureValuePolarContainer = new MeasureValuePolarContainer({azimuth: 0, distance: 1, polarEdges: [33, 45.5]});
|
|
14
|
+
expect(measureValuePolarContainer.polarEdges[0]).eq(33);
|
|
15
|
+
expect(measureValuePolarContainer.polarEdges[1]).eq(45.5);
|
|
16
|
+
|
|
17
|
+
const polarMeasureValue = new PolarMeasureValue({measureValuePolarContainers: [measureValuePolarContainer]});
|
|
18
|
+
const polarValueFound = polarMeasureValue.getPolarValue({azimuthIndex: 0, edgeIndex: 1, strict: false});
|
|
19
|
+
expect(polarValueFound.value).eq(45.5);
|
|
20
|
+
expect(polarValueFound.polarAzimuthInDegrees).eq(0);
|
|
21
|
+
expect(polarValueFound.polarDistanceInMeters).eq(1);
|
|
22
|
+
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {Position} from '../../src';
|
|
3
|
+
|
|
4
|
+
describe('Position', () => {
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
it('should getXYScaled', () => {
|
|
8
|
+
|
|
9
|
+
const pos1 = new Position({x: 10.0001, y: 12.1});
|
|
10
|
+
expect(pos1.getXYScaled(0.01).x).eq(10);
|
|
11
|
+
expect(pos1.getXYScaled(0.01).y).eq(12.1);
|
|
12
|
+
|
|
13
|
+
const pos2 = new Position({x: 10.0001, y: 12.1});
|
|
14
|
+
expect(pos2.getXYScaled(0.0001).x).eq(10.0001);
|
|
15
|
+
expect(pos2.getXYScaled(0.0001).y).eq(12.1);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
});
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {LatLng, Position, QualityTools} from '../../src';
|
|
3
|
+
|
|
4
|
+
describe('QualityTools', () => {
|
|
5
|
+
|
|
6
|
+
it('should get roundLatLng', () => {
|
|
7
|
+
expect(QualityTools.RoundLatLng(12.1234)).eq(12.120000000000001);
|
|
8
|
+
expect(QualityTools.RoundLatLng(12.1234, 0.005)).eq(12.125);
|
|
9
|
+
expect(QualityTools.RoundLatLng(12.1234, 0.001)).eq(12.123000000000001); // => needPrecision
|
|
10
|
+
expect(QualityTools.RoundLatLng(12.1234, 0.001, true)).eq(12.123);
|
|
11
|
+
expect(QualityTools.RoundLatLng(12.1234, 0.01, true)).eq(12.12);
|
|
12
|
+
expect(QualityTools.RoundLatLng(12.1234, 0.1, true)).eq(12.1);
|
|
13
|
+
expect(QualityTools.RoundLatLng(12.1234, 1)).eq(12);
|
|
14
|
+
|
|
15
|
+
expect(QualityTools.RoundLatLng(-2.8000000000000003, 0.1, true)).eq(-2.8);
|
|
16
|
+
expect(QualityTools.RoundLatLng(-2.8000000000000003, 0.002, true)).eq(-2.8);
|
|
17
|
+
|
|
18
|
+
expect(QualityTools.RoundLatLng(-23.8000000000000003, 10)).eq(-20);
|
|
19
|
+
expect(QualityTools.RoundLatLng(345.1200000000000003, 200)).eq(400);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should isAroundLatLng', () => {
|
|
23
|
+
const center = new LatLng({lat: 12.3456, lng: 1.234});
|
|
24
|
+
|
|
25
|
+
expect(QualityTools.IsAroundLatLng(center, new LatLng({lat: 12.3456, lng: 1.234}), 0)).eq(true);
|
|
26
|
+
expect(QualityTools.IsAroundLatLng(center, new LatLng({lat: 12.3457, lng: 1.234}), 0)).eq(true);
|
|
27
|
+
expect(QualityTools.IsAroundLatLng(center, new LatLng({lat: 12.0006, lng: 1.234}), 0)).eq(false);
|
|
28
|
+
|
|
29
|
+
expect(QualityTools.IsAroundLatLng(center, new LatLng({lat: 12.3456, lng: 1.234}), 0, 0.1)).eq(true);
|
|
30
|
+
expect(QualityTools.IsAroundLatLng(center, new LatLng({lat: 12.3556, lng: 1.234}), 0, 0.1)).eq(false);
|
|
31
|
+
|
|
32
|
+
expect(QualityTools.IsAroundLatLng(center, new LatLng({lat: 12.3456, lng: 1.234}), 1, 0.1)).eq(true);
|
|
33
|
+
expect(QualityTools.IsAroundLatLng(center, new LatLng({lat: 12.3457, lng: 1.234}), 1, 0.1)).eq(true);
|
|
34
|
+
expect(QualityTools.IsAroundLatLng(center, new LatLng({lat: 12.3457, lng: 1.434}), 1, 0.1)).eq(false);
|
|
35
|
+
|
|
36
|
+
expect(QualityTools.IsAroundLatLng(center, new LatLng({lat: 12.3456, lng: 1.234}), 6, 0.01)).eq(true);
|
|
37
|
+
expect(QualityTools.IsAroundLatLng(center, new LatLng({lat: 12.3456, lng: 1.299}), 6, 0.01)).eq(false);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should isNotAroundLatLng', () => {
|
|
41
|
+
const center = new LatLng({lat: 12.3456, lng: 1.234});
|
|
42
|
+
|
|
43
|
+
expect(QualityTools.IsNotAroundLatLng(center, new LatLng({lat: 12.3456, lng: 1.234}), 0)).eq(false);
|
|
44
|
+
expect(QualityTools.IsNotAroundLatLng(center, new LatLng({lat: 12.3457, lng: 1.234}), 0)).eq(false);
|
|
45
|
+
expect(QualityTools.IsNotAroundLatLng(center, new LatLng({lat: 12.0006, lng: 1.234}), 0)).eq(true);
|
|
46
|
+
|
|
47
|
+
expect(QualityTools.IsNotAroundLatLng(center, new LatLng({lat: 12.3456, lng: 1.234}), 0, 0.1)).eq(false);
|
|
48
|
+
expect(QualityTools.IsNotAroundLatLng(center, new LatLng({lat: 12.3556, lng: 1.234}), 0, 0.1)).eq(true);
|
|
49
|
+
|
|
50
|
+
expect(QualityTools.IsNotAroundLatLng(center, new LatLng({lat: 12.3456, lng: 1.234}), 1, 0.1)).eq(false);
|
|
51
|
+
expect(QualityTools.IsNotAroundLatLng(center, new LatLng({lat: 12.3457, lng: 1.234}), 1, 0.1)).eq(false);
|
|
52
|
+
expect(QualityTools.IsNotAroundLatLng(center, new LatLng({lat: 12.3457, lng: 1.434}), 1, 0.1)).eq(true);
|
|
53
|
+
|
|
54
|
+
expect(QualityTools.IsNotAroundLatLng(center, new LatLng({lat: 12.3456, lng: 1.234}), 6, 0.01)).eq(false);
|
|
55
|
+
expect(QualityTools.IsNotAroundLatLng(center, new LatLng({lat: 12.3456, lng: 1.299}), 6, 0.01)).eq(true);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
it('should MapPositionToLatLng and MapLatLngToPosition', () => {
|
|
60
|
+
|
|
61
|
+
let point = new Position({x: 0, y: 0});
|
|
62
|
+
let latLng = QualityTools.MapPositionToLatLng(point);
|
|
63
|
+
expect(QualityTools.MapLatLngToPosition(latLng).x).eq(point.x);
|
|
64
|
+
expect(QualityTools.MapLatLngToPosition(latLng).y).eq(point.y);
|
|
65
|
+
expect(latLng.lat).eq(0);
|
|
66
|
+
expect(latLng.lng).eq(0);
|
|
67
|
+
|
|
68
|
+
point = new Position({x: 10, y: -10});
|
|
69
|
+
latLng = QualityTools.MapPositionToLatLng(point);
|
|
70
|
+
expect(QualityTools.MapLatLngToPosition(latLng).x).eq(point.x);
|
|
71
|
+
expect(QualityTools.MapLatLngToPosition(latLng).y).eq(point.y);
|
|
72
|
+
expect(latLng.lat).eq(-10);
|
|
73
|
+
expect(latLng.lng).eq(10);
|
|
74
|
+
|
|
75
|
+
point = new Position({x: 11.0003, y: -11.03});
|
|
76
|
+
latLng = QualityTools.MapPositionToLatLng(point);
|
|
77
|
+
expect(QualityTools.MapLatLngToPosition(latLng).x).eq(point.x);
|
|
78
|
+
expect(QualityTools.MapLatLngToPosition(latLng).y).eq(point.y);
|
|
79
|
+
|
|
80
|
+
point = new Position({x: 11.0003, y: -11.03});
|
|
81
|
+
const cartesianWidthDefault = new LatLng({lat: QualityTools.DEFAULT_SCALE, lng: QualityTools.DEFAULT_SCALE});
|
|
82
|
+
latLng = QualityTools.MapPositionToLatLng(point);
|
|
83
|
+
expect(QualityTools.MapLatLngToPosition(latLng, true, cartesianWidthDefault).x).eq(11);
|
|
84
|
+
expect(QualityTools.MapLatLngToPosition(latLng, true, cartesianWidthDefault).y).eq(-11.03);
|
|
85
|
+
|
|
86
|
+
const cartesianWidth = new LatLng({lat: 0.01426, lng: 0.00898});
|
|
87
|
+
expect(QualityTools.MapLatLngToPosition(latLng, true, cartesianWidth).y).eq(-11.02298);
|
|
88
|
+
expect(QualityTools.MapLatLngToPosition(latLng, true, cartesianWidth).x).eq(11.0005);
|
|
89
|
+
|
|
90
|
+
latLng = new LatLng({lat: 48.86420972077865, lng: 2.2681507839189115});
|
|
91
|
+
expect(QualityTools.MapLatLngToPosition(latLng, true, cartesianWidth).x).eq(2.27194);
|
|
92
|
+
expect(QualityTools.MapLatLngToPosition(latLng, true, cartesianWidth).y).eq(48.86902);
|
|
93
|
+
latLng = new LatLng({lat: 48.86423959124331, lng: 2.254480156320581});
|
|
94
|
+
expect(QualityTools.MapLatLngToPosition(latLng, true, cartesianWidth).x).eq(2.25398);
|
|
95
|
+
expect(QualityTools.MapLatLngToPosition(latLng, true, cartesianWidth).y).eq(48.86902);
|
|
96
|
+
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should CreateNDimArray', () => {
|
|
100
|
+
const createdEmptyNDimArray = QualityTools.CreateNDimArray([1, 2, 3]);
|
|
101
|
+
expect(createdEmptyNDimArray.length).eq(1);
|
|
102
|
+
expect(createdEmptyNDimArray[0].length).eq(2);
|
|
103
|
+
expect(createdEmptyNDimArray[0][1].length).eq(3);
|
|
104
|
+
expect(createdEmptyNDimArray[0][1][2]).eq(undefined);
|
|
105
|
+
|
|
106
|
+
const createdFilledNDimArray = QualityTools.CreateNDimArray([1, 2, 3], 4321);
|
|
107
|
+
expect(createdFilledNDimArray.length).eq(1);
|
|
108
|
+
expect(createdFilledNDimArray[0].length).eq(2);
|
|
109
|
+
expect(createdFilledNDimArray[0][1].length).eq(3);
|
|
110
|
+
expect(createdFilledNDimArray[0][1][2]).eq(4321);
|
|
111
|
+
|
|
112
|
+
const createdFilledWithZeroNDimArray = QualityTools.CreateNDimArray([1, 2, 3], 0);
|
|
113
|
+
expect(createdFilledWithZeroNDimArray[0][1][2]).eq(0);
|
|
114
|
+
|
|
115
|
+
const createdFilledWithAnyNDimArray = QualityTools.CreateNDimArray([1, 2, 3], []);
|
|
116
|
+
createdFilledWithAnyNDimArray[0][1][2].push('test');
|
|
117
|
+
expect(createdFilledWithAnyNDimArray[0][1][2][0]).eq('test');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
});
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {CartesianValue, Position, QualityPoint, QualityTools, SpeedMatrix, SpeedMatrixContainer} from '../../src';
|
|
3
|
+
|
|
4
|
+
describe('SpeedMatrix', () => {
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
it('should manipulate SpeedMatrixContainer', () => {
|
|
8
|
+
|
|
9
|
+
const speedMatrices = [];
|
|
10
|
+
speedMatrices.push(new SpeedMatrix('1', []));
|
|
11
|
+
speedMatrices.push(new SpeedMatrix('2', []));
|
|
12
|
+
const speedMatrixContainer = new SpeedMatrixContainer({matrices: speedMatrices});
|
|
13
|
+
|
|
14
|
+
const speedMatrixContainerTwin = SpeedMatrixContainer.CreateFromJson(speedMatrixContainer.toJSON());
|
|
15
|
+
const optionsForFairCompare = {
|
|
16
|
+
removeFlatten: true,
|
|
17
|
+
removeMatrices: true,
|
|
18
|
+
removeIndicators: true,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
expect(JSON.stringify(speedMatrixContainer.toJSON(optionsForFairCompare)))
|
|
22
|
+
.equal(JSON.stringify(speedMatrixContainerTwin.toJSON(optionsForFairCompare)));
|
|
23
|
+
|
|
24
|
+
const qualityPoint1 = new QualityPoint({
|
|
25
|
+
gaugeId: 'id1',
|
|
26
|
+
gaugeLabel: 'label1',
|
|
27
|
+
gaugeDate: null,
|
|
28
|
+
rainDate: null,
|
|
29
|
+
gaugeCartesianValue: new CartesianValue({value: 1, lat: 0, lng: 0}),
|
|
30
|
+
rainCartesianValues: [new CartesianValue({value: 2, lat: 0, lng: 0}), new CartesianValue({value: 3, lat: 0.01, lng: 0.02})],
|
|
31
|
+
speed: null,
|
|
32
|
+
remark: 'none',
|
|
33
|
+
});
|
|
34
|
+
const qualityPoint2 = new QualityPoint({
|
|
35
|
+
gaugeId: 'id2',
|
|
36
|
+
gaugeLabel: 'label2',
|
|
37
|
+
gaugeDate: null,
|
|
38
|
+
rainDate: null,
|
|
39
|
+
gaugeCartesianValue: new CartesianValue({value: 10, lat: 0, lng: 0}),
|
|
40
|
+
rainCartesianValues: [new CartesianValue({value: 20, lat: 0, lng: 0}), new CartesianValue({value: 30, lat: 0.01, lng: 0.02})],
|
|
41
|
+
speed: null,
|
|
42
|
+
remark: 'none',
|
|
43
|
+
});
|
|
44
|
+
const qualityPoints = [qualityPoint1, qualityPoint2];
|
|
45
|
+
|
|
46
|
+
const speedMatrixContainerToMerge = SpeedMatrixContainer.CreateFromJson({
|
|
47
|
+
matrices: [new SpeedMatrix('3', qualityPoints)],
|
|
48
|
+
trustedIndicator: 0.85
|
|
49
|
+
});
|
|
50
|
+
speedMatrixContainer.merge(speedMatrixContainerToMerge);
|
|
51
|
+
|
|
52
|
+
expect(speedMatrixContainer.getQualityPoints().length).eq(0);
|
|
53
|
+
expect(speedMatrixContainer.getQualityPoints('1').length).eq(0);
|
|
54
|
+
expect(speedMatrixContainer.getQualityPoints('2').length).eq(0);
|
|
55
|
+
expect(speedMatrixContainer.getQualityPoints('3').length).eq(2);
|
|
56
|
+
expect(speedMatrixContainer.getQualityPoints('3')[0].rainCartesianValues.length).eq(2);
|
|
57
|
+
|
|
58
|
+
const mergedMatrix = speedMatrixContainer.renderMergedMatrix();
|
|
59
|
+
expect(mergedMatrix.length).eq(Math.pow(SpeedMatrix.DEFAULT_MATRIX_RANGE * 2 + 1, 2));
|
|
60
|
+
expect(mergedMatrix[179].value).eq(1);
|
|
61
|
+
expect(mergedMatrix[179].x).eq(2);
|
|
62
|
+
expect(mergedMatrix[179].y).eq(1);
|
|
63
|
+
speedMatrixContainer.logMergedMatrix({normalize: false});
|
|
64
|
+
speedMatrixContainer.logMergedMatrix({normalize: true});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should manipulate SpeedMatrixContainer - other approach', async () => {
|
|
68
|
+
|
|
69
|
+
const speed = {angleInDegrees: 1, pixelsPerPeriod: 2};
|
|
70
|
+
const qp = {
|
|
71
|
+
gaugeId: 'id',
|
|
72
|
+
gaugeLabel: 'gaugeLabel',
|
|
73
|
+
gaugeDate: new Date(100000),
|
|
74
|
+
rainDate: new Date(200000),
|
|
75
|
+
gaugeCartesianValue: new CartesianValue({value: 10, lat: 1, lng: 2}),
|
|
76
|
+
rainCartesianValues: [new CartesianValue({value: 8, lat: 1, lng: 2}), new CartesianValue({value: 13, lat: 1.01, lng: 2.02})],
|
|
77
|
+
speed: {x: 1, y: 2},
|
|
78
|
+
remark: 'none',
|
|
79
|
+
};
|
|
80
|
+
const qualityPoint1 = new QualityPoint(qp);
|
|
81
|
+
const qualityPoints1: QualityPoint[] = [qualityPoint1];
|
|
82
|
+
const roundScale: Position = new Position({x: QualityTools.DEFAULT_SCALE, y: QualityTools.DEFAULT_SCALE});
|
|
83
|
+
|
|
84
|
+
const flattenPositionRange = {xMin: -4, xMax: 4, yMin: -4, yMax: 4};
|
|
85
|
+
const speedMatrix1 = new SpeedMatrix('1', qualityPoints1, speed, 1, flattenPositionRange, roundScale);
|
|
86
|
+
const qualitySpeedMatrixContainer1 = new SpeedMatrixContainer({matrices: [speedMatrix1]});
|
|
87
|
+
|
|
88
|
+
// Verify creation
|
|
89
|
+
qualitySpeedMatrixContainer1.logMergedMatrix({normalize: false});
|
|
90
|
+
expect(qualitySpeedMatrixContainer1.getQuality()).eq(0.5);
|
|
91
|
+
expect(qualitySpeedMatrixContainer1.getMaxGauge()).eq(10);
|
|
92
|
+
expect(qualitySpeedMatrixContainer1.getMaxRain()).eq(10.5);
|
|
93
|
+
expect(qualitySpeedMatrixContainer1.getQualityPoints().length).eq(1);
|
|
94
|
+
expect(qualitySpeedMatrixContainer1.getQualityPoints()[0].getGaugeValue()).eq(10);
|
|
95
|
+
expect(qualitySpeedMatrixContainer1.getQualityPoints()[0].getRainValue()).eq(10.5);
|
|
96
|
+
expect(qualityPoint1.getTimeDeltaInMinutes()).eq(2);
|
|
97
|
+
|
|
98
|
+
// Second container to merge
|
|
99
|
+
qp.gaugeId = 'otherGaugeId';
|
|
100
|
+
const qualityPoint2 = new QualityPoint(qp);
|
|
101
|
+
const qualityPoints2: QualityPoint[] = [qualityPoint1, qualityPoint2];
|
|
102
|
+
const speedMatrix2 = new SpeedMatrix('2', qualityPoints2, speed, 1, flattenPositionRange, roundScale);
|
|
103
|
+
const qualitySpeedMatrixContainer2 = new SpeedMatrixContainer({matrices: [speedMatrix2]});
|
|
104
|
+
qualitySpeedMatrixContainer1.merge(qualitySpeedMatrixContainer2);
|
|
105
|
+
|
|
106
|
+
// Verify merging
|
|
107
|
+
qualitySpeedMatrixContainer1.logMergedMatrix({normalize: false});
|
|
108
|
+
expect(qualitySpeedMatrixContainer1.getQuality()).eq(0.5);
|
|
109
|
+
expect(qualitySpeedMatrixContainer1.getMaxGauge()).eq(10);
|
|
110
|
+
expect(qualitySpeedMatrixContainer1.getMaxRain()).eq(10.5);
|
|
111
|
+
expect(qualitySpeedMatrixContainer1.getQualityPoints().length).eq(1);
|
|
112
|
+
expect(qualitySpeedMatrixContainer1.getQualityPoints()[0].getGaugeValue()).eq(10);
|
|
113
|
+
expect(qualitySpeedMatrixContainer1.getQualityPoints()[0].getRainValue()).eq(10.5);
|
|
114
|
+
|
|
115
|
+
expect(qualitySpeedMatrixContainer1.getQualityPoints('1').length).eq(1);
|
|
116
|
+
expect(qualitySpeedMatrixContainer1.getQualityPoints('1')[0].getGaugeValue()).eq(10);
|
|
117
|
+
expect(qualitySpeedMatrixContainer1.getQualityPoints('1')[0].getRainValue()).eq(10.5);
|
|
118
|
+
|
|
119
|
+
expect(qualitySpeedMatrixContainer1.getQualityPoints('2').length).eq(2);
|
|
120
|
+
expect(qualitySpeedMatrixContainer1.getQualityPoints('2')[0].getGaugeValue()).eq(10);
|
|
121
|
+
expect(qualitySpeedMatrixContainer1.getQualityPoints('2')[0].getRainValue()).eq(10.5);
|
|
122
|
+
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {RadarMeasure, RadarNode} from '../../src';
|
|
3
|
+
|
|
4
|
+
describe('Radar', () => {
|
|
5
|
+
|
|
6
|
+
it('should create ones', () => {
|
|
7
|
+
|
|
8
|
+
const radarNode = new RadarNode({
|
|
9
|
+
id: 'RadarNode looks OK.', name: 'name', links: [], latitude: 1, longitude: 1
|
|
10
|
+
});
|
|
11
|
+
expect(radarNode.id).eq('RadarNode looks OK.');
|
|
12
|
+
expect(JSON.stringify(radarNode.toJSON())).eq('{"id":"RadarNode looks OK.","links":[],"name":"name","latitude":1,"longitude":1}');
|
|
13
|
+
|
|
14
|
+
const measure = new RadarMeasure({id: 'measure', values: [10, 11]});
|
|
15
|
+
expect(JSON.stringify(measure.toJSON())).eq('{"id":"measure","links":[],"validity":-1,"values":[10,11]}');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {
|
|
3
|
+
RadarNode,
|
|
4
|
+
RainComputation,
|
|
5
|
+
RainComputationQuality,
|
|
6
|
+
RainMeasure,
|
|
7
|
+
RainNode,
|
|
8
|
+
RainPolarMeasureValue,
|
|
9
|
+
SpeedMatrixContainer
|
|
10
|
+
} from '../../src';
|
|
11
|
+
|
|
12
|
+
describe('Rain', () => {
|
|
13
|
+
|
|
14
|
+
it('should create ones', () => {
|
|
15
|
+
|
|
16
|
+
const radarNode = new RadarNode({id: 'any', latitude: 1, longitude: 1});
|
|
17
|
+
const rainComputationEmpty = new RainComputation({id: 'any', periodBegin: null, periodEnd: null, isReady: null, results: null});
|
|
18
|
+
|
|
19
|
+
const rainNode = new RainNode({
|
|
20
|
+
id: 'RainNode looks OK.',
|
|
21
|
+
name: 'name',
|
|
22
|
+
links: [radarNode, rainComputationEmpty, null],
|
|
23
|
+
latitude: 1,
|
|
24
|
+
longitude: 1
|
|
25
|
+
});
|
|
26
|
+
expect(rainNode.id).eq('RainNode looks OK.');
|
|
27
|
+
expect(JSON.stringify(rainNode.toJSON())).eq('' +
|
|
28
|
+
'{"id":"RainNode looks OK.",' +
|
|
29
|
+
'"links":[{"rel":"radar","href":"../radars/any"},{"rel":"rain-computation","href":"../rain-computations/any"},{"rel":"gauge","href":"../gauges/any"}],' +
|
|
30
|
+
'"name":"name","status":-1,"quality":-1,"latitude":1,"longitude":1}');
|
|
31
|
+
|
|
32
|
+
const rainComputation = new RainComputation({
|
|
33
|
+
id: 'RainComputation looks OK.',
|
|
34
|
+
periodBegin: new Date('2022-01-01'),
|
|
35
|
+
periodEnd: new Date('2022-01-02'),
|
|
36
|
+
links: [radarNode, radarNode, null],
|
|
37
|
+
quality: 1,
|
|
38
|
+
progressIngest: 1,
|
|
39
|
+
progressComputing: 1,
|
|
40
|
+
timeSpentInMs: 100,
|
|
41
|
+
isReady: true,
|
|
42
|
+
isDoneDate: new Date(),
|
|
43
|
+
results: [new RainPolarMeasureValue({
|
|
44
|
+
polars: '[]',
|
|
45
|
+
version: 'version2'
|
|
46
|
+
})],
|
|
47
|
+
launchedBy: 'oneUser',
|
|
48
|
+
version: 'v1',
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
expect(rainComputation.id).eq('RainComputation looks OK.');
|
|
52
|
+
expect(rainComputation.getVersion()).eq('v1');
|
|
53
|
+
|
|
54
|
+
const rainComputationQuality = new RainComputationQuality({
|
|
55
|
+
id: 'RainComputationQuality looks OK.',
|
|
56
|
+
periodBegin: new Date(),
|
|
57
|
+
periodEnd: new Date(),
|
|
58
|
+
links: [radarNode],
|
|
59
|
+
quality: 1,
|
|
60
|
+
isReady: true,
|
|
61
|
+
qualitySpeedMatrixContainer: new SpeedMatrixContainer({matrices: []}),
|
|
62
|
+
version: 'v1'
|
|
63
|
+
});
|
|
64
|
+
expect(rainComputationQuality.id).eq('RainComputationQuality looks OK.');
|
|
65
|
+
expect(rainComputationQuality.getVersion()).eq('v1');
|
|
66
|
+
|
|
67
|
+
const measure = new RainMeasure({id: 'measure', values: [10, 11], configurationAsJSON: '{"test": true}'});
|
|
68
|
+
expect(JSON.stringify(measure.toJSON())).eq('{"id":"measure","links":[],"validity":-1,"configurationAsJSON":"{\\"test\\":true}","values":[10,11]}');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
});
|