@centreon/ui 23.10.18-MON-17793-create-graph-component-centreon-ui.19 → 23.10.18-MON-17793-create-graph-component-centreon-ui.20

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.
Files changed (41) hide show
  1. package/package.json +3 -1
  2. package/src/Button/Save/index.stories.tsx +10 -5
  3. package/src/Graph/BasicComponents/Lines/RegularLines/index.tsx +1 -1
  4. package/src/Graph/BasicComponents/Lines/Threshold/BasicThreshold.tsx +5 -6
  5. package/src/Graph/BasicComponents/Lines/Threshold/Circle.tsx +9 -11
  6. package/src/Graph/BasicComponents/Lines/Threshold/ThresholdWithPatternLines.tsx +14 -23
  7. package/src/Graph/BasicComponents/Lines/Threshold/ThresholdWithVariation.tsx +28 -41
  8. package/src/Graph/BasicComponents/Lines/Threshold/helpers/index.ts +14 -67
  9. package/src/Graph/BasicComponents/Lines/Threshold/index.tsx +125 -27
  10. package/src/Graph/BasicComponents/Lines/Threshold/models.ts +61 -17
  11. package/src/Graph/BasicComponents/Lines/Threshold/useCoordinateCircle.ts +9 -22
  12. package/src/Graph/BasicComponents/Lines/Threshold/useScaleThreshold.ts +171 -0
  13. package/src/Graph/BasicComponents/Lines/index.tsx +19 -80
  14. package/src/Graph/BasicComponents/useFilterLines.ts +3 -2
  15. package/src/Graph/Graph.tsx +3 -2
  16. package/src/Graph/helpers/doc.ts +66 -73
  17. package/src/Graph/helpers/index.ts +3 -33
  18. package/src/Graph/index.stories.tsx +66 -54
  19. package/src/Graph/index.tsx +1 -1
  20. package/src/Graph/mockedData/exclusionPeriodFirstPeriod.json +306 -432
  21. package/src/Graph/mockedData/exclusionPeriodSecondPeriod.json +306 -565
  22. package/src/Graph/mockedData/exclusionPeriodThirdPeriod.json +299 -152
  23. package/src/Graph/mockedData/lastDay.json +601 -1281
  24. package/src/Graph/mockedData/lastDayThreshold.json +2054 -2054
  25. package/src/Graph/models.ts +27 -4
  26. package/src/Graph/useGraphData.ts +1 -1
  27. package/src/InputField/Text/index.tsx +3 -0
  28. package/src/Snackbar/index.tsx +14 -4
  29. package/src/Snackbar/useSnackbar.tsx +5 -1
  30. package/src/TimePeriods/ResolutionTimePeriod.cypress.spec.tsx +2 -2
  31. package/src/TimePeriods/index.stories.tsx +7 -7
  32. package/src/TimePeriods/index.tsx +4 -4
  33. package/src/TimePeriods/{useAwesomeTimePeriod.ts → useTimePeriod.ts} +2 -2
  34. package/src/components/Button/Button.tsx +1 -1
  35. package/src/components/Form/Dashboard/Dashboard.resource.ts +1 -1
  36. package/src/components/Form/Dashboard/DashboardForm.tsx +10 -6
  37. package/src/components/Form/Dashboard/translatedLabels.ts +1 -0
  38. package/src/utils/index.ts +1 -0
  39. package/src/utils/sanitizedHTML.ts +18 -0
  40. package/src/Graph/BasicComponents/Lines/Threshold/useDataThreshold.ts +0 -114
  41. package/src/Graph/mockedData/exclusionPeriodFourthPeriod.json +0 -588
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "23.10.18-MON-17793-create-graph-component-centreon-ui.19",
3
+ "version": "23.10.18-MON-17793-create-graph-component-centreon-ui.20",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings 0",
@@ -104,8 +104,10 @@
104
104
  "lexical": "0.8.0",
105
105
  "notistack": "^2.0.8",
106
106
  "react-grid-layout": "^1.3.4",
107
+ "react-html-parser": "^2.0.2",
107
108
  "react-resizable": "^3.0.5",
108
109
  "react-transition-group": "^4.4.5",
110
+ "sanitize-html": "^2.10.0",
109
111
  "ulog": "^2.0.0-beta.19"
