Browse Source

Merge branch 'develop' into docs/#1819-docs-updating-docs-on-element-definition

Nam Nguyen 7 months ago
parent
commit
13097ee2e6
100 changed files with 939 additions and 644 deletions
  1. 9 9
      .github/workflows/build-and-release-single-package.yml
  2. 10 19
      .github/workflows/build-and-release.yml
  3. 1 1
      .github/workflows/check-config-pyi.yml
  4. 6 18
      .github/workflows/partial-tests.yml
  5. 1 1
      .github/workflows/publish-single-package.yml
  6. 1 1
      .github/workflows/publish.yml
  7. 25 0
      doc/gui/examples/controls/input_active.py
  8. 39 0
      doc/gui/examples/controls/input_change_delay_on_change.py
  9. 25 0
      doc/gui/examples/controls/input_line_shown.py
  10. 26 0
      doc/gui/examples/controls/input_multiline.py
  11. 36 0
      doc/gui/examples/controls/input_on_action.py
  12. 23 0
      doc/gui/examples/controls/input_password.py
  13. 25 0
      doc/gui/examples/controls/input_type.py
  14. 1 0
      doc/gui/examples/controls/toggle_list_tuples/__init__.py
  15. 33 0
      doc/gui/examples/controls/toggle_list_tuples/builder.py
  16. 31 0
      doc/gui/examples/controls/toggle_list_tuples/markdown.py
  17. 44 0
      doc/gui/examples/controls/toggle_objects.py
  18. 26 0
      doc/gui/examples/controls/toggle_simple.py
  19. 38 0
      doc/gui/examples/controls/toggle_styling.py
  20. 26 0
      doc/gui/examples/controls/toggle_switch.py
  21. 21 0
      doc/gui/examples/controls/toggle_theme.py
  22. 26 0
      doc/gui/examples/controls/toggle_unselect.py
  23. 156 156
      frontend/taipy-gui/package-lock.json
  24. 0 19
      frontend/taipy-gui/packaging/taipy-gui.d.ts
  25. 0 25
      frontend/taipy-gui/src/context/taipyReducers.spec.ts
  26. 24 57
      frontend/taipy-gui/src/context/taipyReducers.ts
  27. 0 4
      frontend/taipy-gui/src/extensions/exports.ts
  28. 94 95
      frontend/taipy/package-lock.json
  29. 6 16
      frontend/taipy/src/CoreSelector.tsx
  30. 4 14
      frontend/taipy/src/DataNodeViewer.tsx
  31. 3 13
      frontend/taipy/src/JobSelector.tsx
  32. 2 12
      frontend/taipy/src/JobViewer.tsx
  33. 7 25
      frontend/taipy/src/ScenarioDag.tsx
  34. 7 18
      frontend/taipy/src/ScenarioViewer.tsx
  35. 2 2
      frontend/taipy/src/utils.ts
  36. 1 1
      pyproject.toml
  37. 2 2
      taipy/__init__.py
  38. 4 4
      taipy/_entrypoint.py
  39. 8 8
      taipy/common/INSTALLATION.md
  40. 0 0
      taipy/common/LICENSE
  41. 64 0
      taipy/common/README.md
  42. 0 0
      taipy/common/__init__.py
  43. 0 0
      taipy/common/_cli/__init__.py
  44. 0 0
      taipy/common/_cli/_base_cli/__init__.py
  45. 1 1
      taipy/common/_cli/_base_cli/_abstract_cli.py
  46. 0 0
      taipy/common/_cli/_base_cli/_taipy_parser.py
  47. 0 0
      taipy/common/_cli/_create_cli.py
  48. 0 0
      taipy/common/_cli/_help_cli.py
  49. 0 0
      taipy/common/_cli/_run_cli.py
  50. 5 8
      taipy/common/config/__init__.py
  51. 0 0
      taipy/common/config/_config.py
  52. 0 0
      taipy/common/config/_config_comparator/__init__.py
  53. 0 0
      taipy/common/config/_config_comparator/_comparator_result.py
  54. 0 0
      taipy/common/config/_config_comparator/_config_comparator.py
  55. 0 0
      taipy/common/config/_init.py
  56. 0 0
      taipy/common/config/_serializer/__init__.py
  57. 2 2
      taipy/common/config/_serializer/_base_serializer.py
  58. 0 0
      taipy/common/config/_serializer/_json_serializer.py
  59. 0 0
      taipy/common/config/_serializer/_toml_serializer.py
  60. 0 0
      taipy/common/config/checker/__init__.py
  61. 0 0
      taipy/common/config/checker/_checker.py
  62. 0 0
      taipy/common/config/checker/_checkers/__init__.py
  63. 0 0
      taipy/common/config/checker/_checkers/_auth_config_checker.py
  64. 8 9
      taipy/common/config/checker/_checkers/_config_checker.py
  65. 0 0
      taipy/common/config/checker/issue.py
  66. 0 0
      taipy/common/config/checker/issue_collector.py
  67. 11 0
      taipy/common/config/common/__init__.py
  68. 0 0
      taipy/common/config/common/_classproperty.py
  69. 0 0
      taipy/common/config/common/_config_blocker.py
  70. 0 0
      taipy/common/config/common/_repr_enum.py
  71. 0 0
      taipy/common/config/common/_template_handler.py
  72. 0 0
      taipy/common/config/common/_validate_id.py
  73. 0 0
      taipy/common/config/common/frequency.py
  74. 0 0
      taipy/common/config/common/scope.py
  75. 0 0
      taipy/common/config/common/typing.py
  76. 6 4
      taipy/common/config/config.py
  77. 1 2
      taipy/common/config/config.pyi
  78. 2 1
      taipy/common/config/exceptions/__init__.py
  79. 0 0
      taipy/common/config/exceptions/exceptions.py
  80. 0 0
      taipy/common/config/global_app/__init__.py
  81. 0 0
      taipy/common/config/global_app/global_app_config.py
  82. 0 0
      taipy/common/config/section.py
  83. 3 3
      taipy/common/config/stubs/generate_pyi.py
  84. 1 2
      taipy/common/config/stubs/pyi_header.py
  85. 0 0
      taipy/common/config/unique_section.py
  86. 0 0
      taipy/common/logger/__init__.py
  87. 0 0
      taipy/common/logger/_taipy_logger.py
  88. 8 8
      taipy/common/package_desc.md
  89. 15 5
      taipy/common/pyproject.toml
  90. 8 6
      taipy/common/setup.py
  91. 1 0
      taipy/common/version.json
  92. 0 0
      taipy/common/version.py
  93. 0 62
      taipy/config/README.md
  94. 0 1
      taipy/config/version.json
  95. 1 1
      taipy/core/__init__.py
  96. 2 2
      taipy/core/_cli/_core_cli.py
  97. 4 4
      taipy/core/_cli/_core_cli_factory.py
  98. 1 1
      taipy/core/_core.py
  99. 1 1
      taipy/core/_entity/_migrate/_migrate_fs.py
  100. 1 1
      taipy/core/_entity/_migrate/_migrate_mongo.py

+ 9 - 9
.github/workflows/build-and-release-single-package.yml

@@ -15,7 +15,7 @@ on:
         description: "The version of the package to be released"
         required: true
       target_package:
-        description: "The package to be released (gui, config, core, rest, templates, taipy)"
+        description: "The package to be released (gui, common, core, rest, templates, taipy)"
         required: true
 
 env:
@@ -28,7 +28,7 @@ jobs:
   fetch-versions:
     runs-on: ubuntu-latest
     outputs:
-        config_VERSION: ${{ steps.version-setup.outputs.config_VERSION }}
+        common_VERSION: ${{ steps.version-setup.outputs.common_VERSION }}
         core_VERSION: ${{ steps.version-setup.outputs.core_VERSION }}
         gui_VERSION: ${{ steps.version-setup.outputs.gui_VERSION }}
         rest_VERSION: ${{ steps.version-setup.outputs.rest_VERSION }}
@@ -73,11 +73,11 @@ jobs:
       - name: Set Build Variables
         id: set-variables
         run: |
-          if [ "${{ github.event.inputs.target_package }}" == "config" ]; then
-            echo "package_version=${{needs.fetch-versions.outputs.config_VERSION}}" >> $GITHUB_OUTPUT
-            echo "package_dir=./taipy/config" >> $GITHUB_OUTPUT
-            echo "release_name=${{needs.fetch-versions.outputs.config_VERSION}}-config" >> $GITHUB_OUTPUT
-            echo "tar_path=./dist/${{ github.event.repository.name }}-config-${{needs.fetch-versions.outputs.config_VERSION}}.tar.gz" >> $GITHUB_OUTPUT
+          if [ "${{ github.event.inputs.target_package }}" == "common" ]; then
+            echo "package_version=${{needs.fetch-versions.outputs.common_VERSION}}" >> $GITHUB_OUTPUT
+            echo "package_dir=./taipy/common" >> $GITHUB_OUTPUT
+            echo "release_name=${{needs.fetch-versions.outputs.common_VERSION}}-common" >> $GITHUB_OUTPUT
+            echo "tar_path=./dist/${{ github.event.repository.name }}-common-${{needs.fetch-versions.outputs.common_VERSION}}.tar.gz" >> $GITHUB_OUTPUT
           elif [ "${{ github.event.inputs.target_package }}" == "core" ]; then
             echo "package_version=${{needs.fetch-versions.outputs.core_VERSION}}" >> $GITHUB_OUTPUT
             echo "package_dir=./taipy/core" >> $GITHUB_OUTPUT
@@ -104,7 +104,7 @@ jobs:
       - name: Update setup.requirements.txt
         run: |
           python tools/release/update_setup_requirements.py taipy-${{ github.event.inputs.target_package }} \
-            ${{needs.fetch-versions.outputs.config_VERSION}} \
+            ${{needs.fetch-versions.outputs.common_VERSION}} \
             ${{needs.fetch-versions.outputs.core_VERSION}} \
             ${{needs.fetch-versions.outputs.gui_VERSION}} \
             ${{needs.fetch-versions.outputs.rest_VERSION}} \
@@ -145,7 +145,7 @@ jobs:
           python tools/release/build_package_structure.py  ${{ github.event.inputs.target_package }}
 
       - name: Copy Taipy Logger
-        if: github.event.inputs.target_package == 'config'
+        if: github.event.inputs.target_package == 'common'
         run: |
           cp -r taipy/logger/. ${{ steps.set-variables.outputs.package_dir }}/taipy/logger
 

+ 10 - 19
.github/workflows/build-and-release.yml

@@ -25,7 +25,7 @@ jobs:
   fetch-versions:
     runs-on: ubuntu-latest
     outputs:
-        config_VERSION: ${{ steps.version-setup.outputs.config_VERSION }}
+        common_VERSION: ${{ steps.version-setup.outputs.common_VERSION }}
         core_VERSION: ${{ steps.version-setup.outputs.core_VERSION }}
         gui_VERSION: ${{ steps.version-setup.outputs.gui_VERSION }}
         rest_VERSION: ${{ steps.version-setup.outputs.rest_VERSION }}
@@ -50,7 +50,7 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        package: [config, core, gui, rest, templates]
+        package: [common, core, gui, rest, templates]
       max-parallel: 1
     steps:
       - uses: actions/checkout@v4
@@ -71,11 +71,11 @@ jobs:
       - name: Set Build Variables
         id: set-variables
         run: |
-          if [ "${{ matrix.package }}" == "config" ]; then
-            echo "package_version=${{needs.fetch-versions.outputs.config_VERSION}}" >> $GITHUB_OUTPUT
-            echo "package_dir=./taipy/config" >> $GITHUB_OUTPUT
-            echo "release_name=${{needs.fetch-versions.outputs.config_VERSION}}-config" >> $GITHUB_OUTPUT
-            echo "tar_path=./dist/${{ github.event.repository.name }}-config-${{needs.fetch-versions.outputs.config_VERSION}}.tar.gz" >> $GITHUB_OUTPUT
+          if [ "${{ matrix.package }}" == "common" ]; then
+            echo "package_version=${{needs.fetch-versions.outputs.common_VERSION}}" >> $GITHUB_OUTPUT
+            echo "package_dir=./taipy/common" >> $GITHUB_OUTPUT
+            echo "release_name=${{needs.fetch-versions.outputs.common_VERSION}}-common" >> $GITHUB_OUTPUT
+            echo "tar_path=./dist/${{ github.event.repository.name }}-common-${{needs.fetch-versions.outputs.common_VERSION}}.tar.gz" >> $GITHUB_OUTPUT
           elif [ "${{ matrix.package }}" == "core" ]; then
             echo "package_version=${{needs.fetch-versions.outputs.core_VERSION}}" >> $GITHUB_OUTPUT
             echo "package_dir=./taipy/core" >> $GITHUB_OUTPUT
@@ -102,7 +102,7 @@ jobs:
       - name: Update setup.requirements.txt
         run: |
           python tools/release/update_setup_requirements.py taipy-${{ matrix.package }} \
-            ${{needs.fetch-versions.outputs.config_VERSION}} \
+            ${{needs.fetch-versions.outputs.common_VERSION}} \
             ${{needs.fetch-versions.outputs.core_VERSION}} \
             ${{needs.fetch-versions.outputs.gui_VERSION}} \
             ${{needs.fetch-versions.outputs.rest_VERSION}} \
@@ -142,15 +142,6 @@ jobs:
         run: |
           python tools/release/build_package_structure.py ${{ matrix.package }}
 
-      - name: Copy Taipy Logger
-        if: matrix.package == 'config'
-        run: |
-          cp -r taipy/logger/. ${{ steps.set-variables.outputs.package_dir }}/taipy/logger
-
-      - name: Copy _cli folder
-        run: |
-          cp -r taipy/_cli/. ${{ steps.set-variables.outputs.package_dir }}/taipy/_cli
-
       - name: Build package
         working-directory: ${{ steps.set-variables.outputs.package_dir }}
         run: |
@@ -192,7 +183,7 @@ jobs:
       - name: Update setup.requirements.txt
         run: |
           python tools/release/update_setup_requirements.py taipy \
-            ${{needs.fetch-versions.outputs.config_VERSION}} \
+            ${{needs.fetch-versions.outputs.common_VERSION}} \
             ${{needs.fetch-versions.outputs.core_VERSION}} \
             ${{needs.fetch-versions.outputs.gui_VERSION}} \
             ${{needs.fetch-versions.outputs.rest_VERSION}} \
@@ -233,7 +224,7 @@ jobs:
 
       - name: Download packages
         run: |
-          gh release download ${{ needs.fetch-versions.outputs.config_VERSION }}-config --skip-existing --dir dist
+          gh release download ${{ needs.fetch-versions.outputs.common_VERSION }}-common --skip-existing --dir dist
           gh release download ${{ needs.fetch-versions.outputs.core_VERSION }}-core --skip-existing --dir dist
           gh release download ${{ needs.fetch-versions.outputs.gui_VERSION }}-gui --skip-existing --dir dist
           gh release download ${{ needs.fetch-versions.outputs.rest_VERSION }}-rest --skip-existing --dir dist

+ 1 - 1
.github/workflows/check-config-pyi.yml

@@ -17,7 +17,7 @@ jobs:
         with:
           python-version: '3.11'
       - name: Update config.pyi
-        run: python taipy/config/stubs/generate_pyi.py
+        run: python taipy/common/config/stubs/generate_pyi.py
       - uses: stefanzweifel/git-auto-commit-action@v5
         with:
           commit_message: "Update config.pyi"

+ 6 - 18
.github/workflows/partial-tests.yml

@@ -14,7 +14,7 @@ jobs:
 
       - uses: jpetrucciani/mypy-check@master
         with:
-          mypy_flags:  "--ignore-missing-imports --implicit-optional --no-namespace-packages --exclude (taipy/templates/|tools/|doc/gui/examples/.*/builder.py) --follow-imports skip --disable-error-code import-untyped"
+          mypy_flags:  "--ignore-missing-imports --implicit-optional --disable-error-code attr-defined --no-namespace-packages --exclude (taipy/templates/|tools/|doc/gui/examples/.*/builder.py|taipy/common/config/config.pyi) --follow-imports skip --disable-error-code import-untyped"
 
       - uses: chartboost/ruff-action@v1
   tests:
@@ -33,10 +33,8 @@ jobs:
         id: changes
         with:
           filters: |
-            cli:
-              - 'taipy/_cli/**'
-            config:
-              - 'taipy/config/**'
+            common:
+              - 'taipy/common/**'
             core:
               - 'taipy/core/**'
             gui:
@@ -44,8 +42,6 @@ jobs:
               - 'frontend/taipy-gui/**'
             gui-core:
               - 'taipy/gui_core/**'
-            logger:
-              - 'taipy/logger/**'
             rest:
               - 'taipy/rest/**'
             templates:
@@ -103,13 +99,9 @@ jobs:
         if: steps.changes.outputs.gui == 'true' || steps.changes.outputs.gui-core == 'true'
         run: pipenv run playwright install chromium --with-deps
 
-      - name: Pytest CLI
-        if: steps.changes.outputs.cli == 'true'
-        run: pipenv run pytest tests/cli
-
-      - name: Pytest Config
-        if: steps.changes.outputs.config == 'true'
-        run: pipenv run pytest tests/config
+      - name: Pytest Common
+        if: steps.changes.outputs.common == 'true'
+        run: pipenv run pytest tests/common
 
       - name: Pytest Core
         if: steps.changes.outputs.core == 'true'
@@ -125,10 +117,6 @@ jobs:
         if: steps.changes.outputs.gui-core == 'true'
         run: pipenv run pytest tests/gui_core
 
-      - name: Pytest Logger
-        if: steps.changes.outputs.logger == 'true'
-        run: pipenv run pytest tests/logger
-
       - name: Pytest Rest
         if: steps.changes.outputs.rest == 'true'
         run: pipenv run pytest tests/rest

+ 1 - 1
.github/workflows/publish-single-package.yml

@@ -7,7 +7,7 @@ on:
         description: "The tag of the package to publish on Pypi (ex: 1.0.0, 1.0.0.dev0)"
         required: true
       target_package:
-        description: "The package to be released (gui, config, core, rest, templates, taipy)"
+        description: "The package to be released (gui, common, core, rest, templates, taipy)"
         required: true
 
 jobs:

+ 1 - 1
.github/workflows/publish.yml

@@ -38,7 +38,7 @@ jobs:
     timeout-minutes: 20
     strategy:
       matrix:
-        package: [ config, core, gui, rest, templates ]
+        package: [ common, core, gui, rest, templates ]
       max-parallel: 1
     environment: publish
     runs-on: ubuntu-latest

+ 25 - 0
doc/gui/examples/controls/input_active.py

@@ -0,0 +1,25 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+from taipy.gui import Gui
+
+value = 20
+
+page = """
+<|{value}|input|active=false|>
+"""
+
+if __name__ == "__main__":
+    Gui(page).run(title="Input - Inactive")

+ 39 - 0
doc/gui/examples/controls/input_change_delay_on_change.py

@@ -0,0 +1,39 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+import logging
+
+from taipy.gui import Gui
+
+# Configure logging
+logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
+
+value = ""
+
+
+# The [on_change] property is not set: Taipy GUI automatically finds and binds the global on_change()
+# function to handle changes in the input control. You could set this property to your own function if necessary.
+def on_change(state, var_name, v):
+    logging.info(f"Value of {var_name} changed to {v}")
+
+
+# If change_delay is set to -1, the change event is triggered on Enter key press
+page = """
+<|{value}|input|change_delay=-1|>
+"""
+
+
+if __name__ == "__main__":
+    Gui(page).run(title="Input - on_change")

+ 25 - 0
doc/gui/examples/controls/input_line_shown.py

@@ -0,0 +1,25 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+from taipy.gui import Gui
+
+lines = "1 \n2 \n3 \n4 \n5"
+
+page = """
+<|{lines}|input|multiline|lines_shown=5|>
+"""
+
+if __name__ == "__main__":
+    Gui(page).run(title="Input - Lines shown")

+ 26 - 0
doc/gui/examples/controls/input_multiline.py

@@ -0,0 +1,26 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+from taipy.gui import Gui
+
+text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam nec purus et nunc lacinia gravida. "
+
+
+page = """
+<|{text}|input|multiline|>
+"""
+
+if __name__ == "__main__":
+    Gui(page).run(title="Input - Multiline")

+ 36 - 0
doc/gui/examples/controls/input_on_action.py

@@ -0,0 +1,36 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+import logging
+
+from taipy.gui import Gui
+
+logging.basicConfig(level=logging.INFO)
+
+def key_pressed(state, id, payload):
+    key = payload.get('args', [None])[0]
+    if key in ["F1", "F2", "F3"]:
+        logging.info(f"{key} key pressed")
+
+
+value = 0
+
+# on_action function is called when the action_keys are pressed
+page = """
+<|{value}|input|change_delay=300|on_action=key_pressed|action_keys=F1;F2;F3|>
+"""
+
+if __name__ == "__main__":
+    Gui(page).run(title="Input - On change")

+ 23 - 0
doc/gui/examples/controls/input_password.py

@@ -0,0 +1,23 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+from taipy.gui import Gui
+
+page = """
+<|input|password|>
+"""
+
+if __name__ == "__main__":
+    Gui(page).run(title="Input - Password")

+ 25 - 0
doc/gui/examples/controls/input_type.py

@@ -0,0 +1,25 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+from taipy.gui import Gui
+
+number = 0
+
+page = """
+<|{number}|input|type=number|>
+"""
+
+if __name__ == "__main__":
+    Gui(page).run(title="Input - Type")

+ 1 - 0
doc/gui/examples/controls/toggle_list_tuples/__init__.py

@@ -0,0 +1 @@
+# This file makes this directory a module on its own, mandatory for mypy.

+ 33 - 0
doc/gui/examples/controls/toggle_list_tuples/builder.py

@@ -0,0 +1,33 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+from taipy.gui import Gui, Icon
+from taipy.gui import builder as tgb
+
+lov = [
+    ("id1", "Label 1"),
+    ("id2", Icon("https://docs.taipy.io/en/latest/assets/images/favicon.png", "Taipy Logo"), "Label 2"),
+    ("id3", "Label 3"),
+]
+value = lov[0]
+
+with tgb.Page() as page:
+    tgb.toggle("{value}", lov="{lov}")  # type: ignore[attr-defined]
+    tgb.html(None, "Value: ")
+    tgb.text("{value[1].text if isinstance(value[1], Icon) else value[1]}", inline=True)  # type: ignore[attr-defined]
+
+
+if __name__ == "__main__":
+    Gui(page).run(title="Toggle - List tuples")

+ 31 - 0
doc/gui/examples/controls/toggle_list_tuples/markdown.py

@@ -0,0 +1,31 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+from taipy.gui import Gui, Icon
+
+lov = [
+    ("id1", "Label 1"),
+    ("id2", Icon("https://docs.taipy.io/en/latest/assets/images/favicon.png", "Taipy Logo"), "Label 2"),
+    ("id3", "Label 3"),
+]
+value = lov[0]
+
+page = """<|{value}|toggle|lov={lov}|>
+Value: <|"{value[1].text if isinstance(value[1], Icon) else value[1]}"|>
+"""
+
+
+if __name__ == "__main__":
+    Gui(page).run(title="Toggle - List tuples")

+ 44 - 0
doc/gui/examples/controls/toggle_objects.py

@@ -0,0 +1,44 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+from dataclasses import dataclass
+
+from taipy.gui import Gui
+
+
+@dataclass
+class User:
+    id: int
+    name: str
+    birth_year: int
+
+users = [
+    User(231, "Johanna", 1987),
+    User(125, "John", 1979),
+    User(4,   "Peter", 1968),
+    User(31,  "Mary", 1974)
+    ]
+
+user_sel = users[2]
+page ="""
+<|{user_sel}|toggle|lov={users}|type=User|adapter={lambda u: (u.id, u.name)}|>
+
+User: <|{user_sel.name}|>
+
+Born in: <|{user_sel.birth_year}|>
+"""
+
+if __name__ == "__main__":
+    Gui(page).run(title="Toggle - Objects")

+ 26 - 0
doc/gui/examples/controls/toggle_simple.py

@@ -0,0 +1,26 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+from taipy.gui import Gui
+
+value = "Item 2"
+
+page = """
+<|{value}|toggle|lov=Item 1;Item 2;Item 3|>
+Value: <|{value}|>
+"""
+
+if __name__ == "__main__":
+    Gui(page).run(title="Toggle - Simple")

+ 38 - 0
doc/gui/examples/controls/toggle_styling.py

@@ -0,0 +1,38 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+from taipy.gui import Gui, Markdown
+
+value = "Item 2"
+
+page = Markdown("<|{value}|toggle|lov=Item 1;Item 2;Item 3|>", style={
+        ".taipy-toggle": {
+            ".MuiList-root": {  # list
+                "height": "70vh",  # limit height
+                "overflow-y": "auto",  # show vertical scroll if necessary
+                ".MuiListItemButton-root:nth-child(even)": {  # change colors
+                    "background-color": "lightgrey",
+                    "color": "darkgrey",
+                },
+                ".MuiListItemButton-root:nth-child(odd)": {
+                    "background-color": "darkgrey",
+                    "color": "lightgrey",
+                },
+            },
+        }
+    },)
+
+if __name__ == "__main__":
+    Gui(page).run(title="Toggle - Styling")

+ 26 - 0
doc/gui/examples/controls/toggle_switch.py

@@ -0,0 +1,26 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+from taipy.gui import Gui
+
+value = True
+
+page = """
+<|{value}|toggle|label=Is this True?|>
+Value: <|{str(value)}|>
+"""
+
+if __name__ == "__main__":
+    Gui(page).run(title="Toggle - Switch")

+ 21 - 0
doc/gui/examples/controls/toggle_theme.py

