master-data-management-react 0.0.1 → 0.1.2

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/README.md CHANGED
@@ -1,127 +1,191 @@
1
- # Master Data Management React Package
2
1
 
3
- A flexible React package for managing master data with dynamic forms, tables, and multi-column sorting.
2
+ # master-data-management-react
4
3
 
5
- ## Features
4
+ A reusable **React library** for managing master data using **metadata-driven forms and tables**.
5
+ It automatically generates grids and forms while letting you fully control **APIs, routing, and authentication**.
6
6
 
7
- - 🔄 **Dynamic Entity Management** - Auto-generated forms and grids from metadata
8
- - 🎯 **Flexible Filtering** - Text, number, date, dropdown, and date-range filters
9
- - ✅ **Full CRUD** - Create, read, update with auto-generated forms
10
- - 📊 **Advanced Grid** - AG Grid with pagination, multi-column sorting, export (CSV/Excel)
11
- - 🎨 **Material-UI** - Built with MUI components and theming
7
+ ---
12
8
 
13
- ## Installation
9
+ ## ✨ Features
10
+
11
+ - 📊 **Server-side data grid**
12
+ - Pagination
13
+ - Filters
14
+ - Multi-column sorting
15
+ - 📝 **Auto-generated forms**
16
+ - Create / View / Edit
17
+ - 🔄 **Full CRUD support**
18
+ - 📤 **CSV & Excel export**
19
+ - 🎯 **Metadata-driven UI** (no hardcoded fields)
20
+ - 🎨 **Material-UI based components**
21
+ - 🧩 **Works with any backend and routing setup**
22
+
23
+ ---
24
+
25
+ ## 📦 Installation
14
26
 
15
27
  ```bash
16
28
  npm install master-data-management-react
17
- ```
29
+ ````
30
+
31
+ ---
32
+
33
+ ## 📚 Peer Dependencies
18
34
 
19
- **Peer Dependencies:**
20
35
  ```bash
21
- npm install react react-dom react-router-dom @mui/material @emotion/react @emotion/styled ag-grid-react ag-grid-community
36
+ npm install react react-dom react-router-dom axios \
37
+ @mui/material @emotion/react @emotion/styled \
38
+ ag-grid-react ag-grid-community
22
39
  ```
23
40
 
24
- ## Quick Start
25
-
26
- ```tsx
27
- import { MasterDataProvider, AppRoutes } from 'master-data-management-react';
28
- import 'master-data-management-react/styles';
29
- import axios from 'axios';
41
+ ---
30
42
 
31
- const apiClient = axios.create({ baseURL: 'http://localhost:3000/api' });
43
+ ## 🚀 Quick Start
32
44
 
33
- function App() {
45
+ ```tsx
46
+ import { MasterView } from "master-data-management-react";
47
+ import axios from "axios";
48
+
49
+ const apiClient = axios.create({
50
+ baseURL: "https://api.example.com",
51
+ });
52
+
53
+ const apiEndpoints = {
54
+ entities: "/master/entities",
55
+ metadata: (entity) => `/master/${entity}/metadata`,
56
+ records: (entity) => `/master/${entity}/records`,
57
+ recordById: (entity, id) => `/master/${entity}/records/${id}`,
58
+ exportCSV: (entity) => `/master/${entity}/export/csv`,
59
+ exportExcel: (entity) => `/master/${entity}/export/excel`,
60
+ };
61
+
62
+ export default function App() {
34
63
  return (
35
- <MasterDataProvider apiClient={apiClient}>
36
- <AppRoutes />
37
- </MasterDataProvider>
64
+ <MasterView
65
+ apiClient={apiClient}
66
+ apiEndpoints={apiEndpoints}
67
+ />
38
68
  );
39
69
  }
40
70
  ```
41
71
 
42
- ## Configuration
72
+ ---
43
73
 
44
- ### Custom Endpoints
74
+ ## 📝 Forms (Create / View / Edit)
45
75
 
46
76
  ```tsx
47
- <MasterDataProvider
77
+ import { MasterForm } from "master-data-management-react";
78
+ import { FORM_MODES } from "master-data-management-react/constants";
79
+
80
+ <MasterForm
48
81
  apiClient={apiClient}
49
- apiEndpoints={{
50
- entities: '/custom/entities',
51
- metadata: (entity) => `/custom/${entity}/meta`,
52
- records: (entity) => `/custom/${entity}/data`,
53
- }}
54
- />
82
+ apiEndpoints={apiEndpoints}
83
+ entity="country"
84
+ id="10"
85
+ mode={FORM_MODES.EDIT}
86
+ onBack={() => navigate("/master")}
87
+ onSuccess={() => navigate("/master")}
88
+ />;
55
89
  ```
56
90
 
57
- ### Custom Routes
91
+ ---
92
+
93
+ ## 🧭 Routing (Example)
94
+
95
+ This package **does not enforce routing**.
96
+ You define routes however your application prefers.
58
97
 
59
98
  ```tsx
60
- <MasterDataProvider
61
- routes={{ basePath: '/admin/master' }}
62
- />
99
+ <Route path="master" element={<MasterView />} />
100
+ <Route path="master/:entity/new" element={<MasterForm />} />
101
+ <Route path="master/:entity/:id" element={<MasterForm />} />
102
+ <Route path="master/:entity/:id/edit" element={<MasterForm />} />
63
103
  ```
64
104
 
65
- ## API Requirements
66
-
67
- Your backend must implement these endpoints:
105
+ ---
68
106
 
69
- | Endpoint | Method | Description |
70
- |----------|--------|-------------|
71
- | `/master/entities` | GET | List all entities |
72
- | `/master/:entity/metadata` | GET | Entity metadata (fields, form config) |
73
- | `/master/:entity/records` | GET | Records with filters/sort/pagination |
74
- | `/master/:entity/records/:id` | GET | Single record |
75
- | `/master/:entity/records` | POST | Create record |
76
- | `/master/:entity/records/:id` | PUT | Update record |
77
- | `/master/:entity/export/csv` | GET | Export to CSV |
78
- | `/master/:entity/export/excel` | GET | Export to Excel |
107
+ ## 🎨 Styling
79
108
 
80
- ### Multi-Column Sorting
109
+ Import styles **once** in your app entry file:
81
110
 
82
- Supports comma-separated sorting:
83
- ```
84
- GET /master/country/records?sortBy=countryName,isoCode&sortOrder=ASC,DESC
111
+ ```ts
112
+ import "master-data-management-react/dist/style.css";
113
+ import "ag-grid-community/styles/ag-grid.css";
114
+ import "ag-grid-community/styles/ag-theme-alpine.css";
85
115
  ```
86
116
 
87
- ## Metadata Format
117
+ ---
118
+
119
+ ## 🔗 Backend API Contract
120
+
121
+ Your backend must expose the following endpoints:
122
+
123
+ | Endpoint | Method |
124
+ | ------------------------------ | ------ |
125
+ | `/master/entities` | GET |
126
+ | `/master/:entity/metadata` | GET |
127
+ | `/master/:entity/records` | GET |
128
+ | `/master/:entity/records/:id` | GET |
129
+ | `/master/:entity/records` | POST |
130
+ | `/master/:entity/records/:id` | PUT |
131
+ | `/master/:entity/export/csv` | GET |
132
+ | `/master/:entity/export/excel` | GET |
133
+
134
+ ---
135
+
136
+ ## 🧩 Metadata Example
88
137
 
89
138
  ```json
90
139
  {
91
140
  "parameterList": [
92
- { "name": "countryName", "label": "Country", "dataType": "string", "options": null },
93
- { "name": "regionId", "label": "Region", "dataType": "string", "options": [...] }
141
+ { "name": "countryName", "label": "Country", "dataType": "string" }
94
142
  ],
95
143
  "resultsList": [
96
- { "name": "countryName", "label": "Country Name", "dataType": "string" },
97
- { "name": "isoCode", "label": "ISO Code", "dataType": "string" }
144
+ { "name": "countryName", "label": "Country Name" }
98
145
  ],
99
146
  "formConfig": {
100
147
  "Country Name": {
101
148
  "fieldName": "countryName",
102
- "dataType": "string",
103
149
  "fieldType": "input",
104
- "validation": { "max": 100 }
150
+ "validation": { "required": true }
105
151
  }
106
152
  }
107
153
  }
108
154
  ```
109
155
 
110
- ## Routes
156
+ ---
111
157
 
112
- - `/master` - Grid view with filters
113
- - `/master/:entity/new` - Create form
114
- - `/master/:entity/:id` - View form
115
- - `/master/:entity/:id/edit` - Edit form
158
+ ## ⚙️ Customization
116
159
 
117
- ## Development
160
+ You can customize:
118
161
 
