Fix GC time calculation (#113992)
Was in µs. Corrected to be in ms. Also use correct duration formatting on the GC time chart and time spent by dependency chart.
This commit is contained in:
parent
4436ed2f71
commit
c9e3e0e9b5
|
@ -27,8 +27,8 @@ import { Annotation } from '../../../../../common/annotations';
|
|||
import { useChartTheme } from '../../../../../../observability/public';
|
||||
import {
|
||||
asAbsoluteDateTime,
|
||||
asDuration,
|
||||
asPercent,
|
||||
getDurationFormatter,
|
||||
} from '../../../../../common/utils/formatters';
|
||||
import { Coordinate, TimeSeries } from '../../../../../typings/timeseries';
|
||||
import { useChartPointerEventContext } from '../../../../context/chart_pointer_event/use_chart_pointer_event_context';
|
||||
|
@ -39,6 +39,10 @@ import { ChartContainer } from '../../charts/chart_container';
|
|||
import { isTimeseriesEmpty, onBrushEnd } from '../../charts/helper/helper';
|
||||
import { useApmParams } from '../../../../hooks/use_apm_params';
|
||||
import { useTimeRange } from '../../../../hooks/use_time_range';
|
||||
import {
|
||||
getMaxY,
|
||||
getResponseTimeTickFormatter,
|
||||
} from '../../../shared/charts/transaction_charts/helper';
|
||||
|
||||
interface Props {
|
||||
fetchStatus: FETCH_STATUS;
|
||||
|
@ -50,7 +54,6 @@ interface Props {
|
|||
}
|
||||
|
||||
const asPercentBound = (y: number | null) => asPercent(y, 1);
|
||||
const asDurationBound = (y: number | null) => asDuration(y);
|
||||
|
||||
export function BreakdownChart({
|
||||
fetchStatus,
|
||||
|
@ -82,8 +85,11 @@ export function BreakdownChart({
|
|||
|
||||
const isEmpty = isTimeseriesEmpty(timeseries);
|
||||
|
||||
const maxY = getMaxY(timeseries);
|
||||
const yTickFormat: TickFormatter =
|
||||
yAxisType === 'duration' ? asDurationBound : asPercentBound;
|
||||
yAxisType === 'duration'
|
||||
? getResponseTimeTickFormatter(getDurationFormatter(maxY))
|
||||
: asPercentBound;
|
||||
|
||||
return (
|
||||
<ChartContainer height={height} hasData={!isEmpty} status={fetchStatus}>
|
||||
|
|
|
@ -9,9 +9,9 @@ import { EuiTitle } from '@elastic/eui';
|
|||
import React from 'react';
|
||||
import {
|
||||
asDecimal,
|
||||
asDuration,
|
||||
asInteger,
|
||||
asPercent,
|
||||
getDurationFormatter,
|
||||
getFixedByteFormatter,
|
||||
} from '../../../../../common/utils/formatters';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
|
@ -19,22 +19,24 @@ import { GenericMetricsChart } from '../../../../../server/lib/metrics/transform
|
|||
import { Maybe } from '../../../../../typings/common';
|
||||
import { FETCH_STATUS } from '../../../../hooks/use_fetcher';
|
||||
import { TimeseriesChart } from '../timeseries_chart';
|
||||
import {
|
||||
getMaxY,
|
||||
getResponseTimeTickFormatter,
|
||||
} from '../transaction_charts/helper';
|
||||
|
||||
function getYTickFormatter(chart: GenericMetricsChart) {
|
||||
const max = getMaxY(chart.series);
|
||||
|
||||
switch (chart.yUnit) {
|
||||
case 'bytes': {
|
||||
const max = Math.max(
|
||||
...chart.series.map(({ data }) =>
|
||||
Math.max(...data.map(({ y }) => y || 0))
|
||||
)
|
||||
);
|
||||
return getFixedByteFormatter(max);
|
||||
}
|
||||
case 'percent': {
|
||||
return (y: Maybe<number>) => asPercent(y || 0, 1);
|
||||
}
|
||||
case 'time': {
|
||||
return asDuration;
|
||||
const durationFormatter = getDurationFormatter(max);
|
||||
return getResponseTimeTickFormatter(durationFormatter);
|
||||
}
|
||||
case 'integer': {
|
||||
return asInteger;
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
METRIC_JAVA_GC_COUNT,
|
||||
METRIC_JAVA_GC_TIME,
|
||||
} from '../../../../../../common/elasticsearch_fieldnames';
|
||||
import { Setup } from '../../../../helpers/setup_request';
|
||||
import { ChartBase } from '../../../types';
|
||||
|
||||
import { fetchAndTransformGcMetrics } from './fetch_and_transform_gc_metrics';
|
||||
|
||||
describe('fetchAndTransformGcMetrics', () => {
|
||||
describe('given "jvm.gc.time"', () => {
|
||||
it('converts the value to milliseconds', async () => {
|
||||
const chartBase = {} as unknown as ChartBase;
|
||||
const response = {
|
||||
hits: { total: { value: 1 } },
|
||||
aggregations: {
|
||||
per_pool: {
|
||||
buckets: [
|
||||
{
|
||||
key: 'Copy',
|
||||
doc_count: 30,
|
||||
timeseries: {
|
||||
buckets: [
|
||||
{
|
||||
key_as_string: '2021-10-05T16:03:30.000Z',
|
||||
key: 1633449810000,
|
||||
doc_count: 1,
|
||||
max: {
|
||||
value: 23750,
|
||||
},
|
||||
derivative: {
|
||||
value: 11,
|
||||
},
|
||||
value: {
|
||||
value: 11,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
const setup = {
|
||||
apmEventClient: { search: () => Promise.resolve(response) },
|
||||
config: { 'xpack.gc.metricsInterval': 0 },
|
||||
} as unknown as Setup;
|
||||
const fieldName = METRIC_JAVA_GC_TIME;
|
||||
|
||||
const { series } = await fetchAndTransformGcMetrics({
|
||||
chartBase,
|
||||
environment: 'test environment',
|
||||
fieldName,
|
||||
kuery: '',
|
||||
operationName: 'test operation name',
|
||||
setup,
|
||||
serviceName: 'test service name',
|
||||
start: 1633456140000,
|
||||
end: 1633457078105,
|
||||
});
|
||||
|
||||
expect(series[0].data[0].y).toEqual(22000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('given "jvm.gc.rate"', () => {
|
||||
it('does not convert the value to milliseconds', async () => {
|
||||
const chartBase = {} as unknown as ChartBase;
|
||||
const response = {
|
||||
hits: {
|
||||
total: {
|
||||
value: 62,
|
||||
},
|
||||
},
|
||||
aggregations: {
|
||||
per_pool: {
|
||||
buckets: [
|
||||
{
|
||||
key: 'Copy',
|
||||
doc_count: 31,
|
||||
timeseries: {
|
||||
buckets: [
|
||||
{
|
||||
key_as_string: '2021-10-05T18:01:30.000Z',
|
||||
key: 1633456890000,
|
||||
doc_count: 1,
|
||||
max: {
|
||||
value: 815,
|
||||
},
|
||||
derivative: {
|
||||
value: 4,
|
||||
},
|
||||
value: {
|
||||
value: 4,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
const setup = {
|
||||
apmEventClient: { search: () => Promise.resolve(response) },
|
||||
config: { 'xpack.gc.metricsInterval': 0 },
|
||||
} as unknown as Setup;
|
||||
const fieldName = METRIC_JAVA_GC_COUNT;
|
||||
|
||||
const { series } = await fetchAndTransformGcMetrics({
|
||||
chartBase,
|
||||
environment: 'test environment',
|
||||
fieldName,
|
||||
kuery: '',
|
||||
operationName: 'test operation name',
|
||||
setup,
|
||||
serviceName: 'test service name',
|
||||
start: 1633456140000,
|
||||
end: 1633457078105,
|
||||
});
|
||||
|
||||
expect(series[0].data[0].y).toEqual(8);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -135,10 +135,17 @@ export async function fetchAndTransformGcMetrics({
|
|||
const data = timeseriesData.buckets.map((bucket) => {
|
||||
// derivative/value will be undefined for the first hit and if the `max` value is null
|
||||
const bucketValue = bucket.value?.value;
|
||||
const y = isFiniteNumber(bucketValue)
|
||||
|
||||
const unconvertedY = isFiniteNumber(bucketValue)
|
||||
? round(bucketValue * (60 / bucketSize), 1)
|
||||
: null;
|
||||
|
||||
// convert to milliseconds if we're calculating time, but not for rate
|
||||
const y =
|
||||
unconvertedY !== null && fieldName === METRIC_JAVA_GC_TIME
|
||||
? unconvertedY * 1000
|
||||
: unconvertedY;
|
||||
|
||||
return {
|
||||
y,
|
||||
x: bucket.key,
|
||||
|
|
|
@ -39,11 +39,11 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
it('contains CPU usage and System memory usage chart data', async () => {
|
||||
expect(chartsResponse.status).to.be(200);
|
||||
expectSnapshot(chartsResponse.body.charts.map((chart) => chart.title)).toMatchInline(`
|
||||
Array [
|
||||
"CPU usage",
|
||||
"System memory usage",
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
"CPU usage",
|
||||
"System memory usage",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
describe('CPU usage', () => {
|
||||
|
@ -57,25 +57,25 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
it('has correct series', () => {
|
||||
expect(cpuUsageChart).to.not.empty();
|
||||
expectSnapshot(cpuUsageChart?.series.map(({ title }) => title)).toMatchInline(`
|
||||
Array [
|
||||
"System max",
|
||||
"System average",
|
||||
"Process max",
|
||||
"Process average",
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
"System max",
|
||||
"System average",
|
||||
"Process max",
|
||||
"Process average",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('has correct series overall values', () => {
|
||||
expectSnapshot(cpuUsageChart?.series.map(({ overallValue }) => overallValue))
|
||||
.toMatchInline(`
|
||||
Array [
|
||||
0.714,
|
||||
0.3877,
|
||||
0.75,
|
||||
0.2543,
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
0.714,
|
||||
0.3877,
|
||||
0.75,
|
||||
0.2543,
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -91,21 +91,21 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
expect(systemMemoryUsageChart).to.not.empty();
|
||||
expectSnapshot(systemMemoryUsageChart?.series.map(({ title }) => title))
|
||||
.toMatchInline(`
|
||||
Array [
|
||||
"Max",
|
||||
"Average",
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
"Max",
|
||||
"Average",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('has correct series overall values', () => {
|
||||
expectSnapshot(systemMemoryUsageChart?.series.map(({ overallValue }) => overallValue))
|
||||
.toMatchInline(`
|
||||
Array [
|
||||
0.722093920925555,
|
||||
0.718173546796348,
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
0.722093920925555,
|
||||
0.718173546796348,
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -128,16 +128,16 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
it('has correct chart data', async () => {
|
||||
expect(chartsResponse.status).to.be(200);
|
||||
expectSnapshot(chartsResponse.body.charts.map((chart) => chart.title)).toMatchInline(`
|
||||
Array [
|
||||
"CPU usage",
|
||||
"System memory usage",
|
||||
"Heap Memory",
|
||||
"Non-Heap Memory",
|
||||
"Thread Count",
|
||||
"Garbage collection per minute",
|
||||
"Garbage collection time spent per minute",
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
"CPU usage",
|
||||
"System memory usage",
|
||||
"Heap Memory",
|
||||
"Non-Heap Memory",
|
||||
"Thread Count",
|
||||
"Garbage collection per minute",
|
||||
"Garbage collection time spent per minute",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
describe('CPU usage', () => {
|
||||
|
@ -151,37 +151,37 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
it('has correct series', () => {
|
||||
expect(cpuUsageChart).to.not.empty();
|
||||
expectSnapshot(cpuUsageChart?.series.map(({ title }) => title)).toMatchInline(`
|
||||
Array [
|
||||
"System max",
|
||||
"System average",
|
||||
"Process max",
|
||||
"Process average",
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
"System max",
|
||||
"System average",
|
||||
"Process max",
|
||||
"Process average",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('has correct series overall values', () => {
|
||||
expectSnapshot(cpuUsageChart?.series.map(({ overallValue }) => overallValue))
|
||||
.toMatchInline(`
|
||||
Array [
|
||||
0.203,
|
||||
0.178777777777778,
|
||||
0.01,
|
||||
0.009,
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
0.203,
|
||||
0.178777777777778,
|
||||
0.01,
|
||||
0.009,
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('has the correct rate', async () => {
|
||||
const yValues = cpuUsageChart?.series.map((serie) => first(serie.data)?.y);
|
||||
expectSnapshot(yValues).toMatchInline(`
|
||||
Array [
|
||||
0.193,
|
||||
0.193,
|
||||
0.009,
|
||||
0.009,
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
0.193,
|
||||
0.193,
|
||||
0.009,
|
||||
0.009,
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -197,31 +197,31 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
expect(systemMemoryUsageChart).to.not.empty();
|
||||
expectSnapshot(systemMemoryUsageChart?.series.map(({ title }) => title))
|
||||
.toMatchInline(`
|
||||
Array [
|
||||
"Max",
|
||||
"Average",
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
"Max",
|
||||
"Average",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('has correct series overall values', () => {
|
||||
expectSnapshot(systemMemoryUsageChart?.series.map(({ overallValue }) => overallValue))
|
||||
.toMatchInline(`
|
||||
Array [
|
||||
0.707924703557837,
|
||||
0.705395980841182,
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
0.707924703557837,
|
||||
0.705395980841182,
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('has the correct rate', async () => {
|
||||
const yValues = systemMemoryUsageChart?.series.map((serie) => first(serie.data)?.y);
|
||||
expectSnapshot(yValues).toMatchInline(`
|
||||
Array [
|
||||
0.707924703557837,
|
||||
0.707924703557837,
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
0.707924703557837,
|
||||
0.707924703557837,
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -236,34 +236,34 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
it('has correct series', () => {
|
||||
expect(cpuUsageChart).to.not.empty();
|
||||
expectSnapshot(cpuUsageChart?.series.map(({ title }) => title)).toMatchInline(`
|
||||
Array [
|
||||
"Avg. used",
|
||||
"Avg. committed",
|
||||
"Avg. limit",
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
"Avg. used",
|
||||
"Avg. committed",
|
||||
"Avg. limit",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('has correct series overall values', () => {
|
||||
expectSnapshot(cpuUsageChart?.series.map(({ overallValue }) => overallValue))
|
||||
.toMatchInline(`
|
||||
Array [
|
||||
222501617.777778,
|
||||
374341632,
|
||||
1560281088,
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
222501617.777778,
|
||||
374341632,
|
||||
1560281088,
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('has the correct rate', async () => {
|
||||
const yValues = cpuUsageChart?.series.map((serie) => first(serie.data)?.y);
|
||||
expectSnapshot(yValues).toMatchInline(`
|
||||
Array [
|
||||
211472896,
|
||||
374341632,
|
||||
1560281088,
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
211472896,
|
||||
374341632,
|
||||
1560281088,
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -278,31 +278,31 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
it('has correct series', () => {
|
||||
expect(cpuUsageChart).to.not.empty();
|
||||
expectSnapshot(cpuUsageChart?.series.map(({ title }) => title)).toMatchInline(`
|
||||
Array [
|
||||
"Avg. used",
|
||||
"Avg. committed",
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
"Avg. used",
|
||||
"Avg. committed",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('has correct series overall values', () => {
|
||||
expectSnapshot(cpuUsageChart?.series.map(({ overallValue }) => overallValue))
|
||||
.toMatchInline(`
|
||||
Array [
|
||||
138573397.333333,
|
||||
147677639.111111,
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
138573397.333333,
|
||||
147677639.111111,
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('has the correct rate', async () => {
|
||||
const yValues = cpuUsageChart?.series.map((serie) => first(serie.data)?.y);
|
||||
expectSnapshot(yValues).toMatchInline(`
|
||||
Array [
|
||||
138162752,
|
||||
147386368,
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
138162752,
|
||||
147386368,
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -317,31 +317,31 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
it('has correct series', () => {
|
||||
expect(cpuUsageChart).to.not.empty();
|
||||
expectSnapshot(cpuUsageChart?.series.map(({ title }) => title)).toMatchInline(`
|
||||
Array [
|
||||
"Avg. count",
|
||||
"Max count",
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
"Avg. count",
|
||||
"Max count",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('has correct series overall values', () => {
|
||||
expectSnapshot(cpuUsageChart?.series.map(({ overallValue }) => overallValue))
|
||||
.toMatchInline(`
|
||||
Array [
|
||||
44.4444444444444,
|
||||
45,
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
44.4444444444444,
|
||||
45,
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('has the correct rate', async () => {
|
||||
const yValues = cpuUsageChart?.series.map((serie) => first(serie.data)?.y);
|
||||
expectSnapshot(yValues).toMatchInline(`
|
||||
Array [
|
||||
44,
|
||||
44,
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
44,
|
||||
44,
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -356,21 +356,21 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
it('has correct series', () => {
|
||||
expect(cpuUsageChart).to.not.empty();
|
||||
expectSnapshot(cpuUsageChart?.series.map(({ title }) => title)).toMatchInline(`
|
||||
Array [
|
||||
"G1 Old Generation",
|
||||
"G1 Young Generation",
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
"G1 Old Generation",
|
||||
"G1 Young Generation",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('has correct series overall values', () => {
|
||||
expectSnapshot(cpuUsageChart?.series.map(({ overallValue }) => overallValue))
|
||||
.toMatchInline(`
|
||||
Array [
|
||||
0,
|
||||
3,
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
0,
|
||||
3,
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -385,21 +385,21 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
it('has correct series', () => {
|
||||
expect(cpuUsageChart).to.not.empty();
|
||||
expectSnapshot(cpuUsageChart?.series.map(({ title }) => title)).toMatchInline(`
|
||||
Array [
|
||||
"G1 Old Generation",
|
||||
"G1 Young Generation",
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
"G1 Old Generation",
|
||||
"G1 Young Generation",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('has correct series overall values', () => {
|
||||
expectSnapshot(cpuUsageChart?.series.map(({ overallValue }) => overallValue))
|
||||
.toMatchInline(`
|
||||
Array [
|
||||
0,
|
||||
37.5,
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
0,
|
||||
37500,
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -419,26 +419,26 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
|
||||
expect(systemMemoryUsageChart).to.not.empty();
|
||||
expectSnapshot(systemMemoryUsageChart?.series.map(({ title }) => title)).toMatchInline(`
|
||||
Array [
|
||||
"Max",
|
||||
"Average",
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
"Max",
|
||||
"Average",
|
||||
]
|
||||
`);
|
||||
expectSnapshot(systemMemoryUsageChart?.series.map(({ overallValue }) => overallValue))
|
||||
.toMatchInline(`
|
||||
Array [
|
||||
0.114523896426499,
|
||||
0.114002376090415,
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
0.114523896426499,
|
||||
0.114002376090415,
|
||||
]
|
||||
`);
|
||||
|
||||
const yValues = systemMemoryUsageChart?.series.map((serie) => first(serie.data)?.y);
|
||||
expectSnapshot(yValues).toMatchInline(`
|
||||
Array [
|
||||
0.11383724014064,
|
||||
0.11383724014064,
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
0.11383724014064,
|
||||
0.11383724014064,
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue