diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 7ce9806b098..38a9d076a96 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -15,40 +15,40 @@ importers: version: 7.25.2 '@babel/eslint-parser': specifier: ^7.17.0 - version: 7.25.1(@babel/core@7.25.2)(eslint@8.57.0) + version: 7.25.1(@babel/core@7.25.2)(eslint@8.57.1) '@typescript-eslint/eslint-plugin': specifier: ~7.8.0 - version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)(typescript@4.9.5) + version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.1)(typescript@4.9.5) '@typescript-eslint/parser': specifier: ~7.8.0 - version: 7.8.0(eslint@8.57.0)(typescript@4.9.5) + version: 7.8.0(eslint@8.57.1)(typescript@4.9.5) eslint: specifier: ^8.8.0 - version: 8.57.0 + version: 8.57.1 eslint-config-airbnb: specifier: ^19.0.4 - version: 19.0.4(eslint-plugin-import@2.30.0)(eslint-plugin-jsx-a11y@6.10.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.36.1)(eslint@8.57.0) + version: 19.0.4(eslint-plugin-import@2.30.0)(eslint-plugin-jsx-a11y@6.10.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.36.1)(eslint@8.57.1) eslint-config-prettier: specifier: ^8.3.0 - version: 8.10.0(eslint@8.57.0) + version: 8.10.0(eslint@8.57.1) eslint-plugin-import: specifier: ^2.25.4 - version: 2.30.0(eslint@8.57.0) + version: 2.30.0(eslint@8.57.1) eslint-plugin-jest: specifier: ^26.0.0 - version: 26.9.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint@8.57.0)(jest@27.5.1)(typescript@4.9.5) + version: 26.9.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint@8.57.1)(jest@27.5.1)(typescript@4.9.5) eslint-plugin-jsx-a11y: specifier: ^6.5.1 - version: 6.10.0(eslint@8.57.0) + version: 6.10.0(eslint@8.57.1) eslint-plugin-prettier: specifier: ^4.0.0 - version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.0)(prettier@2.8.8) + version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.1)(prettier@2.8.8) eslint-plugin-react: specifier: ^7.28.0 - version: 7.36.1(eslint@8.57.0) + version: 7.36.1(eslint@8.57.1) eslint-plugin-react-hooks: specifier: ^4.3.0 - version: 4.6.2(eslint@8.57.0) + version: 4.6.2(eslint@8.57.1) prettier: specifier: ^2.6.0 version: 2.8.8 @@ -67,49 +67,49 @@ importers: version: 7.25.2 '@babel/eslint-parser': specifier: ^7.17.0 - version: 7.25.1(@babel/core@7.25.2)(eslint@8.57.0) + version: 7.25.1(@babel/core@7.25.2)(eslint@8.57.1) '@babel/runtime': specifier: ^7.17.0 version: 7.25.6 '@types/react': specifier: ^18.2.0 - version: 18.3.5 + version: 18.3.8 '@types/react-dom': specifier: ^18.2.0 version: 18.3.0 '@typescript-eslint/eslint-plugin': specifier: ~7.8.0 - version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)(typescript@4.9.5) + version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.1)(typescript@4.9.5) '@typescript-eslint/parser': specifier: ~7.8.0 - version: 7.8.0(eslint@8.57.0)(typescript@4.9.5) + version: 7.8.0(eslint@8.57.1)(typescript@4.9.5) eslint: specifier: ^8.8.0 - version: 8.57.0 + version: 8.57.1 eslint-config-airbnb: specifier: ^19.0.4 - version: 19.0.4(eslint-plugin-import@2.30.0)(eslint-plugin-jsx-a11y@6.10.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.36.1)(eslint@8.57.0) + version: 19.0.4(eslint-plugin-import@2.30.0)(eslint-plugin-jsx-a11y@6.10.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.36.1)(eslint@8.57.1) eslint-config-prettier: specifier: ^8.3.0 - version: 8.10.0(eslint@8.57.0) + version: 8.10.0(eslint@8.57.1) eslint-plugin-import: specifier: ^2.25.4 - version: 2.30.0(eslint@8.57.0) + version: 2.30.0(eslint@8.57.1) eslint-plugin-jest: specifier: ^26.0.0 - version: 26.9.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint@8.57.0)(jest@27.5.1)(typescript@4.9.5) + version: 26.9.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint@8.57.1)(jest@27.5.1)(typescript@4.9.5) eslint-plugin-jsx-a11y: specifier: ^6.5.1 - version: 6.10.0(eslint@8.57.0) + version: 6.10.0(eslint@8.57.1) eslint-plugin-prettier: specifier: ^4.0.0 - version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.0)(prettier@2.8.8) + version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.1)(prettier@2.8.8) eslint-plugin-react: specifier: ^7.28.0 - version: 7.36.1(eslint@8.57.0) + version: 7.36.1(eslint@8.57.1) eslint-plugin-react-hooks: specifier: ^4.3.0 - version: 4.6.2(eslint@8.57.0) + version: 4.6.2(eslint@8.57.1) prettier: specifier: ^2.6.0 version: 2.8.8 @@ -134,49 +134,49 @@ importers: version: 7.25.2 '@babel/eslint-parser': specifier: ^7.17.0 - version: 7.25.1(@babel/core@7.25.2)(eslint@8.57.0) + version: 7.25.1(@babel/core@7.25.2)(eslint@8.57.1) '@babel/runtime': specifier: ^7.17.0 version: 7.25.6 '@types/react': specifier: ^18.2.0 - version: 18.3.5 + version: 18.3.8 '@types/react-dom': specifier: ^18.2.0 version: 18.3.0 '@typescript-eslint/eslint-plugin': specifier: ~7.8.0 - version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)(typescript@4.9.5) + version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.1)(typescript@4.9.5) '@typescript-eslint/parser': specifier: ~7.8.0 - version: 7.8.0(eslint@8.57.0)(typescript@4.9.5) + version: 7.8.0(eslint@8.57.1)(typescript@4.9.5) eslint: specifier: ^8.8.0 - version: 8.57.0 + version: 8.57.1 eslint-config-airbnb: specifier: ^19.0.4 - version: 19.0.4(eslint-plugin-import@2.30.0)(eslint-plugin-jsx-a11y@6.10.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.36.1)(eslint@8.57.0) + version: 19.0.4(eslint-plugin-import@2.30.0)(eslint-plugin-jsx-a11y@6.10.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.36.1)(eslint@8.57.1) eslint-config-prettier: specifier: ^8.3.0 - version: 8.10.0(eslint@8.57.0) + version: 8.10.0(eslint@8.57.1) eslint-plugin-import: specifier: ^2.25.4 - version: 2.30.0(eslint@8.57.0) + version: 2.30.0(eslint@8.57.1) eslint-plugin-jest: specifier: ^26.0.0 - version: 26.9.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint@8.57.0)(jest@27.5.1)(typescript@4.9.5) + version: 26.9.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint@8.57.1)(jest@27.5.1)(typescript@4.9.5) eslint-plugin-jsx-a11y: specifier: ^6.5.1 - version: 6.10.0(eslint@8.57.0) + version: 6.10.0(eslint@8.57.1) eslint-plugin-prettier: specifier: ^4.0.0 - version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.0)(prettier@2.8.8) + version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.1)(prettier@2.8.8) eslint-plugin-react: specifier: ^7.28.0 - version: 7.36.1(eslint@8.57.0) + version: 7.36.1(eslint@8.57.1) eslint-plugin-react-hooks: specifier: ^4.3.0 - version: 4.6.2(eslint@8.57.0) + version: 4.6.2(eslint@8.57.1) prettier: specifier: ^2.6.0 version: 2.8.8 @@ -194,34 +194,37 @@ importers: dependencies: '@emotion/react': specifier: ^11.13.3 - version: 11.13.3(@types/react@18.3.5)(react@18.3.1) + version: 11.13.3(@types/react@18.3.8)(react@18.3.1) '@emotion/styled': specifier: ^11.13.0 - version: 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.5)(react@18.3.1) + version: 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.8)(react@18.3.1) '@fontsource/roboto': specifier: ^5.0.13 version: 5.1.0 '@mui/base': specifier: 5.0.0-beta.37 - version: 5.0.0-beta.37(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1) + version: 5.0.0-beta.37(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1) '@mui/icons-material': specifier: ^6.0.2 - version: 6.1.0(@mui/material@6.1.0)(@types/react@18.3.5)(react@18.3.1) + version: 6.1.1(@mui/material@6.1.1)(@types/react@18.3.8)(react@18.3.1) '@mui/lab': specifier: 6.0.0-beta.9 - version: 6.0.0-beta.9(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@mui/material@6.1.0)(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1) + version: 6.0.0-beta.9(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@mui/material@6.1.1)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1) '@mui/material': specifier: ^6.0.2 - version: 6.1.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1) + version: 6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1) '@mui/styles': specifier: ^6.0.2 - version: 6.1.0(@types/react@18.3.5)(react@18.3.1) + version: 6.1.1(@types/react@18.3.8)(react@18.3.1) '@mui/system': specifier: ^6.0.2 - version: 6.1.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react@18.3.1) + version: 6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react@18.3.1) '@mui/x-date-pickers': - specifier: ^7.15.0 - version: 7.17.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@mui/material@6.1.0)(@mui/system@6.1.0)(@types/react@18.3.5)(dayjs@1.11.13)(react-dom@18.3.1)(react@18.3.1) + specifier: ^7.6.1 + version: 7.18.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@mui/material@6.1.1)(@mui/system@6.1.1)(@types/react@18.3.8)(dayjs@1.11.13)(react-dom@18.3.1)(react@18.3.1) + '@mui/x-tree-view': + specifier: ^7.6.1 + version: 7.18.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@mui/material@6.1.1)(@mui/system@6.1.1)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1) '@nieuwlandgeo/sldreader': specifier: ^0.3.1 version: 0.3.1(ol@10.1.0) @@ -275,7 +278,7 @@ importers: version: 7.4.7(react@18.3.1) material-react-table: specifier: ^2.13.2 - version: 2.13.3(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@mui/icons-material@6.1.0)(@mui/material@6.1.0)(@mui/x-date-pickers@7.17.0)(react-dom@18.3.1)(react@18.3.1) + version: 2.13.3(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@mui/icons-material@6.1.1)(@mui/material@6.1.1)(@mui/x-date-pickers@7.18.0)(react-dom@18.3.1)(react@18.3.1) ol: specifier: ^10.1.0 version: 10.1.0 @@ -314,10 +317,10 @@ importers: version: 1.11.0 yet-another-react-lightbox: specifier: ^3.11.3 - version: 3.21.5(react-dom@18.3.1)(react@18.3.1) + version: 3.21.6(react-dom@18.3.1)(react@18.3.1) zustand: specifier: ~4.4.1 - version: 4.4.7(@types/react@18.3.5)(react@18.3.1) + version: 4.4.7(@types/react@18.3.8)(react@18.3.1) devDependencies: '@babel/cli': specifier: ^7.17.0 @@ -327,7 +330,7 @@ importers: version: 7.25.2 '@babel/eslint-parser': specifier: ^7.17.0 - version: 7.25.1(@babel/core@7.25.2)(eslint@8.57.0) + version: 7.25.1(@babel/core@7.25.2)(eslint@8.57.1) '@babel/plugin-proposal-decorators': specifier: ^7.17.0 version: 7.24.7(@babel/core@7.25.2) @@ -420,7 +423,7 @@ importers: version: 2.5.5 '@types/react': specifier: ^18.2.0 - version: 18.3.5 + version: 18.3.8 '@types/react-dom': specifier: ^18.2.0 version: 18.3.0 @@ -435,16 +438,16 @@ importers: version: 1.4.9 '@typescript-eslint/eslint-plugin': specifier: ~7.8.0 - version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)(typescript@4.9.5) + version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.1)(typescript@4.9.5) '@typescript-eslint/parser': specifier: ~7.8.0 - version: 7.8.0(eslint@8.57.0)(typescript@4.9.5) + version: 7.8.0(eslint@8.57.1)(typescript@4.9.5) babel-jest: specifier: ^27.4.6 version: 27.5.1(@babel/core@7.25.2) babel-loader: specifier: ^8.2.3 - version: 8.3.0(@babel/core@7.25.2)(webpack@5.94.0) + version: 8.4.1(@babel/core@7.25.2)(webpack@5.94.0) babel-plugin-import: specifier: ^1.13.3 version: 1.13.8 @@ -462,31 +465,31 @@ importers: version: 6.11.0(webpack@5.94.0) eslint: specifier: ^8.8.0 - version: 8.57.0 + version: 8.57.1 eslint-config-airbnb: specifier: ^19.0.4 - version: 19.0.4(eslint-plugin-import@2.30.0)(eslint-plugin-jsx-a11y@6.10.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.36.1)(eslint@8.57.0) + version: 19.0.4(eslint-plugin-import@2.30.0)(eslint-plugin-jsx-a11y@6.10.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.36.1)(eslint@8.57.1) eslint-config-prettier: specifier: ^8.3.0 - version: 8.10.0(eslint@8.57.0) + version: 8.10.0(eslint@8.57.1) eslint-plugin-import: specifier: ^2.25.4 - version: 2.30.0(eslint@8.57.0) + version: 2.30.0(eslint@8.57.1) eslint-plugin-jest: specifier: ^26.0.0 - version: 26.9.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint@8.57.0)(jest@27.5.1)(typescript@4.9.5) + version: 26.9.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint@8.57.1)(jest@27.5.1)(typescript@4.9.5) eslint-plugin-jsx-a11y: specifier: ^6.5.1 - version: 6.10.0(eslint@8.57.0) + version: 6.10.0(eslint@8.57.1) eslint-plugin-prettier: specifier: ^4.0.0 - version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.0)(prettier@2.8.8) + version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.1)(prettier@2.8.8) eslint-plugin-react: specifier: ^7.28.0 - version: 7.36.1(eslint@8.57.0) + version: 7.36.1(eslint@8.57.1) eslint-plugin-react-hooks: specifier: ^4.3.0 - version: 4.6.2(eslint@8.57.0) + version: 4.6.2(eslint@8.57.1) file-loader: specifier: ^6.2.0 version: 6.2.0(webpack@5.94.0) @@ -516,13 +519,13 @@ importers: version: 2.8.8 sass: specifier: ^1.49.7 - version: 1.78.0 + version: 1.79.2 sass-loader: specifier: ^12.4.0 - version: 12.6.0(sass@1.78.0)(webpack@5.94.0) + version: 12.6.0(sass@1.79.2)(webpack@5.94.0) simple-zustand-devtools: specifier: ^1.1.0 - version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1)(zustand@4.4.7) + version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1)(zustand@4.4.7) style-loader: specifier: ^3.3.1 version: 3.3.4(webpack@5.94.0) @@ -558,10 +561,10 @@ importers: dependencies: '@mui/material': specifier: ^6.0.2 - version: 6.1.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1) + version: 6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1) geochart: specifier: Canadian-Geospatial-Platform/geochart#develop - version: github.com/Canadian-Geospatial-Platform/geochart/62b1611c028dd27e8b275b070a18b199222becbb(@types/react@18.3.5) + version: github.com/Canadian-Geospatial-Platform/geochart/62b1611c028dd27e8b275b070a18b199222becbb(@types/react@18.3.8) geoview-core: specifier: workspace:~1.0.0 version: link:../geoview-core @@ -574,7 +577,7 @@ importers: version: 7.25.2 '@babel/eslint-parser': specifier: ^7.17.0 - version: 7.25.1(@babel/core@7.25.2)(eslint@8.57.0) + version: 7.25.1(@babel/core@7.25.2)(eslint@8.57.1) '@babel/runtime': specifier: ^7.17.0 version: 7.25.6 @@ -583,43 +586,43 @@ importers: version: 4.17.7 '@types/react': specifier: ^18.2.0 - version: 18.3.5 + version: 18.3.8 '@types/react-dom': specifier: ^18.2.0 version: 18.3.0 '@typescript-eslint/eslint-plugin': specifier: ~7.8.0 - version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)(typescript@4.9.5) + version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.1)(typescript@4.9.5) '@typescript-eslint/parser': specifier: ~7.8.0 - version: 7.8.0(eslint@8.57.0)(typescript@4.9.5) + version: 7.8.0(eslint@8.57.1)(typescript@4.9.5) eslint: specifier: ^8.8.0 - version: 8.57.0 + version: 8.57.1 eslint-config-airbnb: specifier: ^19.0.4 - version: 19.0.4(eslint-plugin-import@2.30.0)(eslint-plugin-jsx-a11y@6.10.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.36.1)(eslint@8.57.0) + version: 19.0.4(eslint-plugin-import@2.30.0)(eslint-plugin-jsx-a11y@6.10.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.36.1)(eslint@8.57.1) eslint-config-prettier: specifier: ^8.3.0 - version: 8.10.0(eslint@8.57.0) + version: 8.10.0(eslint@8.57.1) eslint-plugin-import: specifier: ^2.25.4 - version: 2.30.0(eslint@8.57.0) + version: 2.30.0(eslint@8.57.1) eslint-plugin-jest: specifier: ^26.0.0 - version: 26.9.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint@8.57.0)(jest@27.5.1)(typescript@4.9.5) + version: 26.9.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint@8.57.1)(jest@27.5.1)(typescript@4.9.5) eslint-plugin-jsx-a11y: specifier: ^6.5.1 - version: 6.10.0(eslint@8.57.0) + version: 6.10.0(eslint@8.57.1) eslint-plugin-prettier: specifier: ^4.0.0 - version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.0)(prettier@2.8.8) + version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.1)(prettier@2.8.8) eslint-plugin-react: specifier: ^7.28.0 - version: 7.36.1(eslint@8.57.0) + version: 7.36.1(eslint@8.57.1) eslint-plugin-react-hooks: specifier: ^4.3.0 - version: 4.6.2(eslint@8.57.0) + version: 4.6.2(eslint@8.57.1) markdown-to-jsx: specifier: ~7.4.0 version: 7.4.7(react@18.3.1) @@ -656,7 +659,7 @@ importers: version: 7.25.2 '@babel/eslint-parser': specifier: ^7.17.0 - version: 7.25.1(@babel/core@7.25.2)(eslint@8.57.0) + version: 7.25.1(@babel/core@7.25.2)(eslint@8.57.1) '@babel/runtime': specifier: ^7.17.0 version: 7.25.6 @@ -665,37 +668,37 @@ importers: version: 4.17.7 '@typescript-eslint/eslint-plugin': specifier: ~7.8.0 - version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)(typescript@4.9.5) + version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.1)(typescript@4.9.5) '@typescript-eslint/parser': specifier: ~7.8.0 - version: 7.8.0(eslint@8.57.0)(typescript@4.9.5) + version: 7.8.0(eslint@8.57.1)(typescript@4.9.5) eslint: specifier: ^8.8.0 - version: 8.57.0 + version: 8.57.1 eslint-config-airbnb: specifier: ^19.0.4 - version: 19.0.4(eslint-plugin-import@2.30.0)(eslint-plugin-jsx-a11y@6.10.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.36.1)(eslint@8.57.0) + version: 19.0.4(eslint-plugin-import@2.30.0)(eslint-plugin-jsx-a11y@6.10.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.36.1)(eslint@8.57.1) eslint-config-prettier: specifier: ^8.3.0 - version: 8.10.0(eslint@8.57.0) + version: 8.10.0(eslint@8.57.1) eslint-plugin-import: specifier: ^2.25.4 - version: 2.30.0(eslint@8.57.0) + version: 2.30.0(eslint@8.57.1) eslint-plugin-jest: specifier: ^26.0.0 - version: 26.9.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint@8.57.0)(jest@27.5.1)(typescript@4.9.5) + version: 26.9.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint@8.57.1)(jest@27.5.1)(typescript@4.9.5) eslint-plugin-jsx-a11y: specifier: ^6.5.1 - version: 6.10.0(eslint@8.57.0) + version: 6.10.0(eslint@8.57.1) eslint-plugin-prettier: specifier: ^4.0.0 - version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.0)(prettier@2.8.8) + version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.1)(prettier@2.8.8) eslint-plugin-react: specifier: ^7.28.0 - version: 7.36.1(eslint@8.57.0) + version: 7.36.1(eslint@8.57.1) eslint-plugin-react-hooks: specifier: ^4.3.0 - version: 4.6.2(eslint@8.57.0) + version: 4.6.2(eslint@8.57.1) prettier: specifier: ^2.6.0 version: 2.8.8 @@ -713,7 +716,7 @@ importers: dependencies: '@mui/material': specifier: ^6.0.2 - version: 6.1.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1) + version: 6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1) geoview-core: specifier: workspace:~1.0.0 version: link:../geoview-core @@ -723,49 +726,49 @@ importers: version: 7.25.2 '@babel/eslint-parser': specifier: ^7.17.0 - version: 7.25.1(@babel/core@7.25.2)(eslint@8.57.0) + version: 7.25.1(@babel/core@7.25.2)(eslint@8.57.1) '@babel/runtime': specifier: ^7.17.0 version: 7.25.6 '@types/react': specifier: ^18.2.0 - version: 18.3.5 + version: 18.3.8 '@types/react-dom': specifier: ^18.2.0 version: 18.3.0 '@typescript-eslint/eslint-plugin': specifier: ~7.8.0 - version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)(typescript@4.9.5) + version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.1)(typescript@4.9.5) '@typescript-eslint/parser': specifier: ~7.8.0 - version: 7.8.0(eslint@8.57.0)(typescript@4.9.5) + version: 7.8.0(eslint@8.57.1)(typescript@4.9.5) eslint: specifier: ^8.8.0 - version: 8.57.0 + version: 8.57.1 eslint-config-airbnb: specifier: ^19.0.4 - version: 19.0.4(eslint-plugin-import@2.30.0)(eslint-plugin-jsx-a11y@6.10.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.36.1)(eslint@8.57.0) + version: 19.0.4(eslint-plugin-import@2.30.0)(eslint-plugin-jsx-a11y@6.10.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.36.1)(eslint@8.57.1) eslint-config-prettier: specifier: ^8.3.0 - version: 8.10.0(eslint@8.57.0) + version: 8.10.0(eslint@8.57.1) eslint-plugin-import: specifier: ^2.25.4 - version: 2.30.0(eslint@8.57.0) + version: 2.30.0(eslint@8.57.1) eslint-plugin-jest: specifier: ^26.0.0 - version: 26.9.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint@8.57.0)(jest@27.5.1)(typescript@4.9.5) + version: 26.9.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint@8.57.1)(jest@27.5.1)(typescript@4.9.5) eslint-plugin-jsx-a11y: specifier: ^6.5.1 - version: 6.10.0(eslint@8.57.0) + version: 6.10.0(eslint@8.57.1) eslint-plugin-prettier: specifier: ^4.0.0 - version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.0)(prettier@2.8.8) + version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.1)(prettier@2.8.8) eslint-plugin-react: specifier: ^7.28.0 - version: 7.36.1(eslint@8.57.0) + version: 7.36.1(eslint@8.57.1) eslint-plugin-react-hooks: specifier: ^4.3.0 - version: 4.6.2(eslint@8.57.0) + version: 4.6.2(eslint@8.57.1) markdown-to-jsx: specifier: ~7.4.0 version: 7.4.7(react@18.3.1) @@ -847,7 +850,7 @@ packages: - supports-color dev: true - /@babel/eslint-parser@7.25.1(@babel/core@7.25.2)(eslint@8.57.0): + /@babel/eslint-parser@7.25.1(@babel/core@7.25.2)(eslint@8.57.1): resolution: {integrity: sha512-Y956ghgTT4j7rKesabkh5WeqgSFZVFwaPR0IWFm7KFHFmmJ4afbG49SmfW4S+GyRPx0Dy5jxEWA5t0rpxfElWg==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} peerDependencies: @@ -856,7 +859,7 @@ packages: dependencies: '@babel/core': 7.25.2 '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 - eslint: 8.57.0 + eslint: 8.57.1 eslint-visitor-keys: 2.1.0 semver: 6.3.1 dev: true @@ -2398,7 +2401,7 @@ packages: resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} dev: false - /@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1): + /@emotion/react@11.13.3(@types/react@18.3.8)(react@18.3.1): resolution: {integrity: sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==} peerDependencies: '@types/react': '*' @@ -2414,7 +2417,7 @@ packages: '@emotion/use-insertion-effect-with-fallbacks': 1.1.0(react@18.3.1) '@emotion/utils': 1.4.0 '@emotion/weak-memoize': 0.4.0 - '@types/react': 18.3.5 + '@types/react': 18.3.8 hoist-non-react-statics: 3.3.2 react: 18.3.1 transitivePeerDependencies: @@ -2435,7 +2438,7 @@ packages: resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} dev: false - /@emotion/styled@11.13.0(@emotion/react@11.13.3)(@types/react@18.3.5)(react@18.3.1): + /@emotion/styled@11.13.0(@emotion/react@11.13.3)(@types/react@18.3.8)(react@18.3.1): resolution: {integrity: sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==} peerDependencies: '@emotion/react': ^11.0.0-rc.0 @@ -2448,11 +2451,11 @@ packages: '@babel/runtime': 7.25.6 '@emotion/babel-plugin': 11.12.0 '@emotion/is-prop-valid': 1.3.0 - '@emotion/react': 11.13.3(@types/react@18.3.5)(react@18.3.1) + '@emotion/react': 11.13.3(@types/react@18.3.8)(react@18.3.1) '@emotion/serialize': 1.3.1 '@emotion/use-insertion-effect-with-fallbacks': 1.1.0(react@18.3.1) '@emotion/utils': 1.4.0 - '@types/react': 18.3.5 + '@types/react': 18.3.8 react: 18.3.1 transitivePeerDependencies: - supports-color @@ -2478,18 +2481,18 @@ packages: resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} dev: false - /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.57.1): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.57.0 + eslint: 8.57.1 eslint-visitor-keys: 3.4.3 dev: true - /@eslint-community/regexpp@4.11.0: - resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} + /@eslint-community/regexpp@4.11.1: + resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true @@ -2510,45 +2513,45 @@ packages: - supports-color dev: true - /@eslint/js@8.57.0: - resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + /@eslint/js@8.57.1: + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@floating-ui/core@1.6.7: - resolution: {integrity: sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==} + /@floating-ui/core@1.6.8: + resolution: {integrity: sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==} dependencies: - '@floating-ui/utils': 0.2.7 + '@floating-ui/utils': 0.2.8 dev: false - /@floating-ui/dom@1.6.10: - resolution: {integrity: sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==} + /@floating-ui/dom@1.6.11: + resolution: {integrity: sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==} dependencies: - '@floating-ui/core': 1.6.7 - '@floating-ui/utils': 0.2.7 + '@floating-ui/core': 1.6.8 + '@floating-ui/utils': 0.2.8 dev: false - /@floating-ui/react-dom@2.1.1(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==} + /@floating-ui/react-dom@2.1.2(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' dependencies: - '@floating-ui/dom': 1.6.10 + '@floating-ui/dom': 1.6.11 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false - /@floating-ui/utils@0.2.7: - resolution: {integrity: sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==} + /@floating-ui/utils@0.2.8: + resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==} dev: false /@fontsource/roboto@5.1.0: resolution: {integrity: sha512-cFRRC1s6RqPygeZ8Uw/acwVHqih8Czjt6Q0MwoUoDe9U3m4dH1HmNDRBZyqlMSFwgNAUKgFImncKdmDHyKpwdg==} dev: false - /@humanwhocodes/config-array@0.11.14: - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + /@humanwhocodes/config-array@0.13.0: + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} engines: {node: '>=10.10.0'} deprecated: Use @eslint/config-array instead dependencies: @@ -2590,7 +2593,7 @@ packages: engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@jest/types': 27.5.1 - '@types/node': 22.5.4 + '@types/node': 22.5.5 chalk: 4.1.2 jest-message-util: 27.5.1 jest-util: 27.5.1 @@ -2611,7 +2614,7 @@ packages: '@jest/test-result': 27.5.1 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.5.4 + '@types/node': 22.5.5 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.8.1 @@ -2648,7 +2651,7 @@ packages: dependencies: '@jest/fake-timers': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.5.4 + '@types/node': 22.5.5 jest-mock: 27.5.1 dev: true @@ -2658,7 +2661,7 @@ packages: dependencies: '@jest/types': 27.5.1 '@sinonjs/fake-timers': 8.1.0 - '@types/node': 22.5.4 + '@types/node': 22.5.5 jest-message-util: 27.5.1 jest-mock: 27.5.1 jest-util: 27.5.1 @@ -2687,7 +2690,7 @@ packages: '@jest/test-result': 27.5.1 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.5.4 + '@types/node': 22.5.5 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -2771,7 +2774,7 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.5.4 + '@types/node': 22.5.5 '@types/yargs': 16.0.9 chalk: 4.1.2 dev: true @@ -2843,7 +2846,7 @@ packages: resolution: {integrity: sha512-HPnRdYO0WjFjRTSwO3frz1wKaU649OBFPX3Zo/2WZvuRi6zMiRGui8SnPQiQABgqCf8YikDe5t3HViTVw1WUzA==} dev: false - /@mui/base@5.0.0-beta.37(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1): + /@mui/base@5.0.0-beta.37(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-/o3anbb+DeCng8jNsd3704XtmmLDZju1Fo8R2o7ugrVtPQ/QpcqddwKNzKPZwa0J5T8YNW3ZVuHyQgbTnQLisQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -2855,18 +2858,18 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@floating-ui/react-dom': 2.1.1(react-dom@18.3.1)(react@18.3.1) - '@mui/types': 7.2.16(@types/react@18.3.5) - '@mui/utils': 5.16.6(@types/react@18.3.5)(react@18.3.1) + '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1)(react@18.3.1) + '@mui/types': 7.2.17(@types/react@18.3.8) + '@mui/utils': 5.16.6(@types/react@18.3.8)(react@18.3.1) '@popperjs/core': 2.11.8 - '@types/react': 18.3.5 + '@types/react': 18.3.8 clsx: 2.1.1 prop-types: 15.8.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false - /@mui/base@5.0.0-beta.58(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1): + /@mui/base@5.0.0-beta.58(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-P0E7ZrxOuyYqBvVv9w8k7wm+Xzx/KRu+BGgFcR2htTsGCpJNQJCSUXNUZ50MUmSU9hzqhwbQWNXhV1MBTl6F7A==} engines: {node: '>=14.0.0'} peerDependencies: @@ -2878,11 +2881,11 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@floating-ui/react-dom': 2.1.1(react-dom@18.3.1)(react@18.3.1) - '@mui/types': 7.2.16(@types/react@18.3.5) - '@mui/utils': 6.0.0-rc.0(@types/react@18.3.5)(react@18.3.1) + '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1)(react@18.3.1) + '@mui/types': 7.2.17(@types/react@18.3.8) + '@mui/utils': 6.0.0-rc.0(@types/react@18.3.8)(react@18.3.1) '@popperjs/core': 2.11.8 - '@types/react': 18.3.5 + '@types/react': 18.3.8 clsx: 2.1.1 prop-types: 15.8.1 react: 18.3.1 @@ -2893,11 +2896,11 @@ packages: resolution: {integrity: sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ==} dev: false - /@mui/core-downloads-tracker@6.1.0: - resolution: {integrity: sha512-covEnIn/2er5YdtuukDRA52kmARhKrHjOvPsyTFMQApZdrTBI4h8jbEy2mxZqwMwcAFS9coonQXnEZKL1rUNdQ==} + /@mui/core-downloads-tracker@6.1.1: + resolution: {integrity: sha512-VdQC1tPIIcZAnf62L2M1eQif0x2vlKg3YK4kGYbtijSH4niEgI21GnstykW1vQIs+Bc6L+Hua2GATYVjilJ22A==} dev: false - /@mui/icons-material@5.16.7(@mui/material@5.16.7)(@types/react@18.3.5)(react@18.3.1): + /@mui/icons-material@5.16.7(@mui/material@5.16.7)(@types/react@18.3.8)(react@18.3.1): resolution: {integrity: sha512-UrGwDJCXEszbDI7yV047BYU5A28eGJ79keTCP4cc74WyncuVrnurlmIRxaHL8YK+LI1Kzq+/JM52IAkNnv4u+Q==} engines: {node: '>=12.0.0'} peerDependencies: @@ -2909,16 +2912,16 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@mui/material': 5.16.7(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1) - '@types/react': 18.3.5 + '@mui/material': 5.16.7(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.8 react: 18.3.1 dev: false - /@mui/icons-material@6.1.0(@mui/material@6.1.0)(@types/react@18.3.5)(react@18.3.1): - resolution: {integrity: sha512-HxfB0jxwiMTYMN8gAnYn3avbF1aDrqBEuGIj6JDQ3YkLl650E1Wy8AIhwwyP47wdrv0at9aAR0iOO6VLb74A9w==} + /@mui/icons-material@6.1.1(@mui/material@6.1.1)(@types/react@18.3.8)(react@18.3.1): + resolution: {integrity: sha512-sy/YKwcLPW8VcacNP2uWMYR9xyWuwO9NN9FXuGEU90bRshBXj8pdKk+joe3TCW7oviVS3zXLHlc94wQ0jNsQRQ==} engines: {node: '>=14.0.0'} peerDependencies: - '@mui/material': ^6.1.0 + '@mui/material': ^6.1.1 '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: @@ -2926,12 +2929,12 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@mui/material': 6.1.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1) - '@types/react': 18.3.5 + '@mui/material': 6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.8 react: 18.3.1 dev: false - /@mui/lab@6.0.0-beta.9(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@mui/material@6.1.0)(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1): + /@mui/lab@6.0.0-beta.9(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@mui/material@6.1.1)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-rgwgf9mNUpXxPlI3tnM3i+HNAtDZ2amAollDqbe6RZ/3fltcir/o/0zBvnZRkJIBOAk6qIGmL59GCasuQQtPKA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -2953,21 +2956,21 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@emotion/react': 11.13.3(@types/react@18.3.5)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.5)(react@18.3.1) - '@mui/base': 5.0.0-beta.58(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1) - '@mui/material': 6.1.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1) - '@mui/system': 6.1.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react@18.3.1) - '@mui/types': 7.2.16(@types/react@18.3.5) - '@mui/utils': 6.1.0(@types/react@18.3.5)(react@18.3.1) - '@types/react': 18.3.5 + '@emotion/react': 11.13.3(@types/react@18.3.8)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.8)(react@18.3.1) + '@mui/base': 5.0.0-beta.58(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1) + '@mui/material': 6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1) + '@mui/system': 6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react@18.3.1) + '@mui/types': 7.2.17(@types/react@18.3.8) + '@mui/utils': 6.1.1(@types/react@18.3.8)(react@18.3.1) + '@types/react': 18.3.8 clsx: 2.1.1 prop-types: 15.8.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false - /@mui/material@5.16.7(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1): + /@mui/material@5.16.7(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-cwwVQxBhK60OIOqZOVLFt55t01zmarKJiJUWbk0+8s/Ix5IaUzAShqlJchxsIQ4mSrWqgcKCCXKtIlG5H+/Jmg==} engines: {node: '>=12.0.0'} peerDependencies: @@ -2985,14 +2988,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@emotion/react': 11.13.3(@types/react@18.3.5)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.5)(react@18.3.1) + '@emotion/react': 11.13.3(@types/react@18.3.8)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.8)(react@18.3.1) '@mui/core-downloads-tracker': 5.16.7 - '@mui/system': 5.16.7(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react@18.3.1) - '@mui/types': 7.2.16(@types/react@18.3.5) - '@mui/utils': 5.16.6(@types/react@18.3.5)(react@18.3.1) + '@mui/system': 5.16.7(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react@18.3.1) + '@mui/types': 7.2.17(@types/react@18.3.8) + '@mui/utils': 5.16.6(@types/react@18.3.8)(react@18.3.1) '@popperjs/core': 2.11.8 - '@types/react': 18.3.5 + '@types/react': 18.3.8 '@types/react-transition-group': 4.4.11 clsx: 2.1.1 csstype: 3.1.3 @@ -3003,13 +3006,13 @@ packages: react-transition-group: 4.4.5(react-dom@18.3.1)(react@18.3.1) dev: false - /@mui/material@6.1.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-4MJ46vmy1xbm8x+ZdRcWm8jEMMowdS8pYlhKQzg/qoKhOcLhImZvf2Jn6z9Dj6gl+lY+C/0MxaHF/avAAGys3Q==} + /@mui/material@6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-b+eULldTqtqTCbN++2BtBWCir/1LwEYw+2mIlOt2GiEUh1EBBw4/wIukGKKNt3xrCZqRA80yLLkV6tF61Lq3cA==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.5.0 '@emotion/styled': ^11.3.0 - '@mui/material-pigment-css': ^6.1.0 + '@mui/material-pigment-css': ^6.1.1 '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -3024,14 +3027,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@emotion/react': 11.13.3(@types/react@18.3.5)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.5)(react@18.3.1) - '@mui/core-downloads-tracker': 6.1.0 - '@mui/system': 6.1.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react@18.3.1) - '@mui/types': 7.2.16(@types/react@18.3.5) - '@mui/utils': 6.1.0(@types/react@18.3.5)(react@18.3.1) + '@emotion/react': 11.13.3(@types/react@18.3.8)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.8)(react@18.3.1) + '@mui/core-downloads-tracker': 6.1.1 + '@mui/system': 6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react@18.3.1) + '@mui/types': 7.2.17(@types/react@18.3.8) + '@mui/utils': 6.1.1(@types/react@18.3.8)(react@18.3.1) '@popperjs/core': 2.11.8 - '@types/react': 18.3.5 + '@types/react': 18.3.8 '@types/react-transition-group': 4.4.11 clsx: 2.1.1 csstype: 3.1.3 @@ -3042,7 +3045,7 @@ packages: react-transition-group: 4.4.5(react-dom@18.3.1)(react@18.3.1) dev: false - /@mui/private-theming@5.16.6(@types/react@18.3.5)(react@18.3.1): + /@mui/private-theming@5.16.6(@types/react@18.3.8)(react@18.3.1): resolution: {integrity: sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==} engines: {node: '>=12.0.0'} peerDependencies: @@ -3053,14 +3056,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@mui/utils': 5.16.6(@types/react@18.3.5)(react@18.3.1) - '@types/react': 18.3.5 + '@mui/utils': 5.16.6(@types/react@18.3.8)(react@18.3.1) + '@types/react': 18.3.8 prop-types: 15.8.1 react: 18.3.1 dev: false - /@mui/private-theming@6.1.0(@types/react@18.3.5)(react@18.3.1): - resolution: {integrity: sha512-+L5qccs4gwsR0r1dgjqhN24QEQRkqIbfOdxILyMbMkuI50x6wNyt9XrV+J3WtjtZTMGJCrUa5VmZBE6OEPGPWA==} + /@mui/private-theming@6.1.1(@types/react@18.3.8)(react@18.3.1): + resolution: {integrity: sha512-JlrjIdhyZUtewtdAuUsvi3ZnO0YS49IW4Mfz19ZWTlQ0sDGga6LNPVwHClWr2/zJK2we2BQx9/i8M32rgKuzrg==} engines: {node: '>=14.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -3070,8 +3073,8 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@mui/utils': 6.1.0(@types/react@18.3.5)(react@18.3.1) - '@types/react': 18.3.5 + '@mui/utils': 6.1.1(@types/react@18.3.8)(react@18.3.1) + '@types/react': 18.3.8 prop-types: 15.8.1 react: 18.3.1 dev: false @@ -3091,15 +3094,15 @@ packages: dependencies: '@babel/runtime': 7.25.6 '@emotion/cache': 11.13.1 - '@emotion/react': 11.13.3(@types/react@18.3.5)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.5)(react@18.3.1) + '@emotion/react': 11.13.3(@types/react@18.3.8)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.8)(react@18.3.1) csstype: 3.1.3 prop-types: 15.8.1 react: 18.3.1 dev: false - /@mui/styled-engine@6.1.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(react@18.3.1): - resolution: {integrity: sha512-MZ+vtaCkjamrT41+b0Er9OMenjAtP/32+L6fARL9/+BZKuV2QbR3q3TmavT2x0NhDu35IM03s4yKqj32Ziqnyg==} + /@mui/styled-engine@6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(react@18.3.1): + resolution: {integrity: sha512-HJyIoMpFb11fnHuRtUILOXgq6vj4LhIlE8maG4SwP/W+E5sa7HFexhnB3vOMT7bKys4UKNxhobC8jwWxYilGsA==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.4.1 @@ -3113,16 +3116,16 @@ packages: dependencies: '@babel/runtime': 7.25.6 '@emotion/cache': 11.13.1 - '@emotion/react': 11.13.3(@types/react@18.3.5)(react@18.3.1) + '@emotion/react': 11.13.3(@types/react@18.3.8)(react@18.3.1) '@emotion/sheet': 1.4.0 - '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.5)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.8)(react@18.3.1) csstype: 3.1.3 prop-types: 15.8.1 react: 18.3.1 dev: false - /@mui/styles@6.1.0(@types/react@18.3.5)(react@18.3.1): - resolution: {integrity: sha512-E18VFiRIUraVXdcxXy6PyBpK73nCN1xbVPEWREVFKYHjZrd1vR8RJ/zLdZDHwpubAxs8Jqr+7JPWmzBt79qAWw==} + /@mui/styles@6.1.1(@types/react@18.3.8)(react@18.3.1): + resolution: {integrity: sha512-gZxluffgoVPjpe6YCJRGoTTTmi/YBJnJQzUhkyfjXTyNzMMPlifau0cA+b7c/c1cshlwYm5JJWIRRlvSk0PivA==} engines: {node: '>=14.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -3133,10 +3136,10 @@ packages: dependencies: '@babel/runtime': 7.25.6 '@emotion/hash': 0.9.2 - '@mui/private-theming': 6.1.0(@types/react@18.3.5)(react@18.3.1) - '@mui/types': 7.2.16(@types/react@18.3.5) - '@mui/utils': 6.1.0(@types/react@18.3.5)(react@18.3.1) - '@types/react': 18.3.5 + '@mui/private-theming': 6.1.1(@types/react@18.3.8)(react@18.3.1) + '@mui/types': 7.2.17(@types/react@18.3.8) + '@mui/utils': 6.1.1(@types/react@18.3.8)(react@18.3.1) + '@types/react': 18.3.8 clsx: 2.1.1 csstype: 3.1.3 hoist-non-react-statics: 3.3.2 @@ -3152,7 +3155,7 @@ packages: react: 18.3.1 dev: false - /@mui/system@5.16.7(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react@18.3.1): + /@mui/system@5.16.7(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react@18.3.1): resolution: {integrity: sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA==} engines: {node: '>=12.0.0'} peerDependencies: @@ -3169,21 +3172,21 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@emotion/react': 11.13.3(@types/react@18.3.5)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.5)(react@18.3.1) - '@mui/private-theming': 5.16.6(@types/react@18.3.5)(react@18.3.1) + '@emotion/react': 11.13.3(@types/react@18.3.8)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.8)(react@18.3.1) + '@mui/private-theming': 5.16.6(@types/react@18.3.8)(react@18.3.1) '@mui/styled-engine': 5.16.6(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(react@18.3.1) - '@mui/types': 7.2.16(@types/react@18.3.5) - '@mui/utils': 5.16.6(@types/react@18.3.5)(react@18.3.1) - '@types/react': 18.3.5 + '@mui/types': 7.2.17(@types/react@18.3.8) + '@mui/utils': 5.16.6(@types/react@18.3.8)(react@18.3.1) + '@types/react': 18.3.8 clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 react: 18.3.1 dev: false - /@mui/system@6.1.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react@18.3.1): - resolution: {integrity: sha512-NumkGDqT6EdXfcoFLYQ+M4XlTW5hH3+aK48xAbRqKPXJfxl36CBt4DLduw/Voa5dcayGus9T6jm1AwU2hoJ5hQ==} + /@mui/system@6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react@18.3.1): + resolution: {integrity: sha512-PaYsCz2tUOcpu3T0okDEsSuP/yCDIj9JZ4Tox1JovRSKIjltHpXPsXZSGr3RiWdtM1MTQMFMCZzu0+CKbyy+Kw==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -3199,31 +3202,31 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@emotion/react': 11.13.3(@types/react@18.3.5)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.5)(react@18.3.1) - '@mui/private-theming': 6.1.0(@types/react@18.3.5)(react@18.3.1) - '@mui/styled-engine': 6.1.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(react@18.3.1) - '@mui/types': 7.2.16(@types/react@18.3.5) - '@mui/utils': 6.1.0(@types/react@18.3.5)(react@18.3.1) - '@types/react': 18.3.5 + '@emotion/react': 11.13.3(@types/react@18.3.8)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.8)(react@18.3.1) + '@mui/private-theming': 6.1.1(@types/react@18.3.8)(react@18.3.1) + '@mui/styled-engine': 6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(react@18.3.1) + '@mui/types': 7.2.17(@types/react@18.3.8) + '@mui/utils': 6.1.1(@types/react@18.3.8)(react@18.3.1) + '@types/react': 18.3.8 clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 react: 18.3.1 dev: false - /@mui/types@7.2.16(@types/react@18.3.5): - resolution: {integrity: sha512-qI8TV3M7ShITEEc8Ih15A2vLzZGLhD+/UPNwck/hcls2gwg7dyRjNGXcQYHKLB5Q7PuTRfrTkAoPa2VV1s67Ag==} + /@mui/types@7.2.17(@types/react@18.3.8): + resolution: {integrity: sha512-oyumoJgB6jDV8JFzRqjBo2daUuHpzDjoO/e3IrRhhHo/FxJlaVhET6mcNrKHUq2E+R+q3ql0qAtvQ4rfWHhAeQ==} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true dependencies: - '@types/react': 18.3.5 + '@types/react': 18.3.8 dev: false - /@mui/utils@5.16.6(@types/react@18.3.5)(react@18.3.1): + /@mui/utils@5.16.6(@types/react@18.3.8)(react@18.3.1): resolution: {integrity: sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==} engines: {node: '>=12.0.0'} peerDependencies: @@ -3234,16 +3237,16 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@mui/types': 7.2.16(@types/react@18.3.5) - '@types/prop-types': 15.7.12 - '@types/react': 18.3.5 + '@mui/types': 7.2.17(@types/react@18.3.8) + '@types/prop-types': 15.7.13 + '@types/react': 18.3.8 clsx: 2.1.1 prop-types: 15.8.1 react: 18.3.1 react-is: 18.3.1 dev: false - /@mui/utils@6.0.0-rc.0(@types/react@18.3.5)(react@18.3.1): + /@mui/utils@6.0.0-rc.0(@types/react@18.3.8)(react@18.3.1): resolution: {integrity: sha512-tBp0ILEXDL0bbDDT8PnZOjCqSm5Dfk2N0Z45uzRw+wVl6fVvloC9zw8avl+OdX1Bg3ubs/ttKn8nRNv17bpM5A==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3254,17 +3257,17 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@mui/types': 7.2.16(@types/react@18.3.5) - '@types/prop-types': 15.7.12 - '@types/react': 18.3.5 + '@mui/types': 7.2.17(@types/react@18.3.8) + '@types/prop-types': 15.7.13 + '@types/react': 18.3.8 clsx: 2.1.1 prop-types: 15.8.1 react: 18.3.1 react-is: 18.3.1 dev: false - /@mui/utils@6.1.0(@types/react@18.3.5)(react@18.3.1): - resolution: {integrity: sha512-oT8ZzMISRUhTVpdbYzY0CgrCBb3t/YEdcaM13tUnuTjZ15pdA6g5lx15ZJUdgYXV6PbJdw7tDQgMEr4uXK5TXQ==} + /@mui/utils@6.1.1(@types/react@18.3.8)(react@18.3.1): + resolution: {integrity: sha512-HlRrgdJSPbYDXPpoVMWZV8AE7WcFtAk13rWNWAEVWKSanzBBkymjz3km+Th/Srowsh4pf1fTSP1B0L116wQBYw==} engines: {node: '>=14.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -3274,24 +3277,24 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@mui/types': 7.2.16(@types/react@18.3.5) - '@types/prop-types': 15.7.12 - '@types/react': 18.3.5 + '@mui/types': 7.2.17(@types/react@18.3.8) + '@types/prop-types': 15.7.13 + '@types/react': 18.3.8 clsx: 2.1.1 prop-types: 15.8.1 react: 18.3.1 react-is: 18.3.1 dev: false - /@mui/x-date-pickers@7.17.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@mui/material@6.1.0)(@mui/system@6.1.0)(@types/react@18.3.5)(dayjs@1.11.13)(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-3mIw1uOZU/yKweZsVAo9QnwVFzLHqXgXG1TbGbDJ4AU6FhN2TCUlR9tzKHSlYdAHZ0bEWDS1/bgeGsQC7skXMA==} + /@mui/x-date-pickers@7.18.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@mui/material@6.1.1)(@mui/system@6.1.1)(@types/react@18.3.8)(dayjs@1.11.13)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-12tXIoMj9vpS8fS/bS3kWPCoVrH38vNGCxgplI0vOnUrN9rJuYJz3agLPJe1S0xciTw+9W8ZSe3soaW+owoz1Q==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.9.0 '@emotion/styled': ^11.8.1 '@mui/material': ^5.15.14 || ^6.0.0 '@mui/system': ^5.15.14 || ^6.0.0 - date-fns: ^2.25.0 || ^3.2.0 + date-fns: ^2.25.0 || ^3.2.0 || ^4.0.0 date-fns-jalali: ^2.13.0-0 || ^3.2.0-0 dayjs: ^1.10.7 luxon: ^3.0.2 @@ -3321,12 +3324,12 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@emotion/react': 11.13.3(@types/react@18.3.5)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.5)(react@18.3.1) - '@mui/material': 6.1.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1) - '@mui/system': 6.1.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react@18.3.1) - '@mui/utils': 5.16.6(@types/react@18.3.5)(react@18.3.1) - '@mui/x-internals': 7.17.0(@types/react@18.3.5)(react@18.3.1) + '@emotion/react': 11.13.3(@types/react@18.3.8)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.8)(react@18.3.1) + '@mui/material': 6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1) + '@mui/system': 6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react@18.3.1) + '@mui/utils': 5.16.6(@types/react@18.3.8)(react@18.3.1) + '@mui/x-internals': 7.18.0(@types/react@18.3.8)(react@18.3.1) '@types/react-transition-group': 4.4.11 clsx: 2.1.1 dayjs: 1.11.13 @@ -3338,19 +3341,52 @@ packages: - '@types/react' dev: false - /@mui/x-internals@7.17.0(@types/react@18.3.5)(react@18.3.1): - resolution: {integrity: sha512-FLlAGSJl/vsuaA/8hPGazXFppyzIzxApJJDZMoTS0geUmHd0hyooISV2ltllLmrZ/DGtHhI08m8GGnHL6/vVeg==} + /@mui/x-internals@7.18.0(@types/react@18.3.8)(react@18.3.1): + resolution: {integrity: sha512-lzCHOWIR0cAIY1bGrWSprYerahbnH5C31ql/2OWCEjcngL2NAV1M6oKI2Vp4HheqzJ822c60UyWyapvyjSzY/A==} engines: {node: '>=14.0.0'} peerDependencies: react: ^17.0.0 || ^18.0.0 dependencies: '@babel/runtime': 7.25.6 - '@mui/utils': 5.16.6(@types/react@18.3.5)(react@18.3.1) + '@mui/utils': 5.16.6(@types/react@18.3.8)(react@18.3.1) react: 18.3.1 transitivePeerDependencies: - '@types/react' dev: false + /@mui/x-tree-view@7.18.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@mui/material@6.1.1)(@mui/system@6.1.1)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-3UJAYtBquc0SzKxEEdM68XlKOuuCl70ktZPqqI3z4wTZ0HK445XXc32t/s0VPIL94kRxWQcGPpgWFauScDwhug==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.9.0 + '@emotion/styled': ^11.8.1 + '@mui/material': ^5.15.14 || ^6.0.0 + '@mui/system': ^5.15.14 || ^6.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@emotion/react': 11.13.3(@types/react@18.3.8)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.8)(react@18.3.1) + '@mui/material': 6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1) + '@mui/system': 6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react@18.3.1) + '@mui/utils': 5.16.6(@types/react@18.3.8)(react@18.3.1) + '@mui/x-internals': 7.18.0(@types/react@18.3.8)(react@18.3.1) + '@types/react-transition-group': 4.4.11 + clsx: 2.1.1 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-transition-group: 4.4.5(react-dom@18.3.1)(react@18.3.1) + transitivePeerDependencies: + - '@types/react' + dev: false + /@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3: resolution: {integrity: sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==} requiresBuild: true @@ -3396,8 +3432,8 @@ packages: resolution: {integrity: sha512-/Ri4xDDpe12NT6Ex/DRgHzLlobiQXEW/hmG08w1wj/YU7hLemk97c+zHQFp0iZQ9r7YqgLEXZR2sls4HxBf9NA==} dev: false - /@polka/url@1.0.0-next.25: - resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==} + /@polka/url@1.0.0-next.28: + resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} dev: true /@popperjs/core@2.11.8: @@ -3550,48 +3586,48 @@ packages: resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} dependencies: '@types/connect': 3.4.38 - '@types/node': 22.5.4 + '@types/node': 22.5.5 dev: true /@types/bonjour@3.5.13: resolution: {integrity: sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==} dependencies: - '@types/node': 22.5.4 + '@types/node': 22.5.5 dev: true /@types/connect-history-api-fallback@1.5.4: resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} dependencies: '@types/express-serve-static-core': 4.19.5 - '@types/node': 22.5.4 + '@types/node': 22.5.5 dev: true /@types/connect@3.4.38: resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} dependencies: - '@types/node': 22.5.4 + '@types/node': 22.5.5 dev: true /@types/create-react-class@15.6.8: resolution: {integrity: sha512-s5HocgHXvN4Phoypsz8+4TLFreWRUrMcq9MHgwVleqNNR5EipSrFN49LCU/N7j8nIiQoRExY9n79LBrTDdsE1Q==} dependencies: - '@types/prop-types': 15.7.12 - '@types/react': 18.3.5 + '@types/prop-types': 15.7.13 + '@types/react': 18.3.8 dev: true /@types/emscripten@1.39.13: resolution: {integrity: sha512-cFq+fO/isvhvmuP/+Sl4K4jtU6E23DoivtbO4r50e3odaxAiVdbfSYRDdJ4gCdxx+3aRjhphS5ZMwIH4hFy/Cw==} dev: true - /@types/estree@1.0.5: - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + /@types/estree@1.0.6: + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} dev: true /@types/express-serve-static-core@4.19.5: resolution: {integrity: sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==} dependencies: - '@types/node': 22.5.4 - '@types/qs': 6.9.15 + '@types/node': 22.5.5 + '@types/qs': 6.9.16 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 dev: true @@ -3601,7 +3637,7 @@ packages: dependencies: '@types/body-parser': 1.19.5 '@types/express-serve-static-core': 4.19.5 - '@types/qs': 6.9.15 + '@types/qs': 6.9.16 '@types/serve-static': 1.15.7 dev: true @@ -3613,20 +3649,20 @@ packages: resolution: {integrity: sha512-WRXN0kQPCnqxN0/PgNgc7WBF6c8rbSHsEep3/qBLpsQ824RONdOmTs0TV7XhIW2GDNRAHO2CqCgAFLR5PChosw==} dependencies: '@types/fbemitter': 2.0.35 - '@types/react': 18.3.5 + '@types/react': 18.3.8 dev: true /@types/glob@7.2.0: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 22.5.4 + '@types/node': 22.5.5 dev: true /@types/graceful-fs@4.1.9: resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} dependencies: - '@types/node': 22.5.4 + '@types/node': 22.5.5 dev: true /@types/history@4.7.11: @@ -3644,7 +3680,7 @@ packages: /@types/http-proxy@1.17.15: resolution: {integrity: sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==} dependencies: - '@types/node': 22.5.4 + '@types/node': 22.5.5 dev: true /@types/istanbul-lib-coverage@2.0.6: @@ -3699,11 +3735,11 @@ packages: /@types/node-forge@1.3.11: resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} dependencies: - '@types/node': 22.5.4 + '@types/node': 22.5.5 dev: true - /@types/node@22.5.4: - resolution: {integrity: sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==} + /@types/node@22.5.5: + resolution: {integrity: sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==} dependencies: undici-types: 6.19.8 dev: true @@ -3720,11 +3756,11 @@ packages: resolution: {integrity: sha512-y4tHUVVoMEOm2nxRLQ2/ET8upj/pBmoutGxFw2LZJTQWPgWXI+cbxVEUFFmIzr/bpFR83hGDOTSXX6HBeObvZA==} dev: true - /@types/prop-types@15.7.12: - resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} + /@types/prop-types@15.7.13: + resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==} - /@types/qs@6.9.15: - resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} + /@types/qs@6.9.16: + resolution: {integrity: sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==} dev: true /@types/range-parser@1.2.7: @@ -3738,14 +3774,14 @@ packages: /@types/react-dom@18.3.0: resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} dependencies: - '@types/react': 18.3.5 + '@types/react': 18.3.8 dev: true /@types/react-router-dom@5.3.3: resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} dependencies: '@types/history': 4.7.11 - '@types/react': 18.3.5 + '@types/react': 18.3.8 '@types/react-router': 5.1.20 dev: true @@ -3753,19 +3789,19 @@ packages: resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} dependencies: '@types/history': 4.7.11 - '@types/react': 18.3.5 + '@types/react': 18.3.8 dev: true /@types/react-transition-group@4.4.11: resolution: {integrity: sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==} dependencies: - '@types/react': 18.3.5 + '@types/react': 18.3.8 dev: false - /@types/react@18.3.5: - resolution: {integrity: sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==} + /@types/react@18.3.8: + resolution: {integrity: sha512-syBUrW3/XpnW4WJ41Pft+I+aPoDVbrBVQGEnbD7NijDGlVC+8gV/XKRY+7vMDlfPpbwYt0l1vd/Sj8bJGMbs9Q==} dependencies: - '@types/prop-types': 15.7.12 + '@types/prop-types': 15.7.13 csstype: 3.1.3 /@types/retry@0.12.0: @@ -3786,7 +3822,7 @@ packages: resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} dependencies: '@types/mime': 1.3.5 - '@types/node': 22.5.4 + '@types/node': 22.5.5 dev: true /@types/serve-index@1.9.4: @@ -3799,14 +3835,14 @@ packages: resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} dependencies: '@types/http-errors': 2.0.4 - '@types/node': 22.5.4 + '@types/node': 22.5.5 '@types/send': 0.17.4 dev: true /@types/sockjs@0.3.36: resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} dependencies: - '@types/node': 22.5.4 + '@types/node': 22.5.5 dev: true /@types/source-list-map@0.1.6: @@ -3817,7 +3853,7 @@ packages: resolution: {integrity: sha512-ep8b36RKHlgWPqjNG9ToUrPiwkhwh0AEzy883mO5Xnd+cL6VBH1EvSjBAAuxLUFF2Vn/moE3Me6v9E1Lo+48GQ==} dependencies: '@types/emscripten': 1.39.13 - '@types/node': 22.5.4 + '@types/node': 22.5.5 dev: true /@types/stack-utils@2.0.3: @@ -3837,7 +3873,7 @@ packages: /@types/webpack-sources@3.2.3: resolution: {integrity: sha512-4nZOdMwSPHZ4pTEZzSp0AsTM4K7Qmu40UKW4tJDiOVs20UzYF9l+qUe4s0ftfN0pin06n+5cWWDJXH+sbhAiDw==} dependencies: - '@types/node': 22.5.4 + '@types/node': 22.5.5 '@types/source-list-map': 0.1.6 source-map: 0.7.4 dev: true @@ -3845,7 +3881,7 @@ packages: /@types/webpack@4.41.39: resolution: {integrity: sha512-otxUJvoi6FbBq/64gGH34eblpKLgdi+gf08GaAh8Bx6So0ZZic028Ev/SUxD22gbthMKCkeeiXEat1kHLDJfYg==} dependencies: - '@types/node': 22.5.4 + '@types/node': 22.5.5 '@types/tapable': 1.0.12 '@types/uglify-js': 3.17.5 '@types/webpack-sources': 3.2.3 @@ -3856,7 +3892,7 @@ packages: /@types/ws@8.5.12: resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} dependencies: - '@types/node': 22.5.4 + '@types/node': 22.5.5 dev: true /@types/yargs-parser@21.0.3: @@ -3869,7 +3905,7 @@ packages: '@types/yargs-parser': 21.0.3 dev: true - /@typescript-eslint/eslint-plugin@7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)(typescript@4.9.5): + /@typescript-eslint/eslint-plugin@7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.1)(typescript@4.9.5): resolution: {integrity: sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: @@ -3880,14 +3916,14 @@ packages: typescript: optional: true dependencies: - '@eslint-community/regexpp': 4.11.0 - '@typescript-eslint/parser': 7.8.0(eslint@8.57.0)(typescript@4.9.5) + '@eslint-community/regexpp': 4.11.1 + '@typescript-eslint/parser': 7.8.0(eslint@8.57.1)(typescript@4.9.5) '@typescript-eslint/scope-manager': 7.8.0 - '@typescript-eslint/type-utils': 7.8.0(eslint@8.57.0)(typescript@4.9.5) - '@typescript-eslint/utils': 7.8.0(eslint@8.57.0)(typescript@4.9.5) + '@typescript-eslint/type-utils': 7.8.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/utils': 7.8.0(eslint@8.57.1)(typescript@4.9.5) '@typescript-eslint/visitor-keys': 7.8.0 debug: 4.3.7 - eslint: 8.57.0 + eslint: 8.57.1 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 @@ -3898,7 +3934,7 @@ packages: - supports-color dev: true - /@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@4.9.5): + /@typescript-eslint/parser@7.8.0(eslint@8.57.1)(typescript@4.9.5): resolution: {integrity: sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: @@ -3913,7 +3949,7 @@ packages: '@typescript-eslint/typescript-estree': 7.8.0(typescript@4.9.5) '@typescript-eslint/visitor-keys': 7.8.0 debug: 4.3.7 - eslint: 8.57.0 + eslint: 8.57.1 typescript: 4.9.5 transitivePeerDependencies: - supports-color @@ -3935,7 +3971,7 @@ packages: '@typescript-eslint/visitor-keys': 7.8.0 dev: true - /@typescript-eslint/type-utils@7.8.0(eslint@8.57.0)(typescript@4.9.5): + /@typescript-eslint/type-utils@7.8.0(eslint@8.57.1)(typescript@4.9.5): resolution: {integrity: sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: @@ -3946,9 +3982,9 @@ packages: optional: true dependencies: '@typescript-eslint/typescript-estree': 7.8.0(typescript@4.9.5) - '@typescript-eslint/utils': 7.8.0(eslint@8.57.0)(typescript@4.9.5) + '@typescript-eslint/utils': 7.8.0(eslint@8.57.1)(typescript@4.9.5) debug: 4.3.7 - eslint: 8.57.0 + eslint: 8.57.1 ts-api-utils: 1.3.0(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: @@ -4008,19 +4044,19 @@ packages: - supports-color dev: true - /@typescript-eslint/utils@5.62.0(eslint@8.57.0)(typescript@4.9.5): + /@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@4.9.5): resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) '@types/json-schema': 7.0.15 '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) - eslint: 8.57.0 + eslint: 8.57.1 eslint-scope: 5.1.1 semver: 7.6.3 transitivePeerDependencies: @@ -4028,19 +4064,19 @@ packages: - typescript dev: true - /@typescript-eslint/utils@7.8.0(eslint@8.57.0)(typescript@4.9.5): + /@typescript-eslint/utils@7.8.0(eslint@8.57.1)(typescript@4.9.5): resolution: {integrity: sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) '@types/json-schema': 7.0.15 '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 7.8.0 '@typescript-eslint/types': 7.8.0 '@typescript-eslint/typescript-estree': 7.8.0(typescript@4.9.5) - eslint: 8.57.0 + eslint: 8.57.1 semver: 7.6.3 transitivePeerDependencies: - supports-color @@ -4572,8 +4608,8 @@ packages: - supports-color dev: true - /babel-loader@8.3.0(@babel/core@7.25.2)(webpack@5.94.0): - resolution: {integrity: sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==} + /babel-loader@8.4.1(@babel/core@7.25.2)(webpack@5.94.0): + resolution: {integrity: sha512-nXzRChX+Z1GoE6yWavBQg6jDslyFF3SDjl2paADuoQtQW10JqShJt62R6eJQ5m/pjJFDT8xgKIWSP85OY8eXeA==} engines: {node: '>= 8.9'} peerDependencies: '@babel/core': ^7.0.0 @@ -4785,8 +4821,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001660 - electron-to-chromium: 1.5.22 + caniuse-lite: 1.0.30001662 + electron-to-chromium: 1.5.26 node-releases: 2.0.18 update-browserslist-db: 1.1.0(browserslist@4.23.3) dev: true @@ -4843,8 +4879,8 @@ packages: engines: {node: '>=10'} dev: true - /caniuse-lite@1.0.30001660: - resolution: {integrity: sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg==} + /caniuse-lite@1.0.30001662: + resolution: {integrity: sha512-sgMUVwLmGseH8ZIrm1d51UbrhqMCH3jvS7gF/M6byuHOnKyLOBL7W8yz5V02OHwgLGA36o/AFhWzzh4uc5aqTA==} dev: true /chalk@2.4.2: @@ -4900,6 +4936,13 @@ packages: fsevents: 2.3.3 dev: true + /chokidar@4.0.0: + resolution: {integrity: sha512-mxIojEAQcuEvT/lyXq+jf/3cO/KoA6z4CeNDGGevTybECPOMFCnQy3OPahluUkbqgPNGw5Bi78UC7Po6Lhy+NA==} + engines: {node: '>= 14.16.0'} + dependencies: + readdirp: 4.0.1 + dev: true + /chrome-trace-event@1.0.4: resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} engines: {node: '>=6.0'} @@ -5178,12 +5221,12 @@ packages: webpack: optional: true dependencies: - icss-utils: 5.1.0(postcss@8.4.45) - postcss: 8.4.45 - postcss-modules-extract-imports: 3.1.0(postcss@8.4.45) - postcss-modules-local-by-default: 4.0.5(postcss@8.4.45) - postcss-modules-scope: 3.2.0(postcss@8.4.45) - postcss-modules-values: 4.0.0(postcss@8.4.45) + icss-utils: 5.1.0(postcss@8.4.47) + postcss: 8.4.47 + postcss-modules-extract-imports: 3.1.0(postcss@8.4.47) + postcss-modules-local-by-default: 4.0.5(postcss@8.4.47) + postcss-modules-scope: 3.2.0(postcss@8.4.47) + postcss-modules-values: 4.0.0(postcss@8.4.47) postcss-value-parser: 4.2.0 semver: 7.6.3 webpack: 5.94.0(webpack-cli@4.10.0) @@ -5529,8 +5572,8 @@ packages: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} dev: true - /electron-to-chromium@1.5.22: - resolution: {integrity: sha512-tKYm5YHPU1djz0O+CGJ+oJIvimtsCcwR2Z9w7Skh08lUdyzXY5djods3q+z2JkWdb7tCcmM//eVavSRAiaPRNg==} + /electron-to-chromium@1.5.26: + resolution: {integrity: sha512-Z+OMe9M/V6Ep9n/52+b7lkvYEps26z4Yz3vjWL1V61W0q+VLF1pOHhMY17sa4roz4AWmULSI8E6SAojZA5L0YQ==} dev: true /email-addresses@3.1.0: @@ -5763,7 +5806,7 @@ packages: source-map: 0.6.1 dev: true - /eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.30.0)(eslint@8.57.0): + /eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.30.0)(eslint@8.57.1): resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -5771,14 +5814,14 @@ packages: eslint-plugin-import: ^2.25.2 dependencies: confusing-browser-globals: 1.0.11 - eslint: 8.57.0 - eslint-plugin-import: 2.30.0(eslint@8.57.0) + eslint: 8.57.1 + eslint-plugin-import: 2.30.0(eslint@8.57.1) object.assign: 4.1.5 object.entries: 1.1.8 semver: 6.3.1 dev: true - /eslint-config-airbnb@19.0.4(eslint-plugin-import@2.30.0)(eslint-plugin-jsx-a11y@6.10.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.36.1)(eslint@8.57.0): + /eslint-config-airbnb@19.0.4(eslint-plugin-import@2.30.0)(eslint-plugin-jsx-a11y@6.10.0)(eslint-plugin-react-hooks@4.6.2)(eslint-plugin-react@7.36.1)(eslint@8.57.1): resolution: {integrity: sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==} engines: {node: ^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -5788,23 +5831,23 @@ packages: eslint-plugin-react: ^7.28.0 eslint-plugin-react-hooks: ^4.3.0 dependencies: - eslint: 8.57.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.30.0)(eslint@8.57.0) - eslint-plugin-import: 2.30.0(eslint@8.57.0) - eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.0) - eslint-plugin-react: 7.36.1(eslint@8.57.0) - eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) + eslint: 8.57.1 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.30.0)(eslint@8.57.1) + eslint-plugin-import: 2.30.0(eslint@8.57.1) + eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.1) + eslint-plugin-react: 7.36.1(eslint@8.57.1) + eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) object.assign: 4.1.5 object.entries: 1.1.8 dev: true - /eslint-config-prettier@8.10.0(eslint@8.57.0): + /eslint-config-prettier@8.10.0(eslint@8.57.1): resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.57.0 + eslint: 8.57.1 dev: true /eslint-import-resolver-node@0.3.9: @@ -5815,7 +5858,7 @@ packages: resolve: 1.22.8 dev: true - /eslint-module-utils@2.11.0(eslint@8.57.0): + /eslint-module-utils@2.11.0(eslint@8.57.1): resolution: {integrity: sha512-gbBE5Hitek/oG6MUVj6sFuzEjA/ClzNflVrLovHi/JgLdC7fiN5gLAY1WIPW1a0V5I999MnsrvVrCOGmmVqDBQ==} engines: {node: '>=4'} peerDependencies: @@ -5825,10 +5868,10 @@ packages: optional: true dependencies: debug: 3.2.7 - eslint: 8.57.0 + eslint: 8.57.1 dev: true - /eslint-plugin-import@2.30.0(eslint@8.57.0): + /eslint-plugin-import@2.30.0(eslint@8.57.1): resolution: {integrity: sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==} engines: {node: '>=4'} peerDependencies: @@ -5841,9 +5884,9 @@ packages: array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.57.0 + eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.11.0(eslint@8.57.0) + eslint-module-utils: 2.11.0(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -5855,7 +5898,7 @@ packages: tsconfig-paths: 3.15.0 dev: true - /eslint-plugin-jest@26.9.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint@8.57.0)(jest@27.5.1)(typescript@4.9.5): + /eslint-plugin-jest@26.9.0(@typescript-eslint/eslint-plugin@7.8.0)(eslint@8.57.1)(jest@27.5.1)(typescript@4.9.5): resolution: {integrity: sha512-TWJxWGp1J628gxh2KhaH1H1paEdgE2J61BBF1I59c6xWeL5+D1BzMxGDN/nXAfX+aSkR5u80K+XhskK6Gwq9ng==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -5868,16 +5911,16 @@ packages: jest: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)(typescript@4.9.5) - '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@4.9.5) - eslint: 8.57.0 + '@typescript-eslint/eslint-plugin': 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: 8.57.1 jest: 27.5.1 transitivePeerDependencies: - supports-color - typescript dev: true - /eslint-plugin-jsx-a11y@6.10.0(eslint@8.57.0): + /eslint-plugin-jsx-a11y@6.10.0(eslint@8.57.1): resolution: {integrity: sha512-ySOHvXX8eSN6zz8Bywacm7CvGNhUtdjvqfQDVe6020TUK34Cywkw7m0KsCCk1Qtm9G1FayfTN1/7mMYnYO2Bhg==} engines: {node: '>=4.0'} peerDependencies: @@ -5892,7 +5935,7 @@ packages: damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 es-iterator-helpers: 1.0.19 - eslint: 8.57.0 + eslint: 8.57.1 hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -5902,7 +5945,7 @@ packages: string.prototype.includes: 2.0.0 dev: true - /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.0)(prettier@2.8.8): + /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.1)(prettier@2.8.8): resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -5913,22 +5956,22 @@ packages: eslint-config-prettier: optional: true dependencies: - eslint: 8.57.0 - eslint-config-prettier: 8.10.0(eslint@8.57.0) + eslint: 8.57.1 + eslint-config-prettier: 8.10.0(eslint@8.57.1) prettier: 2.8.8 prettier-linter-helpers: 1.0.0 dev: true - /eslint-plugin-react-hooks@4.6.2(eslint@8.57.0): + /eslint-plugin-react-hooks@4.6.2(eslint@8.57.1): resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==} engines: {node: '>=10'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 dependencies: - eslint: 8.57.0 + eslint: 8.57.1 dev: true - /eslint-plugin-react@7.36.1(eslint@8.57.0): + /eslint-plugin-react@7.36.1(eslint@8.57.1): resolution: {integrity: sha512-/qwbqNXZoq+VP30s1d4Nc1C5GTxjJQjk4Jzs4Wq2qzxFM7dSmuG2UkIjg2USMLh3A/aVcUNrK7v0J5U1XEGGwA==} engines: {node: '>=4'} peerDependencies: @@ -5940,7 +5983,7 @@ packages: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.0.19 - eslint: 8.57.0 + eslint: 8.57.1 estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -5981,16 +6024,16 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.57.0: - resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + /eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@eslint-community/regexpp': 4.11.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@eslint-community/regexpp': 4.11.1 '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.0 - '@humanwhocodes/config-array': 0.11.14 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 '@ungap/structured-clone': 1.2.0 @@ -6704,7 +6747,7 @@ packages: he: 1.2.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.32.0 + terser: 5.33.0 dev: true /html-minifier-terser@7.2.0: @@ -6718,7 +6761,7 @@ packages: entities: 4.5.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.32.0 + terser: 5.33.0 dev: true /html-parse-stringify@3.0.1: @@ -6909,13 +6952,13 @@ packages: safer-buffer: 2.1.2 dev: true - /icss-utils@5.1.0(postcss@8.4.45): + /icss-utils@5.1.0(postcss@8.4.47): resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.45 + postcss: 8.4.47 dev: true /ignore@5.3.2: @@ -7323,7 +7366,7 @@ packages: '@jest/environment': 27.5.1 '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.5.4 + '@types/node': 22.5.5 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 @@ -7448,7 +7491,7 @@ packages: '@jest/environment': 27.5.1 '@jest/fake-timers': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.5.4 + '@types/node': 22.5.5 jest-mock: 27.5.1 jest-util: 27.5.1 jsdom: 16.7.0 @@ -7466,7 +7509,7 @@ packages: '@jest/environment': 27.5.1 '@jest/fake-timers': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.5.4 + '@types/node': 22.5.5 jest-mock: 27.5.1 jest-util: 27.5.1 dev: true @@ -7482,7 +7525,7 @@ packages: dependencies: '@jest/types': 27.5.1 '@types/graceful-fs': 4.1.9 - '@types/node': 22.5.4 + '@types/node': 22.5.5 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -7504,7 +7547,7 @@ packages: '@jest/source-map': 27.5.1 '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.5.4 + '@types/node': 22.5.5 chalk: 4.1.2 co: 4.6.0 expect: 27.5.1 @@ -7559,7 +7602,7 @@ packages: engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@jest/types': 27.5.1 - '@types/node': 22.5.4 + '@types/node': 22.5.5 dev: true /jest-pnp-resolver@1.2.3(jest-resolve@27.5.1): @@ -7615,7 +7658,7 @@ packages: '@jest/test-result': 27.5.1 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.5.4 + '@types/node': 22.5.5 chalk: 4.1.2 emittery: 0.8.1 graceful-fs: 4.2.11 @@ -7672,7 +7715,7 @@ packages: resolution: {integrity: sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@types/node': 22.5.4 + '@types/node': 22.5.5 graceful-fs: 4.2.11 dev: true @@ -7711,7 +7754,7 @@ packages: engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@jest/types': 27.5.1 - '@types/node': 22.5.4 + '@types/node': 22.5.5 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -7736,7 +7779,7 @@ packages: dependencies: '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.5.4 + '@types/node': 22.5.5 ansi-escapes: 4.3.2 chalk: 4.1.2 jest-util: 27.5.1 @@ -7747,7 +7790,7 @@ packages: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 22.5.4 + '@types/node': 22.5.5 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true @@ -8157,7 +8200,7 @@ packages: hasBin: true dev: true - /material-react-table@2.13.3(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@mui/icons-material@6.1.0)(@mui/material@6.1.0)(@mui/x-date-pickers@7.17.0)(react-dom@18.3.1)(react@18.3.1): + /material-react-table@2.13.3(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@mui/icons-material@6.1.1)(@mui/material@6.1.1)(@mui/x-date-pickers@7.18.0)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-xeyAEG6UYG3qgBIo17epAP5zsWT1pH0uCEkaUxvhki9sGcP35OqfOMSZJNhISvmqEqXKYHdqKbZI6iOwsg1sYA==} engines: {node: '>=16'} peerDependencies: @@ -8169,11 +8212,11 @@ packages: react: '>=17.0' react-dom: '>=17.0' dependencies: - '@emotion/react': 11.13.3(@types/react@18.3.5)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.5)(react@18.3.1) - '@mui/icons-material': 6.1.0(@mui/material@6.1.0)(@types/react@18.3.5)(react@18.3.1) - '@mui/material': 6.1.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1) - '@mui/x-date-pickers': 7.17.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@mui/material@6.1.0)(@mui/system@6.1.0)(@types/react@18.3.5)(dayjs@1.11.13)(react-dom@18.3.1)(react@18.3.1) + '@emotion/react': 11.13.3(@types/react@18.3.8)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.8)(react@18.3.1) + '@mui/icons-material': 6.1.1(@mui/material@6.1.1)(@types/react@18.3.8)(react@18.3.1) + '@mui/material': 6.1.1(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1) + '@mui/x-date-pickers': 7.18.0(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@mui/material@6.1.1)(@mui/system@6.1.1)(@types/react@18.3.8)(dayjs@1.11.13)(react-dom@18.3.1)(react@18.3.1) '@tanstack/match-sorter-utils': 8.19.4 '@tanstack/react-table': 8.20.5(react-dom@18.3.1)(react@18.3.1) '@tanstack/react-virtual': 3.10.6(react-dom@18.3.1)(react@18.3.1) @@ -8696,45 +8739,45 @@ packages: engines: {node: '>= 0.4'} dev: true - /postcss-modules-extract-imports@3.1.0(postcss@8.4.45): + /postcss-modules-extract-imports@3.1.0(postcss@8.4.47): resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.45 + postcss: 8.4.47 dev: true - /postcss-modules-local-by-default@4.0.5(postcss@8.4.45): + /postcss-modules-local-by-default@4.0.5(postcss@8.4.47): resolution: {integrity: sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - icss-utils: 5.1.0(postcss@8.4.45) - postcss: 8.4.45 + icss-utils: 5.1.0(postcss@8.4.47) + postcss: 8.4.47 postcss-selector-parser: 6.1.2 postcss-value-parser: 4.2.0 dev: true - /postcss-modules-scope@3.2.0(postcss@8.4.45): + /postcss-modules-scope@3.2.0(postcss@8.4.47): resolution: {integrity: sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.45 + postcss: 8.4.47 postcss-selector-parser: 6.1.2 dev: true - /postcss-modules-values@4.0.0(postcss@8.4.45): + /postcss-modules-values@4.0.0(postcss@8.4.47): resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - icss-utils: 5.1.0(postcss@8.4.45) - postcss: 8.4.45 + icss-utils: 5.1.0(postcss@8.4.47) + postcss: 8.4.47 dev: true /postcss-selector-parser@6.1.2: @@ -8749,8 +8792,8 @@ packages: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} dev: true - /postcss@8.4.45: - resolution: {integrity: sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==} + /postcss@8.4.47: + resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.7 @@ -9071,6 +9114,11 @@ packages: picomatch: 2.3.1 dev: true + /readdirp@4.0.1: + resolution: {integrity: sha512-GkMg9uOTpIWWKbSsgwb5fA4EavTR+SG/PMPoAY8hkhHfEEY0/vqljY+XHqtDf2cr2IJtoNRDbrrEpZUiZCkYRw==} + engines: {node: '>= 14.16.0'} + dev: true + /rechoir@0.7.1: resolution: {integrity: sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==} engines: {node: '>= 0.10'} @@ -9287,10 +9335,10 @@ packages: htmlparser2: 8.0.2 is-plain-object: 5.0.0 parse-srcset: 1.0.2 - postcss: 8.4.45 + postcss: 8.4.47 dev: false - /sass-loader@12.6.0(sass@1.78.0)(webpack@5.94.0): + /sass-loader@12.6.0(sass@1.79.2)(webpack@5.94.0): resolution: {integrity: sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==} engines: {node: '>= 12.13.0'} peerDependencies: @@ -9311,16 +9359,16 @@ packages: dependencies: klona: 2.0.6 neo-async: 2.6.2 - sass: 1.78.0 + sass: 1.79.2 webpack: 5.94.0(webpack-cli@4.10.0) dev: true - /sass@1.78.0: - resolution: {integrity: sha512-AaIqGSrjo5lA2Yg7RvFZrlXDBCp3nV4XP73GrLGvdRWWwk+8H3l0SDvq/5bA4eF+0RFPLuWUk3E+P1U/YqnpsQ==} + /sass@1.79.2: + resolution: {integrity: sha512-YmT1aoF1MwHsZEu/eXhbAJNsPGAhNP4UixW9ckEwWCvPcVdVF0/C104OGDVEqtoctKq0N+wM20O/rj+sSPsWeg==} engines: {node: '>=14.0.0'} hasBin: true dependencies: - chokidar: 3.6.0 + chokidar: 4.0.0 immutable: 4.3.7 source-map-js: 1.2.1 dev: true @@ -9517,7 +9565,7 @@ packages: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true - /simple-zustand-devtools@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1)(zustand@4.4.7): + /simple-zustand-devtools@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1)(zustand@4.4.7): resolution: {integrity: sha512-Axfcfr9L3YL3kto7aschCQLY2VUlXXMnIVtaTe9Y0qWbNmPsX/y7KsNprmxBZoB0pww5ZGs1u/ohcrvQ3tE6jA==} peerDependencies: '@types/react': '>=18.0.0' @@ -9526,18 +9574,18 @@ packages: react-dom: '>=18.0.0' zustand: '>=1.0.2' dependencies: - '@types/react': 18.3.5 + '@types/react': 18.3.8 '@types/react-dom': 18.3.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - zustand: 4.4.7(@types/react@18.3.5)(react@18.3.1) + zustand: 4.4.7(@types/react@18.3.8)(react@18.3.1) dev: true /sirv@2.0.4: resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} engines: {node: '>= 10'} dependencies: - '@polka/url': 1.0.0-next.25 + '@polka/url': 1.0.0-next.28 mrmime: 2.0.0 totalist: 3.0.1 dev: true @@ -9897,12 +9945,12 @@ packages: jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 - terser: 5.32.0 + terser: 5.33.0 webpack: 5.94.0(webpack-cli@4.10.0) dev: true - /terser@5.32.0: - resolution: {integrity: sha512-v3Gtw3IzpBJ0ugkxEX8U0W6+TnPKRRCWGh1jC/iM/e3Ki5+qvO1L1EAZ56bZasc64aXHwRHNIQEzm6//i5cemQ==} + /terser@5.33.0: + resolution: {integrity: sha512-JuPVaB7s1gdFKPKTelwUyRq5Sid2A3Gko2S0PncwdBq7kN9Ti9HPWDQ06MPsEDGsZeVESjKEnyGy68quBk1w6g==} engines: {node: '>=10'} hasBin: true dependencies: @@ -10463,7 +10511,7 @@ packages: webpack-cli: optional: true dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 '@webassemblyjs/ast': 1.12.1 '@webassemblyjs/wasm-edit': 1.12.1 '@webassemblyjs/wasm-parser': 1.12.1 @@ -10695,8 +10743,8 @@ packages: yargs-parser: 20.2.9 dev: true - /yet-another-react-lightbox@3.21.5(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-ri73f6IMZD2UC7fdkmhNeDVh+1GZWeAnoSUHII/nyRovcRkUM+OwVAhwl1d5ZoNFGKjd+nHNMroAaoQONqRDZQ==} + /yet-another-react-lightbox@3.21.6(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-uKcRmmezsj1Fbj38B6hFOGwbAu94fPr8d5H6I0+1FmcToX56freEGXXXtdA1oRo6036ug+UgrKZzzvsw/MIM/w==} engines: {node: '>=14'} peerDependencies: react: '>=16.8.0' @@ -10715,7 +10763,7 @@ packages: resolution: {integrity: sha512-w2NTI8+3l3eeltKAdK8QpiLo/flRAr2p8AGeakfMZOXBxOg9HIu4LVDxBi81sYgVhFhdJjv1OrB5ssI8uFPoLg==} dev: false - /zustand@4.4.7(@types/react@18.3.5)(react@18.3.1): + /zustand@4.4.7(@types/react@18.3.8)(react@18.3.1): resolution: {integrity: sha512-QFJWJMdlETcI69paJwhSMJz7PPWjVP8Sjhclxmxmxv/RYI7ZOvR5BHX+ktH0we9gTWQMxcne8q1OY8xxz604gw==} engines: {node: '>=12.7.0'} peerDependencies: @@ -10730,20 +10778,20 @@ packages: react: optional: true dependencies: - '@types/react': 18.3.5 + '@types/react': 18.3.8 react: 18.3.1 use-sync-external-store: 1.2.0(react@18.3.1) - github.com/Canadian-Geospatial-Platform/geochart/62b1611c028dd27e8b275b070a18b199222becbb(@types/react@18.3.5): + github.com/Canadian-Geospatial-Platform/geochart/62b1611c028dd27e8b275b070a18b199222becbb(@types/react@18.3.8): resolution: {tarball: https://codeload.github.com/Canadian-Geospatial-Platform/geochart/tar.gz/62b1611c028dd27e8b275b070a18b199222becbb} id: github.com/Canadian-Geospatial-Platform/geochart/62b1611c028dd27e8b275b070a18b199222becbb name: geoview-geochart version: 0.1.0 dependencies: - '@emotion/react': 11.13.3(@types/react@18.3.5)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.5)(react@18.3.1) - '@mui/icons-material': 5.16.7(@mui/material@5.16.7)(@types/react@18.3.5)(react@18.3.1) - '@mui/material': 5.16.7(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.5)(react-dom@18.3.1)(react@18.3.1) + '@emotion/react': 11.13.3(@types/react@18.3.8)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3)(@types/react@18.3.8)(react@18.3.1) + '@mui/icons-material': 5.16.7(@mui/material@5.16.7)(@types/react@18.3.8)(react@18.3.1) + '@mui/material': 5.16.7(@emotion/react@11.13.3)(@emotion/styled@11.13.0)(@types/react@18.3.8)(react-dom@18.3.1)(react@18.3.1) ajv: 8.17.1 ajv-formats: 2.1.1 chart.js: 4.4.4 diff --git a/packages/geoview-core/package.json b/packages/geoview-core/package.json index 049bb790057..829c750bda3 100644 --- a/packages/geoview-core/package.json +++ b/packages/geoview-core/package.json @@ -54,8 +54,9 @@ "@mui/material": "^6.0.2", "@mui/styles": "^6.0.2", "@mui/system": "^6.0.2", + "@mui/x-tree-view": "^7.17.0", "@nieuwlandgeo/sldreader": "^0.3.1", - "@mui/x-date-pickers": "^7.15.0", + "@mui/x-date-pickers": "^7.6.1", "@react-spring/web": "^9.7.3", "ajv": "^8.16.0", "ajv-errors": "^3.0.0", diff --git a/packages/geoview-core/public/datasets/geojson/metadata-new.meta b/packages/geoview-core/public/datasets/geojson/metadata.meta similarity index 79% rename from packages/geoview-core/public/datasets/geojson/metadata-new.meta rename to packages/geoview-core/public/datasets/geojson/metadata.meta index 7b6a31e1b3a..6635099dadd 100644 --- a/packages/geoview-core/public/datasets/geojson/metadata-new.meta +++ b/packages/geoview-core/public/datasets/geojson/metadata.meta @@ -126,12 +126,27 @@ "color": "rgba(0,0,255,0.5)", "paternSize": 10, "paternWidth": 2, - "fillStyle": "diagonalCross", "stroke": { "color": "rgba(128,0,0,1)", "lineStyle": "dot" } } + }, + { + "label": "Default", + "visible": true, + "values": ["Default"], + "settings": { + "type": "filledPolygon", + "color": "rgba(0,0,255,0.5)", + "paternSize": 10, + "paternWidth": 2, + "fillStyle": "diagonalCross", + "stroke": { + "color": "rgba(0,0,128,1)", + "lineStyle": "dot" + } + } } ] } @@ -168,14 +183,18 @@ }, "style": { "type": "simple", - "label": "LineString label", - "settings": { - "type": "lineString", - "stroke": { - "lineStyle": "shortDash-dot-dot", - "color": "rgba(128,0,0,1)" + "fields": ["LineString label"], + "info": [ + { + "settings": { + "type": "lineString", + "stroke": { + "lineStyle": "shortDash-dot-dot", + "color": "rgba(128,0,0,1)" + } + } } - } + ] } }, { @@ -215,14 +234,18 @@ } }, "style": { - "styleType": "simple", - "label": "Icon point label", - "settings": { - "type": "iconSymbol", - "mimeType": "image/png", - "src": "iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IB2cksfwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAcNJREFUKJFjYSATsCBz/v//z/Tp8+fwO/cf273/+FmckZHxn6iQwBMVJbldXJyc27Bq/P//v8jVm3cmtUxf7rX+3nN+ZEVJ+srhd+8/3KikIFfMyMj4Fa7x////zBeu3JjuXDM55Ou//xjOmnfxrsS+8t7Uze1FLAwMDClwjU+fv0irmLzYH5smGHjw/TdTz7yVIe/ef9wiJMi/gYWBgYHhxp2HXgeev2dFVtjhb8Pw7dtPhqbdp+FiCy894E+4cz+IgYEBovHDp88qyJpmxngwxIf5wfnImt+9f68Ed+rff3/ZkTVycnDA2dxcHMhSDH/+/WeHa+Tm5HzJwMCgCJMsW7SZgYmZkeHHj18M5RsPo2jk4eJ+DdcoKSZyQoeX0+LK5+8MDAwMDC9+/WWImbkeI4D85MUZJMWED8A1qirKVjUlBvgETVqugqEa5mQmRoacKO9zWurKPXCNfHx8389evha5Njd8bfPCLXIXPn1F0eQgLshQGut7XUREOJCRkfEfXCMDAwODsa7WmQOnT+t150VMevn6ne33bz+kGBgZ/3FzcTyUEBXZxcb4p0RbTek3TD1KWnUwNf3IwMAQj8u5yAAAupehfivnXOEAAAAASUVORK5CYII=", - "opacity": 0.5 - } + "type": "simple", + "fields": ["Icon point label"], + "info": [ + { + "settings": { + "type": "iconSymbol", + "mimeType": "image/png", + "src": "iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IB2cksfwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAcNJREFUKJFjYSATsCBz/v//z/Tp8+fwO/cf273/+FmckZHxn6iQwBMVJbldXJyc27Bq/P//v8jVm3cmtUxf7rX+3nN+ZEVJ+srhd+8/3KikIFfMyMj4Fa7x////zBeu3JjuXDM55Ou//xjOmnfxrsS+8t7Uze1FLAwMDClwjU+fv0irmLzYH5smGHjw/TdTz7yVIe/ef9wiJMi/gYWBgYHhxp2HXgeev2dFVtjhb8Pw7dtPhqbdp+FiCy894E+4cz+IgYEBovHDp88qyJpmxngwxIf5wfnImt+9f68Ed+rff3/ZkTVycnDA2dxcHMhSDH/+/WeHa+Tm5HzJwMCgCJMsW7SZgYmZkeHHj18M5RsPo2jk4eJ+DdcoKSZyQoeX0+LK5+8MDAwMDC9+/WWImbkeI4D85MUZJMWED8A1qirKVjUlBvgETVqugqEa5mQmRoacKO9zWurKPXCNfHx8389evha5Njd8bfPCLXIXPn1F0eQgLshQGut7XUREOJCRkfEfXCMDAwODsa7WmQOnT+t150VMevn6ne33bz+kGBgZ/3FzcTyUEBXZxcb4p0RbTek3TD1KWnUwNf3IwMAQj8u5yAAAupehfivnXOEAAAAASUVORK5CYII=", + "opacity": 0.5 + } + } + ] } }, { @@ -274,12 +297,16 @@ } }, "style": { - "styleType": "simple", - "label": "Point label", - "settings": { - "type": "simpleSymbol", - "symbol": "star" - } + "type": "simple", + "fields": ["Point label"], + "info": [ + { + "settings": { + "type": "simpleSymbol", + "symbol": "star" + } + } + ] } }, { @@ -336,12 +363,16 @@ } }, "style": { - "styleType": "simple", - "label": "Point label", - "settings": { - "type": "simpleSymbol", - "symbol": "star" - } + "type": "simple", + "fields": ["Point label"], + "info": [ + { + "settings": { + "type": "simpleSymbol", + "symbol": "star" + } + } + ] } }, { @@ -393,12 +424,16 @@ } }, "style": { - "styleType": "simple", - "label": "Point label", - "settings": { - "type": "simpleSymbol", - "symbol": "star" - } + "type": "simple", + "fields": ["Point label"], + "info": [ + { + "settings": { + "type": "simpleSymbol", + "symbol": "star" + } + } + ] } }, { @@ -450,12 +485,16 @@ } }, "style": { - "styleType": "simple", - "label": "Point label", - "settings": { - "type": "simpleSymbol", - "symbol": "star" - } + "type": "simple", + "fields": ["Point label"], + "info": [ + { + "settings": { + "type": "simpleSymbol", + "symbol": "star" + } + } + ] } } ] diff --git a/packages/geoview-core/public/templates/layers/geojson.html b/packages/geoview-core/public/templates/layers/geojson.html index c77fcb2304e..952a0edbca0 100644 --- a/packages/geoview-core/public/templates/layers/geojson.html +++ b/packages/geoview-core/public/templates/layers/geojson.html @@ -64,7 +64,7 @@

1. Many GeoJSON Layers

'projection': 3978 }, 'basemapOptions': { - 'basemapId': 'imagery', + 'basemapId': 'transport', 'shaded': false, 'labeled': false }, @@ -77,13 +77,11 @@

1. Many GeoJSON Layers

'listOfLayerEntryConfig': [ { 'layerId': 'polygons.json', - 'layerName': { 'en': 'Polygons' }, - 'layerFilter': 'creationDate >= date \'2020/02/15\'' + 'layerName': { 'en': 'Polygons' } }, { 'layerId': 'lines.json', - 'layerName': { 'en': 'Lines' }, - 'layerFilter': 'creationDate >= date \'2020-05-28T12:00:00-05:00\'' + 'layerName': { 'en': 'Lines' } }, { 'entryType': 'group', @@ -93,13 +91,11 @@

1. Many GeoJSON Layers

{ 'layerId': 'icon_points.json', 'layerName': { 'en': 'Icons' }, - 'initialSettings': { 'states': {'visible' : false} }, - 'layerFilter': 'creationDate >= date \'2020-01-14T12:00:01-05:00\'' + 'initialSettings': { 'states': {'visible' : false} } }, { 'layerId': 'points.json', - 'layerName': { 'en': 'Points' }, - 'layerFilter': 'creationDate >= date \'2019-02-15T22:00:00Z\'' + 'layerName': { 'en': 'Points' } } ] } @@ -112,7 +108,7 @@

1. Many GeoJSON Layers

'corePackages': [], 'theme': 'geo.ca' }"> - +

   
   
@@ -223,7 +219,7 @@ 

1. Many GeoJSON Layers

window.addEventListener('load', () => { createCodeSnippet(); createConfigSnippet(); - }); + }); diff --git a/packages/geoview-core/public/templates/layers/layerlib.js b/packages/geoview-core/public/templates/layers/layerlib.js index 19edc18b8bf..888d210dafc 100644 --- a/packages/geoview-core/public/templates/layers/layerlib.js +++ b/packages/geoview-core/public/templates/layers/layerlib.js @@ -351,37 +351,35 @@ const createTableOfFilter = (mapId) => { mapButtonsDiv.appendChild(br); } } - if (geoviewLayer.getLayerFilter(layerPath)) { - const layerFilterText = document.createElement('p'); - layerFilterText.innerText = `Extra filter: `; - mapButtonsDiv.appendChild(layerFilterText); - const layerFilterInput = document.createElement('input'); - layerFilterInput.id = `filter-input-${mapId}-${geoviewLayer.getGeoviewLayerId()}`; - layerFilterInput.style.width = '50%'; - layerFilterText.appendChild(layerFilterInput); - layerFilterInput.value = geoviewLayer.getLayerFilter(layerPath) || ''; - const layerFilterButton = document.createElement('button'); - layerFilterButton.addEventListener('click', (e) => { - const checkbox = document.getElementById(`checkbox-${mapId}-${geoviewLayer.getGeoviewLayerId()}`); - geoviewLayer.applyViewFilter(layerPath, layerFilterInput.value, checkbox.value !== 'true'); - }); - layerFilterButton.innerText = 'Apply'; - layerFilterText.style.width = 'max-content'; - layerFilterText.appendChild(layerFilterButton); + const layerFilterText = document.createElement('p'); + layerFilterText.innerText = `Extra filter: `; + mapButtonsDiv.appendChild(layerFilterText); + const layerFilterInput = document.createElement('input'); + layerFilterInput.id = `filter-input-${mapId}-${geoviewLayer.getGeoviewLayerId()}`; + layerFilterInput.style.width = '50%'; + layerFilterText.appendChild(layerFilterInput); + layerFilterInput.value = geoviewLayer.getLayerFilter(layerPath) || ''; + const layerFilterButton = document.createElement('button'); + layerFilterButton.addEventListener('click', (e) => { + const checkbox = document.getElementById(`checkbox-${mapId}-${geoviewLayer.getGeoviewLayerId()}`); + geoviewLayer.applyViewFilter(layerPath, layerFilterInput.value, checkbox.value !== 'true'); + }); + layerFilterButton.innerText = 'Apply'; + layerFilterText.style.width = 'max-content'; + layerFilterText.appendChild(layerFilterButton); - const checkboxInput = document.createElement('input'); - checkboxInput.type = 'checkbox'; - checkboxInput.value = 'false'; - checkboxInput.id = `checkbox-${mapId}-${geoviewLayer.getGeoviewLayerId()}`; - checkboxInput.addEventListener('click', (e) => { - checkboxInput.value = checkboxInput.value === 'true' ? 'false' : 'true'; - geoviewLayer.applyViewFilter(layerPath, layerFilterInput.value, checkboxInput.value !== 'true'); - }); - mapButtonsDiv.appendChild(checkboxInput); - const checkboxText = document.createElement('label'); - checkboxText.innerText = `apply only the extra filter`; - mapButtonsDiv.appendChild(checkboxText); - } + const checkboxInput = document.createElement('input'); + checkboxInput.type = 'checkbox'; + checkboxInput.value = 'false'; + checkboxInput.id = `checkbox-${mapId}-${geoviewLayer.getGeoviewLayerId()}`; + checkboxInput.addEventListener('click', (e) => { + checkboxInput.value = checkboxInput.value === 'true' ? 'false' : 'true'; + geoviewLayer.applyViewFilter(layerPath, layerFilterInput.value, checkboxInput.value !== 'true'); + }); + mapButtonsDiv.appendChild(checkboxInput); + const checkboxText = document.createElement('label'); + checkboxText.innerText = `apply only the extra filter`; + mapButtonsDiv.appendChild(checkboxText); }); } }); diff --git a/packages/geoview-core/src/api/config/types/classes/geoview-config/abstract-geoview-esri-layer-config.ts b/packages/geoview-core/src/api/config/types/classes/geoview-config/abstract-geoview-esri-layer-config.ts index f7bc681bc2b..9d114b2d986 100644 --- a/packages/geoview-core/src/api/config/types/classes/geoview-config/abstract-geoview-esri-layer-config.ts +++ b/packages/geoview-core/src/api/config/types/classes/geoview-config/abstract-geoview-esri-layer-config.ts @@ -235,15 +235,15 @@ export abstract class AbstractGeoviewEsriLayerConfig extends AbstractGeoviewLaye }; // #endregion PRIVATE - // ================= - // #region PROTECTED + // ============== + // #region STATIC /** * Converts an esri geometry type string to a TypeStyleGeometry. * @param {string} esriGeometryType - The esri geometry type to convert * @returns {TypeStyleGeometry} The corresponding TypeStyleGeometry - * @protected @static + * @static */ - protected static convertEsriGeometryTypeToOLGeometryType(esriGeometryType: string): TypeStyleGeometry { + static convertEsriGeometryTypeToOLGeometryType(esriGeometryType: string): TypeStyleGeometry { switch (esriGeometryType) { case 'esriGeometryPoint': case 'esriGeometryMultipoint': @@ -260,7 +260,7 @@ export abstract class AbstractGeoviewEsriLayerConfig extends AbstractGeoviewLaye throw new Error(`Unsupported geometry type: ${esriGeometryType}`); } } - // #endregion PROTECTED + // #endregion STATIC // #endregion METHODS // #endregion CLASS HEADER } diff --git a/packages/geoview-core/src/api/config/types/classes/geoview-config/abstract-geoview-layer-config.ts b/packages/geoview-core/src/api/config/types/classes/geoview-config/abstract-geoview-layer-config.ts index 614cccfdd3c..33295f438ab 100644 --- a/packages/geoview-core/src/api/config/types/classes/geoview-config/abstract-geoview-layer-config.ts +++ b/packages/geoview-core/src/api/config/types/classes/geoview-config/abstract-geoview-layer-config.ts @@ -279,7 +279,9 @@ export abstract class AbstractGeoviewLayerConfig { if (layerTreeFilter !== undefined) { // When the filter is an empty array, we create the layer tree for all the metadata in the service metadata. if (layerTreeFilter.length === 0) { - this.setMetadataLayerTree(this.processListOfLayerEntryConfig(this.createLayerTreeFromServiceMetadata())); + const layerTree = this.processListOfLayerEntryConfig(this.createLayerTreeFromServiceMetadata()); + await this.fetchListOfLayerMetadata(layerTree); + this.setMetadataLayerTree(layerTree); } else { // When the filter contains one or many layer identifiers, we create the layer tree using only the specified layers. // If the filter contains several layer identifiers, we create a group layer, as the root of the tree must contain @@ -312,7 +314,7 @@ export abstract class AbstractGeoviewLayerConfig { /** * A recursive method to process the listOfLayerEntryConfig. The goal is to process each valid sublayer, searching the service's * metadata to verify the layer's existence and whether it is a layer group, in order to determine the node's final structure. - * If it is a layer group, it will be created. + * If the metadata indicate the node is a layer group, it will be created by the createLayerEntryNode. * * @param {EntryConfigBaseClass[]} listOfLayerEntryConfig the list of sublayers to process. * diff --git a/packages/geoview-core/src/api/config/types/classes/geoview-config/raster-config/wms-config.ts b/packages/geoview-core/src/api/config/types/classes/geoview-config/raster-config/wms-config.ts index 6934cbb3aaf..85214d2e32c 100644 --- a/packages/geoview-core/src/api/config/types/classes/geoview-config/raster-config/wms-config.ts +++ b/packages/geoview-core/src/api/config/types/classes/geoview-config/raster-config/wms-config.ts @@ -276,7 +276,8 @@ export class WmsLayerConfig extends AbstractGeoviewLayerConfig { const response = await fetch(metadataUrl); const capabilitiesString = await response.text(); this.setServiceMetadata(parser.read(capabilitiesString)); - if (this.getServiceMetadata()) { + // GV: If this.getServiceMetadata() returns {}, we need to verify if the object is empty to conclude there is no metadata. + if (Object.keys(this.getServiceMetadata()).length) { this.#processMetadataInheritance(); this.metadataAccessPath = this.getServiceMetadata().Capability.Request.GetMap.DCPType[0].HTTP.Get.OnlineResource as string; } else throw new GeoviewLayerConfigError('Unable to read the metadata, value returned is empty.'); diff --git a/packages/geoview-core/src/api/config/types/classes/geoview-config/vector-config/geojson-config.ts b/packages/geoview-core/src/api/config/types/classes/geoview-config/vector-config/geojson-config.ts index 10ca706a0cc..e050e29cdb8 100644 --- a/packages/geoview-core/src/api/config/types/classes/geoview-config/vector-config/geojson-config.ts +++ b/packages/geoview-core/src/api/config/types/classes/geoview-config/vector-config/geojson-config.ts @@ -48,7 +48,7 @@ export class GeoJsonLayerConfig extends AbstractGeoviewLayerConfig { const pathItemLength = metadataAccessPathItems.length; const lastPathItem = metadataAccessPathItems[pathItemLength - 1]; if (lastPathItem.toLowerCase().endsWith('.json') || lastPathItem.toLowerCase().endsWith('.geojson')) { - // The metadataAccessPath ends with a layer index. It is therefore a path to a data layer rather than a path to service metadata. + // The metadataAccessPath ends with a layer reference. It is therefore a path to a data layer rather than a path to service metadata. // We therefore need to correct the configuration by separating the layer index and the path to the service metadata. this.metadataAccessPath = metadataAccessPathItems.slice(0, -1).join('/'); if (this.listOfLayerEntryConfig.length) { @@ -134,17 +134,12 @@ export class GeoJsonLayerConfig extends AbstractGeoviewLayerConfig { const fetchResponse = await fetch(this.metadataAccessPath); if (fetchResponse.status === 404) throw new GeoviewLayerConfigError('The service metadata fetch returned a 404 status (Not Found)'); const layerMetadata = (await fetchResponse.json()) as TypeJsonObject; - const metadataAccessPathElements = this.metadataAccessPath.split('/'); - this.metadataAccessPath = metadataAccessPathElements.slice(0, metadataAccessPathElements.length - 1).join('/'); if (layerMetadata) this.setServiceMetadata(layerMetadata); else throw new GeoviewLayerConfigError('The metadata object returned is undefined'); - } else { - await this.createLayerTree(); - return; - } - this.listOfLayerEntryConfig = this.processListOfLayerEntryConfig(this.listOfLayerEntryConfig); - await this.fetchListOfLayerMetadata(); + this.listOfLayerEntryConfig = this.processListOfLayerEntryConfig(this.listOfLayerEntryConfig); + await this.fetchListOfLayerMetadata(); + } await this.createLayerTree(); } catch (error) { @@ -166,13 +161,15 @@ export class GeoJsonLayerConfig extends AbstractGeoviewLayerConfig { * @protected @override */ protected override createLayerEntryNode(layerId: string, parentNode: EntryConfigBaseClass | undefined): EntryConfigBaseClass { - if (this.getServiceMetadata()) + // GV: To determine if service metadata exists, we must verify that the object is not empty. + if (Object.keys(this.getServiceMetadata()).length === 0) return this.createLeafNode( toJsonObject({ layerId, layerName: createLocalizedString(layerId) }), this.getLanguage(), this, parentNode )!; + // If we cannot find the layerId in the layer definitions, throw an error. const layerFound = this.findLayerMetadataEntry(layerId); if (!layerFound) { diff --git a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/entry-config-base-class.ts b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/entry-config-base-class.ts index 792ab7e373d..96c777b6a34 100644 --- a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/entry-config-base-class.ts +++ b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/entry-config-base-class.ts @@ -148,6 +148,12 @@ export abstract class EntryConfigBaseClass { */ abstract fetchLayerMetadata(): Promise; + /** + * This method is used to parse the layer metadata and extract the style, source information and other properties. + * @abstract @protected + */ + protected abstract parseLayerMetadata(): void; + // #endregion ABSTRACT // ================= @@ -157,7 +163,32 @@ export abstract class EntryConfigBaseClass { * @protected */ protected validateLayerConfig(layerConfig: TypeJsonObject): void { + // TODO: Code to be deleted when the configuration api is used permanently. We do that to avoid validation errors. + // GV: Delete this + // GV: ||| + // GV: vvv + const entryType = layerConfig?.entryType; + // eslint-disable-next-line no-param-reassign + delete layerConfig.entryType; + // eslint-disable-next-line no-param-reassign + if (entryType === 'group') (layerConfig.isLayerGroup as boolean) = true; + // GV: ^^^ + // GV: ||| + + // GV: Do not delete the following line. + if (!isvalidComparedToInputSchema(this.getSchemaPath(), layerConfig)) this.setErrorDetectedFlag(); + + // TODO: Code to be deleted when the configuration api is used permanently. + // GV: Delete this + // GV: ||| + // GV: vvv + // eslint-disable-next-line no-param-reassign + if (entryType) layerConfig.entryType = entryType; + // eslint-disable-next-line no-param-reassign + if (entryType === 'group') delete layerConfig.isLayerGroup; + // GV: ^^^ + // GV: ||| } // #endregion PROTECTED @@ -326,6 +357,7 @@ export abstract class EntryConfigBaseClass { cloneOfTheNode.layerName = this.layerName; cloneOfTheNode.setErrorDetectedFlag(this.#errorDetectedFlag); cloneOfTheNode.setLayerMetadata(this.#layerMetadata); + cloneOfTheNode.parseLayerMetadata(); return cloneOfTheNode; } diff --git a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/group-node/esri-group-layer-config.ts b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/group-node/esri-group-layer-config.ts index 3a946c2f964..640d4dbd949 100644 --- a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/group-node/esri-group-layer-config.ts +++ b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/group-node/esri-group-layer-config.ts @@ -59,7 +59,7 @@ export class EsriGroupLayerConfig extends GroupLayerEntryConfig { // The metadata used are the layer metadata. this.setLayerMetadata(data); // Parse the raw layer metadata and build the geoview configuration. - this.#parseLayerMetadata(); + this.parseLayerMetadata(); return; } } catch (error) { @@ -76,28 +76,25 @@ export class EsriGroupLayerConfig extends GroupLayerEntryConfig { ); } } - // #endregion OVERRIDE - // =============== - // #region PRIVATE /** * This method is used to analyze metadata and extract the relevant information from a group layer based on a definition * provided by the ESRI service. - * @private + * @override @protected */ - #parseLayerMetadata(): void { + protected override parseLayerMetadata(): void { const layerMetadata = this.getLayerMetadata(); this.minScale = layerMetadata.minScale as number; this.maxScale = layerMetadata.maxScale as number; const metadataExtent = [ - layerMetadata.extent.xmin, - layerMetadata.extent.ymin, - layerMetadata.extent.xmax, - layerMetadata.extent.ymax, + layerMetadata.initialExtent.xmin, + layerMetadata.initialExtent.ymin, + layerMetadata.initialExtent.xmax, + layerMetadata.initialExtent.ymax, ] as Extent; - const sourceProj = layerMetadata.extent.spatialReference.wkid; + const sourceProj = layerMetadata.initialExtent.spatialReference.wkid; if (sourceProj === '4326') this.initialSettings.extent = validateExtentWhenDefined(metadataExtent); else this.initialSettings.extent = validateExtentWhenDefined( @@ -111,6 +108,10 @@ export class EsriGroupLayerConfig extends GroupLayerEntryConfig { if (layerMetadata.copyrightText) this.attributions.push(layerMetadata.copyrightText as string); } + // #endregion OVERRIDE + + // =============== + // #region PRIVATE /** * This method is used to analyze metadata and extract the relevant information from a group layer based on a definition * provided by the user's configuration. In this case, we use the service metadata. diff --git a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/group-node/geojson-group-layer-config.ts b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/group-node/geojson-group-layer-config.ts index ea4206d552e..3f00af7bea0 100644 --- a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/group-node/geojson-group-layer-config.ts +++ b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/group-node/geojson-group-layer-config.ts @@ -47,7 +47,7 @@ export class GeoJsonGroupLayerConfig extends GroupLayerEntryConfig { this.setLayerMetadata(layerMetadata); // Parse the raw layer metadata and build the geoview configuration. - this.#parseLayerMetadata(); + this.parseLayerMetadata(); } // Fetch the sub-layers metadata that compose the group. @@ -60,15 +60,11 @@ export class GeoJsonGroupLayerConfig extends GroupLayerEntryConfig { } } - // #endregion OVERRIDE - - // =============== - // #region PRIVATE /** * This method is used to parse the layer metadata and extract the source information and other properties. - * @private + * @override @protected */ - #parseLayerMetadata(): void { + protected override parseLayerMetadata(): void { const layerMetadata = this.getLayerMetadata(); if (layerMetadata?.attributions) this.attributions.push(layerMetadata.attributions as string); @@ -95,7 +91,7 @@ export class GeoJsonGroupLayerConfig extends GroupLayerEntryConfig { } } - // #endregion PRIVATE + // #endregion OVERRIDE // #endregion METHODS // #endregion CLASS HEADER } diff --git a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/group-node/wfs-group-layer-config.ts b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/group-node/wfs-group-layer-config.ts index 52bebf05837..b3ce3885237 100644 --- a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/group-node/wfs-group-layer-config.ts +++ b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/group-node/wfs-group-layer-config.ts @@ -35,6 +35,14 @@ export class WfsGroupLayerConfig extends GroupLayerEntryConfig { } } + /** *************************************************************************************************************************** + * This method is used to parse the layer metadata and extract the style, source information and other properties. + * However, since WFS doesn't have groups in its metadata, this routine does nothing for the group nodes. + * + * @protected @override + */ + protected override parseLayerMetadata(): void {} + // #endregion OVERRIDE // #endregion METHODS // #endregion CLASS HEADER diff --git a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/group-node/wms-group-layer-config.ts b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/group-node/wms-group-layer-config.ts index 0121fe3e5b7..5c073e7c0a2 100644 --- a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/group-node/wms-group-layer-config.ts +++ b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/group-node/wms-group-layer-config.ts @@ -51,7 +51,7 @@ export class WmsGroupLayerConfig extends GroupLayerEntryConfig { } // Parse the raw layer metadata and build the geoview configuration. - this.#parseLayerMetadata(); + this.parseLayerMetadata(); await this.fetchListOfLayerMetadata(); @@ -62,16 +62,12 @@ export class WmsGroupLayerConfig extends GroupLayerEntryConfig { } } - // #endregion OVERRIDE - - // =============== - // #region PRIVATE /** *************************************************************************************************************************** * This method is used to analyze metadata and extract the relevant information from a group layer based on a definition * provided by the WMS service. - * @private + * @override @protected */ - #parseLayerMetadata(): void { + protected override parseLayerMetadata(): void { const layerMetadata = this.getLayerMetadata(); this.layerName = layerMetadata.Title as string; @@ -86,7 +82,8 @@ export class WmsGroupLayerConfig extends GroupLayerEntryConfig { this.initialSettings.extent = validateExtentWhenDefined(layerMetadata.EX_GeographicBoundingBox as Extent); this.initialSettings.bounds = this.initialSettings.extent; } - // #endregion PRIVATE + + // #endregion OVERRIDE // #endregion METHODS // #endregion CLASS HEADER } diff --git a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/leaf/abstract-base-esri-layer-entry-config.ts b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/leaf/abstract-base-esri-layer-entry-config.ts index 8f0bff4454b..90e5113727d 100644 --- a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/leaf/abstract-base-esri-layer-entry-config.ts +++ b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/leaf/abstract-base-esri-layer-entry-config.ts @@ -2,14 +2,16 @@ import axios from 'axios'; import { Cast, TypeJsonArray, TypeJsonObject } from '@config/types/config-types'; import { codedValueType, Extent, rangeDomainType, TypeFeatureInfoLayerConfig, TypeOutfields } from '@config/types/map-schema-types'; -import { AbstractBaseLayerEntryConfig } from '@/api/config/types/classes/sub-layer-config/leaf/abstract-base-layer-entry-config'; +import { AbstractBaseLayerEntryConfig } from '@config/types/classes/sub-layer-config/leaf/abstract-base-layer-entry-config'; + +import { GeoviewLayerConfigError } from '@config/types/classes/config-exceptions'; +import { AbstractGeoviewEsriLayerConfig } from '@config/types/classes/geoview-config/abstract-geoview-esri-layer-config'; -import { logger } from '@/core/utils/logger'; -import { DateMgt, TimeDimensionESRI } from '@/core/utils/date-mgt'; import { Projection } from '@/geo/utils/projection'; import { validateExtentWhenDefined } from '@/geo/utils/utilities'; import { isvalidComparedToInternalSchema } from '@/api/config/utils'; -import { GeoviewLayerConfigError } from '../../config-exceptions'; +import { logger } from '@/core/utils/logger'; +import { DateMgt, TimeDimensionESRI } from '@/core/utils/date-mgt'; // ======================== // #region CLASS HEADER @@ -60,33 +62,17 @@ export abstract class AbstractBaseEsriLayerEntryConfig extends AbstractBaseLayer } this.setErrorDetectedFlag(); } - // #endregion OVERRIDE - - // ========================== - // #region PROTECTED - /** - * This method will create a Geoview temporal dimension if it exist in the service metadata. - * - * @param {TypeJsonObject} timeDimension The ESRI time dimension object. - * @protected - */ - // TODO: Issue #2139 - There is a bug with the temporal dimension returned by service URL: - // TODO.CONT: https://maps-cartes.services.geo.ca/server_serveur/rest/services/NRCan/Temporal_Test_Bed_fr/MapServer/0 - protected processTemporalDimension(timeDimension: TypeJsonObject): void { - if (timeDimension?.timeExtent) { - // The singleHandle property is True for ESRI Image and false for ESRI Feature and Dynamic. - const singleHandle = false; - this.temporalDimension = DateMgt.createDimensionFromESRI(Cast(timeDimension), singleHandle); - } - } /** * This method is used to parse the layer metadata and extract the style, source information and other properties. - * @protected + * @override @protected */ - protected parseLayerMetadata(): void { + protected override parseLayerMetadata(): void { const layerMetadata = this.getLayerMetadata(); + if (layerMetadata.geometryType) + this.geometryType = AbstractGeoviewEsriLayerConfig.convertEsriGeometryTypeToOLGeometryType(layerMetadata.geometryType as string); + this.minScale = layerMetadata.minScale as number; this.maxScale = layerMetadata.maxScale as number; @@ -118,6 +104,26 @@ export abstract class AbstractBaseEsriLayerEntryConfig extends AbstractBaseLayer if (layerMetadata.copyrightText) this.attributions.push(layerMetadata.copyrightText as string); } + // #endregion OVERRIDE + + // ========================== + // #region PROTECTED + /** + * This method will create a Geoview temporal dimension if it exist in the service metadata. + * + * @param {TypeJsonObject} timeDimension The ESRI time dimension object. + * @protected + */ + // TODO: Issue #2139 - There is a bug with the temporal dimension returned by service URL: + // TODO.CONT: https://maps-cartes.services.geo.ca/server_serveur/rest/services/NRCan/Temporal_Test_Bed_fr/MapServer/0 + protected processTemporalDimension(timeDimension: TypeJsonObject): void { + if (timeDimension?.timeExtent) { + // The singleHandle property is True for ESRI Image and false for ESRI Feature and Dynamic. + const singleHandle = false; + this.temporalDimension = DateMgt.createDimensionFromESRI(Cast(timeDimension), singleHandle); + } + } + /** * This method creates the feature information from the layer metadata. * diff --git a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/leaf/raster/wms-layer-entry-config.ts b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/leaf/raster/wms-layer-entry-config.ts index 44baa144d5f..8ce767101bb 100644 --- a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/leaf/raster/wms-layer-entry-config.ts +++ b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/leaf/raster/wms-layer-entry-config.ts @@ -78,7 +78,7 @@ export class WmsLayerEntryConfig extends AbstractBaseLayerEntryConfig { if (layerMetadata) { this.setLayerMetadata(layerMetadata); // Parse the raw layer metadata and build the geoview configuration. - this.#parseLayerMetadata(); + this.parseLayerMetadata(); if (!isvalidComparedToInternalSchema(this.getSchemaPath(), this, true)) { throw new GeoviewLayerConfigError( @@ -112,15 +112,12 @@ export class WmsLayerEntryConfig extends AbstractBaseLayerEntryConfig { }, }; } - // #endregion OVERRIDE - // =============== - // #region PRIVATE /** * This method is used to parse the layer metadata and extract the source information and other properties. - * @private + * @override @protected */ - #parseLayerMetadata(): void { + protected override parseLayerMetadata(): void { const layerMetadata = this.getLayerMetadata(); if (layerMetadata?.Attribution?.Title) this.attributions.push(layerMetadata.Attribution.Title as string); @@ -138,6 +135,10 @@ export class WmsLayerEntryConfig extends AbstractBaseLayerEntryConfig { this.#processTemporalDimension(layerMetadata.Dimension); } + // #endregion OVERRIDE + + // =============== + // #region PRIVATE /** *************************************************************************************************************************** * This method will create a Geoview temporal dimension if it existds in the service metadata * @param {TypeJsonObject} wmsDimension The WMS time dimension object diff --git a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/leaf/vector/geojson-layer-entry-config.ts b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/leaf/vector/geojson-layer-entry-config.ts index a145831a263..1b27088491c 100644 --- a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/leaf/vector/geojson-layer-entry-config.ts +++ b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/leaf/vector/geojson-layer-entry-config.ts @@ -84,6 +84,8 @@ export class GeoJsonLayerEntryConfig extends AbstractBaseLayerEntryConfig { // If an error has already been detected, then the layer is unusable. if (this.getErrorDetectedFlag()) return Promise.resolve(); + // If the GeoJson GeoView layer doesn't have service metadata, the layer metadata are set using an empty object and they + // will be fetch on the fly by the layer api. if (Object.keys(this.getGeoviewLayerConfig().getServiceMetadata()).length === 0) { this.setLayerMetadata({}); return Promise.resolve(); @@ -94,7 +96,7 @@ export class GeoJsonLayerEntryConfig extends AbstractBaseLayerEntryConfig { this.setLayerMetadata(layerMetadata); // Parse the raw layer metadata and build the geoview configuration. - this.#parseLayerMetadata(); + this.parseLayerMetadata(); if (!isvalidComparedToInternalSchema(this.getSchemaPath(), this, true)) { throw new GeoviewLayerConfigError( @@ -129,16 +131,15 @@ export class GeoJsonLayerEntryConfig extends AbstractBaseLayerEntryConfig { }, }; } - // #endregion OVERRIDE - // =============== - // #region PRIVATE /** * This method is used to parse the layer metadata and extract the source information and other properties. - * @private + * @override @protected */ - #parseLayerMetadata(): void { + protected override parseLayerMetadata(): void { const layerMetadata = this.getLayerMetadata(); + // return if the layer has no metadata. + if (Object.keys(layerMetadata).length === 0) return; if (layerMetadata?.attributions) this.attributions.push(layerMetadata.attributions as string); this.geometryType = (layerMetadata.geometryType || this.geometryType) as TypeStyleGeometry; @@ -168,7 +169,7 @@ export class GeoJsonLayerEntryConfig extends AbstractBaseLayerEntryConfig { } } - // #endregion PRIVATE + // #endregion OVERRIDE // #endregion METHODS // #endregion CLASS HEADER } diff --git a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/leaf/vector/wfs-layer-entry-config.ts b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/leaf/vector/wfs-layer-entry-config.ts index a6838385c53..ea8949de830 100644 --- a/packages/geoview-core/src/api/config/types/classes/sub-layer-config/leaf/vector/wfs-layer-entry-config.ts +++ b/packages/geoview-core/src/api/config/types/classes/sub-layer-config/leaf/vector/wfs-layer-entry-config.ts @@ -93,7 +93,7 @@ export class WfsLayerEntryConfig extends AbstractBaseLayerEntryConfig { }); // Parse the raw layer metadata and build the geoview configuration. - this.#parseLayerMetadata(); + this.parseLayerMetadata(); this.source.featureInfo = this.#createFeatureInfoUsingMetadata(); @@ -129,6 +129,37 @@ export class WfsLayerEntryConfig extends AbstractBaseLayerEntryConfig { }, }; } + + /** + * This method is used to parse the layer metadata and extract the source information and other properties. + * @override @protected + */ + protected override parseLayerMetadata(): void { + const layerMetadata = this.getLayerMetadata().fromGetCapabilities; + + if (findPropertyNameByRegex(layerMetadata, /(?:WGS84BoundingBox)/)) { + const lowerCorner = ( + findPropertyNameByRegex(layerMetadata, [/(?:WGS84BoundingBox)/, /(?:LowerCorner)/, /(?:#text)/]) as string + ).split(' '); + const upperCorner = ( + findPropertyNameByRegex(layerMetadata, [/(?:WGS84BoundingBox)/, /(?:UpperCorner)/, /(?:#text)/]) as string + ).split(' '); + const bounds = [Number(lowerCorner[0]), Number(lowerCorner[1]), Number(upperCorner[0]), Number(upperCorner[1])] as Extent; + + this.initialSettings!.extent = validateExtentWhenDefined(bounds); + if (this.initialSettings?.extent?.find?.((value, i) => value !== bounds[i])) + logger.logWarning( + `The extent specified in the metadata for the layer path “${this.getLayerPath()}” is considered invalid and has been corrected.` + ); + + this.bounds = this.initialSettings!.extent; + } + + this.source.featureInfo!.queryable = this.#layerIsQueryable(); + + // this.#processTemporalDimension(layerMetadata.Dimension); + } + // #endregion OVERRIDE // =============== @@ -209,36 +240,6 @@ export class WfsLayerEntryConfig extends AbstractBaseLayerEntryConfig { return []; } - /** - * This method is used to parse the layer metadata and extract the source information and other properties. - * @private - */ - #parseLayerMetadata(): void { - const layerMetadata = this.getLayerMetadata().fromGetCapabilities; - - if (findPropertyNameByRegex(layerMetadata, /(?:WGS84BoundingBox)/)) { - const lowerCorner = ( - findPropertyNameByRegex(layerMetadata, [/(?:WGS84BoundingBox)/, /(?:LowerCorner)/, /(?:#text)/]) as string - ).split(' '); - const upperCorner = ( - findPropertyNameByRegex(layerMetadata, [/(?:WGS84BoundingBox)/, /(?:UpperCorner)/, /(?:#text)/]) as string - ).split(' '); - const bounds = [Number(lowerCorner[0]), Number(lowerCorner[1]), Number(upperCorner[0]), Number(upperCorner[1])] as Extent; - - this.initialSettings!.extent = validateExtentWhenDefined(bounds); - if (this.initialSettings?.extent?.find?.((value, i) => value !== bounds[i])) - logger.logWarning( - `The extent specified in the metadata for the layer path “${this.getLayerPath()}” is considered invalid and has been corrected.` - ); - - this.bounds = this.initialSettings!.extent; - } - - this.source.featureInfo!.queryable = this.#layerIsQueryable(); - - // this.#processTemporalDimension(layerMetadata.Dimension); - } - /** * This method creates the feature information from the layer metadata. * diff --git a/packages/geoview-core/src/core/components/layers/left-panel/add-new-layer/add-layer-tree.tsx b/packages/geoview-core/src/core/components/layers/left-panel/add-new-layer/add-layer-tree.tsx new file mode 100644 index 00000000000..c67c30fdb05 --- /dev/null +++ b/packages/geoview-core/src/core/components/layers/left-panel/add-new-layer/add-layer-tree.tsx @@ -0,0 +1,139 @@ +/** + * This component improves Mui's TreeView component to be able to process Layers data. + */ +import React, { useEffect, useState } from 'react'; +import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; +import { TreeItem } from '@mui/x-tree-view/TreeItem'; +import _ from 'lodash'; +import { logger } from '@/core/utils/logger'; +import { EntryConfigBaseClass, GroupLayerEntryConfig } from '@/api/config/types/map-schema-types'; +import { getLayerById } from './add-new-layers-utils'; + +export interface AddLayerTreeProps { + layersData: GroupLayerEntryConfig[]; + onSelectedItemsChange(items: string[]): void; + startingSelectedItems: string[]; +} + +export function AddLayerTree(props: AddLayerTreeProps): JSX.Element | null { + // Log + logger.logTraceRender('components/layers/left-panel/add-layer-tree/add-layer-tree'); + + const { layersData, startingSelectedItems, onSelectedItemsChange } = props; + const [defaultExpandedItems, setDefaultExpandedItems] = useState([]); // e.g. ["layer1", "layer2"] + const [defaultSelectedItems, setDefaultSelectedItems] = useState([]); + const [isInitialized, setIsInitialized] = useState(false); + const [selectedItems, setSelectedItems] = useState([]); // e.g. ["group1/layer1", "group2/layer2"] + + // this use effect acts like onComponentDidMount + useEffect(() => { + if (isInitialized) return; + // Log + logger.logTraceUseEffect('Add Layer Tree - startingSelectedItems', startingSelectedItems); + + setSelectedItems(startingSelectedItems); + setDefaultSelectedItems(startingSelectedItems); + + const result = startingSelectedItems + .map((item: string) => { + return item.split('/'); + }) + .flat() + .concat(selectedItems); + setDefaultExpandedItems(result); + setIsInitialized(true); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [startingSelectedItems]); + + useEffect(() => { + // Log + logger.logTraceUseEffect('Add Layer Tree - selectedItems ', selectedItems); + onSelectedItemsChange(selectedItems); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [selectedItems]); + + /** + * Recursive function to render tree item. It renders the layer and its children. + * @param layer - the layer to render + * @param parentId - the parent id of the layer + */ + const renderTreeItem = (layer: GroupLayerEntryConfig, parentId: string | null): JSX.Element => { + const curLayerId = `${parentId ? `${parentId}/` : ''}${layer.layerId}`; + return ( + + {layer?.listOfLayerEntryConfig?.length > 0 && + layer.listOfLayerEntryConfig.map((subLayer: EntryConfigBaseClass) => + renderTreeItem(subLayer as GroupLayerEntryConfig, curLayerId) + )} + + ); + }; + + /** + * Get all children of a layer + * @param treeLayerId - the id of the layer + * @returns - the list of children of the layer + */ + const getLayerChildren = (treeLayerId: string): string[] => { + const result: string[] = []; + + function populateLayerChildren(origLayerId: string, parentViewId: string | null): void { + const viewLayerId = `${parentViewId ? `${parentViewId}/` : ''}${origLayerId}`; + result.push(viewLayerId); + const layerDetails = getLayerById(layersData, origLayerId); + + const childLayerIds = layerDetails?.listOfLayerEntryConfig?.map((child: EntryConfigBaseClass) => { + return child.layerId; + }); + + childLayerIds?.forEach((childLayerId) => { + populateLayerChildren(childLayerId, viewLayerId); + }); + } + + const layerTokens = treeLayerId.split('/'); + const origLayerId = layerTokens.pop() as string; + let parentLayerId = null; + if (layerTokens.length > 0) { + parentLayerId = layerTokens.join('/'); + } + populateLayerChildren(origLayerId, parentLayerId); + + return _.uniq(result).sort(); + }; + + const handleItemSelectionToggle = (event: React.SyntheticEvent, itemId: string, isSelected: boolean): void => { + const layerChildren = getLayerChildren(itemId); + const toAddOrRemove = [itemId, ...layerChildren]; + + if (isSelected) { + setSelectedItems(_.uniq([...selectedItems, ...toAddOrRemove]).sort()); + } else { + setSelectedItems(selectedItems.filter((item) => !toAddOrRemove.includes(item))); + } + }; + + if (!isInitialized) { + return null; + } + + const renderTreeItems = (): JSX.Element[] => { + return layersData.map((layer) => renderTreeItem(layer as GroupLayerEntryConfig, null)); + }; + + return ( + + handleItemSelectionToggle(event, itemId, isSelected) + } + > + {renderTreeItems()} + + ); +} diff --git a/packages/geoview-core/src/core/components/layers/left-panel/add-new-layer/add-new-layer.tsx b/packages/geoview-core/src/core/components/layers/left-panel/add-new-layer/add-new-layer.tsx index 60b6a72ecd1..7562e6b53c4 100644 --- a/packages/geoview-core/src/core/components/layers/left-panel/add-new-layer/add-new-layer.tsx +++ b/packages/geoview-core/src/core/components/layers/left-panel/add-new-layer/add-new-layer.tsx @@ -1,15 +1,11 @@ import React, { ChangeEvent, useEffect, useRef, useState, KeyboardEvent } from 'react'; import { useTranslation } from 'react-i18next'; -import { SelectChangeEvent, useTheme } from '@mui/material'; +import { SelectChangeEvent } from '@mui/material'; import { - Autocomplete, Box, Button, ButtonGroup, ButtonPropsLayerPanel, - CheckBoxIcon, - CheckBoxOutlineBlankIcon, - Checkbox, CircularProgressBase, FileUploadIcon, Paper, @@ -17,67 +13,41 @@ import { Stepper, TextField, } from '@/ui'; -import { Projection } from '@/geo/utils/projection'; -import { OgcFeature, TypeOgcFeatureLayerConfig } from '@/geo/layer/geoview-layers/vector/ogc-feature'; -import { TypeWMSLayerConfig, WMS as WmsGeoviewClass } from '@/geo/layer/geoview-layers/raster/wms'; -import { TypeWFSLayerConfig, WFS as WfsGeoviewClass } from '@/geo/layer/geoview-layers/vector/wfs'; -import { TypeCSVLayerConfig, CSV as CsvGeoviewClass } from '@/geo/layer/geoview-layers/vector/csv'; -import { Cast, TypeJsonArray, TypeJsonObject } from '@/core/types/global-types'; import { useGeoViewMapId } from '@/core/stores/geoview-store'; -import { createLocalizedString } from '@/core/utils/utilities'; import { useLayerStoreActions } from '@/core/stores/store-interface-and-intial-values/layer-state'; import { api } from '@/app'; import { logger } from '@/core/utils/logger'; -import { EsriImage, TypeEsriImageLayerConfig } from '@/geo/layer/geoview-layers/raster/esri-image'; import { MapEventProcessor } from '@/api/event-processors/event-processor-children/map-event-processor'; -import { WfsLayerEntryConfig } from '@/core/utils/config/validation-classes/vector-validation-classes/wfs-layer-entry-config'; -import { OgcFeatureLayerEntryConfig } from '@/core/utils/config/validation-classes/vector-validation-classes/ogc-layer-entry-config'; -import { CsvLayerEntryConfig } from '@/core/utils/config/validation-classes/vector-validation-classes/csv-layer-entry-config'; -import { GeoJSONLayerEntryConfig } from '@/core/utils/config/validation-classes/vector-validation-classes/geojson-layer-entry-config'; -import { EsriFeatureLayerEntryConfig } from '@/core/utils/config/validation-classes/vector-validation-classes/esri-feature-layer-entry-config'; -import { GeoPackageLayerEntryConfig } from '@/core/utils/config/validation-classes/vector-validation-classes/geopackage-layer-config-entry'; -import { XYZTilesLayerEntryConfig } from '@/core/utils/config/validation-classes/raster-validation-classes/xyz-layer-entry-config'; -import { EsriDynamicLayerEntryConfig } from '@/core/utils/config/validation-classes/raster-validation-classes/esri-dynamic-layer-entry-config'; -import { EsriImageLayerEntryConfig } from '@/core/utils/config/validation-classes/raster-validation-classes/esri-image-layer-entry-config'; -import { OgcWmsLayerEntryConfig } from '@/core/utils/config/validation-classes/raster-validation-classes/ogc-wms-layer-entry-config'; -import { GeoPackage, TypeGeoPackageLayerConfig } from '@/geo/layer/geoview-layers/vector/geopackage'; -import { GeoCore } from '@/geo/layer/other/geocore'; -import { GeoViewLayerAddedResult } from '@/geo/layer/layer'; import { CONST_LAYER_TYPES, TypeGeoviewLayerTypeWithGeoCore, AbstractGeoViewLayer, + TypeGeoviewLayerType, } from '@/geo/layer/geoview-layers/abstract-geoview-layers'; -import { CONST_LAYER_ENTRY_TYPES, TypeLayerEntryConfig, TypeGeoviewLayerConfig } from '@/geo/map/map-schema-types'; -import { EsriDynamic, TypeEsriDynamicLayerConfig } from '@/geo/layer/geoview-layers/raster/esri-dynamic'; -import { TypeXYZTilesConfig, XYZTiles } from '@/geo/layer/geoview-layers/raster/xyz-tiles'; -import { EsriFeature, TypeEsriFeatureLayerConfig } from '@/geo/layer/geoview-layers/vector/esri-feature'; -import { GeoJSON, TypeGeoJSONLayerConfig } from '@/geo/layer/geoview-layers/vector/geojson'; -import { ConfigValidation } from '@/core/utils/config/config-validation'; - -type EsriOptions = { - err: string; - capability: string; -}; +import { CONST_LAYER_ENTRY_TYPES } from '@/geo/map/map-schema-types'; +import { EntryConfigBaseClass, GroupLayerEntryConfig } from '@/api/config/types/map-schema-types'; +import { AddLayerTree } from './add-layer-tree'; +import { buildGeoLayerToAdd } from './add-new-layers-utils'; +import { useAppDisplayLanguage } from '@/core/stores/store-interface-and-intial-values/app-state'; +import { GeoviewLayerConfigError } from '@/api/config/types/classes/config-exceptions'; export function AddNewLayer(): JSX.Element { // Log logger.logTraceRender('components/layers/left-panel/add-new-layer/add-new-layer'); const { t } = useTranslation(); - const theme = useTheme(); const { CSV, ESRI_DYNAMIC, ESRI_FEATURE, ESRI_IMAGE, GEOJSON, GEOPACKAGE, WMS, WFS, OGC_FEATURE, XYZ_TILES } = CONST_LAYER_TYPES; const { GEOCORE } = CONST_LAYER_ENTRY_TYPES; - const [geoviewLayerInstance, setGeoviewLayerInstance] = useState(); const [activeStep, setActiveStep] = useState(0); const [layerURL, setLayerURL] = useState(''); const [displayURL, setDisplayURL] = useState(''); const [layerType, setLayerType] = useState(''); - const [layerList, setLayerList] = useState([]); + const [layerList, setLayerList] = useState([]); + const [layerName, setLayerName] = useState(''); - const [layerEntries, setLayerEntries] = useState([]); + const [layerIdsToAdd, setLayerIdsToAdd] = useState([]); const [isLoading, setIsLoading] = useState(false); const [drag, setDrag] = useState(false); const [hasMetadata, setHasMetadata] = useState(false); @@ -92,6 +62,7 @@ export function AddNewLayer(): JSX.Element { // get values from store const mapId = useGeoViewMapId(); const { setDisplayState } = useLayerStoreActions(); + const language = useAppDisplayLanguage(); const isMultiple = (): boolean => hasMetadata && (layerType === ESRI_DYNAMIC || layerType === WFS || layerType === WMS || layerType === GEOJSON); @@ -120,23 +91,6 @@ export function AddNewLayer(): JSX.Element { }, }; - /** - * Returns the appropriate error config for ESRI layer types - * - * @param type one of esriDynamic or esriFeature - * @returns {EsriOptions} an error configuration object for populating dialogues - */ - const esriOptions = (type: string): EsriOptions => { - switch (type) { - case ESRI_DYNAMIC: - return { err: 'ESRI Map', capability: 'Map' }; - case ESRI_FEATURE: - return { err: 'ESRI Feature', capability: 'Query' }; - default: - return { err: '', capability: '' }; - } - }; - /** * Emits an error dialogue when a text field is empty * @@ -176,598 +130,6 @@ export function AddNewLayer(): JSX.Element { api.maps[mapId].notifications.showError(`${serviceName} ${t('layers.errorServer')}`, [], false); }; - /** - * Emits an error when a service does not support the current map projection - * - * @param serviceName type of service provided by the URL - * @param proj current map projection - */ - const emitErrorProj = (serviceName: string, proj: string | undefined, supportedProj: TypeJsonArray | string[]): void => { - setIsLoading(false); - const message = `${serviceName} ${t('layers.errorProj')} ${proj}, ${t('layers.only')} ${supportedProj.join(', ')}`; - api.maps[mapId].notifications.showError(message, [], false); - }; - - // TODO: REFACTOR ALL VALIDATION!!! - // TODOCONT: All validation MUST be refactored. For the moment they are creating config entries to be able to produce the needed - // TODOCONT: information for user to select the layer he wants. In the refactor we NEED single function to read metadata from url - // TODOCONT: and service type. At this point no layer or neither config is created, metadata is read to create the selection tree (step 3) - // TODOCONT: Once the user has selected the layers he wants, we create the config snippet and start the config validation process. - - /** - * Using the layerURL state object, check whether URL is a valid WMS, - * and add either Name and Entry directly to state if a single layer, - * or a list of Names / Entries if multiple layer options exist. - * - * @returns {Promise} True if layer passes validation - */ - // TODO: Move all the validations in a utility add layer file inside geo. Also delete old utilities that were used - // TODOCONT: in the previous version. - const wmsValidation = async (): Promise => { - const proj = Projection.PROJECTIONS[api.maps[mapId].getMapState().currentProjection].getCode(); - let supportedProj: string[] = []; - - try { - const [accessPath, queryString] = layerURL.split('?'); - const urlParams = new URLSearchParams(queryString); - const paramLayers = urlParams.get('layers')?.split(',') || []; - // query layers are not sent, as not all services support asking for multiple layers - const wmsGeoviewLayerConfig = { - geoviewLayerType: WMS, - listOfLayerEntryConfig: [] as OgcWmsLayerEntryConfig[], - metadataAccessPath: createLocalizedString(accessPath), - } as TypeWMSLayerConfig; - const wmsGeoviewLayerInstance = new WmsGeoviewClass(mapId, wmsGeoviewLayerConfig); - // Synchronize the geoviewLayerId. - wmsGeoviewLayerConfig.geoviewLayerId = wmsGeoviewLayerInstance.geoviewLayerId; - setGeoviewLayerInstance(wmsGeoviewLayerInstance); - await wmsGeoviewLayerInstance.createGeoViewLayers(); - if (!wmsGeoviewLayerInstance.metadata) throw new Error('Cannot get metadata'); - setHasMetadata(true); - const wmsMetadata = wmsGeoviewLayerInstance.metadata; - - if (!wmsMetadata) { - emitErrorServer('OGC WMS'); - return false; - } - - supportedProj = wmsMetadata.Capability.Layer.CRS as string[]; - if (!supportedProj.includes(proj)) throw new Error('proj'); - - const layers: OgcWmsLayerEntryConfig[] = []; - - const hasChildLayers = (layer: TypeJsonObject): void => { - if (layer.Layer && (layer.Layer as TypeJsonArray).length > 0) { - (layer.Layer as TypeJsonObject[]).forEach((childLayer: TypeJsonObject) => { - const name = childLayer.Name as string; - - // if there is no paramLayers, take them all; If there is paramLayers must be included in layers parameter from url - if (paramLayers.length === 0 || paramLayers.includes(name)) { - logger.logDebug('NAME', name); - layers.push( - new OgcWmsLayerEntryConfig({ - geoviewLayerConfig: wmsGeoviewLayerConfig, - layerId: childLayer.Name as string, - layerName: createLocalizedString(childLayer.Title as string), - } as OgcWmsLayerEntryConfig) - ); - } - - hasChildLayers(childLayer); - }); - } - }; - - if (wmsMetadata.Capability.Layer) { - hasChildLayers(wmsMetadata.Capability.Layer); - } - - if (layers.length === 1) { - setLayerName(layers[0].layerName!.en!); - setLayerEntries([layers[0]]); - } else { - setLayerList(layers); - } - } catch (err) { - if ((err as Error).message === 'proj') { - emitErrorProj('WMS', proj, supportedProj); - } else { - emitErrorServer('WMS'); - } - return false; - } - return true; - }; - - /** - * Using the layerURL state object, check whether URL is a valid WFS, - * and add either Name and Entry directly to state if a single layer, - * or a list of Names / Entries if multiple layer options exist. - * - * @returns {Promise} True if layer passes validation - */ - const wfsValidation = async (): Promise => { - try { - const wfsGeoviewLayerConfig = { - geoviewLayerType: WFS, - listOfLayerEntryConfig: [] as WfsLayerEntryConfig[], - metadataAccessPath: createLocalizedString(layerURL), - } as TypeWFSLayerConfig; - const wfsGeoviewLayerInstance = new WfsGeoviewClass(mapId, wfsGeoviewLayerConfig); - // Synchronize the geoviewLayerId. - wfsGeoviewLayerConfig.geoviewLayerId = wfsGeoviewLayerInstance.geoviewLayerId; - setGeoviewLayerInstance(wfsGeoviewLayerInstance); - await wfsGeoviewLayerInstance.createGeoViewLayers(); - if (!wfsGeoviewLayerInstance.metadata) throw new Error('Cannot get metadata'); - setHasMetadata(true); - const wfsMetadata = wfsGeoviewLayerInstance.metadata; - const layers = (wfsMetadata.FeatureTypeList.FeatureType as TypeJsonArray).map( - (aFeatureType) => - new WfsLayerEntryConfig({ - geoviewLayerConfig: wfsGeoviewLayerConfig, - layerId: (aFeatureType.Name['#text'] as string).split(':')[1] as string, - layerName: createLocalizedString(aFeatureType.Title['#text'] as string), - } as WfsLayerEntryConfig) - ); - - if (layers.length === 1) { - setLayerName(layers[0].layerName!.en! as string); - setLayerEntries([layers[0]]); - } else { - setLayerList(layers); - } - } catch (err) { - emitErrorServer('WFS'); - return false; - } - return true; - }; - - /** - * Using the layerURL state object, check whether URL is a valid OGC API. You can either provide a single - * layer URL or the root OGC API where the user can select any number of layers in the collection - * - * @returns {Promise} True if layer passes validation - */ - const ogcFeatureValidation = async (): Promise => { - try { - const ogcFeatureGeoviewLayerConfig = { - geoviewLayerType: OGC_FEATURE, - listOfLayerEntryConfig: [] as OgcFeatureLayerEntryConfig[], - metadataAccessPath: createLocalizedString(layerURL.split('collections')[0]), - } as TypeOgcFeatureLayerConfig; - const ogcFeatureInstance = new OgcFeature(mapId, ogcFeatureGeoviewLayerConfig); - // Synchronize the geoviewLayerId. - ogcFeatureGeoviewLayerConfig.geoviewLayerId = ogcFeatureInstance.geoviewLayerId; - setGeoviewLayerInstance(ogcFeatureInstance); - await ogcFeatureInstance.createGeoViewLayers(); - const ogcFeatureMetadata = ogcFeatureInstance.metadata!; - if (!ogcFeatureInstance.metadata) throw new Error('Cannot get metadata'); - setHasMetadata(true); - - if (!Object.keys(ogcFeatureMetadata).length) { - emitErrorServer('OGC API Feature'); - return false; - } - - // TODO: this type of query is not implemented in the ogc feature class. When we have time, we Should add - // TODOCONT: it to the code. - /* - const keysSingleLayer = ['id', 'title']; - const isSingleLayerValid = keysSingleLayer.every((key) => Object.keys(ogcFeatureMetadata).includes(key)); - if (isSingleLayerValid) { - setLayerEntries([ - new TypeOgcFeatureLayerEntryConfig({ - layerId: ogcFeatureMetadata.id as string, - layerName: createLocalizedString(ogcFeatureMetadata.title as string), - } as TypeOgcFeatureLayerEntryConfig), - ]); - setLayerName(ogcFeatureMetadata.title as string); - return true; - } - */ - - const keys = ['collections', 'links']; - const isCollectionValid = keys.every((key) => Object.keys(ogcFeatureMetadata).includes(key)); - if (!isCollectionValid) throw new Error('err'); - - // If there is collections, only the selected collection is set - let layers: OgcFeatureLayerEntryConfig[] = []; - if (layerURL.split('/collections/').length === 2) { - (ogcFeatureMetadata.collections as TypeJsonArray).forEach((aFeatureType) => { - if (layerURL.split('/collections/')[1] === aFeatureType.id) { - layers.push( - new OgcFeatureLayerEntryConfig({ - geoviewLayerConfig: ogcFeatureGeoviewLayerConfig, - layerId: aFeatureType.id as string, - layerName: createLocalizedString(aFeatureType.title as string), - } as OgcFeatureLayerEntryConfig) - ); - } - }); - } - - // if there is no collections in url, or layers not set properly from provided collection take them all; - if (layers.length === 0) { - layers = (ogcFeatureMetadata.collections as TypeJsonArray).map( - (aFeatureType) => - new OgcFeatureLayerEntryConfig({ - geoviewLayerConfig: ogcFeatureGeoviewLayerConfig, - layerId: aFeatureType.id as string, - layerName: createLocalizedString(aFeatureType.title as string), - } as OgcFeatureLayerEntryConfig) - ); - } - - if (layers.length === 1) { - setLayerName(layers[0].layerName!.en! as string); - setLayerEntries([layers[0]]); - } else { - setLayerList(layers); - } - } catch (err) { - emitErrorServer('OGC API Feature'); - return false; - } - return true; - }; - - /** - * Using the layerURL state object, check whether URL is a valid Geocore UUID. - * - * @returns {Promise} True if layer passes validation - */ - const geocoreValidation = async (): Promise => { - try { - const isValid = layerURL.indexOf('/') === -1 && layerURL.replaceAll('-', '').length === 32; - if (!isValid) throw new Error('err'); - - const geoCoreGeoviewLayerInstance = new GeoCore(mapId, api.maps[mapId].getDisplayLanguage()); - const layers = await geoCoreGeoviewLayerInstance.createLayersFromUUID(layerURL); - if (layers.length === 1) { - if (layers.length === 1) { - setLayerName(layers[0].geoviewLayerName!.en! as string); - setLayerEntries(layers); - } else { - setLayerList(layers); - } - } - } catch (err) { - emitErrorServer('GeoCore UUID'); - return false; - } - return true; - }; - - /** - * Using the layerURL state object, check whether URL is a valid ESRI Server, - * and add either Name and Entry directly to state if a single layer, - * or a list of Names / Entries if multiple layer options exist. - * - * @returns {Promise} True if layer passes validation - */ - const esriValidation = async (type: string): Promise => { - try { - const esriGeoviewLayerConfig = - type === ESRI_DYNAMIC - ? ({ - geoviewLayerType: type, - listOfLayerEntryConfig: [] as EsriDynamicLayerEntryConfig[], - metadataAccessPath: createLocalizedString(layerURL), - } as TypeEsriDynamicLayerConfig) - : ({ - geoviewLayerType: type, - listOfLayerEntryConfig: [] as EsriFeatureLayerEntryConfig[], - metadataAccessPath: createLocalizedString(layerURL.substring(0, layerURL.lastIndexOf('/'))), - } as TypeEsriFeatureLayerConfig); - const esriGeoviewLayerInstance = - type === ESRI_DYNAMIC - ? new EsriDynamic(mapId, esriGeoviewLayerConfig as TypeEsriDynamicLayerConfig) - : new EsriFeature(mapId, esriGeoviewLayerConfig as TypeEsriFeatureLayerConfig); - // Synchronize the geoviewLayerId. - esriGeoviewLayerConfig.geoviewLayerId = esriGeoviewLayerInstance.geoviewLayerId; - setGeoviewLayerInstance(esriGeoviewLayerInstance); - await esriGeoviewLayerInstance.createGeoViewLayers(); - const esriMetadata = esriGeoviewLayerInstance.metadata!; - if (!esriMetadata) throw new Error('Cannot get metadata'); - setHasMetadata(true); - if (esriMetadata !== null && (esriMetadata.capabilities as string).includes(esriOptions(type).capability)) { - if ('layers' in esriMetadata) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const layers: any = []; - if (type === ESRI_DYNAMIC) { - (esriMetadata.layers as TypeJsonArray).forEach((aLayer) => - layers.push( - new EsriDynamicLayerEntryConfig({ - geoviewLayerConfig: esriGeoviewLayerConfig, - layerId: aLayer.id as string, - layerName: createLocalizedString(aLayer.name as string), - } as EsriDynamicLayerEntryConfig) - ) - ); - } else { - layers.push( - new EsriFeatureLayerEntryConfig({ - geoviewLayerConfig: esriGeoviewLayerConfig, - layerId: esriMetadata.layers[0].id as string, - layerName: createLocalizedString(esriMetadata.layers[0].name as string), - } as EsriFeatureLayerEntryConfig) - ); - } - - if (layers.length === 1) { - setLayerName(layers[0].layerName!.en!); - setLayerEntries([layers[0]]); - } else { - setLayerList(layers); - } - } - } else { - throw new Error('err'); - } - } catch (err) { - emitErrorServer(esriOptions(type).err); - return false; - } - return true; - }; - - /** - * Using the layerURL state object, check whether URL is a valid ESRI Image. - * - * @returns {Promise} True if layer passes validation - */ - const esriImageValidation = async (): Promise => { - try { - const esriImageGeoviewLayerConfig = { - geoviewLayerType: ESRI_IMAGE, - listOfLayerEntryConfig: [] as EsriImageLayerEntryConfig[], - metadataAccessPath: createLocalizedString(layerURL), - } as TypeEsriImageLayerConfig; - const esriImageGeoviewLayerInstance = new EsriImage(mapId, esriImageGeoviewLayerConfig); - // Synchronize the geoviewLayerId. - esriImageGeoviewLayerConfig.geoviewLayerId = esriImageGeoviewLayerInstance.geoviewLayerId; - setGeoviewLayerInstance(esriImageGeoviewLayerInstance); - await esriImageGeoviewLayerInstance.createGeoViewLayers(); - const layers = [ - new EsriImageLayerEntryConfig({ - geoviewLayerConfig: esriImageGeoviewLayerConfig, - layerId: esriImageGeoviewLayerConfig.geoviewLayerId, - layerName: createLocalizedString( - typeof esriImageGeoviewLayerInstance.metadata?.name === 'string' ? esriImageGeoviewLayerInstance.metadata?.name : '' - ), - source: { - dataAccessPath: createLocalizedString(layerURL), - }, - } as EsriImageLayerEntryConfig), - ]; - setLayerName(layers[0].layerName!.en!); - setLayerEntries([layers[0]]); - } catch (err) { - emitErrorServer('ESRI Image'); - return false; - } - return true; - }; - - /** - * Using the layerURL state object, check whether URL is a valid XYZ Server. - * - * @returns {boolean} True if layer passes validation - */ - const xyzValidation = async (): Promise => { - try { - const tiles = ['{x}', '{y}', '{z}']; - for (let i = 0; i < tiles.length; i += 1) { - if (!layerURL.includes(tiles[i])) { - emitErrorServer('XYZ Tile'); - return false; - } - } - const xyzGeoviewLayerConfig = { - geoviewLayerType: XYZ_TILES, - listOfLayerEntryConfig: [] as XYZTilesLayerEntryConfig[], - } as TypeXYZTilesConfig; - const xyzGeoviewLayerInstance = new XYZTiles(mapId, xyzGeoviewLayerConfig); - // Synchronize the geoviewLayerId. - xyzGeoviewLayerConfig.geoviewLayerId = xyzGeoviewLayerInstance.geoviewLayerId; - setGeoviewLayerInstance(xyzGeoviewLayerInstance); - await xyzGeoviewLayerInstance.createGeoViewLayers(); - setHasMetadata(false); - const layers = [ - new XYZTilesLayerEntryConfig({ - geoviewLayerConfig: xyzGeoviewLayerConfig, - layerId: xyzGeoviewLayerConfig.geoviewLayerId, - layerName: createLocalizedString(''), - source: { - dataAccessPath: createLocalizedString(layerURL), - }, - } as XYZTilesLayerEntryConfig), - ]; - setLayerName(layers[0].layerName!.en!); - setLayerEntries([layers[0]]); - } catch (err) { - emitErrorServer('XYZ Tile'); - return false; - } - return true; - }; - - /** - * Using the layerURL state object, check whether URL is a valid CSV file. - * - * @returns {Promise} True if layer passes validation - */ - const csvValidation = async (): Promise => { - try { - // We assume a single CSV file is present - setHasMetadata(false); - const csvGeoviewLayerConfig = { - geoviewLayerType: CSV, - listOfLayerEntryConfig: [] as CsvLayerEntryConfig[], - } as TypeCSVLayerConfig; - const csvGeoviewLayerInstance = new CsvGeoviewClass(mapId, csvGeoviewLayerConfig); - // Synchronize the geoviewLayerId. - csvGeoviewLayerConfig.geoviewLayerId = csvGeoviewLayerInstance.geoviewLayerId; - setGeoviewLayerInstance(csvGeoviewLayerInstance); - await csvGeoviewLayerInstance.createGeoViewLayers(); - const layers = [ - new CsvLayerEntryConfig({ - geoviewLayerConfig: csvGeoviewLayerConfig, - layerId: csvGeoviewLayerConfig.geoviewLayerId, - layerName: createLocalizedString(''), - schemaTag: CONST_LAYER_TYPES.CSV, - source: { - dataAccessPath: createLocalizedString(layerURL), - }, - } as CsvLayerEntryConfig), - ]; - setLayerName(layers[0].layerName!.en!); - setLayerEntries([layers[0]]); - } catch (err) { - emitErrorServer('CSV'); - return false; - } - return true; - }; - - /** - * Using the layerURL state object, check whether URL is a valid GeoJSON. - * - * @returns {Promise} True if layer passes validation - */ - const geoJSONValidation = async (): Promise => { - try { - const response = await fetch(layerURL); - const json = await response.json(); - if (!['FeatureCollection', 'Feature'].includes(json.type)) { - // We assume that a metadata file is present - const geojsonGeoviewLayerConfig = { - geoviewLayerType: GEOJSON, - listOfLayerEntryConfig: [] as GeoJSONLayerEntryConfig[], - metadataAccessPath: createLocalizedString(layerURL), - } as TypeGeoJSONLayerConfig; - const geojsonGeoviewLayerInstance = new GeoJSON(mapId, geojsonGeoviewLayerConfig); - // Synchronize the geoviewLayerId. - geojsonGeoviewLayerConfig.geoviewLayerId = geojsonGeoviewLayerInstance.geoviewLayerId; - setGeoviewLayerInstance(geojsonGeoviewLayerInstance); - await geojsonGeoviewLayerInstance.createGeoViewLayers(); - setHasMetadata(true); - if (!geojsonGeoviewLayerInstance.metadata) throw new Error('Cannot get metadata'); - const geojsonFeatureMetadata = geojsonGeoviewLayerInstance.metadata!; - geojsonGeoviewLayerConfig.listOfLayerEntryConfig = Cast(geojsonFeatureMetadata.listOfLayerEntryConfig); - // validate and instanciate layer configs - ConfigValidation.validateListOfGeoviewLayerConfig(api.maps[mapId].getDisplayLanguage(), [geojsonGeoviewLayerConfig]); - const layers = geojsonGeoviewLayerConfig.listOfLayerEntryConfig; - if (layers.length === 1) { - setLayerName(layers[0].layerName!.en! as string); - setLayerEntries([Cast(layers[0])]); - } else { - setLayerList(Cast(layers)); - } - } else { - // We assume a single GeoJSON file is present - setHasMetadata(false); - const geojsonGeoviewLayerConfig = { - geoviewLayerType: GEOJSON, - listOfLayerEntryConfig: [] as GeoJSONLayerEntryConfig[], - } as TypeGeoJSONLayerConfig; - const geojsonGeoviewLayerInstance = new GeoJSON(mapId, geojsonGeoviewLayerConfig); - // Synchronize the geoviewLayerId. - geojsonGeoviewLayerConfig.geoviewLayerId = geojsonGeoviewLayerInstance.geoviewLayerId; - setGeoviewLayerInstance(geojsonGeoviewLayerInstance); - await geojsonGeoviewLayerInstance.createGeoViewLayers(); - const layers = [ - new GeoJSONLayerEntryConfig({ - geoviewLayerConfig: geojsonGeoviewLayerConfig, - layerId: geojsonGeoviewLayerConfig.geoviewLayerId, - layerName: createLocalizedString(''), - source: { - dataAccessPath: createLocalizedString(layerURL), - }, - } as GeoJSONLayerEntryConfig), - ]; - setLayerName(layers[0].layerName!.en!); - setLayerEntries([layers[0]]); - } - } catch (err) { - emitErrorServer('GeoJSON'); - return false; - } - return true; - }; - - /** - * Using the layerURL state object, check whether URL is a valid GeoPackage. - * - * @returns {boolean} True if layer passes validation - */ - const geoPackageValidation = (): boolean => { - try { - // We assume a single GeoPackage file is present - setHasMetadata(false); - const geoPackageGeoviewLayerConfig = { - geoviewLayerType: GEOPACKAGE, - listOfLayerEntryConfig: [] as GeoPackageLayerEntryConfig[], - } as TypeGeoPackageLayerConfig; - const geopackageGeoviewLayerInstance = new GeoPackage(mapId, geoPackageGeoviewLayerConfig); - // Synchronize the geoviewLayerId. - geoPackageGeoviewLayerConfig.geoviewLayerId = geopackageGeoviewLayerInstance.geoviewLayerId; - setGeoviewLayerInstance(geopackageGeoviewLayerInstance); - const layers = [ - new GeoPackageLayerEntryConfig({ - geoviewLayerConfig: geoPackageGeoviewLayerConfig, - layerId: geoPackageGeoviewLayerConfig.geoviewLayerId, - layerName: createLocalizedString(''), - source: { - dataAccessPath: createLocalizedString(layerURL), - }, - } as GeoPackageLayerEntryConfig), - ]; - setLayerName(layers[0].layerName!.en!); - setLayerEntries([layers[0]]); - } catch (err) { - emitErrorServer('GeoPackage'); - return false; - } - return true; - }; - - /** - * Attempt to determine the layer type based on the URL format - */ - const bestGuessLayerType = (): void => { - const layerTokens = displayURL.toUpperCase().split('/'); - const layerId = parseInt(layerTokens[layerTokens.length - 1], 10); - if (displayURL.toUpperCase().endsWith('MAPSERVER') || displayURL.toUpperCase().endsWith('MAPSERVER/')) { - setLayerType(ESRI_DYNAMIC); - } else if ( - displayURL.toUpperCase().indexOf('FEATURESERVER') !== -1 || - (displayURL.toUpperCase().indexOf('MAPSERVER') !== -1 && !Number.isNaN(layerId)) - ) { - setLayerType(ESRI_FEATURE); - } else if (displayURL.toUpperCase().indexOf('IMAGESERVER') !== -1) { - setLayerType(ESRI_IMAGE); - } else if (layerTokens.indexOf('WFS') !== -1) { - setLayerType(WFS); - } else if (displayURL.toUpperCase().endsWith('.JSON') || displayURL.toUpperCase().endsWith('.GEOJSON')) { - setLayerType(GEOJSON); - } else if (displayURL.toUpperCase().endsWith('.GPKG')) { - setLayerType(GEOPACKAGE); - } else if (displayURL.toUpperCase().indexOf('{Z}/{X}/{Y}') !== -1 || displayURL.toUpperCase().indexOf('{Z}/{Y}/{X}') !== -1) { - setLayerType(XYZ_TILES); - } else if (displayURL.indexOf('/') === -1 && displayURL.replaceAll('-', '').length === 32) { - setLayerType(GEOCORE); - } else if (displayURL.toUpperCase().indexOf('WMS') !== -1) { - setLayerType(WMS); - } else if (displayURL.toUpperCase().endsWith('.CSV')) { - setLayerType(CSV); - } else { - setLayerType(''); - setStepButtonDisable(true); - } - }; - /** * Handle the behavior of the 'Continue' button in the Stepper UI */ @@ -778,7 +140,8 @@ export function AddNewLayer(): JSX.Element { emitErrorNone(); } if (valid) { - bestGuessLayerType(); + const guestedLayerType = api.config.guessLayerType(layerURL); + setLayerType(guestedLayerType as TypeGeoviewLayerType); setActiveStep(1); } }; @@ -789,21 +152,62 @@ export function AddNewLayer(): JSX.Element { const handleStep2 = (): void => { setIsLoading(true); + const populateLayerList = async (curlayerType: TypeGeoviewLayerType): Promise => { + try { + // create an instance of the GeoView layer. The list of layer entry config is empty, but if the URL specify a sublayer + // the instance created will adjust the metadata access path and the list of sublayers accordingly. + const geoviewLayerConfig = await api.config.createLayerConfig(layerURL, curlayerType, [], language); + if (geoviewLayerConfig && !geoviewLayerConfig.getErrorDetectedFlag()) { + // GV: Here, the list of layer entry config may be empty or it may contain one layer Id specified in the URL. + // GV: This list of layer entry config will be used as a filter for the layer tree. Also, when we want to build the layer tree, + // GV: we set the metadata layer tree with the layer tree filter and use an empty list of layer entry config. This is how the + // GV: GeoView instance differentiate the creation of a layer tree and the creation of a GeoView layer with its list of sublayers. + // Set the layer tree filter. + geoviewLayerConfig.setMetadataLayerTree( + (geoviewLayerConfig.listOfLayerEntryConfig.length + ? [{ layerId: geoviewLayerConfig.listOfLayerEntryConfig[0].layerId }] + : []) as EntryConfigBaseClass[] + ); + // GV: The listOfLayerEntryConfig must be empty when we want to build the layer tree. + geoviewLayerConfig.listOfLayerEntryConfig = []; + // Then, we fetch the service metadata. This will populate the layer tree. + await geoviewLayerConfig.fetchServiceMetadata(); + const layersTree = geoviewLayerConfig.getMetadataLayerTree()!; + logger.logDebug('layersTree', layersTree); + setLayerList(layersTree as GroupLayerEntryConfig[]); + if (layersTree.length > 0) { + setLayerName(layersTree[0].layerName ?? ''); + } + setHasMetadata(true); + return true; + } + throw new GeoviewLayerConfigError(`Unable to create ${curlayerType} GeoView layer using "${layerURL} URL.`); + } catch (err) { + emitErrorServer(curlayerType); + return false; + } + }; + let promise; if (layerType === undefined) { setIsLoading(false); emitErrorEmpty(t('layers.service')); - } else if (layerType === WMS) promise = wmsValidation(); - else if (layerType === WFS) promise = wfsValidation(); - else if (layerType === OGC_FEATURE) promise = ogcFeatureValidation(); - else if (layerType === XYZ_TILES) promise = xyzValidation(); - else if (layerType === ESRI_DYNAMIC) promise = esriValidation(ESRI_DYNAMIC); - else if (layerType === ESRI_FEATURE) promise = esriValidation(ESRI_FEATURE); - else if (layerType === ESRI_IMAGE) promise = esriImageValidation(); - else if (layerType === GEOJSON) promise = geoJSONValidation(); - else if (layerType === GEOPACKAGE) promise = Promise.resolve(geoPackageValidation()); - else if (layerType === GEOCORE) promise = geocoreValidation(); - else if (layerType === CSV) promise = csvValidation(); + } else if ( + layerType === WMS || + layerType === WFS || + layerType === OGC_FEATURE || + layerType === XYZ_TILES || + layerType === ESRI_DYNAMIC || + layerType === ESRI_FEATURE || + layerType === ESRI_IMAGE || + layerType === GEOJSON || + layerType === GEOPACKAGE || + layerType === CSV + ) { + promise = populateLayerList(layerType); + // wmsValidation(); + // wfsValidation(); + } // If we have a promise of a layer validation if (promise) { @@ -829,9 +233,11 @@ export function AddNewLayer(): JSX.Element { */ const handleStep3 = (): void => { let valid = true; - if (layerEntries.length === 0) { - valid = false; - emitErrorEmpty(t('layers.layer')); + if (layerIdsToAdd.length === 0) { + if (!layerName) { + valid = false; + emitErrorEmpty(t('layers.layer')); + } } if (valid) setActiveStep(3); }; @@ -856,67 +262,35 @@ export function AddNewLayer(): JSX.Element { */ const handleStepLast = (): void => { setIsLoading(true); - if (layerType === GEOCORE) { - // TODO: Refactor - When reworking on this component, fix this weird thing of layerList vs layerEntries confusion for GeoCore - const addedLayers: GeoViewLayerAddedResult[] = []; - if (layerList.length > 1) { - (layerList as TypeGeoviewLayerConfig[]).forEach((geoviewLayerConfig) => { - const addedLayer = api.maps[mapId].layer.addGeoviewLayer(geoviewLayerConfig); - if (addedLayer) addedLayers.push(addedLayer); - }); - } else if (layerEntries.length > 0) { - (layerEntries as TypeGeoviewLayerConfig[]).forEach((geoviewLayerConfig) => { - const addedLayer = api.maps[mapId].layer.addGeoviewLayer(geoviewLayerConfig); - if (addedLayer) addedLayers.push(addedLayer); - }); - } - // When each promise is done - Promise.allSettled(addedLayers.map((addedLayer) => addedLayer.promiseLayer)) + const newGeoViewLayer = buildGeoLayerToAdd({ + layerIdsToAdd, + layerName, + layerType, + layerURL, + layersList: layerList, + language, + }); + + logger.logDebug('newGeoViewLayer to add', newGeoViewLayer); + + // Add the layer using the proper function + const addedLayer = api.maps[mapId].layer.addGeoviewLayer(newGeoViewLayer); + if (addedLayer) { + // Wait on the promise + addedLayer.promiseLayer .then(() => { // Done adding doneAdding(); - addedLayers.forEach((addedLayer) => doneAddedShowMessage(addedLayer.layer)); + doneAddedShowMessage(addedLayer.layer); }) .catch((error) => { // Log - logger.logPromiseFailed('Promise.allSettled in handleStepLast in AddNewLayer', error); + logger.logPromiseFailed('addedLayer.promiseLayer in handleStepLast in AddNewLayer', error); }); - } else if (geoviewLayerInstance) { - // Get config - const { geoviewLayerConfig } = layerEntries[0] as TypeLayerEntryConfig; - - // Have to massage this so the `setListOfLayerEntryConfig` inside the layer constructor works - // TODO: Refactor - Try to find a way to simplify/clarify what's going on in the layer constructor's call to `setListOfLayerEntryConfig`. - // TO.DOCONT: The recursion is necessary, but can the root be a derived type of the branches/leaves or something? - // TO.DOCONT: Maybe just me, but seems a bit hard to understand what needs to be set in the `geoviewLayerConfig.listOfLayerEntryConfig`. - // TO.DOCONT: Anyways, this works as-it-was before the refactor for now. - geoviewLayerConfig.listOfLayerEntryConfig = layerEntries as TypeLayerEntryConfig[]; - - // TODO: Bug - Fix this layer naming not working, wasn't working before the refactor either, leaving it as-is - geoviewLayerConfig.geoviewLayerName = createLocalizedString(layerName); - if (layerType === XYZ_TILES) (layerEntries[0] as TypeLayerEntryConfig).layerName = createLocalizedString(layerName); - if (geoviewLayerConfig.listOfLayerEntryConfig.length === 1) - geoviewLayerConfig.listOfLayerEntryConfig[0].layerName = geoviewLayerConfig.geoviewLayerName; - - // Add the layer using the proper function - const addedLayer = api.maps[mapId].layer.addGeoviewLayer(geoviewLayerConfig); - if (addedLayer) { - // Wait on the promise - addedLayer.promiseLayer - .then(() => { - // Done adding - doneAdding(); - doneAddedShowMessage(addedLayer.layer); - }) - .catch((error) => { - // Log - logger.logPromiseFailed('addedLayer.promiseLayer in handleStepLast in AddNewLayer', error); - }); - } else { - // Failed to add, remove spinning, but stay on the add ui - setIsLoading(false); - } + } else { + // Failed to add, remove spinning, but stay on the add ui + setIsLoading(false); } }; @@ -943,7 +317,7 @@ export function AddNewLayer(): JSX.Element { setLayerType(''); setLayerList([]); setLayerName(fileName); - setLayerEntries([]); + setLayerIdsToAdd([]); }; /** @@ -957,7 +331,7 @@ export function AddNewLayer(): JSX.Element { setLayerType(''); setLayerList([]); setLayerName(''); - setLayerEntries([]); + setLayerIdsToAdd([]); // TODO: create a utilities function to test valid URL before we enable the continue button // TODO.CONT: This function should try to ping the server for an answer... @@ -973,37 +347,11 @@ export function AddNewLayer(): JSX.Element { const handleSelectType = (event: SelectChangeEvent): void => { setLayerType(event.target.value as TypeGeoviewLayerTypeWithGeoCore); setLayerList([]); - setLayerEntries([]); + setLayerIdsToAdd([]); setStepButtonDisable(false); }; - /** - * Set the currently selected layer from a list - * - * @param {Event} event - Select event - * @param {TypeLayerEntryConfig[] | TypeLayerEntryConfig} newValue - The new layer entry config value - * - * @param newValue value/label pairs of select options - */ - const handleSelectLayer = (event: Event, newValue: TypeLayerEntryConfig[] | TypeLayerEntryConfig): void => { - setStepButtonDisable(true); - - if (isMultiple()) { - if (!((newValue as TypeLayerEntryConfig[]).length === 0)) { - setLayerEntries(newValue as TypeLayerEntryConfig[]); - setLayerName((newValue as TypeLayerEntryConfig[]).map((layerConfig) => layerConfig.layerName!.en).join(', ')); - - setStepButtonDisable(false); - } - } else { - setLayerEntries([newValue as TypeLayerEntryConfig]); - setLayerName((newValue as TypeLayerEntryConfig).layerName!.en!); - - setStepButtonDisable(false); - } - }; - /** * Set the layer name from form input * @@ -1016,8 +364,8 @@ export function AddNewLayer(): JSX.Element { // To set the button enable when validation set the layerName useEffect(() => { - if (activeStep === 2 && layerEntries.length > 0) setStepButtonDisable(false); - }, [layerName, activeStep, layerEntries]); + if (activeStep === 2 && layerIdsToAdd.length > 0) setStepButtonDisable(false); + }, [layerName, activeStep, layerIdsToAdd]); useEffect(() => { if (activeStep === 0) { @@ -1135,7 +483,7 @@ export function AddNewLayer(): JSX.Element { size="small" type="text" onClick={handleBack} - onKeyDown={(e) => handleKeyDown(e)} + onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e)} > {t('layers.back')} @@ -1144,9 +492,6 @@ export function AddNewLayer(): JSX.Element { ); } - const uncheckedIcon = ; - const checkedIcon = ; - return ( handleDrop(e)} - onDragOver={(e) => handleDragOver(e)} - onDragEnter={(e) => handleDragEnter(e)} - onDragLeave={(e) => handleDragLeave(e)} + onDrop={(e: React.DragEvent) => handleDrop(e)} + onDragOver={(e: React.DragEvent) => handleDragOver(e)} + onDragEnter={(e: React.DragEvent) => handleDragEnter(e)} + onDragLeave={(e: React.DragEvent) => handleDragLeave(e)} > {drag && ( )} - {layerList.length > 1 && (layerList[0] as TypeLayerEntryConfig).layerName && ( - - `${(option as TypeLayerEntryConfig).layerName!.en} (${(option as TypeLayerEntryConfig).layerId})` - } - renderOption={(props, option, { selected }) => ( -
  • - - {(option as TypeLayerEntryConfig).layerName!.en} -
  • - )} - // eslint-disable-next-line @typescript-eslint/no-explicit-any - onChange={handleSelectLayer as any} - ref={isMultipleRef} - renderInput={(params) => } - /> - )} - {layerList.length > 1 && (layerList[0] as TypeGeoviewLayerConfig).geoviewLayerName && ( - - `${(option as TypeGeoviewLayerConfig).geoviewLayerName!.en} (${(option as TypeGeoviewLayerConfig).geoviewLayerId})` - } - disableCloseOnSelect - renderOption={(props, option, { selected }) => ( -
  • - - {(option as TypeGeoviewLayerConfig).geoviewLayerName!.en} -
  • - )} - // eslint-disable-next-line @typescript-eslint/no-explicit-any - onChange={handleSelectLayer as any} - ref={isMultipleRef} - renderInput={(params) => } - /> + {layerList.length > 0 && ( + )}
    @@ -1345,7 +647,6 @@ export function AddNewLayer(): JSX.Element { variant="standard" value={layerName} onChange={handleNameLayer} - ref={isMultipleTextFieldRef} />
    diff --git a/packages/geoview-core/src/core/components/layers/left-panel/add-new-layer/add-new-layers-utils.ts b/packages/geoview-core/src/core/components/layers/left-panel/add-new-layer/add-new-layers-utils.ts new file mode 100644 index 00000000000..ed64b751a7f --- /dev/null +++ b/packages/geoview-core/src/core/components/layers/left-panel/add-new-layer/add-new-layers-utils.ts @@ -0,0 +1,292 @@ +import { Cast, toJsonObject } from '@config/types/config-types'; +import { + EntryConfigBaseClass, + GroupLayerEntryConfig, + MapFeatureConfig, + TypeDisplayLanguage, + TypeGeoviewLayerType, +} from '@config/types/map-schema-types'; +import { layerEntryIsGroupLayer } from '@config/types/type-guards'; +import { createLocalizedString, generateId } from '@/core/utils/utilities'; +import { TypeGeoviewLayerConfig } from '@/geo/map/map-schema-types'; +import { logger } from '@/core/utils/logger'; +import { TypeJsonArray, TypeJsonObject } from '@/app'; + +type BuildGeoViewLayerInput = { + layerIdsToAdd: string[]; + layerName: string; + layerType: string; + layerURL: string; + layersList: GroupLayerEntryConfig[]; + language: TypeDisplayLanguage; +}; + +export const getLayerById = (layersList: GroupLayerEntryConfig[], layerId: string): GroupLayerEntryConfig | null | undefined => { + function searchBranchForLayer(branchGroup: GroupLayerEntryConfig): GroupLayerEntryConfig | null | undefined { + if (branchGroup.layerId === layerId) return branchGroup; + + const layer = branchGroup.listOfLayerEntryConfig?.find((childLayer) => childLayer.layerId === layerId); + + if (layer) return layer as GroupLayerEntryConfig; + + if (branchGroup.listOfLayerEntryConfig) { + let foundLayer: GroupLayerEntryConfig | null = null; + + for (let i = 0; i < branchGroup.listOfLayerEntryConfig.length; i++) { + const layer2 = branchGroup.listOfLayerEntryConfig[i] as GroupLayerEntryConfig; + + if (layer2.listOfLayerEntryConfig) { + const name = searchBranchForLayer(layer2 as GroupLayerEntryConfig); + + if (name) { + foundLayer = name; + break; + } + } + } + + return foundLayer; + } + + return null; + } + + for (let i = 0; i < layersList.length; i++) { + const layer = layersList[i]; + const name = searchBranchForLayer(layer); + if (name) return name; + } + + return null; +}; + +export const getLayerNameById = (layersList: GroupLayerEntryConfig[], layerId: string): string | null | undefined => { + return getLayerById(layersList, layerId)?.layerName; +}; + +export const buildGeoLayerToAdd = (inputProps: BuildGeoViewLayerInput): TypeGeoviewLayerConfig => { + const { layerIdsToAdd, layerName, layerType, layerURL, layersList, language } = inputProps; + logger.logDebug(layersList); + + // If a non empty layer tree is provided, get the geoview layer that contains it, otherwise create the geoview layer using + // the parameters provided. + const geoviewLayerConfig = layersList?.length + ? layersList[0].getGeoviewLayerConfig() + : MapFeatureConfig.nodeFactory( + toJsonObject({ + geoviewLayerId: generateId(), + geoviewLayerType: layerType as TypeGeoviewLayerType, + metadataAccessPath: createLocalizedString(layerURL), + listOfLayerEntryConfig: layerName ? [{ layerId: layerName, layerName: createLocalizedString(layerName) }] : [], + }), + language + ); + geoviewLayerConfig!.geoviewLayerName = layerName; + + if (layersList?.length) { + layerIdsToAdd.forEach((layerPath) => { + const pathItems = layerPath.split('/'); + // get the layer node selected from the layer tree. We search from the root of the tree (layersList[0]). + const layerNode = layersList[0].getSubLayerConfig(layerPath); + // If it is a group layer, create it by cloning each node 0f the path if it is not already created. + if (layerEntryIsGroupLayer(layerNode!)) { + // Search the current node in the geoview layer. + pathItems.forEach((nodeId, i) => { + const groupNode = geoviewLayerConfig?.getSubLayerConfig( + `${geoviewLayerConfig.geoviewLayerId}/${pathItems.slice(0, i + 1).join('/')}` + ); + // if it is not already created, create it. + if (!groupNode) { + // If we are at the top of the tree (index i = 0) ... + if (i === 0) { + // Get a copy of the group and erase its list of layer entry config. + const groupLayerToUse = layersList[0].getSubLayerConfig(nodeId)?.clone() as GroupLayerEntryConfig; + // Insert the copy in the geoview list of layer entry config + geoviewLayerConfig?.listOfLayerEntryConfig.push(groupLayerToUse as EntryConfigBaseClass); + } else { + // Get the parent group node list of sub-layers. + const parentLayerGroup = Cast( + geoviewLayerConfig?.getSubLayerConfig(`${geoviewLayerConfig.geoviewLayerId}/${pathItems.slice(0, i).join('/')}`) + ); + // Get a copy of the group and erase its list of layer entry config. + const groupLayerToUse = layersList[0] + .getSubLayerConfig(pathItems.slice(0, i + 1).join('/'))! + .clone(parentLayerGroup) as GroupLayerEntryConfig; + // Insert the copy in the parent list of layer entry config + parentLayerGroup.listOfLayerEntryConfig.push(groupLayerToUse as EntryConfigBaseClass); + } + } + }); + } else { + // The layer is not a group. Get the parent group node list of sub-layers. If we cannot find it, + // use the geoview list of sub-layers. + let parentLayerGroup: GroupLayerEntryConfig | undefined; + for (let i = 1; i < pathItems.length && !parentLayerGroup; i++) { + parentLayerGroup = Cast( + geoviewLayerConfig?.getSubLayerConfig( + `${geoviewLayerConfig.geoviewLayerId}/${pathItems.slice(0, pathItems.length - i).join('/')}` + ) + ); + } + const parentLayerGroupArray = parentLayerGroup?.listOfLayerEntryConfig || geoviewLayerConfig?.listOfLayerEntryConfig; + // Insert a copy of the current node in the parent list of layer entry config + parentLayerGroupArray!.push(layerNode!.clone(parentLayerGroup)); + } + }); + + const removeUnselectedGroups = (listOfLayerEntryConfig: EntryConfigBaseClass[]): EntryConfigBaseClass[] => { + return listOfLayerEntryConfig.reduce((newList, subLayer) => { + if (layerEntryIsGroupLayer(subLayer)) { + const listOfNodes = removeUnselectedGroups(subLayer.listOfLayerEntryConfig); + const pathItems = subLayer.getLayerPath().split('/'); + const nodePath = pathItems.slice(1).join('/'); + if (!layerIdsToAdd.includes(nodePath)) { + listOfNodes.forEach((node) => { + newList.push(node); + }); + } else newList.push(subLayer); + } else newList.push(subLayer); + return newList; + }, [] as EntryConfigBaseClass[]); + }; + geoviewLayerConfig!.listOfLayerEntryConfig = removeUnselectedGroups(geoviewLayerConfig!.listOfLayerEntryConfig!); + } + + // GV: The following section of code must be deleted when the layer API will be able to consume the new config + // GV: Beginning of the temporary code + const patchForTheListOfLayerEntryConfig = (listOfLayerEntryConfig: EntryConfigBaseClass[]): EntryConfigBaseClass[] => { + return Cast( + listOfLayerEntryConfig.map((layer) => { + if (layerEntryIsGroupLayer(layer)) { + const groupLayerToUse = { + layerId: layer.layerId, + layerName: createLocalizedString(layer.layerName!), + isLayerGroup: layer.isLayerGroup, + entryType: 'group', + listOfLayerEntryConfig: patchForTheListOfLayerEntryConfig(layer.listOfLayerEntryConfig!), + }; + return groupLayerToUse; + } + + const leafToUse = toJsonObject(layer); + leafToUse.schemaTag = Cast(geoviewLayerConfig?.geoviewLayerType); + if (leafToUse.layerName) leafToUse.layerName = toJsonObject(createLocalizedString(layer.layerName!)); + if (leafToUse.source) { + const { source } = leafToUse; + if ('maxRecordCount' in source) delete source.maxRecordCount; + if ('layerFilter' in source) leafToUse.layerFilter = source.layerFilter; + delete leafToUse.maxRecordCount; + if ('projection' in source) { + source.dataProjection = source.projection; + delete source.projection; + } + if (!source.dataAccessPath) { + if (!geoviewLayerConfig!.metadataAccessPath.toLowerCase().endsWith('.xml')) + if (geoviewLayerConfig!.metadataAccessPath.toLowerCase().endsWith('.meta')) { + const metadataAccessPathItems = geoviewLayerConfig!.metadataAccessPath.split('/'); + source.dataAccessPath = Cast( + createLocalizedString(metadataAccessPathItems.slice(0, metadataAccessPathItems.length - 1).join('/')) + ); + } else source.dataAccessPath = Cast(createLocalizedString(geoviewLayerConfig!.metadataAccessPath)); + } + // =================================================================================================== + if (source.featureInfo) { + const { featureInfo } = source; + if ('nameField' in featureInfo) featureInfo.nameField = toJsonObject(createLocalizedString(featureInfo.nameField)); + if (featureInfo?.outfields?.length) { + if (featureInfo.outfields[0].type) + featureInfo.fieldTypes = (featureInfo.outfields as TypeJsonArray) + .map((item) => { + return item.type; + }) + .join(',') as TypeJsonObject; + if (featureInfo.outfields[0].alias) + featureInfo.aliasFields = toJsonObject( + createLocalizedString( + (featureInfo.outfields as TypeJsonArray) + .map((item) => { + return item.alias; + }) + .join(',') + ) + ); + if (featureInfo.outfields[0].name) + featureInfo.outfields = toJsonObject( + createLocalizedString( + (featureInfo.outfields as TypeJsonArray) + .map((item) => { + return item.name; + }) + .join(',') + ) + ); + } + leafToUse.source.dataProjection = leafToUse.source.projection; + delete leafToUse.source.projection; + } + } + // ===================================================================================================== + if (leafToUse.style) { + const { style } = leafToUse; + const geometryStyle = {} as TypeJsonObject; + const geometryType = (leafToUse.geometryType as string) === 'linestring' ? 'LineString' : (leafToUse.geometryType as string); + style[`${geometryType.slice(0, 1).toUpperCase()}${geometryType.slice(1)}`] = geometryStyle; + if (style.type === 'simple') { + geometryStyle.styleType = 'simple' as TypeJsonObject; + geometryStyle.label = style?.info?.label; + geometryStyle.settings = style?.info[0]?.settings; + } else if (style.type === 'uniqueValue') { + geometryStyle.styleType = 'uniqueValue' as TypeJsonObject; + geometryStyle.fields = style?.fields; + const defaultIndex = (style.info.length as number) - 1; + (geometryStyle.uniqueValueStyleInfo as TypeJsonArray) = ( + (style.info as TypeJsonArray).slice(0, style.hasDefault ? defaultIndex : undefined) as TypeJsonArray + ).map((item) => { + return { + label: item.label, + visible: item.visible, + values: item.values, + settings: item.settings, + }; + }) as TypeJsonArray; + if (style.hasDefault) { + geometryStyle.defaultLabel = (style.info as TypeJsonArray)[defaultIndex].label; + geometryStyle.defaultVisible = (style.info as TypeJsonArray)[defaultIndex].visible; + geometryStyle.defaultSettings = (style.info as TypeJsonArray)[defaultIndex].settings; + } + } else { + geometryStyle.styleType = 'classBreaks' as TypeJsonObject; + geometryStyle.fields = style?.fields[0]; + const defaultIndex = (style.info.length as number) - 1; + (geometryStyle.classBreakStyleInfo as TypeJsonArray) = ( + (style.info as TypeJsonArray).slice(0, style.hasDefault ? defaultIndex : undefined) as TypeJsonArray + ).map((item) => { + return { + label: item.label, + visible: item.visible, + minValue: (item.values as TypeJsonArray)[0], + miaxValue: (item.values as TypeJsonArray)[1], + settings: item.settings, + }; + }) as TypeJsonArray; + if (leafToUse.hasDefault) { + geometryStyle.defaultLabel = (style.info as TypeJsonArray)[defaultIndex].label; + geometryStyle.defaultVisible = (style.info as TypeJsonArray)[defaultIndex].visible; + geometryStyle.defaultSettings = (style.info as TypeJsonArray)[defaultIndex].settings; + } + } + delete style.type; + delete style.info; + delete style.fields; + delete style.hasDefault; + } + return leafToUse; + }) + ); + }; + geoviewLayerConfig!.listOfLayerEntryConfig = patchForTheListOfLayerEntryConfig(geoviewLayerConfig!.listOfLayerEntryConfig); + geoviewLayerConfig!.metadataAccessPath = Cast(createLocalizedString(geoviewLayerConfig!.metadataAccessPath)); + // GV: End of temporary code + + return Cast(geoviewLayerConfig!); +}; diff --git a/packages/geoview-core/src/geo/layer/geoview-layers/raster/esri-dynamic.ts b/packages/geoview-core/src/geo/layer/geoview-layers/raster/esri-dynamic.ts index 3415aecc9ae..9f3fac47a4e 100644 --- a/packages/geoview-core/src/geo/layer/geoview-layers/raster/esri-dynamic.ts +++ b/packages/geoview-core/src/geo/layer/geoview-layers/raster/esri-dynamic.ts @@ -273,8 +273,8 @@ export class EsriDynamic extends AbstractGeoViewRaster { sourceOptions.attributions = [(this.metadata?.copyrightText ? this.metadata?.copyrightText : '') as string]; sourceOptions.url = getLocalizedValue(layerConfig.source.dataAccessPath!, AppEventProcessor.getDisplayLanguage(this.mapId)); sourceOptions.params = { LAYERS: `show:${layerConfig.layerId}` }; - if (layerConfig.source.transparent) Object.defineProperty(sourceOptions.params, 'transparent', layerConfig.source.transparent!); - if (layerConfig.source.format) Object.defineProperty(sourceOptions.params, 'format', layerConfig.source.format!); + if (layerConfig.source.transparent) sourceOptions.params.transparent = layerConfig.source.transparent!; + if (layerConfig.source.format) sourceOptions.params.format = layerConfig.source.format!; if (layerConfig.source.crossOrigin) { sourceOptions.crossOrigin = layerConfig.source.crossOrigin; } else { diff --git a/packages/geoview-core/src/geo/layer/geoview-layers/raster/esri-image.ts b/packages/geoview-core/src/geo/layer/geoview-layers/raster/esri-image.ts index a60db3447ed..d460e59c2ea 100644 --- a/packages/geoview-core/src/geo/layer/geoview-layers/raster/esri-image.ts +++ b/packages/geoview-core/src/geo/layer/geoview-layers/raster/esri-image.ts @@ -318,8 +318,8 @@ export class EsriImage extends AbstractGeoViewRaster { sourceOptions.attributions = [(this.metadata!.copyrightText ? this.metadata!.copyrightText : '') as string]; sourceOptions.url = getLocalizedValue(layerConfig.source.dataAccessPath!, AppEventProcessor.getDisplayLanguage(this.mapId)); sourceOptions.params = { LAYERS: `show:${layerConfig.layerId}` }; - if (layerConfig.source.transparent) Object.defineProperty(sourceOptions.params, 'transparent', layerConfig.source.transparent!); - if (layerConfig.source.format) Object.defineProperty(sourceOptions.params, 'format', layerConfig.source.format!); + if (layerConfig.source.transparent) sourceOptions.params.transparent = layerConfig.source.transparent!; + if (layerConfig.source.format) sourceOptions.params.format = layerConfig.source.format!; if (layerConfig.source.crossOrigin) { sourceOptions.crossOrigin = layerConfig.source.crossOrigin; } else { diff --git a/packages/geoview-core/src/geo/layer/geoview-layers/vector/geojson.ts b/packages/geoview-core/src/geo/layer/geoview-layers/vector/geojson.ts index c85e929a067..410e245fe9f 100644 --- a/packages/geoview-core/src/geo/layer/geoview-layers/vector/geojson.ts +++ b/packages/geoview-core/src/geo/layer/geoview-layers/vector/geojson.ts @@ -131,13 +131,10 @@ export class GeoJSON extends AbstractGeoViewVector { // When no metadata are provided, all layers are considered valid. if (!this.metadata) return; - // Note that geojson metadata as we defined it does not contains layer group. If you need geogson layer group, - // you can define them in the configuration section. if (Array.isArray(this.metadata?.listOfLayerEntryConfig)) { - const metadataLayerList = Cast(this.metadata?.listOfLayerEntryConfig); - const foundEntry = metadataLayerList.find( - (layerMetadata) => - layerMetadata.layerId === layerConfig.layerId && layerMetadata.layerIdExtension === layerConfig.layerIdExtension + const foundEntry = this.#recursiveSearch( + `${layerConfig.layerId}${layerConfig.layerIdExtension ? `.${layerConfig.layerIdExtension}` : ''}`, + Cast(this.metadata?.listOfLayerEntryConfig) ); if (!foundEntry) { this.layerLoadError.push({ @@ -156,6 +153,27 @@ export class GeoJSON extends AbstractGeoViewVector { }); } + /** *************************************************************************************************************************** + * This method is used to do a recursive search in the array of layer entry config. + * + * @param {string} layerId The layer list to search. + * @param {TypeLayerEntryConfig[]} metadataLayerList The layer list to search. + * + * @returns {TypeLayerEntryConfig | undefined} The found layer or undefined if not found. + * @private + */ + #recursiveSearch(searchKey: string, metadataLayerList: TypeLayerEntryConfig[]): TypeLayerEntryConfig | undefined { + for (const layerMetadata of metadataLayerList) { + if (searchKey === `${layerMetadata.layerId}${layerMetadata.layerIdExtension ? `.${layerMetadata.layerIdExtension}` : ''}`) + return layerMetadata; + if ('isLayerGroup' in layerMetadata && (layerMetadata.isLayerGroup as boolean)) { + const foundLayer = this.#recursiveSearch(searchKey, layerMetadata.listOfLayerEntryConfig); + if (foundLayer) return foundLayer; + } + } + return undefined; + } + /** *************************************************************************************************************************** * This method is used to process the layer's metadata. It will fill the empty fields of the layer's configuration (renderer, * initial settings, fields and aliases). @@ -170,10 +188,10 @@ export class GeoJSON extends AbstractGeoViewVector { if (!(layerConfig instanceof VectorLayerEntryConfig)) throw new Error('Invalid layer configuration type provided'); if (this.metadata) { - const metadataLayerList = Cast(this.metadata?.listOfLayerEntryConfig); - const layerMetadataFound = metadataLayerList.find( - (layerMetadata) => layerMetadata.layerId === layerConfig.layerId && layerMetadata.layerIdExtension === layerConfig.layerIdExtension - ); + const layerMetadataFound = this.#recursiveSearch( + `${layerConfig.layerId}${layerConfig.layerIdExtension ? `.${layerConfig.layerIdExtension}` : ''}`, + Cast(this.metadata?.listOfLayerEntryConfig) + ) as VectorLayerEntryConfig; if (layerMetadataFound) { layerConfig.layerName = layerConfig.layerName || layerMetadataFound.layerName; layerConfig.source = defaultsDeep(layerConfig.source, layerMetadataFound.source);