119
- ```bash
120
- npm run dev # Start dev server
121
- npm run build:lib # Build package
122
- ```
162
+ * ✅ API URLs
163
+ * Axios instance (auth, interceptors, refresh tokens)
164
+ * Routing & navigation
165
+ * ✅ Permissions / guards
166
+ * ✅ Styling & MUI theme
167
+ * ✅ Backend metadata behavior
168
+
169
+ ---
170
+
171
+ ## ❌ What This Package Does NOT Do
172
+
173
+ * ❌ Force routing
174
+ * ❌ Handle authentication
175
+ * ❌ Assume backend structure
176
+
177
+ ---
178
+
179
+ ## 🧠 How It Works (Simple)
180
+
181
+ 1. Backend sends metadata
182
+ 2. Grid & forms render automatically
183
+ 3. CRUD, sorting, filtering handled internally
184
+ 4. You control navigation and APIs
185
+ 5. If wanted auto routes then use backend package master-data-management (npm i master-data-management) works for nestjs typeorm
123
186
 
124
- ## License
187
+ ---
125
188
 
126
- MIT
189
+ ## 📄 License
127
190
 
191
+ **MIT License**
@@ -1,13 +1,25 @@
1
- export declare const Wrapper: import("@emotion/styled").StyledComponent<import("@mui/system").BoxOwnProps<import("@mui/material").Theme> & Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import("@mui/system").BoxOwnProps<import("@mui/material").Theme>> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
1
+ export declare const Wrapper: import("@emotion/styled").StyledComponent<import("@mui/system").BoxOwnProps<import("@mui/material").Theme> & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
2
+ ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
3
+ }, keyof import("@mui/system").BoxOwnProps<import("@mui/material").Theme>> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
2
4
  export declare const GridContainer: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
3
- export declare const Loader: import("@emotion/styled").StyledComponent<import("@mui/system").BoxOwnProps<import("@mui/material").Theme> & Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import("@mui/system").BoxOwnProps<import("@mui/material").Theme>> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
4
- export declare const PaginationContainer: import("@emotion/styled").StyledComponent<import("@mui/system").BoxOwnProps<import("@mui/material").Theme> & Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import("@mui/system").BoxOwnProps<import("@mui/material").Theme>> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
5
+ export declare const Loader: import("@emotion/styled").StyledComponent<import("@mui/system").BoxOwnProps<import("@mui/material").Theme> & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
6
+ ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
7
+ }, keyof import("@mui/system").BoxOwnProps<import("@mui/material").Theme>> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
8
+ export declare const PaginationContainer: import("@emotion/styled").StyledComponent<import("@mui/system").BoxOwnProps<import("@mui/material").Theme> & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
9
+ ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
10
+ }, keyof import("@mui/system").BoxOwnProps<import("@mui/material").Theme>> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
5
11
  export declare const StyledSelect: import("@emotion/styled").StyledComponent<import("@mui/material").SelectProps<unknown> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
6
12
  interface StyledAgGridWrapperProps {
7
13
  height?: number;
8
14
  }
9
- export declare const StyledAgGridWrapper: import("@emotion/styled").StyledComponent<import("@mui/system").BoxOwnProps<import("@mui/material").Theme> & Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import("@mui/system").BoxOwnProps<import("@mui/material").Theme>> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & StyledAgGridWrapperProps, {}, {}>;
10
- export declare const ServerSideGridStyledFormControl: import("@emotion/styled").StyledComponent<import("@mui/material").FormControlOwnProps & import("@mui/material/OverridableComponent").CommonProps & Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "children" | "style" | "color" | "margin" | "sx" | "className" | "classes" | "disabled" | "error" | "fullWidth" | "required" | "size" | "hiddenLabel" | "focused" | "variant"> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
11
- export declare const StyledBox: import("@emotion/styled").StyledComponent<import("@mui/system").BoxOwnProps<import("@mui/material").Theme> & Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import("@mui/system").BoxOwnProps<import("@mui/material").Theme>> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
15
+ export declare const StyledAgGridWrapper: import("@emotion/styled").StyledComponent<import("@mui/system").BoxOwnProps<import("@mui/material").Theme> & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
16
+ ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
17
+ }, keyof import("@mui/system").BoxOwnProps<import("@mui/material").Theme>> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & StyledAgGridWrapperProps, {}, {}>;
18
+ export declare const ServerSideGridStyledFormControl: import("@emotion/styled").StyledComponent<import("@mui/material").FormControlOwnProps & import("@mui/material/OverridableComponent").CommonProps & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
19
+ ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
20
+ }, "style" | "className" | "color" | "children" | "margin" | "sx" | "classes" | "disabled" | "error" | "fullWidth" | "required" | "size" | "hiddenLabel" | "focused" | "variant"> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
21
+ export declare const StyledBox: import("@emotion/styled").StyledComponent<import("@mui/system").BoxOwnProps<import("@mui/material").Theme> & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
22
+ ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
23
+ }, keyof import("@mui/system").BoxOwnProps<import("@mui/material").Theme>> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
12
24
  export {};