@@ -0,0 +1,21 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+from taipy.gui import Gui
+
+page = "<|toggle|theme|>"
+
+if __name__ == "__main__":
+    Gui(page).run(title="Toggle - Theme")

+ 26 - 0
doc/gui/examples/controls/toggle_unselect.py

@@ -0,0 +1,26 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+from taipy.gui import Gui
+
+value = "Item 2"
+
+page = """
+<|{value}|toggle|lov=Item 1;Item 2;Item 3|unselected_value=No Value|allow_unselect|>
+Value: <|{value}|>
+"""
+
+if __name__ == "__main__":
+    Gui(page).run(title="Toggle - Unselect")

+ 156 - 156
frontend/taipy-gui/package-lock.json

@@ -105,11 +105,11 @@
       }
     },
     "node_modules/@babel/code-frame": {
-      "version": "7.24.7",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
-      "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz",
+      "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==",
       "dependencies": {
-        "@babel/highlight": "^7.24.7",
+        "@babel/highlight": "^7.25.7",
         "picocolors": "^1.0.0"
       },
       "engines": {
@@ -117,30 +117,30 @@
       }
     },
     "node_modules/@babel/compat-data": {
-      "version": "7.25.4",
-      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz",
-      "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.7.tgz",
+      "integrity": "sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/core": {
-      "version": "7.25.2",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz",
-      "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.7.tgz",
+      "integrity": "sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow==",
       "dev": true,
       "dependencies": {
         "@ampproject/remapping": "^2.2.0",
-        "@babel/code-frame": "^7.24.7",
-        "@babel/generator": "^7.25.0",
-        "@babel/helper-compilation-targets": "^7.25.2",
-        "@babel/helper-module-transforms": "^7.25.2",
-        "@babel/helpers": "^7.25.0",
-        "@babel/parser": "^7.25.0",
-        "@babel/template": "^7.25.0",
-        "@babel/traverse": "^7.25.2",
-        "@babel/types": "^7.25.2",
+        "@babel/code-frame": "^7.25.7",
+        "@babel/generator": "^7.25.7",
+        "@babel/helper-compilation-targets": "^7.25.7",
+        "@babel/helper-module-transforms": "^7.25.7",
+        "@babel/helpers": "^7.25.7",
+        "@babel/parser": "^7.25.7",
+        "@babel/template": "^7.25.7",
+        "@babel/traverse": "^7.25.7",
+        "@babel/types": "^7.25.7",
         "convert-source-map": "^2.0.0",
         "debug": "^4.1.0",
         "gensync": "^1.0.0-beta.2",
@@ -171,28 +171,28 @@
       }
     },
     "node_modules/@babel/generator": {
-      "version": "7.25.6",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz",
-      "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz",
+      "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==",
       "dependencies": {
-        "@babel/types": "^7.25.6",
+        "@babel/types": "^7.25.7",
         "@jridgewell/gen-mapping": "^0.3.5",
         "@jridgewell/trace-mapping": "^0.3.25",
-        "jsesc": "^2.5.1"
+        "jsesc": "^3.0.2"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-compilation-targets": {
-      "version": "7.25.2",
-      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz",
-      "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz",
+      "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==",
       "dev": true,
       "dependencies": {
-        "@babel/compat-data": "^7.25.2",
-        "@babel/helper-validator-option": "^7.24.8",
-        "browserslist": "^4.23.1",
+        "@babel/compat-data": "^7.25.7",
+        "@babel/helper-validator-option": "^7.25.7",
+        "browserslist": "^4.24.0",
         "lru-cache": "^5.1.1",
         "semver": "^6.3.1"
       },
@@ -210,27 +210,27 @@
       }
     },
     "node_modules/@babel/helper-module-imports": {
-      "version": "7.24.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
-      "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz",
+      "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==",
       "dependencies": {
-        "@babel/traverse": "^7.24.7",
-        "@babel/types": "^7.24.7"
+        "@babel/traverse": "^7.25.7",
+        "@babel/types": "^7.25.7"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-module-transforms": {
-      "version": "7.25.2",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz",
-      "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz",
+      "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-module-imports": "^7.24.7",
-        "@babel/helper-simple-access": "^7.24.7",
-        "@babel/helper-validator-identifier": "^7.24.7",
-        "@babel/traverse": "^7.25.2"
+        "@babel/helper-module-imports": "^7.25.7",
+        "@babel/helper-simple-access": "^7.25.7",
+        "@babel/helper-validator-identifier": "^7.25.7",
+        "@babel/traverse": "^7.25.7"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -240,71 +240,71 @@
       }
     },
     "node_modules/@babel/helper-plugin-utils": {
-      "version": "7.24.8",
-      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz",
-      "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz",
+      "integrity": "sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-simple-access": {
-      "version": "7.24.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz",
-      "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz",
+      "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==",
       "dev": true,
       "dependencies": {
-        "@babel/traverse": "^7.24.7",
-        "@babel/types": "^7.24.7"
+        "@babel/traverse": "^7.25.7",
+        "@babel/types": "^7.25.7"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-string-parser": {
-      "version": "7.24.8",
-      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
-      "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz",
+      "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==",
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.24.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
-      "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz",
+      "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==",
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-validator-option": {
-      "version": "7.24.8",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz",
-      "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz",
+      "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helpers": {
-      "version": "7.25.6",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz",
-      "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz",
+      "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==",
       "dev": true,
       "dependencies": {
-        "@babel/template": "^7.25.0",
-        "@babel/types": "^7.25.6"
+        "@babel/template": "^7.25.7",
+        "@babel/types": "^7.25.7"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/highlight": {
-      "version": "7.24.7",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
-      "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz",
+      "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==",
       "dependencies": {
-        "@babel/helper-validator-identifier": "^7.24.7",
+        "@babel/helper-validator-identifier": "^7.25.7",
         "chalk": "^2.4.2",
         "js-tokens": "^4.0.0",
         "picocolors": "^1.0.0"
@@ -314,11 +314,11 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.25.6",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
-      "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.7.tgz",
+      "integrity": "sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==",
       "dependencies": {
-        "@babel/types": "^7.25.6"
+        "@babel/types": "^7.25.7"
       },
       "bin": {
         "parser": "bin/babel-parser.js"
@@ -379,12 +379,12 @@
       }
     },
     "node_modules/@babel/plugin-syntax-import-attributes": {
-      "version": "7.25.6",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz",
-      "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.7.tgz",
+      "integrity": "sha512-AqVo+dguCgmpi/3mYBdu9lkngOBlQ2w2vnNpa6gfiCxQZLzV4ZbhsXitJ2Yblkoe1VQwtHSaNmIaGll/26YWRw==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.24.8"
+        "@babel/helper-plugin-utils": "^7.25.7"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -418,12 +418,12 @@
       }
     },
     "node_modules/@babel/plugin-syntax-jsx": {
-      "version": "7.24.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz",
-      "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.7.tgz",
+      "integrity": "sha512-ruZOnKO+ajVL/MVx+PwNBPOkrnXTXoWMtte1MBpegfCArhqOe3Bj52avVj1huLLxNKYKXYaSxZ2F+woK1ekXfw==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.24.7"
+        "@babel/helper-plugin-utils": "^7.25.7"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -535,12 +535,12 @@
       }
     },
     "node_modules/@babel/plugin-syntax-typescript": {
-      "version": "7.25.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz",
-      "integrity": "sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.7.tgz",
+      "integrity": "sha512-rR+5FDjpCHqqZN2bzZm18bVYGaejGq5ZkpVCJLXor/+zlSrSoc4KWcHI0URVWjl/68Dyr1uwZUz/1njycEAv9g==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.24.8"
+        "@babel/helper-plugin-utils": "^7.25.7"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -550,9 +550,9 @@
       }
     },
     "node_modules/@babel/runtime": {
-      "version": "7.25.6",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz",
-      "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz",
+      "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==",
       "dependencies": {
         "regenerator-runtime": "^0.14.0"
       },
@@ -561,28 +561,28 @@
       }
     },
     "node_modules/@babel/template": {
-      "version": "7.25.0",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz",
-      "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz",
+      "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==",
       "dependencies": {
-        "@babel/code-frame": "^7.24.7",
-        "@babel/parser": "^7.25.0",
-        "@babel/types": "^7.25.0"
+        "@babel/code-frame": "^7.25.7",
+        "@babel/parser": "^7.25.7",
+        "@babel/types": "^7.25.7"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/traverse": {
-      "version": "7.25.6",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz",
-      "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==",
-      "dependencies": {
-        "@babel/code-frame": "^7.24.7",
-        "@babel/generator": "^7.25.6",
-        "@babel/parser": "^7.25.6",
-        "@babel/template": "^7.25.0",
-        "@babel/types": "^7.25.6",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz",
+      "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==",
+      "dependencies": {
+        "@babel/code-frame": "^7.25.7",
+        "@babel/generator": "^7.25.7",
+        "@babel/parser": "^7.25.7",
+        "@babel/template": "^7.25.7",
+        "@babel/types": "^7.25.7",
         "debug": "^4.3.1",
         "globals": "^11.1.0"
       },
@@ -591,12 +591,12 @@
       }
     },
     "node_modules/@babel/types": {
-      "version": "7.25.6",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
-      "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.7.tgz",
+      "integrity": "sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==",
       "dependencies": {
-        "@babel/helper-string-parser": "^7.24.8",
-        "@babel/helper-validator-identifier": "^7.24.7",
+        "@babel/helper-string-parser": "^7.25.7",
+        "@babel/helper-validator-identifier": "^7.25.7",
         "to-fast-properties": "^2.0.0"
       },
       "engines": {
@@ -1890,18 +1890,18 @@
       "dev": true
     },
     "node_modules/@mui/core-downloads-tracker": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.1.tgz",
-      "integrity": "sha512-VdQC1tPIIcZAnf62L2M1eQif0x2vlKg3YK4kGYbtijSH4niEgI21GnstykW1vQIs+Bc6L+Hua2GATYVjilJ22A==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.2.tgz",
+      "integrity": "sha512-1oE4U38/TtzLWRYWEm/m70dUbpcvBx0QvDVg6NtpOmSNQC1Mbx0X/rNvYDdZnn8DIsAiVQ+SZ3am6doSswUQ4g==",
       "funding": {
         "type": "opencollective",
         "url": "https://opencollective.com/mui-org"
       }
     },
     "node_modules/@mui/icons-material": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.1.1.tgz",
-      "integrity": "sha512-sy/YKwcLPW8VcacNP2uWMYR9xyWuwO9NN9FXuGEU90bRshBXj8pdKk+joe3TCW7oviVS3zXLHlc94wQ0jNsQRQ==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.1.2.tgz",
+      "integrity": "sha512-7NNcjW5JoT9jHagrVbARA1o41vQY2xezDamtke+mEKKZmsJyejfRBOacSrPDfjZQ//lyhIjNKyzAwisxYJR47w==",
       "dependencies": {
         "@babel/runtime": "^7.25.6"
       },
@@ -1913,7 +1913,7 @@
         "url": "https://opencollective.com/mui-org"
       },
       "peerDependencies": {
-        "@mui/material": "^6.1.1",
+        "@mui/material": "^6.1.2",
         "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
         "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
       },
@@ -1924,15 +1924,15 @@
       }
     },
     "node_modules/@mui/material": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.1.tgz",
-      "integrity": "sha512-b+eULldTqtqTCbN++2BtBWCir/1LwEYw+2mIlOt2GiEUh1EBBw4/wIukGKKNt3xrCZqRA80yLLkV6tF61Lq3cA==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.2.tgz",
+      "integrity": "sha512-5TtHeAVX9D5d2LYfB1GAUn29BcVETVsrQ76Dwb2SpAfQGW3JVy4deJCAd0RrIkI3eEUrsl0E4xuBdreszxdTTg==",
       "dependencies": {
         "@babel/runtime": "^7.25.6",
-        "@mui/core-downloads-tracker": "^6.1.1",
-        "@mui/system": "^6.1.1",
+        "@mui/core-downloads-tracker": "^6.1.2",
+        "@mui/system": "^6.1.2",
         "@mui/types": "^7.2.17",
-        "@mui/utils": "^6.1.1",
+        "@mui/utils": "^6.1.2",
         "@popperjs/core": "^2.11.8",
         "@types/react-transition-group": "^4.4.11",
         "clsx": "^2.1.1",
@@ -1951,7 +1951,7 @@
       "peerDependencies": {
         "@emotion/react": "^11.5.0",
         "@emotion/styled": "^11.3.0",
-        "@mui/material-pigment-css": "^6.1.1",
+        "@mui/material-pigment-css": "^6.1.2",
         "@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"
@@ -1972,12 +1972,12 @@
       }
     },
     "node_modules/@mui/private-theming": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.1.tgz",
