@eeacms/volto-eea-map 3.3.0 → 4.0.0
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/.eslintrc.js +65 -0
- package/CHANGELOG.md +11 -1
- package/jest-addon.config.js +19 -4
- package/jest.setup.js +65 -0
- package/package.json +2 -1
- package/src/components/Blocks/EmbedEEAMap/Schema.js +2 -4
- package/src/components/Blocks/EmbedEEAMap/View.jsx +4 -3
- package/src/components/visualization/VisualizationEditorWidget.jsx +1 -1
- package/src/components/visualization/panelsSchema.js +3 -1
- package/src/components/widgets/LayerSelectWidget.jsx +2 -3
- package/src/components/widgets/LayersPanelWidget.jsx +4 -3
- package/src/components/widgets/SimpleColorPickerWidget.jsx +3 -1
- package/src/index.js +3 -1
- package/src/less/global.less +2 -2
- package/.project.eslintrc.js +0 -48
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const projectRootPath = fs.realpathSync(__dirname + '/../../../');
|
|
4
|
+
|
|
5
|
+
let voltoPath = path.join(projectRootPath, 'node_modules/@plone/volto');
|
|
6
|
+
let configFile;
|
|
7
|
+
if (fs.existsSync(`${projectRootPath}/tsconfig.json`))
|
|
8
|
+
configFile = `${projectRootPath}/tsconfig.json`;
|
|
9
|
+
else if (fs.existsSync(`${projectRootPath}/jsconfig.json`))
|
|
10
|
+
configFile = `${projectRootPath}/jsconfig.json`;
|
|
11
|
+
|
|
12
|
+
if (configFile) {
|
|
13
|
+
const jsConfig = require(configFile).compilerOptions;
|
|
14
|
+
const pathsConfig = jsConfig.paths;
|
|
15
|
+
if (pathsConfig['@plone/volto'])
|
|
16
|
+
voltoPath = `./${jsConfig.baseUrl}/${pathsConfig['@plone/volto'][0]}`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const AddonConfigurationRegistry = require(`${voltoPath}/addon-registry.js`);
|
|
20
|
+
const reg = new AddonConfigurationRegistry(projectRootPath);
|
|
21
|
+
|
|
22
|
+
// Extends ESlint configuration for adding the aliases to `src` directories in Volto addons
|
|
23
|
+
const addonAliases = Object.keys(reg.packages).map((o) => [
|
|
24
|
+
o,
|
|
25
|
+
reg.packages[o].modulePath,
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
const addonExtenders = reg.getEslintExtenders().map((m) => require(m));
|
|
29
|
+
|
|
30
|
+
const defaultConfig = {
|
|
31
|
+
extends: `${voltoPath}/.eslintrc`,
|
|
32
|
+
settings: {
|
|
33
|
+
'import/resolver': {
|
|
34
|
+
alias: {
|
|
35
|
+
map: [
|
|
36
|
+
['@plone/volto', '@plone/volto/src'],
|
|
37
|
+
['@plone/volto-slate', '@plone/volto/packages/volto-slate/src'],
|
|
38
|
+
...addonAliases,
|
|
39
|
+
['@package', `${__dirname}/src`],
|
|
40
|
+
['@root', `${__dirname}/src`],
|
|
41
|
+
['~', `${__dirname}/src`],
|
|
42
|
+
],
|
|
43
|
+
extensions: ['.js', '.jsx', '.json'],
|
|
44
|
+
},
|
|
45
|
+
'babel-plugin-root-import': {
|
|
46
|
+
rootPathSuffix: 'src',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
rules: {
|
|
51
|
+
'react/jsx-no-target-blank': [
|
|
52
|
+
'error',
|
|
53
|
+
{
|
|
54
|
+
allowReferrer: true,
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const config = addonExtenders.reduce(
|
|
61
|
+
(acc, extender) => extender.modify(acc),
|
|
62
|
+
defaultConfig,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
module.exports = config;
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
+
### [4.0.0](https://github.com/eea/volto-eea-map/compare/3.3.1...4.0.0) - 22 April 2024
|
|
8
|
+
|
|
9
|
+
#### :rocket: New Features
|
|
10
|
+
|
|
11
|
+
- feat: Release 4.0.0 - Volto 17 support [alin - [`7f7c700`](https://github.com/eea/volto-eea-map/commit/7f7c700d86f66633da0b6b439d14d29ba5f01eca)]
|
|
12
|
+
- feat: Volto 17 support - refs #264527 [EEA Jenkins - [`dec0c06`](https://github.com/eea/volto-eea-map/commit/dec0c06c3f3cfaf106c876a1a5aa896fcf5ad9b4)]
|
|
13
|
+
|
|
14
|
+
#### :hammer_and_wrench: Others
|
|
15
|
+
|
|
16
|
+
### [3.3.1](https://github.com/eea/volto-eea-map/compare/3.3.0...3.3.1) - 31 January 2024
|
|
17
|
+
|
|
7
18
|
### [3.3.0](https://github.com/eea/volto-eea-map/compare/3.2.1...3.3.0) - 17 January 2024
|
|
8
19
|
|
|
9
20
|
#### :rocket: New Features
|
|
@@ -19,7 +30,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
19
30
|
- use arcgis map for screenshot [andreiggr - [`94cc865`](https://github.com/eea/volto-eea-map/commit/94cc8651667ab351fc761b810634f3b124d6e6bb)]
|
|
20
31
|
- update checks to support older javascript engines(screenshoter) [andreiggr - [`7b58516`](https://github.com/eea/volto-eea-map/commit/7b5851628160a8ff474c6405a0285014eb7da05f)]
|
|
21
32
|
- better check map layers [andreiggr - [`d3e7d6b`](https://github.com/eea/volto-eea-map/commit/d3e7d6bfaa2e06b5de40c1e13bf9d39241d2c0c0)]
|
|
22
|
-
- PP screenshot to mapserver jsapi app [andreiggr - [`a0b4dd4`](https://github.com/eea/volto-eea-map/commit/a0b4dd4033e43bc34b11ede95435a7c76a0cb6b8)]
|
|
23
33
|
### [3.2.1](https://github.com/eea/volto-eea-map/compare/3.2.0...3.2.1) - 13 December 2023
|
|
24
34
|
|
|
25
35
|
### [3.2.0](https://github.com/eea/volto-eea-map/compare/3.1.0...3.2.0) - 13 December 2023
|
package/jest-addon.config.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require('dotenv').config({ path: __dirname + '/.env' })
|
|
2
|
+
|
|
1
3
|
module.exports = {
|
|
2
4
|
testMatch: ['**/src/addons/**/?(*.)+(spec|test).[jt]s?(x)'],
|
|
3
5
|
collectCoverageFrom: [
|
|
@@ -9,18 +11,26 @@ module.exports = {
|
|
|
9
11
|
'@plone/volto/cypress': '<rootDir>/node_modules/@plone/volto/cypress',
|
|
10
12
|
'@plone/volto/babel': '<rootDir>/node_modules/@plone/volto/babel',
|
|
11
13
|
'@plone/volto/(.*)$': '<rootDir>/node_modules/@plone/volto/src/$1',
|
|
12
|
-
'@package/(.*)$': '<rootDir>/src/$1',
|
|
13
|
-
'@root/(.*)$': '<rootDir>/src/$1',
|
|
14
|
+
'@package/(.*)$': '<rootDir>/node_modules/@plone/volto/src/$1',
|
|
15
|
+
'@root/(.*)$': '<rootDir>/node_modules/@plone/volto/src/$1',
|
|
14
16
|
'@plone/volto-quanta/(.*)$': '<rootDir>/src/addons/volto-quanta/src/$1',
|
|
17
|
+
'@eeacms/search/(.*)$': '<rootDir>/src/addons/volto-searchlib/searchlib/$1',
|
|
18
|
+
'@eeacms/search': '<rootDir>/src/addons/volto-searchlib/searchlib',
|
|
15
19
|
'@eeacms/(.*?)/(.*)$': '<rootDir>/node_modules/@eeacms/$1/src/$2',
|
|
16
|
-
'@plone/volto-slate':
|
|
20
|
+
'@plone/volto-slate$':
|
|
17
21
|
'<rootDir>/node_modules/@plone/volto/packages/volto-slate/src',
|
|
22
|
+
'@plone/volto-slate/(.*)$':
|
|
23
|
+
'<rootDir>/node_modules/@plone/volto/packages/volto-slate/src/$1',
|
|
18
24
|
'~/(.*)$': '<rootDir>/src/$1',
|
|
19
25
|
'load-volto-addons':
|
|
20
26
|
'<rootDir>/node_modules/@plone/volto/jest-addons-loader.js',
|
|
21
27
|
},
|
|
28
|
+
transformIgnorePatterns: [
|
|
29
|
+
'/node_modules/(?!(@plone|@root|@package|@eeacms)/).*/',
|
|
30
|
+
],
|
|
22
31
|
transform: {
|
|
23
32
|
'^.+\\.js(x)?$': 'babel-jest',
|
|
33
|
+
'^.+\\.ts(x)?$': 'babel-jest',
|
|
24
34
|
'^.+\\.(png)$': 'jest-file',
|
|
25
35
|
'^.+\\.(jpg)$': 'jest-file',
|
|
26
36
|
'^.+\\.(svg)$': './node_modules/@plone/volto/jest-svgsystem-transform.js',
|
|
@@ -33,4 +43,9 @@ module.exports = {
|
|
|
33
43
|
statements: 5,
|
|
34
44
|
},
|
|
35
45
|
},
|
|
36
|
-
|
|
46
|
+
...(process.env.JEST_USE_SETUP === 'ON' && {
|
|
47
|
+
setupFilesAfterEnv: [
|
|
48
|
+
'<rootDir>/node_modules/@eeacms/volto-eea-map/jest.setup.js',
|
|
49
|
+
],
|
|
50
|
+
}),
|
|
51
|
+
}
|
package/jest.setup.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jest } from '@jest/globals';
|
|
2
|
+
import configureStore from 'redux-mock-store';
|
|
3
|
+
import thunk from 'redux-thunk';
|
|
4
|
+
import { blocksConfig } from '@plone/volto/config/Blocks';
|
|
5
|
+
import installSlate from '@plone/volto-slate/index';
|
|
6
|
+
|
|
7
|
+
var mockSemanticComponents = jest.requireActual('semantic-ui-react');
|
|
8
|
+
var mockComponents = jest.requireActual('@plone/volto/components');
|
|
9
|
+
var config = jest.requireActual('@plone/volto/registry').default;
|
|
10
|
+
|
|
11
|
+
config.blocks.blocksConfig = {
|
|
12
|
+
...blocksConfig,
|
|
13
|
+
...config.blocks.blocksConfig,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
jest.doMock('semantic-ui-react', () => ({
|
|
17
|
+
__esModule: true,
|
|
18
|
+
...mockSemanticComponents,
|
|
19
|
+
Popup: ({ content, trigger }) => {
|
|
20
|
+
return (
|
|
21
|
+
<div className="popup">
|
|
22
|
+
<div className="trigger">{trigger}</div>
|
|
23
|
+
<div className="content">{content}</div>
|
|
24
|
+
</div>
|
|
25
|
+
);
|
|
26
|
+
},
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
jest.doMock('@plone/volto/components', () => {
|
|
30
|
+
return {
|
|
31
|
+
__esModule: true,
|
|
32
|
+
...mockComponents,
|
|
33
|
+
SidebarPortal: ({ children }) => <div id="sidebar">{children}</div>,
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
jest.doMock('@plone/volto/registry', () =>
|
|
38
|
+
[installSlate].reduce((acc, apply) => apply(acc), config),
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const mockStore = configureStore([thunk]);
|
|
42
|
+
|
|
43
|
+
global.fetch = jest.fn(() =>
|
|
44
|
+
Promise.resolve({
|
|
45
|
+
json: () => Promise.resolve({}),
|
|
46
|
+
}),
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
global.store = mockStore({
|
|
50
|
+
intl: {
|
|
51
|
+
locale: 'en',
|
|
52
|
+
messages: {},
|
|
53
|
+
formatMessage: jest.fn(),
|
|
54
|
+
},
|
|
55
|
+
content: {
|
|
56
|
+
create: {},
|
|
57
|
+
subrequests: [],
|
|
58
|
+
},
|
|
59
|
+
connected_data_parameters: {},
|
|
60
|
+
screen: {
|
|
61
|
+
page: {
|
|
62
|
+
width: 768,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eeacms/volto-eea-map",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "@eeacms/volto-eea-map: Volto add-on",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"author": "European Environment Agency: IDM2 A-Team",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"babel-plugin-transform-class-properties": "^6.24.1",
|
|
37
37
|
"cypress": "10.3.1",
|
|
38
38
|
"cypress-fail-fast": "^5.0.1",
|
|
39
|
+
"dotenv": "^16.3.2",
|
|
39
40
|
"husky": "^8.0.3",
|
|
40
41
|
"lint-staged": "^14.0.1",
|
|
41
42
|
"md5": "^2.3.0"
|
|
@@ -24,8 +24,7 @@ const ProtectionSchema = () => ({
|
|
|
24
24
|
{
|
|
25
25
|
children: [
|
|
26
26
|
{
|
|
27
|
-
text:
|
|
28
|
-
'This map is hosted by a third party, Environmental Systems Research Institute. By showing the external content you accept the terms and conditions of ',
|
|
27
|
+
text: 'This map is hosted by a third party, Environmental Systems Research Institute. By showing the external content you accept the terms and conditions of ',
|
|
29
28
|
},
|
|
30
29
|
{
|
|
31
30
|
type: 'a',
|
|
@@ -37,8 +36,7 @@ const ProtectionSchema = () => ({
|
|
|
37
36
|
],
|
|
38
37
|
},
|
|
39
38
|
{
|
|
40
|
-
text:
|
|
41
|
-
'. This includes their cookie policies, which we have no control over.',
|
|
39
|
+
text: '. This includes their cookie policies, which we have no control over.',
|
|
42
40
|
},
|
|
43
41
|
],
|
|
44
42
|
},
|
|
@@ -19,9 +19,10 @@ const View = (props) => {
|
|
|
19
19
|
height = '',
|
|
20
20
|
} = data;
|
|
21
21
|
|
|
22
|
-
const map_visualization_data = useMemo(
|
|
23
|
-
props,
|
|
24
|
-
|
|
22
|
+
const map_visualization_data = useMemo(
|
|
23
|
+
() => getMapVisualizationData(props),
|
|
24
|
+
[props],
|
|
25
|
+
);
|
|
25
26
|
|
|
26
27
|
const [mapData, setMapData] = React.useState('');
|
|
27
28
|
|
|
@@ -10,7 +10,7 @@ const VisualizationEditorWidget = (props) => {
|
|
|
10
10
|
const [open, setOpen] = React.useState(false);
|
|
11
11
|
const { onChange = {}, id } = props;
|
|
12
12
|
const block = React.useMemo(() => props.block, [props.block]);
|
|
13
|
-
const value = React.useMemo(() => props.value, [props.value]);
|
|
13
|
+
const value = React.useMemo(() => props.value || {}, [props.value]);
|
|
14
14
|
|
|
15
15
|
const [intValue, setIntValue] = React.useState(value);
|
|
16
16
|
|
|
@@ -185,7 +185,7 @@ const GeneralSchema = ({ data = {} }) => {
|
|
|
185
185
|
};
|
|
186
186
|
};
|
|
187
187
|
|
|
188
|
-
|
|
188
|
+
const PanelsSchema = ({ data = {} }) => {
|
|
189
189
|
const generalSchema = GeneralSchema({ data });
|
|
190
190
|
const baseLayerSchema = BaseLayerSchema({ data });
|
|
191
191
|
const stylesLayerSchema = StylesLayersSchema({ data });
|
|
@@ -225,3 +225,5 @@ export default ({ data = {} }) => {
|
|
|
225
225
|
required: [],
|
|
226
226
|
};
|
|
227
227
|
};
|
|
228
|
+
|
|
229
|
+
export default PanelsSchema;
|
|
@@ -41,9 +41,8 @@ const LayerSelectWidget = (props) => {
|
|
|
41
41
|
const [serviceUrl, setServiceUrl] = React.useState(map_service_url);
|
|
42
42
|
const [selectedLayer, setSelectedLayer] = React.useState(layer);
|
|
43
43
|
|
|
44
|
-
const [availableLayers, setAvailableLayers] =
|
|
45
|
-
available_layers
|
|
46
|
-
);
|
|
44
|
+
const [availableLayers, setAvailableLayers] =
|
|
45
|
+
React.useState(available_layers);
|
|
47
46
|
|
|
48
47
|
const [builtQuery, setBuiltQuery] = React.useState(query);
|
|
49
48
|
|
|
@@ -3,9 +3,10 @@ import { Button } from 'semantic-ui-react';
|
|
|
3
3
|
import LayerSelectWidget from './LayerSelectWidget';
|
|
4
4
|
|
|
5
5
|
const LayersPanelWidget = ({ data, onChange, block }) => {
|
|
6
|
-
const map_layers = React.useMemo(
|
|
7
|
-
data.map_layers,
|
|
8
|
-
|
|
6
|
+
const map_layers = React.useMemo(
|
|
7
|
+
() => data.map_layers || [],
|
|
8
|
+
[data.map_layers],
|
|
9
|
+
);
|
|
9
10
|
|
|
10
11
|
React.useEffect(() => {
|
|
11
12
|
if (!data.map_layers) {
|
|
@@ -7,7 +7,7 @@ import checkSVG from '@plone/volto/icons/check.svg';
|
|
|
7
7
|
|
|
8
8
|
const ReactColor = loadable.lib(() => import('react-color'));
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
const SimpleColorPickerWidget = (props) => {
|
|
11
11
|
const { id, value, onChange, available_colors } = props;
|
|
12
12
|
const [showPicker, setShowPicker] = React.useState(false);
|
|
13
13
|
|
|
@@ -117,3 +117,5 @@ export default (props) => {
|
|
|
117
117
|
</FormFieldWrapper>
|
|
118
118
|
);
|
|
119
119
|
};
|
|
120
|
+
|
|
121
|
+
export default SimpleColorPickerWidget;
|
package/src/index.js
CHANGED
|
@@ -16,7 +16,7 @@ import SimpleColorPickerWidget from './components/widgets/SimpleColorPickerWidge
|
|
|
16
16
|
|
|
17
17
|
import './less/global.less';
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
const applyConfig = (config) => {
|
|
20
20
|
config.settings.allowed_cors_destinations = [
|
|
21
21
|
...(config.settings.allowed_cors_destinations || []),
|
|
22
22
|
'land.discomap.eea.europa.eu',
|
|
@@ -76,3 +76,5 @@ export default (config) => {
|
|
|
76
76
|
|
|
77
77
|
return config;
|
|
78
78
|
};
|
|
79
|
+
|
|
80
|
+
export default applyConfig;
|
package/src/less/global.less
CHANGED
|
@@ -83,8 +83,8 @@
|
|
|
83
83
|
|
|
84
84
|
.ruleGroup-addRule {
|
|
85
85
|
padding: 7px 10px !important;
|
|
86
|
-
background-color: darkgray !important;
|
|
87
86
|
border-radius: 5px;
|
|
87
|
+
background-color: darkgray !important;
|
|
88
88
|
color: white;
|
|
89
89
|
cursor: pointer;
|
|
90
90
|
font-size: 12px;
|
|
@@ -93,8 +93,8 @@
|
|
|
93
93
|
|
|
94
94
|
.ruleGroup-addGroup {
|
|
95
95
|
padding: 7px 10px !important;
|
|
96
|
-
background-color: darkgray !important;
|
|
97
96
|
border-radius: 5px;
|
|
97
|
+
background-color: darkgray !important;
|
|
98
98
|
color: white;
|
|
99
99
|
cursor: pointer;
|
|
100
100
|
font-size: 12px;
|
package/.project.eslintrc.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
const projectRootPath = fs.existsSync('./project')
|
|
5
|
-
? fs.realpathSync('./project')
|
|
6
|
-
: fs.realpathSync('./../../../');
|
|
7
|
-
const packageJson = require(path.join(projectRootPath, 'package.json'));
|
|
8
|
-
const jsConfig = require(path.join(projectRootPath, 'jsconfig.json')).compilerOptions;
|
|
9
|
-
|
|
10
|
-
const pathsConfig = jsConfig.paths;
|
|
11
|
-
|
|
12
|
-
let voltoPath = path.join(projectRootPath, 'node_modules/@plone/volto');
|
|
13
|
-
|
|
14
|
-
Object.keys(pathsConfig).forEach(pkg => {
|
|
15
|
-
if (pkg === '@plone/volto') {
|
|
16
|
-
voltoPath = `./${jsConfig.baseUrl}/${pathsConfig[pkg][0]}`;
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
const AddonConfigurationRegistry = require(`${voltoPath}/addon-registry.js`);
|
|
20
|
-
const reg = new AddonConfigurationRegistry(projectRootPath);
|
|
21
|
-
|
|
22
|
-
// Extends ESlint configuration for adding the aliases to `src` directories in Volto addons
|
|
23
|
-
const addonAliases = Object.keys(reg.packages).map(o => [
|
|
24
|
-
o,
|
|
25
|
-
reg.packages[o].modulePath,
|
|
26
|
-
]);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
module.exports = {
|
|
30
|
-
extends: `${projectRootPath}/node_modules/@plone/volto/.eslintrc`,
|
|
31
|
-
settings: {
|
|
32
|
-
'import/resolver': {
|
|
33
|
-
alias: {
|
|
34
|
-
map: [
|
|
35
|
-
['@plone/volto', '@plone/volto/src'],
|
|
36
|
-
...addonAliases,
|
|
37
|
-
['@package', `${__dirname}/src`],
|
|
38
|
-
['~', `${__dirname}/src`],
|
|
39
|
-
],
|
|
40
|
-
extensions: ['.js', '.jsx', '.json'],
|
|
41
|
-
},
|
|
42
|
-
'babel-plugin-root-import': {
|
|
43
|
-
rootPathSuffix: 'src',
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
|