13
25
  //# sourceMappingURL=styles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/components/ServerSideGrid/styles.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,OAAO,mXAGjB,CAAC;AAEJ,eAAO,MAAM,aAAa,6NAuCvB,CAAC;AAEJ,eAAO,MAAM,MAAM,mXAQhB,CAAC;AAEJ,eAAO,MAAM,mBAAmB,mXAe7B,CAAC;AAEJ,eAAO,MAAM,YAAY,6KAgBtB,CAAC;AAEJ,UAAU,wBAAwB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,mBAAmB,8YAoC/B,CAAC;AAEF,eAAO,MAAM,+BAA+B,ggBAW3C,CAAC;AAEF,eAAO,MAAM,SAAS,mXAMnB,CAAC"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/components/ServerSideGrid/styles.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,OAAO;;+JAGjB,CAAC;AAEJ,eAAO,MAAM,aAAa,6NAuCvB,CAAC;AAEJ,eAAO,MAAM,MAAM;;+JAQhB,CAAC;AAEJ,eAAO,MAAM,mBAAmB;;+JAe7B,CAAC;AAEJ,eAAO,MAAM,YAAY,6KAgBtB,CAAC;AAEJ,UAAU,wBAAwB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,mBAAmB;;0LAoC/B,CAAC;AAEF,eAAO,MAAM,+BAA+B;;sQAW3C,CAAC;AAEF,eAAO,MAAM,SAAS;;+JAMnB,CAAC"}
@@ -1,8 +1,26 @@
1
1
  /**
2
2
  * API Service Hook
3
- * Provides default API implementations using context config
4
- * Can be fully overridden via apiService in config
3
+ * Provides API operations with configurable axios instance and endpoints
5
4
  */
6
- import type { ApiServiceFunctions } from '../contexts/MasterDataContext';
7
- export declare const useApiService: () => Required<ApiServiceFunctions>;
5
+ import type { AxiosInstance } from 'axios';
6
+ export interface ApiEndpoints {
7
+ entities: string;
8
+ metadata: (entity: string) => string;
9
+ records: (entity: string) => string;
10
+ recordById: (entity: string, id: string | number) => string;
11
+ exportCSV: (entity: string) => string;
12
+ exportExcel: (entity: string) => string;
13
+ }
14
+ export interface ApiService {
15
+ getEntities: () => Promise<any>;
16
+ getMetadata: (entity: string) => Promise<any>;
17
+ getRecords: (entity: string, params?: any) => Promise<any>;
18
+ getRecord: (entity: string, id: string | number) => Promise<any>;
19
+ createRecord: (entity: string, data: any) => Promise<any>;
20
+ updateRecord: (entity: string, id: string | number, data: any) => Promise<any>;
21
+ deleteRecord: (entity: string, id: string | number) => Promise<any>;
22
+ exportCSV: (entity: string, params?: any) => Promise<any>;
23
+ exportExcel: (entity: string, params?: any) => Promise<any>;
24
+ }
25
+ export declare const createApiService: (apiClient: AxiosInstance, endpoints: ApiEndpoints) => ApiService;
8
26
  //# sourceMappingURL=useApiService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useApiService.d.ts","sourceRoot":"","sources":["../../src/hooks/useApiService.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,eAAO,MAAM,aAAa,QAAO,QAAQ,CAAC,mBAAmB,CAgB5D,CAAC"}
1
+ {"version":3,"file":"useApiService.d.ts","sourceRoot":"","sources":["../../src/hooks/useApiService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,KAAK,MAAM,CAAC;IAC5D,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;CACzC;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;IAChC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9C,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3D,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IACjE,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1D,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/E,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IACpE,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1D,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;CAC7D;AAED,eAAO,MAAM,gBAAgB,GAC3B,WAAW,aAAa,EACxB,WAAW,YAAY,KACtB,UAoEF,CAAC"}