-      "integrity": "sha512-JlrjIdhyZUtewtdAuUsvi3ZnO0YS49IW4Mfz19ZWTlQ0sDGga6LNPVwHClWr2/zJK2we2BQx9/i8M32rgKuzrg==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.2.tgz",
+      "integrity": "sha512-S8WcjZdNdi++8UhrrY8Lton5h/suRiQexvdTfdcPAlbajlvgM+kx+uJstuVIEyTb3gMkxzIZep87knZ0tqcR0g==",
       "dependencies": {
         "@babel/runtime": "^7.25.6",
-        "@mui/utils": "^6.1.1",
+        "@mui/utils": "^6.1.2",
         "prop-types": "^15.8.1"
       },
       "engines": {
@@ -1998,9 +1998,9 @@
       }
     },
     "node_modules/@mui/styled-engine": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.1.tgz",
-      "integrity": "sha512-HJyIoMpFb11fnHuRtUILOXgq6vj4LhIlE8maG4SwP/W+E5sa7HFexhnB3vOMT7bKys4UKNxhobC8jwWxYilGsA==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.2.tgz",
+      "integrity": "sha512-uKOfWkR23X39xj7th2nyTcCHqInTAXtUnqD3T5qRVdJcOPvu1rlgTleTwJC/FJvWZJBU6ieuTWDhbcx5SNViHQ==",
       "dependencies": {
         "@babel/runtime": "^7.25.6",
         "@emotion/cache": "^11.13.1",
@@ -2030,15 +2030,15 @@
       }
     },
     "node_modules/@mui/system": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.1.tgz",
-      "integrity": "sha512-PaYsCz2tUOcpu3T0okDEsSuP/yCDIj9JZ4Tox1JovRSKIjltHpXPsXZSGr3RiWdtM1MTQMFMCZzu0+CKbyy+Kw==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.2.tgz",
+      "integrity": "sha512-mzW7F1ZMIYS1aLON48Nrk9c65OrVEVQ+R4lUcTWs1lCSul0VGK23eo4dmY0NX5PS7Oe4xz3P5B9tQZZ7SYgxcg==",
       "dependencies": {
         "@babel/runtime": "^7.25.6",
-        "@mui/private-theming": "^6.1.1",
-        "@mui/styled-engine": "^6.1.1",
+        "@mui/private-theming": "^6.1.2",
+        "@mui/styled-engine": "^6.1.2",
         "@mui/types": "^7.2.17",
-        "@mui/utils": "^6.1.1",
+        "@mui/utils": "^6.1.2",
         "clsx": "^2.1.1",
         "csstype": "^3.1.3",
         "prop-types": "^15.8.1"
@@ -2082,13 +2082,13 @@
       }
     },
     "node_modules/@mui/utils": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.1.tgz",
-      "integrity": "sha512-HlRrgdJSPbYDXPpoVMWZV8AE7WcFtAk13rWNWAEVWKSanzBBkymjz3km+Th/Srowsh4pf1fTSP1B0L116wQBYw==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.2.tgz",
+      "integrity": "sha512-6+B1YZ8cCBWD1fc3RjqpclF9UA0MLUiuXhyCO+XowD/Z2ku5IlxeEhHHlgglyBWFGMu4kib4YU3CDsG5/zVjJQ==",
       "dependencies": {
         "@babel/runtime": "^7.25.6",
         "@mui/types": "^7.2.17",
-        "@types/prop-types": "^15.7.12",
+        "@types/prop-types": "^15.7.13",
         "clsx": "^2.1.1",
         "prop-types": "^15.8.1",
         "react-is": "^18.3.1"
@@ -3063,9 +3063,9 @@
       "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="
     },
     "node_modules/@types/lodash": {
-      "version": "4.17.9",
-      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.9.tgz",
-      "integrity": "sha512-w9iWudx1XWOHW5lQRS9iKpK/XuRhnN+0T7HvdCCd802FYkT1AMTnxndJHGrNJwRoRHkslGr4S29tjm1cT7x/7w==",
+      "version": "4.17.10",
+      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.10.tgz",
+      "integrity": "sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ==",
       "dev": true
     },
     "node_modules/@types/mapbox__point-geometry": {
@@ -3126,9 +3126,9 @@
       "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA=="
     },
     "node_modules/@types/react": {
-      "version": "18.3.10",
-      "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.10.tgz",
-      "integrity": "sha512-02sAAlBnP39JgXwkAq3PeU9DVaaGpZyF3MGcC0MKgQVkZor5IiiDAipVaxQHtDJAmO4GIy/rVBy/LzVj76Cyqg==",
+      "version": "18.3.11",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz",
+      "integrity": "sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==",
       "dependencies": {
         "@types/prop-types": "*",
         "csstype": "^3.0.2"
@@ -11056,14 +11056,14 @@
       }
     },
     "node_modules/jsesc": {
-      "version": "2.5.2",
-      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
-      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
+      "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
       "bin": {
         "jsesc": "bin/jsesc"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=6"
       }
     },
     "node_modules/json-bignum": {
@@ -13854,21 +13854,21 @@
       "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
     },
     "node_modules/regex": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/regex/-/regex-4.3.2.tgz",
-      "integrity": "sha512-kK/AA3A9K6q2js89+VMymcboLOlF5lZRCYJv3gzszXFHBr6kO6qLGzbm+UIugBEV8SMMKCTR59txoY6ctRHYVw==",
+      "version": "4.3.3",
+      "resolved": "https://registry.npmjs.org/regex/-/regex-4.3.3.tgz",
+      "integrity": "sha512-r/AadFO7owAq1QJVeZ/nq9jNS1vyZt+6t1p/E59B56Rn2GCya+gr1KSyOzNL/er+r+B7phv5jG2xU2Nz1YkmJg==",
       "dev": true
     },
     "node_modules/regexp.prototype.flags": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
-      "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==",
+      "version": "1.5.3",
+      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz",
+      "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.6",
+        "call-bind": "^1.0.7",
         "define-properties": "^1.2.1",
         "es-errors": "^1.3.0",
