@oliasoft-open-source/charts-library 5.15.0 → 5.16.0-beta-1

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/dist/index.js CHANGED
@@ -1232,12 +1232,10 @@ var elasticOut = (t, s, p) => Math.pow(2, -10 * t) * Math.sin((t - s) * TAU / p)
1232
1232
  return atEdge(t) ? t : t < .5 ? .5 * elasticIn(t * 2, s, p) : .5 + .5 * elasticOut(t * 2 - 1, s, p);
1233
1233
  },
1234
1234
  easeInBack(t) {
1235
- const s = 1.70158;
1236
- return t * t * ((s + 1) * t - s);
1235
+ return t * t * (2.70158 * t - 1.70158);
1237
1236
  },
1238
1237
  easeOutBack(t) {
1239
- const s = 1.70158;
1240
- return (t -= 1) * t * ((s + 1) * t + s) + 1;
1238
+ return (t -= 1) * t * (2.70158 * t + 1.70158) + 1;
1241
1239
  },
1242
1240
  easeInOutBack(t) {
1243
1241
  let s = 1.70158;
@@ -19162,7 +19160,7 @@ var getMinorTickPositions = (majorTickPositions, scale) => {
19162
19160
  const minorTickWidth = getLargestMajorTickWidth(majorTickPositions) / 10;
19163
19161
  const startPosition = majorTickPositions[0];
19164
19162
  const numMinorTicks = (majorTickPositions.length + 1) * MINOR_TICKS_PER_MAJOR;
19165
- return [...Array(numMinorTicks)]?.map((_, index) => {
19163
+ return [...Array(numMinorTicks)].map((_, index) => {
19166
19164
  const minorTickPosition = startPosition + (index - MINOR_TICKS_PER_MAJOR + 1) * minorTickWidth;
19167
19165
  return parseFloat(minorTickPosition?.toFixed(1));
19168
19166
  })?.filter((position) => isValidPosition(position, sortedMajorTickPositions, scale));
@@ -24705,8 +24703,8 @@ var defaultGraph$2 = (graph) => ({
24705
24703
  var defaultLegend$2 = (legend) => ({
24706
24704
  display: legend?.display ?? true,
24707
24705
  useDataset: legend?.useDataset || false,
24708
- position: legend?.position || Position.Bottom,
24709
- align: legend?.align || AlignOptions.Center
24706
+ position: normalizeLegendPosition(legend?.position, Position.Bottom),
24707
+ align: normalizeLegendAlign(legend?.align, AlignOptions.Center)
24710
24708
  });
24711
24709
  var defaultChartOptions$2 = (options) => ({
24712
24710
  enableZoom: options?.enableZoom || false,
@@ -24720,7 +24718,7 @@ var defaultInteractions$2 = (interactions) => ({
24720
24718
  var defaultChartData$1 = (data) => {
24721
24719
  return {
24722
24720
  labels: data?.labels || [],
24723
- datasets: data?.datasets || []
24721
+ datasets: Array.isArray(data?.datasets) ? data.datasets : []
24724
24722
  };
24725
24723
  };
24726
24724
  var getDefaultProps$2 = (props) => {
@@ -24730,7 +24728,7 @@ var getDefaultProps$2 = (props) => {
24730
24728
  testId: chart?.testId ?? null,
24731
24729
  data: defaultChartData$1(chart?.data),
24732
24730
  options: {
24733
- title: options?.title || "",
24731
+ title: normalizeTitle(options?.title),
24734
24732
  chartStyling: defaultChartStyling$2(options?.chartStyling),
24735
24733
  tooltip: defaultTooltip$2(options?.tooltip),
24736
24734
  graph: defaultGraph$2(options?.graph),
@@ -26188,12 +26186,10 @@ var require_helpers_dataset = /* @__PURE__ */ __commonJSMin(((exports) => {
26188
26186
  return atEdge(t) ? t : t < .5 ? .5 * elasticIn(t * 2, s, p) : .5 + .5 * elasticOut(t * 2 - 1, s, p);
26189
26187
  },
26190
26188
  easeInBack(t) {
26191
- const s = 1.70158;
26192
- return t * t * ((s + 1) * t - s);
26189
+ return t * t * (2.70158 * t - 1.70158);
26193
26190
  },
26194
26191
  easeOutBack(t) {
26195
- const s = 1.70158;
26196
- return (t -= 1) * t * ((s + 1) * t + s) + 1;
26192
+ return (t -= 1) * t * (2.70158 * t + 1.70158) + 1;
26197
26193
  },
26198
26194
  easeInOutBack(t) {
26199
26195
  let s = 1.70158;
@@ -55,17 +55,17 @@ export interface IBarChartData extends ICommonData {
55
55
  data: IBarChartBaseData;
56
56
  options: IBarOptions;
57
57
  }
58
- type ILooseBarAxis = DeepPartial<ICommonAxis<string>> & {
58
+ type ILooseBarAxis = Omit<DeepPartial<ICommonAxis<string>>, 'gridLines'> & {
59
59
  [key: string]: unknown;
60
+ gridLines?: unknown;
60
61
  };
61
- type ILooseBarAnnotation = DeepPartial<ICommonAnnotationsData> & {
62
+ type ILooseBarAnnotation = Omit<DeepPartial<ICommonAnnotationsData>, 'annotationAxis'> & {
62
63
  [key: string]: unknown;
63
- } & {
64
64
  annotationAxis?: string;
65
65
  type?: string;
66
66
  value?: number | string | null;
67
67
  };
68
- export type IBarOptionsInput = Omit<DeepPartial<IBarOptions>, 'title' | 'direction' | 'axes' | 'legend' | 'chartStyling' | 'interactions' | 'annotations'> & {
68
+ export type IBarOptionsInput = Omit<DeepPartial<IBarOptions>, 'title' | 'direction' | 'axes' | 'legend' | 'chartStyling' | 'interactions' | 'annotations' | 'additionalAxesOptions' | 'scales'> & {
69
69
  [key: string]: unknown;
70
70
  title?: unknown;
71
71
  direction?: string;
@@ -84,12 +84,17 @@ export type IBarOptionsInput = Omit<DeepPartial<IBarOptions>, 'title' | 'directi
84
84
  minHeight?: number | string;
85
85
  [key: string]: unknown;
86
86
  };
87
+ additionalAxesOptions?: Omit<DeepPartial<IBarAdditionalAxesOptions>, 'chartScaleType'> & {
88
+ chartScaleType?: string;
89
+ [key: string]: unknown;
90
+ };
91
+ scales?: Record<string, unknown>;
87
92
  interactions?: DeepPartial<ICommonInteractions> & {
88
93
  enableZoom?: boolean;
89
94
  enablePan?: boolean;
90
95
  [key: string]: unknown;
91
96
  };
92
- annotations?: (DeepPartial<ICommonAnnotations> & {
97
+ annotations?: (Omit<DeepPartial<ICommonAnnotations>, 'annotationsData'> & {
93
98
  annotationsData?: ILooseBarAnnotation[];
94
99
  }) | null;
95
100
  };
@@ -5,7 +5,7 @@ import { AnnotationType as DraggableAnnotationType, DragAxis } from './plugins/a
5
5
  import { AlignOptions, Position } from './enums';
6
6
  import { ILineMarkersAnnotation } from '../line-chart/plugins/line-markers-plugin/types';
7
7
  export type TAxisPosition = 'top' | 'bottom' | 'left' | 'right';
8
- export type DeepPartial<T> = T extends (...args: unknown[]) => unknown ? T : T extends Array<infer U> ? Array<DeepPartial<U>> : T extends object ? {
8
+ export type DeepPartial<T> = T extends (...args: any[]) => any ? T : T extends Array<infer U> ? Array<DeepPartial<U>> : T extends object ? {
9
9
  [K in keyof T]?: DeepPartial<T[K]>;
10
10
  } : T;
11
11
  export interface ICommonDataValue {
@@ -139,9 +139,9 @@ export interface ICommonLegend {
139
139
  align?: AlignOptions;
140
140
  }
141
141
  export interface ICommonTooltipCallbacks {
142
- title?: () => void;
143
- label?: () => void;
144
- afterLabel?: () => void;
142
+ title?: (...args: unknown[]) => unknown;
143
+ label?: (...args: unknown[]) => unknown;
144
+ afterLabel?: (...args: unknown[]) => unknown;
145
145
  }
146
146
  export interface ICommonTooltip {
147
147
  tooltips?: boolean;
@@ -204,9 +204,9 @@ export interface ICommonDragData {
204
204
  roundPoints?: boolean;
205
205
  dragX?: boolean;
206
206
  dragY?: boolean;
207
- onDragStart?: () => void;
208
- onDrag?: () => void;
209
- onDragEnd?: () => void;
207
+ onDragStart?: (event: unknown, element: unknown) => unknown;
208
+ onDrag?: (event: unknown, datasetIndex: number, index: number, value: unknown) => unknown;
209
+ onDragEnd?: (event: unknown, datasetIndex: number, index: number, value: unknown) => unknown;
210
210
  }
211
211
  export interface ICommonOptions {
212
212
  title?: string | string[];
@@ -1,8 +1,6 @@
1
- import { Chart, ChartConfiguration, Plugin } from 'chart.js';
1
+ import { Plugin } from 'chart.js';
2
2
  /**
3
3
  * Gets an example custom legend plugin for use in storybook.
4
4
  * @param {string} customLegendContainerID - the id of the div container to put the generated legend in
5
5
  */
6
- export declare const getCustomLegendPlugin: (customLegendContainerID: string) => {
7
- afterUpdate(chart: Chart, _args: Plugin, _options: ChartConfiguration): void;
8
- };
6
+ export declare const getCustomLegendPlugin: (customLegendContainerID: string) => Plugin;
@@ -1,5 +1,5 @@
1
1
  import { Dispatch, RefObject } from 'react';
2
- import { Chart } from 'chart.js';
2
+ import { Chart, ChartOptions } from 'chart.js';
3
3
  import { IState } from '../state/state.interfaces';
4
4
  import { ILineChartOptions, TGeneratedLineChartDatasets } from '../line-chart.interface';
5
5
  interface IUseChartOptions {
@@ -13,7 +13,7 @@ interface IUseChartOptions {
13
13
  /**
14
14
  * Custom hook to generate chart options.
15
15
  */
16
- export declare const useChartOptions: ({ chartRef, state, options, dispatch, generatedDatasets, persistenceId, }: IUseChartOptions) => import('node_modules/chart.js/dist/types/utils')._DeepPartialObject<import('chart.js').CoreChartOptions<"line"> & import('chart.js').ElementChartOptions<"line"> & import('chart.js').PluginChartOptions<"line"> & import('chart.js').DatasetChartOptions<"line"> & import('chart.js').ScaleChartOptions<"line"> & import('chart.js').LineControllerChartOptions> & {
16
+ export declare const useChartOptions: ({ chartRef, state, options, dispatch, generatedDatasets, persistenceId, }: IUseChartOptions) => ChartOptions<"line"> & {
17
17
  persistenceId?: string;
18
18
  };
19
19
  export {};
@@ -7,6 +7,7 @@ export interface ILChartOptions extends ICommonChartOptions {
7
7
  enableZoom?: boolean;
8
8
  enablePan?: boolean;
9
9
  enableDragAnnotation?: boolean;
10
+ enableDragPoints?: boolean;
10
11
  }
11
12
  export interface ILineChartGraph {
12
13
  lineTension?: number;
@@ -38,7 +39,7 @@ export interface ILineChartAdditionalAxesOptions {
38
39
  export interface IUnitOptions {
39
40
  options: string[];
40
41
  selectedUnit: string;
41
- setSelectedUnit: () => void;
42
+ setSelectedUnit: (value: string) => void;
42
43
  }
43
44
  export interface ILineChartAxis<PositionType = TAxisPosition> {
44
45
  id?: string;
@@ -59,7 +60,7 @@ export interface ILineChartAxes {
59
60
  export interface IDepthType {
60
61
  options: string[];
61
62
  selectedUnit: string;
62
- setSelectedUnit: () => void;
63
+ setSelectedUnit: (value: string) => void;
63
64
  }
64
65
  export interface ILineChartStyling extends ICommonStyling {
65
66
  squareAspectRatio?: number | boolean;
@@ -92,9 +93,10 @@ export interface ILineChartOptions extends ICommonOptions {
92
93
  dragData?: ICommonDragData;
93
94
  depthType?: IDepthType | object;
94
95
  }
95
- type ILooseLineAxis = DeepPartial<ILineChartAxis<string>> & {
96
+ type ILooseLineAxis = Omit<DeepPartial<ILineChartAxis<string>>, 'gridLines'> & {
96
97
  [key: string]: unknown;
97
98
  stepSize?: unknown;
99
+ gridLines?: unknown;
98
100
  };
99
101
  type ILooseLineAnnotation = {
100
102
  [key: string]: unknown;
@@ -122,7 +124,7 @@ type ILooseLineAnnotation = {
122
124
  onDrag?: (...args: unknown[]) => void;
123
125
  onDragEnd?: (...args: unknown[]) => void;
124
126
  };
125
- export type ILineChartOptionsInput = Omit<DeepPartial<ILineChartOptions>, 'title' | 'axes' | 'legend' | 'chartStyling' | 'interactions' | 'graph' | 'annotations' | 'additionalAxesOptions'> & {
127
+ export type ILineChartOptionsInput = Omit<DeepPartial<ILineChartOptions>, 'title' | 'axes' | 'legend' | 'chartStyling' | 'interactions' | 'graph' | 'annotations' | 'additionalAxesOptions' | 'scales' | 'plugins'> & {
126
128
  [key: string]: unknown;
127
129
  title?: unknown;
128
130
  direction?: string;
@@ -131,6 +133,8 @@ export type ILineChartOptionsInput = Omit<DeepPartial<ILineChartOptions>, 'title
131
133
  y?: ILooseLineAxis[];
132
134
  [key: string]: ILooseLineAxis[] | undefined;
133
135
  };
136
+ scales?: Record<string, unknown>;
137
+ plugins?: Record<string, unknown>;
134
138
  legend?: Omit<DeepPartial<ILineLegend>, 'position' | 'align'> & {
135
139
  position?: string;
136
140
  align?: string;
@@ -153,7 +157,8 @@ export type ILineChartOptionsInput = Omit<DeepPartial<ILineChartOptions>, 'title
153
157
  annotations?: (Omit<DeepPartial<ICommonAnnotations>, 'annotationsData'> & {
154
158
  annotationsData?: ILooseLineAnnotation[];
155
159
  }) | ILooseLineAnnotation[] | null;
156
- additionalAxesOptions?: DeepPartial<ILineChartAdditionalAxesOptions> & {
160
+ additionalAxesOptions?: Omit<DeepPartial<ILineChartAdditionalAxesOptions>, 'chartScaleType'> & {
161
+ chartScaleType?: string;
157
162
  stepSize?: unknown;
158
163
  range?: ILineRange | ILineChartRange | Record<string, ILineChartRange | undefined>;
159
164
  } & Record<string, unknown>;
@@ -22,9 +22,9 @@ declare const getLineChartToolTips: (options: ILineChartOptions) => {
22
22
  boxHeight: number;
23
23
  boxPadding: number;
24
24
  callbacks: {
25
- title: (() => void) | ((tooltipItem: TooltipItem<any>[]) => string);
26
- label: (() => void) | ((tooltipItem: TooltipItem<any>) => string);
27
- afterLabel: (() => void) | ((tooltipItem: Record<string, any>) => string);
25
+ title: ((...args: unknown[]) => unknown) | ((tooltipItem: TooltipItem<any>[]) => string);
26
+ label: ((...args: unknown[]) => unknown) | ((tooltipItem: TooltipItem<any>) => string);
27
+ afterLabel: ((...args: unknown[]) => unknown) | ((tooltipItem: Record<string, any>) => string);
28
28
  };
29
29
  };
30
30
  export default getLineChartToolTips;
@@ -1,4 +1,4 @@
1
- import { IChartDataLabelsOptions, IChartGeneratedLabel, IChartLegendItemFilter, ICommonData, ICommonDataValue, ICommonDataset, ICommonLegend, ICommonOptions } from '../common/common.interface';
1
+ import { DeepPartial, IChartDataLabelsOptions, IChartGeneratedLabel, IChartLegendItemFilter, ICommonChartOptions, ICommonData, ICommonDataValue, ICommonDataset, ICommonLegend, ICommonOptions, ICommonStyling, ICommonTooltip } from '../common/common.interface';
2
2
  export interface IPieLegend extends ICommonLegend {
3
3
  useDataset?: boolean;
4
4
  }
@@ -35,8 +35,35 @@ export interface IPieChartData extends ICommonData {
35
35
  data: IPieData;
36
36
  options: IPieOptions;
37
37
  }
38
+ export type IPieOptionsInput = Omit<DeepPartial<IPieOptions>, 'title' | 'graph' | 'legend' | 'chartStyling' | 'tooltip' | 'chartOptions' | 'interactions'> & {
39
+ [key: string]: unknown;
40
+ title?: unknown;
41
+ graph?: DeepPartial<IPieGraph>;
42
+ legend?: Omit<DeepPartial<IPieLegend>, 'position' | 'align'> & {
43
+ position?: string;
44
+ align?: string;
45
+ [key: string]: unknown;
46
+ };
47
+ chartStyling?: DeepPartial<ICommonStyling> & {
48
+ [key: string]: unknown;
49
+ };
50
+ tooltip?: DeepPartial<ICommonTooltip>;
51
+ chartOptions?: DeepPartial<ICommonChartOptions>;
52
+ interactions?: DeepPartial<ICommonOptions['interactions']> & {
53
+ [key: string]: unknown;
54
+ };
55
+ };
56
+ export interface IPieChartDataInput extends Omit<IPieChartData, 'data' | 'options'> {
57
+ data?: Omit<DeepPartial<IPieChartData['data']>, 'datasets'> & {
58
+ datasets?: Array<(Omit<DeepPartial<IPieChartDataset>, 'data'> & {
59
+ data?: Array<DeepPartial<IPieDataValue> | number>;
60
+ [key: string]: unknown;
61
+ }) | object | null>;
62
+ };
63
+ options?: IPieOptionsInput;
64
+ }
38
65
  export interface IPieChartProps {
39
- chart: IPieChartData;
66
+ chart: IPieChartDataInput;
40
67
  testId?: string | null;
41
68
  }
42
69
  export type IPieGeneratedLabel = IChartGeneratedLabel;
@@ -48,14 +48,13 @@ export interface IScatterChartData extends ICommonData {
48
48
  type ILooseScatterAxis = DeepPartial<ICommonAxis<string>> & {
49
49
  [key: string]: unknown;
50
50
  };
51
- type ILooseScatterAnnotation = DeepPartial<ICommonAnnotationsData> & {
51
+ type ILooseScatterAnnotation = Omit<DeepPartial<ICommonAnnotationsData>, 'annotationAxis'> & {
52
52
  [key: string]: unknown;
53
- } & {
54
53
  annotationAxis?: string;
55
54
  type?: string;
56
55
  value?: number | string | null;
57
56
  };
58
- export type IScatterOptionsInput = Omit<DeepPartial<IScatterOptions>, 'title' | 'direction' | 'axes' | 'legend' | 'chartStyling' | 'interactions' | 'annotations'> & {
57
+ export type IScatterOptionsInput = Omit<DeepPartial<IScatterOptions>, 'title' | 'direction' | 'axes' | 'legend' | 'chartStyling' | 'interactions' | 'annotations' | 'scales'> & {
59
58
  [key: string]: unknown;
60
59
  title?: unknown;
61
60
  direction?: string;
@@ -64,6 +63,7 @@ export type IScatterOptionsInput = Omit<DeepPartial<IScatterOptions>, 'title' |
64
63
  y?: ILooseScatterAxis[];
65
64
  [key: string]: ILooseScatterAxis[] | undefined;
66
65
  };
66
+ scales?: Record<string, unknown>;
67
67
  legend?: Omit<DeepPartial<IScatterLegend>, 'position' | 'align'> & {
68
68
  position?: string;
69
69
  align?: string;
@@ -77,7 +77,7 @@ export type IScatterOptionsInput = Omit<DeepPartial<IScatterOptions>, 'title' |
77
77
  enablePan?: boolean;
78
78
  [key: string]: unknown;
79
79
  };
80
- annotations?: (DeepPartial<ICommonAnnotations> & {
80
+ annotations?: (Omit<DeepPartial<ICommonAnnotations>, 'annotationsData'> & {
81
81
  annotationsData?: ILooseScatterAnnotation[];
82
82
  }) | null;
83
83
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oliasoft-open-source/charts-library",
3
- "version": "5.15.0",
3
+ "version": "5.16.0-beta-1",
4
4
  "description": "React Chart Library (based on Chart.js and react-chart-js-2)",
5
5
  "homepage": "https://gitlab.com/oliasoft-open-source/charts-library",
6
6
  "bugs": {
@@ -46,20 +46,18 @@
46
46
  "react-use": "^17.6.0"
47
47
  },
48
48
  "devDependencies": {
49
- "@oliasoft-open-source/react-ui-library": "^5.21.5",
49
+ "@dnd-kit/sortable": "^10.0.0",
50
+ "@oliasoft-open-source/react-ui-library": "6.0.0-beta-3",
50
51
  "@oliasoft-open-source/units": "^5.0.0",
51
- "@storybook/addon-docs": "^10.2.17",
52
- "@storybook/addon-themes": "^10.2.17",
53
- "@storybook/react-vite": "^10.3.6",
54
- "@storybook/testing-library": "^0.2.2",
52
+ "@storybook/addon-docs": "^10.4.0",
53
+ "@storybook/addon-themes": "^10.4.0",
54
+ "@storybook/react-vite": "^10.4.0",
55
55
  "@types/node": "^22.15.17",
56
56
  "@types/object-hash": "^3.0.6",
57
57
  "@types/react": "^18.2.24",
58
- "@vitejs/plugin-react": "^6.0.1",
59
- "@vitest/coverage-v8": "4.1.6",
60
- "ajv": "8.17.1",
61
- "ajv-errors": "^3.0.0",
62
- "ajv-keywords": "^5.1.0",
58
+ "@types/react-dom": "^18.3.7",
59
+ "@vitejs/plugin-react": "^6.0.2",
60
+ "@vitest/coverage-v8": "4.1.7",
63
61
  "classnames": "^2.5.1",
64
62
  "es-toolkit": "^1.44.0",
65
63
  "http-server": "^14.1.1",
@@ -73,27 +71,22 @@
73
71
  "prettier": "3.5.3",
74
72
  "react": "^18.2.0",
75
73
  "react-dom": "^18.2.0",
76
- "rollup-plugin-peer-deps-external": "^2.2.4",
77
- "storybook": "^10.2.17",
78
- "typescript": "^5.9.3",
79
- "vite": "8.0.12",
74
+ "storybook": "^10.4.0",
75
+ "typescript": "^6.0.3",
76
+ "vite": "8.0.14",
80
77
  "vite-plugin-css-injected-by-js": "^5.0.1",
81
- "vite-plugin-dts": "^5.0.0",
82
- "vite-plugin-optimize-persist": "^0.1.2",
78
+ "vite-plugin-dts": "^5.0.1",
83
79
  "vite-plugin-svgr": "^5.2.0",
84
- "vitest": "^4.1.6"
80
+ "vitest": "^4.1.7"
85
81
  },
86
82
  "peerDependencies": {
87
- "@oliasoft-open-source/react-ui-library": "^5",
88
- "@oliasoft-open-source/units": "^4",
89
- "ajv": "^8.17.1",
90
- "ajv-errors": "^3.0.0",
91
- "ajv-keywords": "^5.1.0",
83
+ "@oliasoft-open-source/react-ui-library": "^6",
84
+ "@oliasoft-open-source/units": "^5",
92
85
  "classnames": "^2.5.1",
93
86
  "es-toolkit": "^1",
94
87
  "immer": "^9 || ^10",
95
- "react": "^17 || ^18",
96
- "react-dom": "^17 || ^18"
88
+ "react": "^18",
89
+ "react-dom": "^18"
97
90
  },
98
91
  "scripts": {
99
92
  "build:package": "tsc && vite build",
@@ -106,6 +99,7 @@
106
99
  "prettier:fix": "prettier --write \"**/*.{ts,tsx,js,jsx,json,css,less}\"",
107
100
  "preview:storybook": "pnpm exec http-server ./public -o -p 9005 -c-1",
108
101
  "test": "pnpm run prettier:check && pnpm run lint:check && pnpm run test:unit",
102
+ "test:stories:types": "tsc -p tsconfig.stories.json",
109
103
  "test:unit": "vitest run",
110
104
  "test:unit:coverage": "vitest run --coverage"
111
105
  }