110
112
  },
111
113
  "peerDependencies": {
@@ -1,4 +1,4 @@
1
- import { ComponentMeta, ComponentStory } from '@storybook/react';
1
+ import { ComponentStory } from '@storybook/react';
2
2
  import { makeStyles } from 'tss-react/mui';
3
3
 
4
4
  import { Theme } from '@mui/material';
@@ -13,7 +13,7 @@ const useStyles = makeStyles()((theme: Theme) => ({
13
13
  }
14
14
  }));
15
15
 
16
- export default {
16
+ const meta = {
17
17
  argTypes: {
18
18
  labelLoading: { control: 'text' },
19
19
  labelSave: { control: 'text' },
@@ -26,8 +26,13 @@ export default {
26
26
 
27
27
  component: ButtonSave,
28
28
 
29
+ parameters: {
30
+ chromatic: { delay: 300 }
31
+ },
29
32
  title: 'Button/Save'
30
- } as ComponentMeta<typeof ButtonSave>;
33
+ };
34
+
35
+ export default meta;
31
36
 
32
37
  const TemplateButtonSave: ComponentStory<typeof ButtonSave> = (args) => (
33
38
  <ButtonSave {...args} />
@@ -42,7 +47,7 @@ export const loading = (): JSX.Element => <ButtonSave loading />;
42
47
  export const succeeded = (): JSX.Element => <ButtonSave succeeded />;
43
48
 
44
49
  export const normalWithText = (): JSX.Element => (
45
- <ButtonSave labelSave="Save" />
50
+ <ButtonSave labelSave="Save" size="medium" />
46
51
  );
47
52
 
48
53
  export const largeWithText = (): JSX.Element => (
@@ -50,7 +55,7 @@ export const largeWithText = (): JSX.Element => (
50
55
  );
51
56
 
52
57
  export const loadingWithTextAndMediumSize = (): JSX.Element => (
53
- <ButtonSave loading labelLoading="Loading" />
58
+ <ButtonSave loading labelLoading="Loading" size="medium" />
54
59
  );
55
60
 
56
61
  export const succeededWithText = (): JSX.Element => (
@@ -43,7 +43,7 @@ const RegularLine = ({
43
43
  curve: Curve.curveLinear,
44
44
  data: timeSeries,
45
45
  defined: (value): boolean => !isNil(value[metric]),
46
- opacity: highlight === false ? 0.3 : 1,
46
+ opacity: !highlight ? 0.7 : 1,
47
47
  stroke: lineColor,
48
48
  strokeWidth: isHighlighted,
49
49
  unit,
@@ -1,5 +1,4 @@
1
1
  import { curveBasis } from '@visx/curve';
2
- import { ScaleLinear } from 'd3-scale';
3
2
  import { Threshold } from '@visx/threshold';
4
3
 
5
4
  import { TimeValue } from '../../../timeSeries/models';
@@ -8,11 +7,11 @@ interface Props {
8
7
  fillAboveArea: string;
9
8
  fillBelowArea: string;
10
9
  fillOpacity?: number;
11
- getX: ScaleLinear<number, number>;
12
- getY0: ScaleLinear<number, number>;
13
- getY1: ScaleLinear<number, number>;
10
+ getX: (timeValue: TimeValue) => number;
11
+ getY0: (timeValue: TimeValue) => number;
12
+ getY1: (timeValue: TimeValue) => number;
14
13
  graphHeight: number;
15
- id?: string;
14
+ id: string;
16
15
  timeSeries: Array<TimeValue>;
17
16
  }
18
17
 
@@ -23,7 +22,7 @@ const BasicThreshold = ({
23
22
  graphHeight,
24
23
  timeSeries,
25
24
  fillOpacity = 0.1,
26
- id = 'threshold',
25
+ id,
27
26
  fillAboveArea,
28
27
  fillBelowArea
29
28
  }: Props): JSX.Element => {
@@ -5,22 +5,20 @@ import { Circle } from './models';
5
5
  import useCoordinateCircle from './useCoordinateCircle';
6
6
 
7
7
  const Circle = ({
8
- dataY0,
9
- dataY1,
10
- dataYOrigin,
11
- xScale,
12
- factors,
8
+ getY0Variation,
9
+ getY1Variation,
10
+ getYOrigin,
13
11
  timeSeries,
12
+ getX,
14
13
  getCountDisplayedCircles
15
14
  }: Circle): JSX.Element | null => {
16
15
  const coordinates = useCoordinateCircle({
17
- dataY0,
18
- dataY1,
19
- dataYOrigin,
20
- factors,
21
16
  getCountDisplayedCircles,
22
- timeSeries,
23
- xScale
17
+ getX,
18
+ getY0Variation,
19
+ getY1Variation,
20
+ getYOrigin,
21
+ timeSeries
24
22
  });
25
23
 
26
24
  if (isEmpty(coordinates) || isNil(coordinates)) {
@@ -1,22 +1,20 @@
1
1
  import { PatternLines } from '@visx/pattern';
2
2
  import { ScaleLinear } from 'd3-scale';
3
- import { prop } from 'ramda';
4
3
 
5
4
  import { useTheme } from '@mui/material/styles';
6
5
 
7
- import { getTime } from '../../../timeSeries/index';
8
- import { TimeValue } from '../../../timeSeries/models';
9
6
  import { adjustGraphData } from '../../../helpers/index';
10
- import { GraphData } from '../../../models';
7
+ import { GraphData, PatternOrientation } from '../../../models';
11
8
 
12
9
  import BasicThreshold from './BasicThreshold';
13
- import useDataThreshold from './useDataThreshold';
10
+ import useScaleThreshold from './useScaleThreshold';
14
11
 
15
12
  interface Props {
16
13
  data: GraphData;
17
- display: boolean;
18
14
  graphHeight: number;
15
+ id: string;
19
16
  leftScale: ScaleLinear<number, number>;
17
+ orientation?: Array<PatternOrientation>;
20
18
  rightScale: ScaleLinear<number, number>;
21
19
  xScale: ScaleLinear<number, number>;
22
20
  }
@@ -24,35 +22,27 @@ interface Props {
24
22
  const ThresholdWithPatternLines = ({
25
23
  graphHeight,
26
24
  data,
27
- display,
25
+ orientation = ['diagonal'],
28
26
  leftScale,
29
27
  rightScale,
30
- xScale
28
+ xScale,
29
+ id
31
30
  }: Props): JSX.Element | null => {
32
31
  const theme = useTheme();
33
32
 
34
33
  const { lines, timeSeries } = adjustGraphData(data);
35
34
 
36
- const { dataY0, dataY1, displayThreshold } = useDataThreshold({
37
- display,
35
+ const result = useScaleThreshold({
38
36
  leftScale,
39
37
  lines,
40
- rightScale
38
+ rightScale,
39
+ xScale
41
40
  });
42
-
43
- if (!dataY0 || !dataY1 || !displayThreshold) {
41
+ if (!result) {
44
42
  return null;
45
43
  }
46
- const { metric: metricY0, yScale: y0Scale } = dataY0;
47
- const { metric: metricY1, yScale: y1Scale } = dataY1;
48
-
49
- const getX = (timeValue: TimeValue): number => xScale(getTime(timeValue));
50
-
51
- const getY0 = (timeValue: TimeValue): number =>
52
- y0Scale(prop(metricY0, timeValue)) ?? null;
53
44
 
54
- const getY1 = (timeValue: TimeValue): number =>
55
- y1Scale(prop(metricY1, timeValue)) ?? null;
45
+ const { getX, getY0, getY1 } = result;
56
46
 
57
47
  return (
58
48
  <>
@@ -64,13 +54,14 @@ const ThresholdWithPatternLines = ({
64
54
  getY0={getY0}
65
55
  getY1={getY1}
66
56
  graphHeight={graphHeight}
57
+ id={id}
67
58
  timeSeries={timeSeries}
68
59
  />
69
60
  <PatternLines
70
61
  data-testid="patternLinesExclusionPeriods"
71
62
  height={5}
72
63
  id="lines"
73
- orientation={['diagonal']}
64
+ orientation={orientation}
74
65
  stroke={theme.palette.text.primary}
75
66
  strokeWidth={1}
76
67
  width={5}
@@ -1,72 +1,59 @@
1
1
  import { curveBasis } from '@visx/curve';
2
2
  import { LinePath } from '@visx/shape';
3
- import { ScaleLinear } from 'd3-scale';
4
3
 
5
4
  import { useTheme } from '@mui/material/styles';
6
5
 
7
- import { useMemoComponent } from '@centreon/ui';
8
-
9
6
  import { TimeValue } from '../../../timeSeries/models';
10
7
 
11
8
  import BasicThreshold from './BasicThreshold';
12
- import { Data, FactorsVariation } from './models';
13
- import { getVariationEnvelopThresholdData } from './helpers';
14
9
 
15
10
  interface Props {
16
- dataY0: Data;
17
- dataY1: Data;
18
- factors: FactorsVariation;
11
+ getX: (timeValue: TimeValue) => number;
12
+ getY0Variation: (timeValue: TimeValue) => number;
13
+ getY1Variation: (timeValue: TimeValue) => number;
19
14
  graphHeight: number;
15
+ lineColorY0: string;
16
+ lineColorY1: string;
20
17
  timeSeries: Array<TimeValue>;
21
- xScale: ScaleLinear<number, number>;
22
18
  }
23
19
 
24
20
  const ThresholdWithVariation = ({
25
- dataY0,
26
- dataY1,
27
21
  timeSeries,
28
- xScale,
22
+ getX,
23
+ getY0Variation,
24
+ getY1Variation,
29
25
  graphHeight,
30
- factors
26
+ lineColorY1,
27
+ lineColorY0
31
28
  }: Props): JSX.Element => {
32
29
  const theme = useTheme();
33
30
 
34
- const { getX, getY0, getY1, lineColorY0, lineColorY1 } =
35
- getVariationEnvelopThresholdData({
36
- dataY0,
37
- dataY1,
38
- factors,
39
- xScale
40
- });
41
-
42
31
  const props = {
43
32
  curve: curveBasis,
44
33
  data: timeSeries,
45
34
  stroke: theme.palette.secondary.main,
46
35
  strokeDasharray: 5,
47
- strokeOpacity: 0.8,
36
+ strokeOpacity: 0.9,
48
37
  x: getX
49
38
  };
50
39
 
51
- return useMemoComponent({
52
- Component: (
53
- <>
54
- <BasicThreshold
55
- fillAboveArea={lineColorY1}
56
- fillBelowArea={lineColorY0}
57
- getX={getX}
58
- getY0={getY0}
59
- getY1={getY1}
60
- graphHeight={graphHeight}
61
- timeSeries={timeSeries}
62
- />
63
-
64
- <LinePath {...props} y={getY0} />
65
- <LinePath {...props} y={getY1} />
66
- </>
67
- ),
68
- memoProps: [timeSeries, factors]
69
- });
40
+ return (
41
+ <>
42
+ <BasicThreshold
43
+ fillAboveArea={lineColorY1}
44
+ fillBelowArea={lineColorY0}
45
+ getX={getX}
46
+ getY0={getY0Variation}
47
+ getY1={getY1Variation}
48
+ graphHeight={graphHeight}
49
+ id="ThresholdWithVariation"
50
+ timeSeries={timeSeries}
51
+ />
52
+
53
+ <LinePath {...props} y={getY0Variation} />
54
+ <LinePath {...props} y={getY1Variation} />
55
+ </>
56
+ );
70
57
  };
71
58
 
72
59
  export default ThresholdWithVariation;
@@ -1,17 +1,11 @@
1
- import { isNil, prop } from 'ramda';
2
- import { ScaleLinear } from 'd3-scale';
1
+ import { isNil } from 'ramda';
3
2
 
4
3
  import {
5
4
  ArePointsOnline,
6
- Data,
7
- FactorsVariation,
8
- GetEnvelopeVariation,
5
+ EnvelopeVariationFormula,
9
6
  Online,
10
- Point,
11
- Result
7
+ Point
12
8
  } from '../models';
13
- import { TimeValue } from '../../../../timeSeries/models';
14
- import { getTime } from '../../../../timeSeries/index';
15
9
 
16
10
  export const checkArePointsOnline = ({
17
11
  pointOrigin,
@@ -58,65 +52,18 @@ export const checkArePointsOnline = ({
58
52
  return !arePointsOnline && arePointsDefined ? pointOrigin : null;
59
53
  };
60
54
 
61
- interface Props {
62
- dataY0: Data;
63
- dataY1: Data;
64
- factors: FactorsVariation;
65
- xScale: ScaleLinear<number, number>;
66
- }
55
+ export const envelopeVariationFormula = ({
56
+ upperRealValue,
57
+ lowerRealValue,
58
+ factorsData
59
+ }: EnvelopeVariationFormula): number => {
60
+ const { currentFactorMultiplication, simulatedFactorMultiplication } =
61
+ factorsData;
67
62
 
68
- export const getVariationEnvelopThresholdData = ({
69
- dataY0,
70
- dataY1,
71
- factors,
72
- xScale
73
- }: Props): Result => {
74
- const { lineColor: lineColorY0, metric: metricY0, yScale: y0Scale } = dataY0;
75
- const { lineColor: lineColorY1, metric: metricY1, yScale: y1Scale } = dataY1;
63
+ const variation = upperRealValue - lowerRealValue;
76
64
 
77
- const getEnvelopeVariation = ({
78
- metricUpper,
79
- metricLower,
80
- timeValue,
81
- factorsData
82
- }: GetEnvelopeVariation): number => {
83
- const upperRealValue = prop(metricUpper, timeValue);
84
- const lowerRealValue = prop(metricLower, timeValue);
65
+ const factor =
66
+ 1 - simulatedFactorMultiplication / currentFactorMultiplication;
85
67
 
86
- const { currentFactorMultiplication, simulatedFactorMultiplication } =
87
- factorsData;
88
-
89
- const variation = upperRealValue - lowerRealValue;
90
-
91
- const factor =
92
- 1 - simulatedFactorMultiplication / currentFactorMultiplication;
93
-
94
- return (variation / 2) * factor;
95
- };
96
-
97
- const getX = (timeValue: TimeValue): number =>
98
- xScale(getTime(timeValue)) as number;
99
-
100
- const getY0 = (timeValue: TimeValue): number => {
101
- const variation = getEnvelopeVariation({
102
- factorsData: factors,
103
- metricLower: metricY0,
104
- metricUpper: metricY1,
105
- timeValue
106
- });
107
-
108
- return y0Scale(prop(metricY0, timeValue) + variation) ?? null;
109
- };
110
- const getY1 = (timeValue: TimeValue): number => {
111
- const variation = getEnvelopeVariation({
112
- factorsData: factors,
113
- metricLower: metricY0,
114
- metricUpper: metricY1,
115
- timeValue
116
- });
117
-
118
- return y1Scale(prop(metricY1, timeValue) - variation) ?? null;
119
- };
120
-
121
- return { getX, getY0, getY1, lineColorY0, lineColorY1 };
68
+ return (variation / 2) * factor;
122
69
  };
@@ -1,40 +1,138 @@
1
- import { prop } from 'ramda';
1
+ import { equals, isNil } from 'ramda';
2
2
 
3
- import { getTime } from '../../../timeSeries/index';
3
+ import { displayArea } from '../../../helpers/index';
4
+ import {
5
+ PatternThreshold,
6
+ ThresholdType,
7
+ VariationThreshold
8
+ } from '../../../models';
4
9
  import { TimeValue } from '../../../timeSeries/models';
5
10
 
6
11
  import BasicThreshold from './BasicThreshold';
7
- import { ThresholdLinesModel } from './models';
12
+ import Circle from './Circle';
13
+ import ThresholdWithPatternLines from './ThresholdWithPatternLines';
14
+ import ThresholdWithVariation from './ThresholdWithVariation';
15
+ import { WrapperThresholdLinesModel } from './models';
16
+ import useScaleThreshold from './useScaleThreshold';
8
17
 
9
- const ThresholdLines = ({
10
- dataY0,
11
- dataY1,
18
+ interface Props extends WrapperThresholdLinesModel {
19
+ graphHeight: number;
20
+ timeSeries: Array<TimeValue>;
21
+ }
22
+
23
+ const WrapperThresholdLines = ({
24
+ areaThresholdLines,
25
+ graphHeight,
26
+ leftScale,
27
+ lines,
28
+ rightScale,
12
29
  timeSeries,
13
- xScale,
14
- graphHeight
15
- }: ThresholdLinesModel): JSX.Element => {
16
- const { lineColor: lineColorY0, metric: metricY0, yScale: y0Scale } = dataY0;
17
- const { lineColor: lineColorY1, metric: metricY1, yScale: y1Scale } = dataY1;
30
+ xScale
31
+ }: Props): JSX.Element | null => {
32
+ const data = useScaleThreshold({
33
+ areaThresholdLines,
34
+ leftScale,
35
+ lines,
36
+ rightScale,
37
+ xScale
38
+ });
39
+
40
+ if (!data) {
41
+ return null;
42
+ }
43
+
44
+ const { getX, getY0, getY1, lineColorY0, lineColorY1, ...rest } = data;
45
+
46
+ const commonProps = {
47
+ fillAboveArea: lineColorY0,
48
+ fillBelowArea: lineColorY1,
49
+ getX,
50
+ graphHeight,
51
+ timeSeries
52
+ };
53
+
54
+ const thresholdLines = areaThresholdLines?.map((item, index) => {
55
+ const { type } = item;
56
+
57
+ if (equals(type, ThresholdType.basic)) {
58
+ return [
59
+ {
60
+ Component: BasicThreshold,
61
+ key: index,
62
+ props: { ...commonProps, getY0, getY1 }
63
+ }
64
+ ];
65
+ }
66
+ if (equals(type, ThresholdType.variation)) {
67
+ const dataVariation = item as VariationThreshold;
68
+ if (!rest?.getY0Variation || !rest.getY1Variation || !rest.getYOrigin) {
69
+ return null;
70
+ }
71
+
72
+ return [
73
+ {
74
+ Component: ThresholdWithVariation,
75
+ key: index,
76
+ props: {
77
+ factors: dataVariation.factors,
78
+ ...commonProps,
79
+ ...rest
80
+ }
81
+ },
82
+ {
83
+ Component: Circle,
84
+ key: 'circle',
85
+ props: {
86
+ ...rest,
87
+ getCountDisplayedCircles: dataVariation?.getCountDisplayedCircles,
88
+ getX,
89
+ timeSeries
90
+ }
91
+ }
92
+ ];
93
+ }
94
+ if (equals(type, ThresholdType.pattern)) {
95
+ const dataPattern = item as PatternThreshold;
96
+
97
+ if (!displayArea(dataPattern?.data)) {
98
+ return null;
99
+ }
100
+
101
+ const { data: pattern } = dataPattern;
102
+
103
+ return pattern.map((element, ind) => ({
104
+ Component: ThresholdWithPatternLines,
105
+ key: ind,
106
+ props: {
107
+ data: element,
108
+ graphHeight,
109
+ key: ind,
110
+ leftScale,
111
+ orientation: dataPattern?.orientation,
112
+ rightScale,
113
+ xScale
114
+ }
115
+ }));
116
+ }
117
+
118
+ return null;
119
+ });
18
120
 
19
- const getX = (timeValue: TimeValue): number =>
20
- xScale(getTime(timeValue)) as number;
121
+ const filteredThresholdLines = thresholdLines?.filter((item) => !isNil(item));
21
122
 
22
- const getY0 = (timeValue: TimeValue): number =>
23
- y0Scale(prop(metricY0, timeValue)) ?? null;
24
- const getY1 = (timeValue: TimeValue): number =>
25
- y1Scale(prop(metricY1, timeValue)) ?? null;
123
+ if (!filteredThresholdLines) {
124
+ return null;
125
+ }
26
126
 
27
127
  return (
28
- <BasicThreshold
29
- fillAboveArea={lineColorY1}
30
- fillBelowArea={lineColorY0}
31
- getX={getX}
32
- getY0={getY0}
33
- getY1={getY1}
34
- graphHeight={graphHeight}
35
- timeSeries={timeSeries}
36
- />
128
+ <g>
129
+ {filteredThresholdLines.map((element) =>
130
+ element?.map(({ Component, props, key }) => (
131
+ <Component {...props} id={key} key={key} />
132
+ ))
133
+ )}
134
+ </g>
37
135
  );
38
136
  };
39
137
 
40
- export default ThresholdLines;
138
+ export default WrapperThresholdLines;