-        "set-function-name": "^2.0.1"
+        "set-function-name": "^2.0.2"
       },
       "engines": {
         "node": ">= 0.4"

+ 0 - 19
frontend/taipy-gui/packaging/taipy-gui.d.ts

@@ -324,25 +324,6 @@ export declare const createRequestUpdateAction: (
     stateContext?: Record<string, unknown>
 ) => Action;
 
-/**
- * Broadcast stack definition.
- */
-export interface BroadcastDesc {
-    /** Name of the broadcast. */
-    name: string;
-    /** Broadcast stack */
-    stack: Array<unknown>;
-}
-
-/**
- * Create an *un broadcast* `Action` that will be used to update local state.
- *
- * This action will remove a value from a broadcasted stacked variable identified by name.
- * @param name - The name of the variable identifying the broadcast.
- * @param values - The values to remove.
- * @returns The action fed to the reducer.
- */
-export declare const createUnBroadcastAction: (name: string, ...values: Array<unknown>) => Action;
 /**
  * A column description as received by the backend.
  */

+ 0 - 25
frontend/taipy-gui/src/context/taipyReducers.spec.ts

@@ -16,7 +16,6 @@ import {
     addRows,
     AlertMessage,
     BlockMessage,
-    BroadcastDesc,
     createAckAction,
     createAlertAction,
     createBlockAction,
@@ -31,7 +30,6 @@ import {
     createRequestUpdateAction,
     createSendActionNameAction,
     createSendUpdateAction,
-    createUnBroadcastAction,
     FileDownloadProps,
     getPayload,
     getWsMessageListener,
@@ -209,29 +207,6 @@ describe("reducer", () => {
         expect(createAlertAction({ atype: "sUc", message: "message" } as AlertMessage).atype).toBe("success");
         expect(createAlertAction({ atype: "  ", message: "message" } as AlertMessage).atype).toBe("");
     });
-    it("creates a broadcast action", () => {
-        expect(
-            (
-                taipyReducer({ ...INITIAL_STATE }, {
-                    type: "BROADCAST",
-                    name: "broadcast",
-                    payload: { value: 1 },
-                } as TaipyBaseAction).data.broadcast as BroadcastDesc
-            ).stack
-        ).toHaveLength(1);
-    });
-    it("un broadcast", () => {
-        const value = { scenario: "scenario id" };
-        const broadcastState = taipyReducer({ ...INITIAL_STATE }, {
-            type: "BROADCAST",
-            name: "broadcast",
-            payload: { value },
-        } as TaipyBaseAction);
-        expect(
-            (taipyReducer(broadcastState, createUnBroadcastAction("broadcast", value)).data.broadcast as BroadcastDesc)
-                .stack
-        ).toHaveLength(0);
-    });
 });
 
 describe("storeBlockUi function", () => {

+ 24 - 57
frontend/taipy-gui/src/context/taipyReducers.ts

@@ -47,7 +47,6 @@ export enum Types {
     Partial = "PARTIAL",
     Acknowledgement = "ACKNOWLEDGEMENT",
     Broadcast = "BROADCAST",
-    UnBroadcast = "UNBROADCAST",
 }
 
 /**
@@ -158,16 +157,6 @@ export interface FormatConfig {
     number: string;
 }
 
-/**
- * Broadcast stack definition.
- */
-export interface BroadcastDesc {
-    /** Name of the variable identifying the broadcast. */
-    name: string;
-    /** Broadcast stack. */
-    stack: Array<unknown>;
-}
-
 const getUserTheme = (mode: PaletteMode) => {
     const tkTheme = (window.taipyConfig?.stylekit && stylekitTheme) || {};
     const tkModeTheme = (window.taipyConfig?.stylekit && stylekitModeThemes[mode]) || {};
@@ -243,7 +232,7 @@ export const messageToAction = (message: WsMessage) => {
         } else if (message.type === "FV") {
             changeFavicon((message.payload as Record<string, string>)?.value);
         } else if (message.type == "BC") {
-            return createBroadcastAction(message as unknown as NamePayload);
+            stackBroadcast((message as NamePayload).name, (message as NamePayload).payload.value);
         }
     }
     return {} as TaipyBaseAction;
@@ -254,8 +243,8 @@ export const getWsMessageListener = (dispatch: Dispatch<TaipyBaseAction>) => {
         if (message.type === "MU" && Array.isArray(message.payload)) {
             const payloads = message.payload as NamePayload[];
             Promise.all(payloads.map((pl) => parseData(pl.payload.value as Record<string, unknown>)))
-                .then((vals) => {
-                    vals.forEach((val, idx) => (payloads[idx].payload.value = val));
+                .then((values) => {
+                    values.forEach((val, idx) => (payloads[idx].payload.value = val));
                     dispatch(messageToAction(message));
                 })
                 .catch(console.warn);
@@ -269,6 +258,24 @@ export const getWsMessageListener = (dispatch: Dispatch<TaipyBaseAction>) => {
     return dispatchWsMessage;
 };
 
+// Broadcast
+const __BroadcastRepo: Record<string, Array<unknown>> = {};
+
+const stackBroadcast = (name: string, value: unknown) => (__BroadcastRepo[name] = __BroadcastRepo[name] || []).push(value);
+
+const broadcast_timeout = 250;
+
+const initializeBroadcastManagement = (dispatch: Dispatch<TaipyBaseAction>) => {
+    setInterval(() => {
+        Object.entries(__BroadcastRepo).forEach(([name, stack]) => {
+            const broadcastValue = stack.shift();
+            if (broadcastValue !== undefined) {
+                dispatch(createUpdateAction({ name, payload: { value: broadcastValue } }));
+            }
+        });
+    }, broadcast_timeout);
+};
+
 export const initializeWebSocket = (socket: Socket | undefined, dispatch: Dispatch<TaipyBaseAction>): void => {
     if (socket) {
         // Websocket confirm successful initialization
@@ -294,7 +301,10 @@ export const initializeWebSocket = (socket: Socket | undefined, dispatch: Dispat
         socket.on("message", getWsMessageListener(dispatch));
         // only now does the socket tries to open/connect
         socket.connect();
+        // favicon
         changeFavicon();
+        // broadcast
+        initializeBroadcastManagement(dispatch);
     }
 };
 
@@ -356,30 +366,6 @@ export const taipyReducer = (state: TaipyState, baseAction: TaipyBaseAction): Ta
                         : newValue,
                 },
             };
-        case Types.Broadcast:
-            return {
-                ...state,
-                data: {
-                    ...state.data,
-                    [action.name]: {
-                        name: action.name,
-                        stack: [...((state.data[action.name] || {stack: []}) as BroadcastDesc).stack , action.payload.value],
-                    },
-                },
-            };
-        case Types.UnBroadcast:
-            return {
-                ...state,
-                data: {
-                    ...state.data,
-                    [action.name]: {
-                        name: action.name,
-                        stack: ((state.data[action.name] || {stack: []}) as BroadcastDesc).stack.filter(
-                            (v) => !(action.payload.value as Array<unknown>).includes(v)
-                        ),
-                    },
-                },
-            };
         case Types.SetLocations:
             return { ...state, locations: action.payload.value as Record<string, string> };
         case Types.SetAlert:
@@ -523,25 +509,6 @@ export const createUpdateAction = (payload: NamePayload): TaipyAction => ({
     type: Types.Update,
 });
 
-export const createBroadcastAction = (payload: NamePayload): TaipyAction => ({
-    ...payload,
-    type: Types.Broadcast,
-});
-
-/**
- * Create an *un broadcast* `Action` that will be used to update local state.
- *
- * This action will remove a value from a broadcasted stacked variable identified by name.
- * @param name - The name of the variable identifying the broadcast.
- * @param values - The values to remove.
- * @returns The action fed to the reducer.
- */
-export const createUnBroadcastAction = (name: string, ...values: Array<unknown>): TaipyAction => ({
-    type: Types.UnBroadcast,
-    name,
-    payload: getPayload(values),
-});
-
 export const createMultipleUpdateAction = (payload: NamePayload[]): TaipyMultipleAction => ({
     type: Types.MultipleUpdate,
     payload: payload,

+ 0 - 4
frontend/taipy-gui/src/extensions/exports.ts

@@ -40,8 +40,6 @@ import {
     createSendUpdateAction,
     createRequestDataUpdateAction,
     createRequestUpdateAction,
-    createUnBroadcastAction,
-    BroadcastDesc
 } from "../context/taipyReducers";
 
 export {
@@ -55,7 +53,6 @@ export {
     TableSort,
     Metric,
     TaipyContext as Context,
-    createUnBroadcastAction,
     createRequestDataUpdateAction,
     createRequestUpdateAction,
     createSendActionNameAction,
@@ -71,7 +68,6 @@ export {
 };
 
 export type {
-    BroadcastDesc,
     ColumnDesc,
     FilterDesc,
     LoV,

+ 94 - 95
frontend/taipy/package-lock.json

@@ -41,15 +41,14 @@
       }
     },
     "../../taipy/gui/webapp": {
-      "name": "taipy-gui",
       "version": "4.0.0"
     },
     "node_modules/@babel/code-frame": {
-      "version": "7.24.7",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
-      "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz",
+      "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==",
       "dependencies": {
-        "@babel/highlight": "^7.24.7",
+        "@babel/highlight": "^7.25.7",
         "picocolors": "^1.0.0"
       },
       "engines": {
@@ -57,53 +56,53 @@
       }
     },
     "node_modules/@babel/generator": {
-      "version": "7.25.6",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz",
-      "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz",
+      "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==",
       "dependencies": {
-        "@babel/types": "^7.25.6",
+        "@babel/types": "^7.25.7",
         "@jridgewell/gen-mapping": "^0.3.5",
         "@jridgewell/trace-mapping": "^0.3.25",
-        "jsesc": "^2.5.1"
+        "jsesc": "^3.0.2"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-module-imports": {
-      "version": "7.24.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
-      "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz",
+      "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==",
       "dependencies": {
-        "@babel/traverse": "^7.24.7",
-        "@babel/types": "^7.24.7"
+        "@babel/traverse": "^7.25.7",
+        "@babel/types": "^7.25.7"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-string-parser": {
-      "version": "7.24.8",
-      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
-      "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz",
+      "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==",
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.24.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
-      "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz",
+      "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==",
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/highlight": {
-      "version": "7.24.7",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
-      "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz",
+      "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==",
       "dependencies": {
-        "@babel/helper-validator-identifier": "^7.24.7",
+        "@babel/helper-validator-identifier": "^7.25.7",
         "chalk": "^2.4.2",
         "js-tokens": "^4.0.0",
         "picocolors": "^1.0.0"
@@ -113,11 +112,11 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.25.6",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
-      "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.7.tgz",
+      "integrity": "sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==",
       "dependencies": {
-        "@babel/types": "^7.25.6"
+        "@babel/types": "^7.25.7"
       },
       "bin": {
         "parser": "bin/babel-parser.js"
@@ -127,9 +126,9 @@
       }
     },
     "node_modules/@babel/runtime": {
-      "version": "7.25.6",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz",
-      "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz",
+      "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==",
       "dependencies": {
         "regenerator-runtime": "^0.14.0"
       },
@@ -138,28 +137,28 @@
       }
     },
     "node_modules/@babel/template": {
-      "version": "7.25.0",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz",
-      "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz",
+      "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==",
       "dependencies": {
-        "@babel/code-frame": "^7.24.7",
-        "@babel/parser": "^7.25.0",
-        "@babel/types": "^7.25.0"
+        "@babel/code-frame": "^7.25.7",
+        "@babel/parser": "^7.25.7",
+        "@babel/types": "^7.25.7"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/traverse": {
-      "version": "7.25.6",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz",
-      "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==",
-      "dependencies": {
-        "@babel/code-frame": "^7.24.7",
-        "@babel/generator": "^7.25.6",
-        "@babel/parser": "^7.25.6",
-        "@babel/template": "^7.25.0",
-        "@babel/types": "^7.25.6",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz",
+      "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==",
+      "dependencies": {
+        "@babel/code-frame": "^7.25.7",
+        "@babel/generator": "^7.25.7",
+        "@babel/parser": "^7.25.7",
+        "@babel/template": "^7.25.7",
+        "@babel/types": "^7.25.7",
         "debug": "^4.3.1",
         "globals": "^11.1.0"
       },
@@ -168,12 +167,12 @@
       }
     },
     "node_modules/@babel/types": {
-      "version": "7.25.6",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
-      "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
+      "version": "7.25.7",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.7.tgz",
+      "integrity": "sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==",
       "dependencies": {
-        "@babel/helper-string-parser": "^7.24.8",
-        "@babel/helper-validator-identifier": "^7.24.7",
+        "@babel/helper-string-parser": "^7.25.7",
+        "@babel/helper-validator-identifier": "^7.25.7",
         "to-fast-properties": "^2.0.0"
       },
       "engines": {
@@ -665,18 +664,18 @@
       "dev": true
     },
     "node_modules/@mui/core-downloads-tracker": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.1.tgz",
-      "integrity": "sha512-VdQC1tPIIcZAnf62L2M1eQif0x2vlKg3YK4kGYbtijSH4niEgI21GnstykW1vQIs+Bc6L+Hua2GATYVjilJ22A==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.2.tgz",
+      "integrity": "sha512-1oE4U38/TtzLWRYWEm/m70dUbpcvBx0QvDVg6NtpOmSNQC1Mbx0X/rNvYDdZnn8DIsAiVQ+SZ3am6doSswUQ4g==",
       "funding": {
         "type": "opencollective",
         "url": "https://opencollective.com/mui-org"
       }
     },
     "node_modules/@mui/icons-material": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.1.1.tgz",
-      "integrity": "sha512-sy/YKwcLPW8VcacNP2uWMYR9xyWuwO9NN9FXuGEU90bRshBXj8pdKk+joe3TCW7oviVS3zXLHlc94wQ0jNsQRQ==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.1.2.tgz",
+      "integrity": "sha512-7NNcjW5JoT9jHagrVbARA1o41vQY2xezDamtke+mEKKZmsJyejfRBOacSrPDfjZQ//lyhIjNKyzAwisxYJR47w==",
       "dependencies": {
         "@babel/runtime": "^7.25.6"
       },
@@ -688,7 +687,7 @@
         "url": "https://opencollective.com/mui-org"
       },
       "peerDependencies": {
-        "@mui/material": "^6.1.1",
+        "@mui/material": "^6.1.2",
         "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
         "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
       },
@@ -699,15 +698,15 @@
       }
     },
     "node_modules/@mui/material": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.1.tgz",
-      "integrity": "sha512-b+eULldTqtqTCbN++2BtBWCir/1LwEYw+2mIlOt2GiEUh1EBBw4/wIukGKKNt3xrCZqRA80yLLkV6tF61Lq3cA==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.2.tgz",
+      "integrity": "sha512-5TtHeAVX9D5d2LYfB1GAUn29BcVETVsrQ76Dwb2SpAfQGW3JVy4deJCAd0RrIkI3eEUrsl0E4xuBdreszxdTTg==",
       "dependencies": {
         "@babel/runtime": "^7.25.6",
-        "@mui/core-downloads-tracker": "^6.1.1",
-        "@mui/system": "^6.1.1",
+        "@mui/core-downloads-tracker": "^6.1.2",
+        "@mui/system": "^6.1.2",
         "@mui/types": "^7.2.17",
-        "@mui/utils": "^6.1.1",
+        "@mui/utils": "^6.1.2",
         "@popperjs/core": "^2.11.8",
         "@types/react-transition-group": "^4.4.11",
         "clsx": "^2.1.1",
@@ -726,7 +725,7 @@
       "peerDependencies": {
         "@emotion/react": "^11.5.0",
         "@emotion/styled": "^11.3.0",
-        "@mui/material-pigment-css": "^6.1.1",
+        "@mui/material-pigment-css": "^6.1.2",
         "@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"
@@ -747,12 +746,12 @@
       }
     },
     "node_modules/@mui/private-theming": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.1.tgz",
-      "integrity": "sha512-JlrjIdhyZUtewtdAuUsvi3ZnO0YS49IW4Mfz19ZWTlQ0sDGga6LNPVwHClWr2/zJK2we2BQx9/i8M32rgKuzrg==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.2.tgz",
+      "integrity": "sha512-S8WcjZdNdi++8UhrrY8Lton5h/suRiQexvdTfdcPAlbajlvgM+kx+uJstuVIEyTb3gMkxzIZep87knZ0tqcR0g==",
       "dependencies": {
         "@babel/runtime": "^7.25.6",
-        "@mui/utils": "^6.1.1",
+        "@mui/utils": "^6.1.2",
         "prop-types": "^15.8.1"
       },
       "engines": {
@@ -773,9 +772,9 @@
       }
     },
     "node_modules/@mui/styled-engine": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.1.tgz",
-      "integrity": "sha512-HJyIoMpFb11fnHuRtUILOXgq6vj4LhIlE8maG4SwP/W+E5sa7HFexhnB3vOMT7bKys4UKNxhobC8jwWxYilGsA==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.2.tgz",
+      "integrity": "sha512-uKOfWkR23X39xj7th2nyTcCHqInTAXtUnqD3T5qRVdJcOPvu1rlgTleTwJC/FJvWZJBU6ieuTWDhbcx5SNViHQ==",
       "dependencies": {
         "@babel/runtime": "^7.25.6",
         "@emotion/cache": "^11.13.1",
@@ -805,15 +804,15 @@
       }
     },
     "node_modules/@mui/system": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.1.tgz",
-      "integrity": "sha512-PaYsCz2tUOcpu3T0okDEsSuP/yCDIj9JZ4Tox1JovRSKIjltHpXPsXZSGr3RiWdtM1MTQMFMCZzu0+CKbyy+Kw==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.2.tgz",
+      "integrity": "sha512-mzW7F1ZMIYS1aLON48Nrk9c65OrVEVQ+R4lUcTWs1lCSul0VGK23eo4dmY0NX5PS7Oe4xz3P5B9tQZZ7SYgxcg==",
       "dependencies": {
         "@babel/runtime": "^7.25.6",
-        "@mui/private-theming": "^6.1.1",
-        "@mui/styled-engine": "^6.1.1",
+        "@mui/private-theming": "^6.1.2",
+        "@mui/styled-engine": "^6.1.2",
         "@mui/types": "^7.2.17",
-        "@mui/utils": "^6.1.1",
+        "@mui/utils": "^6.1.2",
         "clsx": "^2.1.1",
         "csstype": "^3.1.3",
         "prop-types": "^15.8.1"
@@ -857,13 +856,13 @@
       }
     },
     "node_modules/@mui/utils": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.1.tgz",
-      "integrity": "sha512-HlRrgdJSPbYDXPpoVMWZV8AE7WcFtAk13rWNWAEVWKSanzBBkymjz3km+Th/Srowsh4pf1fTSP1B0L116wQBYw==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.2.tgz",
+      "integrity": "sha512-6+B1YZ8cCBWD1fc3RjqpclF9UA0MLUiuXhyCO+XowD/Z2ku5IlxeEhHHlgglyBWFGMu4kib4YU3CDsG5/zVjJQ==",
       "dependencies": {
         "@babel/runtime": "^7.25.6",
         "@mui/types": "^7.2.17",
-        "@types/prop-types": "^15.7.12",
+        "@types/prop-types": "^15.7.13",
         "clsx": "^2.1.1",
         "prop-types": "^15.8.1",
         "react-is": "^18.3.1"
@@ -1292,9 +1291,9 @@
       "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA=="
     },
     "node_modules/@types/react": {
-      "version": "18.3.10",
-      "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.10.tgz",
-      "integrity": "sha512-02sAAlBnP39JgXwkAq3PeU9DVaaGpZyF3MGcC0MKgQVkZor5IiiDAipVaxQHtDJAmO4GIy/rVBy/LzVj76Cyqg==",
+      "version": "18.3.11",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz",
+      "integrity": "sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==",
       "dependencies": {
         "@types/prop-types": "*",
         "csstype": "^3.0.2"
@@ -4140,14 +4139,14 @@
       }
     },
     "node_modules/jsesc": {
-      "version": "2.5.2",
-      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
-      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
+      "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
       "bin": {
         "jsesc": "bin/jsesc"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=6"
       }
     },
     "node_modules/json-buffer": {
@@ -4855,15 +4854,15 @@
       "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
     },
     "node_modules/regexp.prototype.flags": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
-      "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==",
+      "version": "1.5.3",
+      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz",
+      "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.6",
+        "call-bind": "^1.0.7",
         "define-properties": "^1.2.1",
         "es-errors": "^1.3.0",
-        "set-function-name": "^2.0.1"
+        "set-function-name": "^2.0.2"
       },
       "engines": {
         "node": ">= 0.4"

+ 6 - 16
frontend/taipy/src/CoreSelector.tsx

@@ -49,7 +49,6 @@ import {
     TableFilter,
     SortDesc,
     TableSort,
-    createUnBroadcastAction,
 } from "taipy-gui";
 
 import { Cycles, Cycle, DataNodes, NodeType, Scenarios, Scenario, DataNode, Sequence, Sequences } from "./utils/types";
@@ -136,7 +135,7 @@ const CoreItem = (props: {
     return !props.displayCycles && nodeType === NodeType.CYCLE ? (
         <>
             {items
-                ? items.map((item) => (
+                ? items.filter(v=>v).map((item) => (
                       <CoreItem
                           key={item[0]}
                           item={item}
@@ -206,7 +205,7 @@ const CoreItem = (props: {
             sx={nodeType === NodeType.NODE ? undefined : ParentItemSx}
         >
             {items
-                ? items.map((item) => (
+                ? items.filter(v=>v).map((item) => (
                       <CoreItem
                           key={item[0]}
                           item={item}
@@ -432,19 +431,10 @@ const CoreSelector = (props: CoreSelectorProps) => {
 
     // Refresh on broadcast
     useEffect(() => {
-        if (coreChanged?.name) {
-            const toRemove = [...coreChanged.stack]
-                .map((bc) => {
-                    if ((bc as Record<string, unknown>).scenario) {
-                        const updateVar = getUpdateVar(updateVars, lovPropertyName);
-                        updateVar && dispatch(createRequestUpdateAction(id, module, [updateVar], true));
-                        return bc;
-                    }
-                    return undefined;
-                })
-                .filter((v) => v);
-            toRemove.length && dispatch(createUnBroadcastAction(coreChanged.name, ...toRemove));
-        }
+        if (coreChanged?.scenario) {
+            const updateVar = getUpdateVar(updateVars, lovPropertyName);
+            updateVar && dispatch(createRequestUpdateAction(id, module, [updateVar], true));
+    }
     }, [coreChanged, updateVars, module, dispatch, id, lovPropertyName]);
 
     const treeViewSx = useMemo(() => ({ ...BaseTreeViewSx, maxHeight: props.height || "50vh" }), [props.height]);

+ 4 - 14
frontend/taipy/src/DataNodeViewer.tsx

@@ -69,7 +69,6 @@ import {
     useModule,
     Store,
     FileSelector,
-    createUnBroadcastAction,
 } from "taipy-gui";
 
 import { Cycle as CycleIcon, Scenario as ScenarioIcon } from "./icons";
@@ -663,19 +662,10 @@ const DataNodeViewer = (props: DataNodeViewerProps) => {
 
     // Refresh on broadcast
     useEffect(() => {
-        if (coreChanged?.name) {
-            const toRemove = [...coreChanged.stack]
-                .map((bc) => {
-                    const ids = (bc as Record<string, unknown>).datanode;
-                    if ((typeof ids === "string" && ids === dnId) || (Array.isArray(ids) && ids.includes(dnId))) {
-                        props.updateVarName &&
-                            dispatch(createRequestUpdateAction(id, module, [props.updateVarName], true));
-                        return bc;
-                    }
-                    return undefined;
-                })
-                .filter((v) => v);
-            toRemove.length && dispatch(createUnBroadcastAction(coreChanged.name, ...toRemove));
+        const ids = coreChanged?.datanode;
+        if ((typeof ids === "string" && ids === dnId) || (Array.isArray(ids) && ids.includes(dnId))) {
+            props.updateVarName &&
+                dispatch(createRequestUpdateAction(id, module, [props.updateVarName], true));
         }
     }, [coreChanged, props.updateVarName, id, module, dispatch, dnId]);
 

+ 3 - 13
frontend/taipy/src/JobSelector.tsx

@@ -55,7 +55,6 @@ import {
     createRequestUpdateAction,
     createSendActionNameAction,
     createSendUpdateAction,
-    createUnBroadcastAction,
     getUpdateVar,
     useDispatch,
     useDispatchRequestUpdateOnFirstRender,
@@ -779,18 +778,9 @@ const JobSelector = (props: JobSelectorProps) => {
     }, [props.value, props.defaultValue]);
 
     useEffect(() => {
-        if (coreChanged?.name) {
-            const toRemove = [...coreChanged.stack]
-                .map((bc) => {
-                    if ((bc as Record<string, unknown>).jobs) {
-                        const updateVar = getUpdateVar(props.updateVars, "jobs");
-                        updateVar && dispatch(createRequestUpdateAction(id, module, [updateVar], true));
-                        return bc;
-                    }
-                    return undefined;
-                })
-                .filter((v) => v);
-            toRemove.length && dispatch(createUnBroadcastAction(coreChanged.name, ...toRemove));
+        if (coreChanged?.jobs) {
+            const updateVar = getUpdateVar(props.updateVars, "jobs");
+            updateVar && dispatch(createRequestUpdateAction(id, module, [updateVar], true));
         }
     }, [coreChanged, props.updateVars, module, dispatch, id]);
 

+ 2 - 12
frontend/taipy/src/JobViewer.tsx

@@ -22,7 +22,6 @@ import Typography from "@mui/material/Typography";
 import {
     createRequestUpdateAction,
     createSendActionNameAction,
-    createUnBroadcastAction,
     getUpdateVar,
     useDispatch,
     useDispatchRequestUpdateOnFirstRender,
@@ -86,17 +85,8 @@ const JobViewer = (props: JobViewerProps) => {
     );
 
     useEffect(() => {
-        if (coreChanged?.name) {
-            const toRemove = [...coreChanged.stack]
-                .map((bc) => {
-                    if ((bc as Record<string, unknown>).job  == jobId) {
-                        updateVarName && dispatch(createRequestUpdateAction(id, module, [updateVarName], true));
-                        return bc;
-                    }
-                    return undefined;
-                })
-                .filter((v) => v);
-            toRemove.length && dispatch(createUnBroadcastAction(coreChanged.name, ...toRemove));
+        if (coreChanged?.job  == jobId) {
+            updateVarName && dispatch(createRequestUpdateAction(id, module, [updateVarName], true));
         }
     }, [coreChanged, updateVarName, jobId, module, dispatch, id]);
 

+ 7 - 25
frontend/taipy/src/ScenarioDag.tsx

@@ -23,7 +23,6 @@ import {
     createRequestUpdateAction,
     createSendActionNameAction,
     createSendUpdateAction,
-    createUnBroadcastAction,
     getUpdateVar,
     useDispatch,
     useDynamicProperty,
@@ -99,30 +98,13 @@ const ScenarioDag = (props: ScenarioDagProps) => {
 
     // Refresh on broadcast
     useEffect(() => {
-        if (coreChanged?.name) {
-            const toRemove = [...coreChanged.stack]
-                .map((bc) => {
-                    const ids = (bc as Record<string, unknown>).scenario;
-                    if (
-                        typeof ids === "string"
-                            ? ids === scenarioId
-                            : Array.isArray(ids)
-                            ? ids.includes(scenarioId)
-                            : ids
-                    ) {
-                        props.updateVarName &&
-                            dispatch(createRequestUpdateAction(props.id, module, [props.updateVarName], true));
-                        return bc;
-                    }
-                    const tasks = (bc as Record<string, unknown>).tasks;
-                    if (tasks) {
-                        setTaskStatuses(tasks as TaskStatuses);
-                        return bc;
-                    }
-                    return undefined;
-                })
-                .filter((v) => v);
-            toRemove.length && dispatch(createUnBroadcastAction(coreChanged.name, ...toRemove));
+        const ids = coreChanged?.scenario;
+        if (typeof ids === "string" ? ids === scenarioId : Array.isArray(ids) ? ids.includes(scenarioId) : ids) {
+            props.updateVarName && dispatch(createRequestUpdateAction(props.id, module, [props.updateVarName], true));
+        }
+        const tasks = coreChanged?.tasks;
+        if (tasks) {
+            setTaskStatuses(tasks as TaskStatuses);
         }
     }, [coreChanged, props.updateVarName, scenarioId, module, dispatch, props.id]);
 

+ 7 - 18
frontend/taipy/src/ScenarioViewer.tsx

@@ -40,7 +40,6 @@ import deepEqual from "fast-deep-equal/es6";
 import {
     createRequestUpdateAction,
     createSendActionNameAction,
-    createUnBroadcastAction,
     getUpdateVar,
     useDispatch,
     useDynamicProperty,
@@ -604,23 +603,13 @@ const ScenarioViewer = (props: ScenarioViewerProps) => {
 
     // Refresh on broadcast
     useEffect(() => {
-        if (coreChanged?.name) {
-            const toRemove = [...coreChanged.stack]
-                .map((bc) => {
-                    const ids = (bc as Record<string, unknown>).scenario;
-                    if (typeof ids === "string" ? ids === scId : Array.isArray(ids) ? ids.includes(scId) : ids) {
-                        const submission = (bc as Record<string, unknown>).submission
-                        if (typeof submission === "number") {
-                            setSubmissionStatus(submission as number);
-                        }
-                        props.updateVarName &&
-                            dispatch(createRequestUpdateAction(id, module, [props.updateVarName], true));
-                        return bc;
-                    }
-                    return undefined;
-                })
-                .filter((v) => v);
-            toRemove.length && dispatch(createUnBroadcastAction(coreChanged.name, ...toRemove));
+        const ids = coreChanged?.scenario;
+        if (typeof ids === "string" ? ids === scId : Array.isArray(ids) ? ids.includes(scId) : ids) {
+            const submission = coreChanged?.submission;
+            if (typeof submission === "number") {
+                setSubmissionStatus(submission as number);
+            }
+            props.updateVarName && dispatch(createRequestUpdateAction(id, module, [props.updateVarName], true));
         }
     }, [coreChanged, props.updateVarName, id, module, dispatch, scId]);
 

+ 2 - 2
frontend/taipy/src/utils.ts

@@ -14,7 +14,7 @@ import { Theme, alpha } from "@mui/material";
 import { PopoverOrigin } from "@mui/material/Popover";
 import { ReactNode } from "react";
 
-import { BroadcastDesc, getUpdateVar, useDynamicProperty } from "taipy-gui";
+import { getUpdateVar, useDynamicProperty } from "taipy-gui";
 
 
 export interface CoreProps {
@@ -22,7 +22,7 @@ export interface CoreProps {
     updateVarName?: string;
     active?: boolean;
     defaultActive?: boolean;
-    coreChanged?: BroadcastDesc;
+    coreChanged?: Record<string, unknown>;
     error?: string;
     updateVars: string;
     libClassName?: string;

+ 1 - 1
pyproject.toml

@@ -80,7 +80,7 @@ unfixable = []
 [tool.ruff.lint.per-file-ignores]
 "__init__.py" = ["F401", "F403"]  # unused import
 "_init.py" = ["F401", "F403"]  # unused import
-"taipy/config/stubs/pyi_header.py" = ["F401", "F403"]  # unused import
+"taipy/common/config/stubs/pyi_header.py" = ["F401", "F403"]  # unused import
 "taipy/templates/*" = ["F401", "F403", "T201"]  # unused import, `print` found
 "taipy/gui/utils/types.py" = ["B024"] # abstract base class with no abstract methods
 

+ 2 - 2
taipy/__init__.py

@@ -12,8 +12,8 @@
 from importlib.util import find_spec
 
 if find_spec("taipy"):
-    if find_spec("taipy.config"):
-        from taipy.config._init import *
+    if find_spec("taipy.common"):
+        from taipy.common.config._init import *
 
     if find_spec("taipy.gui"):
         from taipy.gui._init import *

+ 4 - 4
taipy/_entrypoint.py

@@ -13,15 +13,15 @@ import os
 import sys
 from importlib.util import find_spec
 
-from taipy._cli._base_cli._taipy_parser import _TaipyParser
+from taipy.common._cli._base_cli._taipy_parser import _TaipyParser
+from taipy.common._cli._create_cli import _CreateCLI
+from taipy.common._cli._help_cli import _HelpCLI
+from taipy.common._cli._run_cli import _RunCLI
 from taipy.core._cli._core_cli_factory import _CoreCLIFactory
 from taipy.core._entity._migrate_cli import _MigrateCLI
 from taipy.core._version._cli._version_cli_factory import _VersionCLIFactory
 from taipy.gui._gui_cli import _GuiCLI
 
-from ._cli._create_cli import _CreateCLI
-from ._cli._help_cli import _HelpCLI
-from ._cli._run_cli import _RunCLI
 from .version import _get_version
 
 

+ 8 - 8
taipy/config/INSTALLATION.md → taipy/common/INSTALLATION.md

@@ -1,28 +1,28 @@
 # Installation
 
-The latest stable version of *taipy-config* can be installed using `pip`:
+The latest stable version of *taipy-common* can be installed using `pip`:
 ```bash
-pip install taipy-config
+pip install taipy-common
 ```
 
 ## Development version
 
-You can install the development version of *taipy-config* with `pip` and `git` directly from the Taipy repository:
+You can install the development version of *taipy-common* with `pip` and `git` directly from the Taipy repository:
 ```bash
 pip install git+https://git@github.com/Avaiga/taipy
 ```
 
 This command installs the development version of *taipy* package in the Python environment with all
-its dependencies, including the *taipy-config* package.
+its dependencies, including the *taipy-common* package.
 
-If you need the source code for *taipy-config* on your system so you can see how things are done or
+If you need the source code for *taipy-common* on your system so you can see how things are done or
 maybe participate in the improvement of the packages, you can clone the GitHub repository:
 
 ```bash
 git clone https://github.com/Avaiga/taipy.git
 ```
 
-This creates the 'taipy' directory holding all the package's source code, and the 'taipy-config'
+This creates the 'taipy' directory holding all the package's source code, and the 'taipy-common'
 source code is in the 'taipy/config' directory.
 
 ## Running the tests
@@ -36,8 +36,8 @@ pip install pipenv
 pipenv install --dev
 ```
 
-Then you can run *taipy-config* tests with the following command:
+Then you can run *taipy-common* tests with the following command:
 
 ```bash
-pipenv run pytest tests/config
+pipenv run pytest tests/common
 ```

+ 0 - 0
taipy/config/LICENSE → taipy/common/LICENSE


+ 64 - 0
taipy/common/README.md

@@ -0,0 +1,64 @@
+# Taipy Common
+
+## License
+Copyright 2021-2024 Avaiga Private Limited
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+[http://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt)
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+specific language governing permissions and limitations under the License.
+
+## Usage
+- [License](#license)
+- [Usage](#usage)
+- [Taipy Common](#what-is-taipy-common)
+- [Installation](#installation)
+- [Contributing](#contributing)
+- [Code of conduct](#code-of-conduct)
+- [Directory Structure](#directory-structure)
+
+## What is Taipy Common
+
+Taipy is a Python library for creating Business Applications. More information on our
+[website](https://www.taipy.io). Taipy is split into multiple packages including *taipy-common* to let users
+install the minimum they need.
+
+Taipy Common is a package designed to have the code that serves as basis for the other Taipy packages,
+including classes and methods to enable logging, cli and users to configure their Taipy application.
+
+More in-depth documentation of taipy can be found [here](https://docs.taipy.io).
+
+## Installation
+
+Want to install *Taipy Common*? Check out our [`INSTALLATION.md`](INSTALLATION.md) file.
+
+## Contributing
+
+Want to help build *Taipy Common*? Check out our [`CONTRIBUTING.md`](../../CONTRIBUTING.md) file.
+
+## Code of conduct
+
+Want to be part of the *Taipy Common* community? Check out our [`CODE_OF_CONDUCT.md`](../../CODE_OF_CONDUCT.md) file.
+
+## Directory Structure
+
+- `taipy/`:
+  - `common/`: Common data structures, types, and functions.
+    - `config/`: Configuration definition, management, and implementation. `taipy.Config` is the main entrypoint for configuring a Taipy Core application.
+      - `_config_comparator/`: Internal package for comparing configurations.
+      - `_serializer/`: Internal package for serializing and deserializing configurations.
+      - `checker/`: Configuration checker and issue collector implementation.
+      - `common/`: Shared data structures, types, and functions.
+      - `exceptions/`: *taipy-common* exceptions.
+      - `global_app/`: `GlobalAppConfig` implementation.
+      - `stubs/`: Helper functions to create the `config.pyi` file.
+      - `INSTALLATION.md`: Instructions to install *taipy-common*.
+      - `LICENSE`: The Apache 2.0 License.
+      - `README.md`: Current file.
+      - `setup.py`: The setup script managing building, distributing, and installing *taipy-common*.
+    - `logger/`: Taipy logger implementation.
+- `tests/`:
+  - `common/`: Tests for the *taipy-common* package.

+ 0 - 0
taipy/_cli/__init__.py → taipy/common/__init__.py


+ 0 - 0
taipy/_cli/_base_cli/__init__.py → taipy/common/_cli/__init__.py


+ 0 - 0
taipy/config/_config_comparator/__init__.py → taipy/common/_cli/_base_cli/__init__.py


+ 1 - 1
taipy/_cli/_base_cli/_abstract_cli.py → taipy/common/_cli/_base_cli/_abstract_cli.py

@@ -14,7 +14,7 @@ from abc import abstractmethod
 from difflib import SequenceMatcher
 from typing import List, Optional
 
-from taipy.logger._taipy_logger import _TaipyLogger
+from taipy.common.logger._taipy_logger import _TaipyLogger
 
 from ._taipy_parser import _TaipyParser
 

+ 0 - 0
taipy/_cli/_base_cli/_taipy_parser.py → taipy/common/_cli/_base_cli/_taipy_parser.py


+ 0 - 0
taipy/_cli/_create_cli.py → taipy/common/_cli/_create_cli.py


+ 0 - 0
taipy/_cli/_help_cli.py → taipy/common/_cli/_help_cli.py


+ 0 - 0
taipy/_cli/_run_cli.py → taipy/common/_cli/_run_cli.py


+ 5 - 8
taipy/config/__init__.py → taipy/common/config/__init__.py

@@ -11,7 +11,7 @@
 
 """# Taipy `config` Package
 
-The `taipy.config` package provides features to configure a Taipy application.
+The `taipy.common.config` package provides features to configure a Taipy application.
 
 Its main class is the `Config^` singleton. It exposes various static methods
 and attributes to configure the Taipy application and retrieve the configuration values.
@@ -19,9 +19,9 @@ and attributes to configure the Taipy application and retrieve the configuration
 !!! example "Standard usage"
 
     ```python
-    from taipy.config import Config
-    from taipy.config import Frequency
-    from taipy.config import Scope
+    from taipy.common.config import Config
+    from taipy.common.config import Frequency
+    from taipy.common.config import Scope
 
     data_node_cfg = Config.configure_data_node("my_data_node", scope=Scope.SCENARIO)
     Config.configure_scenario("my_scenario", additional_data_node_configs=[data_node_cfg], frequency=Frequency.DAILY)
@@ -39,7 +39,7 @@ and attributes to configure the Taipy application and retrieve the configuration
 
 !!! note "`Frequency^` and `Scope^` for scenario and data nodes configurations"
 
-    Besides the `Config^` class which is the main entrypoint, the `taipy.config` package exposes
+    Besides the `Config^` class which is the main entrypoint, the `taipy.common.config` package exposes
     the `Frequency^` and `Scope^` enums that are frequently used to configure data nodes and
     scenarios.
 
@@ -57,9 +57,6 @@ from .common.scope import Scope
 from .global_app.global_app_config import GlobalAppConfig
 from .section import Section
 from .unique_section import UniqueSection
-from .version import _get_version
-
-__version__ = _get_version()
 
 
 def _config_doc(func):

+ 0 - 0
taipy/config/_config.py → taipy/common/config/_config.py


+ 0 - 0
taipy/config/_serializer/__init__.py → taipy/common/config/_config_comparator/__init__.py


+ 0 - 0
taipy/config/_config_comparator/_comparator_result.py → taipy/common/config/_config_comparator/_comparator_result.py


+ 0 - 0
taipy/config/_config_comparator/_config_comparator.py → taipy/common/config/_config_comparator/_config_comparator.py


+ 0 - 0
taipy/config/_init.py → taipy/common/config/_init.py


+ 0 - 0
taipy/config/checker/__init__.py → taipy/common/config/_serializer/__init__.py


+ 2 - 2
taipy/config/_serializer/_base_serializer.py → taipy/common/config/_serializer/_base_serializer.py

@@ -101,9 +101,9 @@ class _BaseSerializer(object):
         for section_name, sect_as_dict in as_dict.items():
             if section_class := cls._section_class.get(section_name, None):
                 if issubclass(section_class, UniqueSection):
-                    config._unique_sections[section_name] = section_class._from_dict(
+                    config._unique_sections[section_name] = section_class._from_dict(  # type: ignore
                         sect_as_dict, None, None
-                    )  # type: ignore
+                    )
                 elif issubclass(section_class, Section):
                     config._sections[section_name] = cls._extract_node(as_dict, section_class, section_name, config)
         return config

+ 0 - 0
taipy/config/_serializer/_json_serializer.py → taipy/common/config/_serializer/_json_serializer.py


+ 0 - 0
taipy/config/_serializer/_toml_serializer.py → taipy/common/config/_serializer/_toml_serializer.py


+ 0 - 0
taipy/config/checker/_checkers/__init__.py → taipy/common/config/checker/__init__.py


+ 0 - 0
taipy/config/checker/_checker.py → taipy/common/config/checker/_checker.py


+ 0 - 0
taipy/config/common/__init__.py → taipy/common/config/checker/_checkers/__init__.py


+ 0 - 0
taipy/config/checker/_checkers/_auth_config_checker.py → taipy/common/config/checker/_checkers/_auth_config_checker.py


+ 8 - 9
taipy/config/checker/_checkers/_config_checker.py → taipy/common/config/checker/_checkers/_config_checker.py

@@ -52,15 +52,14 @@ class _ConfigChecker:
                 f"{config_key} field of {parent_config_class.__name__} `{config_id}` is empty.",
             )
         elif not (
-                (isinstance(config_value, (List, Set)))
-                and all(isinstance(x, child_config_class) for x in config_value)
-            ):
-                self._error(
-                    config_key,
-                    config_value,
-                    f"{config_key} field of {parent_config_class.__name__} `{config_id}` must be populated with a list "
-                    f"of {child_config_class.__name__} objects.",
-                )
+            (isinstance(config_value, (List, Set))) and all(isinstance(x, child_config_class) for x in config_value)
+        ):
+            self._error(
+                config_key,
+                config_value,
+                f"{config_key} field of {parent_config_class.__name__} `{config_id}` must be populated with a list "
+                f"of {child_config_class.__name__} objects.",
+            )
 
     def _check_existing_config_id(self, config):
         if not config.id:

+ 0 - 0
taipy/config/checker/issue.py → taipy/common/config/checker/issue.py


+ 0 - 0
taipy/config/checker/issue_collector.py → taipy/common/config/checker/issue_collector.py


+ 11 - 0
taipy/common/config/common/__init__.py

@@ -0,0 +1,11 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+from .scope import Scope

+ 0 - 0
taipy/config/common/_classproperty.py → taipy/common/config/common/_classproperty.py


+ 0 - 0
taipy/config/common/_config_blocker.py → taipy/common/config/common/_config_blocker.py


+ 0 - 0
taipy/config/common/_repr_enum.py → taipy/common/config/common/_repr_enum.py


+ 0 - 0
taipy/config/common/_template_handler.py → taipy/common/config/common/_template_handler.py


+ 0 - 0
taipy/config/common/_validate_id.py → taipy/common/config/common/_validate_id.py


+ 0 - 0
taipy/config/common/frequency.py → taipy/common/config/common/frequency.py


+ 0 - 0
taipy/config/common/scope.py → taipy/common/config/common/scope.py


+ 0 - 0
taipy/config/common/typing.py → taipy/common/config/common/typing.py


+ 6 - 4
taipy/config/config.py → taipy/common/config/config.py

@@ -262,7 +262,7 @@ class Config:
             else:
                 cls._default_config._unique_sections[default_section.name] = default_section
         elif def_sections := cls._default_config._sections.get(default_section.name, None):
-                def_sections[default_section.id] = default_section
+            def_sections[default_section.id] = default_section
         else:
             cls._default_config._sections[default_section.name] = {default_section.id: default_section}
         cls._serializer._section_class[default_section.name] = default_section.__class__  # type: ignore
@@ -292,9 +292,11 @@ class Config:
     def _override_env_file(cls):
         if cfg_filename := os.environ.get(cls._ENVIRONMENT_VARIABLE_NAME_WITH_CONFIG_PATH):
             if not os.path.exists(cfg_filename):
-                cls.__logger.error(f"File '{cfg_filename}' provided by environment variable "
-                                   f"'{cls._ENVIRONMENT_VARIABLE_NAME_WITH_CONFIG_PATH}' does not exist. "
-                                   f"No configuration will be loaded from environment variable.")
+                cls.__logger.error(
+                    f"File '{cfg_filename}' provided by environment variable "
+                    f"'{cls._ENVIRONMENT_VARIABLE_NAME_WITH_CONFIG_PATH}' does not exist. "
+                    f"No configuration will be loaded from environment variable."
+                )
                 return
             cls.__logger.info(f"Loading configuration provided by environment variable. Filename: '{cfg_filename}'")
             cls._env_file_config = cls._serializer._read(cfg_filename)

+ 1 - 2
taipy/config/config.pyi → taipy/common/config/config.pyi

@@ -8,12 +8,11 @@
 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
-
 import json
 from datetime import timedelta
 from typing import Any, Callable, Dict, List, Optional, Union
 
-from taipy.config._config import _Config
+from taipy.common.config._config import _Config
 from taipy.core.config import CoreSection, DataNodeConfig, JobConfig, ScenarioConfig, TaskConfig
 
 from .checker.issue_collector import IssueCollector

+ 2 - 1
taipy/config/exceptions/__init__.py → taipy/common/config/exceptions/__init__.py

@@ -9,5 +9,6 @@
 # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
 
-"""# Exceptions raised by the `taipy.config` package."""
+"""# Exceptions raised by the `taipy.common.config` package."""
+
 from .exceptions import *

+ 0 - 0
taipy/config/exceptions/exceptions.py → taipy/common/config/exceptions/exceptions.py


+ 0 - 0
taipy/config/global_app/__init__.py → taipy/common/config/global_app/__init__.py


+ 0 - 0
taipy/config/global_app/global_app_config.py → taipy/common/config/global_app/global_app_config.py


+ 0 - 0
taipy/config/section.py → taipy/common/config/section.py


+ 3 - 3
taipy/config/stubs/generate_pyi.py → taipy/common/config/stubs/generate_pyi.py

@@ -141,9 +141,9 @@ def _build_header(filename) -> str:
 
 
 if __name__ == "__main__":
-    header_file = "taipy/config/stubs/pyi_header.py"
+    header_file = "taipy/common/config/stubs/pyi_header.py"
     config_init = Path("taipy/core/config/__init__.py")
-    base_config = "taipy/config/config.py"
+    base_config = "taipy/common/config/config.py"
 
     dn_filename = "taipy/core/config/data_node_config.py"
     job_filename = "taipy/core/config/job_config.py"
@@ -164,5 +164,5 @@ if __name__ == "__main__":
     # Remove the final redundant \n
     pyi = pyi[:-1]
 
-    with open("taipy/config/config.pyi", "w") as f:
+    with open("taipy/common/config/config.pyi", "w") as f:
         f.writelines(pyi)

+ 1 - 2
taipy/config/stubs/pyi_header.py → taipy/common/config/stubs/pyi_header.py

@@ -8,12 +8,11 @@
 # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
-
 import json
 from datetime import timedelta
 from typing import Any, Callable, Dict, List, Optional, Union
 
-from taipy.config._config import _Config
+from taipy.common.config._config import _Config
 from taipy.core.config import CoreSection, DataNodeConfig, JobConfig, ScenarioConfig, TaskConfig
 
 from .checker.issue_collector import IssueCollector

+ 0 - 0
taipy/config/unique_section.py → taipy/common/config/unique_section.py


+ 0 - 0
taipy/logger/__init__.py → taipy/common/logger/__init__.py


+ 0 - 0
taipy/logger/_taipy_logger.py → taipy/common/logger/_taipy_logger.py


+ 8 - 8
taipy/config/package_desc.md → taipy/common/package_desc.md

@@ -16,32 +16,32 @@ and limitations under the License.
 ## What is Taipy Config
 
 Taipy is a Python library for creating Business Applications. More information on our
-[website](https://www.taipy.io). Taipy is split into multiple packages including *taipy-config*
+[website](https://www.taipy.io). Taipy is split into multiple packages including *taipy-common*
 to let users install the minimum they need.
 
 Taipy Config is a package designed to help users configure their Taipy application.
 
 ## Installation
 
-The latest stable version of *taipy-config* is available through *pip*:
+The latest stable version of *taipy-common* is available through *pip*:
 ```bash
-pip install taipy-config
+pip install taipy-common
 ```
 
-You can install the development version of *taipy-config* with *pip* and *git* via the taipy repository:
+You can install the development version of *taipy-common* with *pip* and *git* via the taipy repository:
 ```bash
 pip install git+https://git@github.com/Avaiga/taipy
 ```
 
 This command installs the development version of *taipy* package in the Python environment with all
-its dependencies, including the *taipy-config* package.
+its dependencies, including the *taipy-common* package.
 
-If you need the source code for *taipy-config* on your system so you can see how things are done or
+If you need the source code for *taipy-common* on your system so you can see how things are done or
 maybe participate in the improvement of the packages, you can clone the GitHub repository:
 
 ```bash
 git clone https://github.com/Avaiga/taipy.git
 ```
 
-This creates the 'taipy' directory holding all the package's source code, and the 'taipy-config'
-source code is in the 'taipy/config' directory.
+This creates the 'taipy' directory holding all the package's source code, and the 'taipy-common'
+source code is in the 'taipy/common' directory.

+ 15 - 5
taipy/config/pyproject.toml → taipy/common/pyproject.toml

@@ -3,13 +3,13 @@ requires = ["setuptools>=42", "wheel"]
 build-backend = "setuptools.build_meta"
 
 [project]
-name = "taipy-config"
-description = "A Taipy package dedicated to easily configure a Taipy application."
+name = "taipy-common"
+description = "A Taipy package dedicated to provide common data structures, types, classes and functions."
 readme = "package_desc.md"
 requires-python = ">=3.9"
 license = {text = "Apache License 2.0"}
 authors = [{name = "Avaiga", email = "dev@taipy.io"}]
-keywords = ["taipy-config"]
+keywords = ["taipy-common"]
 classifiers = [
     "Intended Audience :: Developers",
     "License :: OSI Approved :: Apache Software License",
@@ -23,10 +23,20 @@ classifiers = [
 dynamic = ["version", "dependencies"]
 
 [project.optional-dependencies]
-testing = ["pytest>=3.8"]
+testing = ["pytest>=3.9"]
 
 [tool.setuptools.packages]
-find = {include = ["taipy", "taipy.config", "taipy.config.*", "taipy.logger", "taipy.logger.*", "taipy._cli", "taipy._cli.*"]}
+find = {include = [
+    "taipy",
+    "taipy.common",
+    "taipy.common.*",
+    "taipy.common.config",
+    "taipy.common.config.*",
+    "taipy.common.logger",
+    "taipy.common.logger.*",
+    "taipy.common._cli",
+    "taipy.common._cli.*"
+]}
 
 [project.urls]
 homepage = "https://github.com/avaiga/taipy"

+ 8 - 6
taipy/config/setup.py → taipy/common/setup.py

@@ -41,12 +41,14 @@ setup(
     packages=find_namespace_packages(where=".")+ find_packages(
         include=[
             "taipy",
-            "taipy.config",
-            "taipy.config.*",
-            "taipy.logger",
-            "taipy.logger.*",
-            "taipy._cli",
-            "taipy._cli.*"
+            "taipy.common",
+            "taipy.common.*",
+            "taipy.common.config",
+            "taipy.common.config.*",
+            "taipy.common.logger",
+            "taipy.common.logger.*",
+            "taipy.common._cli",
+            "taipy.common._cli.*"
         ]
     ),
     include_package_data=True,

+ 1 - 0
taipy/common/version.json

@@ -0,0 +1 @@
+{"major": 4, "minor": 0, "patch": 0, "ext": "dev4"}

+ 0 - 0
taipy/config/version.py → taipy/common/version.py


+ 0 - 62
taipy/config/README.md

@@ -1,62 +0,0 @@
-# Taipy Config
-
-## License
-Copyright 2021-2024 Avaiga Private Limited
-
-Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
-the License. You may obtain a copy of the License at
-[http://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0.txt)
-
-Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
-an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
-specific language governing permissions and limitations under the License.
-
-## Usage
-- [License](#license)
-- [Usage](#usage)
-- [Taipy Config](#what-is-taipy-config)
-- [Installation](#installation)
-- [Contributing](#contributing)
-- [Code of conduct](#code-of-conduct)
-- [Directory Structure](#directory-structure)
-
-## What is Taipy Config
-
-Taipy is a Python library for creating Business Applications. More information on our
-[website](https://www.taipy.io). Taipy is split into multiple packages including *taipy-config* to let users
-install the minimum they need.
-
-Taipy Config is a package designed to help users configure their Taipy application.
-
-More in-depth documentation of taipy can be found [here](https://docs.taipy.io).
-
-## Installation
-
-Want to install *Taipy Config*? Check out our [`INSTALLATION.md`](INSTALLATION.md) file.
-
-## Contributing
-
-Want to help build *Taipy Config*? Check out our [`CONTRIBUTING.md`](../../CONTRIBUTING.md) file.
-
-## Code of conduct
-
-Want to be part of the *Taipy Config* community? Check out our [`CODE_OF_CONDUCT.md`](../../CODE_OF_CONDUCT.md) file.
-
-## Directory Structure
-
-- `taipy/`:
-  - `config/`: Configuration definition, management, and implementation. `taipy.Config` is the main entrypoint for configuring a Taipy Core application.
-    - `_config_comparator/`: Internal package for comparing configurations.
-    - `_serializer/`: Internal package for serializing and deserializing configurations.
-    - `checker/`: Configuration checker and issue collector implementation.
-    - `common/`: Shared data structures, types, and functions.
-    - `exceptions/`: *taipy-config* exceptions.
-    - `global_app/`: `GlobalAppConfig` implementation.
-    - `stubs/`: Helper functions to create the `config.pyi` file.
-    - `INSTALLATION.md`: Instructions to install *taipy-config*.
-    - `LICENSE`: The Apache 2.0 License.
-    - `README.md`: Current file.
-    - `setup.py`: The setup script managing building, distributing, and installing *taipy-config*.
-  - `logger/`: Taipy logger implementation.
-- `tests/`:
-  - `config/`: Tests for the *taipy-config* package.

+ 0 - 1
taipy/config/version.json

@@ -1 +0,0 @@
-{"major": 4, "minor": 0, "patch": 0, "ext": "dev3"}

+ 1 - 1
taipy/core/__init__.py

@@ -23,7 +23,7 @@ into a complete back-end application. In particular, it helps with:
 More details on the Core functionalities are available in the user manual.
 
 To use such functionalities, the first step consists of setting up the Taipy configuration to design
-your application's characteristics and behaviors. Use the `Config^` singleton class (from `taipy.config`)
+your application's characteristics and behaviors. Use the `Config^` singleton class (from `taipy.common.config`)
 to configure your application. Please refer to the
 [data nodes](../../../userman/scenario_features/data-integration/data-node-config.md),
 [tasks](../../../userman/scenario_features/task-orchestration/scenario-config.md),

+ 2 - 2
taipy/core/_cli/_core_cli.py

@@ -11,8 +11,8 @@
 
 from typing import Dict
 
-from taipy._cli._base_cli._abstract_cli import _AbstractCLI
-from taipy._cli._base_cli._taipy_parser import _TaipyParser
+from taipy.common._cli._base_cli._abstract_cli import _AbstractCLI
+from taipy.common._cli._base_cli._taipy_parser import _TaipyParser
 
 from ..config import CoreSection
 

+ 4 - 4
taipy/core/_cli/_core_cli_factory.py

@@ -13,17 +13,17 @@ from importlib import import_module
 from operator import attrgetter
 from typing import Type
 
-from taipy._cli._base_cli._abstract_cli import _AbstractCLI
+from taipy.common._cli._base_cli._abstract_cli import _AbstractCLI
 
-from ..common._check_dependencies import _TAIPY_ENTERPRISE_CORE_MODULE, _using_enterprise
+from ..common._check_dependencies import EnterpriseEditionUtils
 from ._core_cli import _CoreCLI
 
 
 class _CoreCLIFactory:
     @staticmethod
     def _build_cli() -> Type[_AbstractCLI]:
-        if _using_enterprise():
-            module = import_module(_TAIPY_ENTERPRISE_CORE_MODULE + "._cli._core_cli")
+        if EnterpriseEditionUtils._using_enterprise():
+            module = import_module(EnterpriseEditionUtils._TAIPY_ENTERPRISE_CORE_MODULE + "._cli._core_cli")
             core_cli = attrgetter("_CoreCLI")(module)
         else:
             core_cli = _CoreCLI

+ 1 - 1
taipy/core/_core.py

@@ -9,7 +9,7 @@
 # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
 
-from taipy.logger._taipy_logger import _TaipyLogger
+from taipy.common.logger._taipy_logger import _TaipyLogger
 
 from .common._warnings import _warn_deprecated
 from .orchestrator import Orchestrator

+ 1 - 1
taipy/core/_entity/_migrate/_migrate_fs.py

@@ -14,7 +14,7 @@ import os
 import shutil
 from typing import Dict
 
-from taipy.logger._taipy_logger import _TaipyLogger
+from taipy.common.logger._taipy_logger import _TaipyLogger
 
 from ._utils import _migrate
 

+ 1 - 1
taipy/core/_entity/_migrate/_migrate_mongo.py

@@ -17,7 +17,7 @@ from typing import Dict
 import bson
 import pymongo
 
-from taipy.logger._taipy_logger import _TaipyLogger
+from taipy.common.logger._taipy_logger import _TaipyLogger
 
 from ._utils import _migrate
 

Some files were not shown because too many files changed in this diff