import re  import typing as t    from .._warnings import _warn  from .boolean import _is_boolean, _is_boolean_true  from .clientvarname import _to_camel_case      def _get_column_desc(columns: t.Dict[str, t.Any], key: str) -> t.Optional[t.Dict[str, t.Any]]:      return next((x for x in columns.values() if x.get("dfid") == key), None)      def _get_name_indexed_property(attributes: t.Dict[str, t.Any], name: str) -> t.Dict[str, t.Any]:      ret = {}      index_re = re.compile(name + r"\[(.*)\]$")      for key in attributes.keys():          if m := index_re.match(key):              ret[m.group(1)] = attributes.get(key)      return ret      def _update_col_desc_from_indexed(      attributes: t.Dict[str, t.Any], columns: t.Dict[str, t.Any], name: str, elt_name: str  ):      col_value = _get_name_indexed_property(attributes, name)      for k, v in col_value.items():          if col_desc := next((x for x in columns.values() if x.get("dfid") == k), None):              if col_desc.get(_to_camel_case(name)) is None:                  col_desc[_to_camel_case(name)] = str(v)          else:              _warn(f"{elt_name}: {name}[{k}] is not in the list of displayed columns.")      def _enhance_columns(  # noqa: C901      attributes: t.Dict[str, t.Any], hash_names: t.Dict[str, str], columns: t.Dict[str, t.Any], elt_name: str  ):      _update_col_desc_from_indexed(attributes, columns, "nan_value", elt_name)      _update_col_desc_from_indexed(attributes, columns, "width", elt_name)      filters = _get_name_indexed_property(attributes, "filter")      for k, v in filters.items():          if _is_boolean_true(v):              if col_desc := _get_column_desc(columns, k):                  col_desc["filter"] = True              else:                  _warn(f"{elt_name}: filter[{k}] is not in the list of displayed columns.")      editables = _get_name_indexed_property(attributes, "editable")      for k, v in editables.items():          if _is_boolean(v):              if col_desc := _get_column_desc(columns, k):                  col_desc["notEditable"] = not _is_boolean_true(v)              else:                  _warn(f"{elt_name}: editable[{k}] is not in the list of displayed columns.")      group_by = _get_name_indexed_property(attributes, "group_by")      for k, v in group_by.items():          if _is_boolean_true(v):              if col_desc := _get_column_desc(columns, k):                  col_desc["groupBy"] = True              else:                  _warn(f"{elt_name}: group_by[{k}] is not in the list of displayed columns.")      apply = _get_name_indexed_property(attributes, "apply")      for k, v in apply.items():  # pragma: no cover          if col_desc := _get_column_desc(columns, k):              if callable(v):                  value = hash_names.get(f"apply[{k}]")              elif isinstance(v, str):                  value = v.strip()              else:                  _warn(f"{elt_name}: apply[{k}] should be a user or predefined function.")                  value = None              if value:                  col_desc["apply"] = value          else:              _warn(f"{elt_name}: apply[{k}] is not in the list of displayed columns.")      styles = _get_name_indexed_property(attributes, "style")      for k, v in styles.items():  # pragma: no cover          if col_desc := _get_column_desc(columns, k):              if callable(v):                  value = hash_names.get(f"style[{k}]")              elif isinstance(v, str):                  value = v.strip()              else:                  value = None              if value in columns.keys():                  _warn(f"{elt_name}: style[{k}]={value} cannot be a column's name.")              elif value:                  col_desc["style"] = value          else:              _warn(f"{elt_name}: style[{k}] is not in the list of displayed columns.")      tooltips = _get_name_indexed_property(attributes, "tooltip")      for k, v in tooltips.items():  # pragma: no cover          if col_desc := _get_column_desc(columns, k):              if callable(v):                  value = hash_names.get(f"tooltip[{k}]")              elif isinstance(v, str):                  value = v.strip()              else:                  value = None              if value in columns.keys():                  _warn(f"{elt_name}: tooltip[{k}]={value} cannot be a column's name.")              elif value:                  col_desc["tooltip"] = value          else:              _warn(f"{elt_name}: tooltip[{k}] is not in the list of displayed columns.")      return columns


import typing as t  from datetime import datetime  from random import random    from ..data.data_scope import _DataScopes  from ._map_dict import _MapDict    if t.TYPE_CHECKING:      from ..gui import Gui      class _Bindings:      def __init__(self, gui: "Gui") -> None:          self.__gui = gui          self.__scopes = _DataScopes()        def _bind(self, name: str, value: t.Any) -> None:          if hasattr(self, name):              raise ValueError(f"Variable '{name}' is already bound")          if not name.isidentifier():              raise ValueError(f"Variable name '{name}' is invalid")          if isinstance(value, dict):              setattr(self._get_data_scope(), name, _MapDict(value))          else:              setattr(self._get_data_scope(), name, value)          # prop = property(self.__value_getter(name), self.__value_setter(name))          setattr(_Bindings, name, self.__get_property(name))        def __get_property(self, name):          def __setter(ud: _Bindings, value: t.Any):              if isinstance(value, dict):                  value = _MapDict(value, None)              ud.__gui._update_var(name, value)            def __getter(ud: _Bindings) -> t.Any:              value = getattr(ud._get_data_scope(), name)              if isinstance(value, _MapDict):                  return _MapDict(value._dict, lambda k, v: ud.__gui._update_var(f"{name}.{k}", v))              else:                  return value            return property(__getter, __setter)  # Getter, Setter        def _set_single_client(self, value: bool) -> None:          self.__scopes.set_single_client(value)        def _is_single_client(self) -> bool:          return self.__scopes.is_single_client()        def _get_or_create_scope(self, id: str):          create = not id          if create:              id = f"{datetime.now().strftime('%Y%m%d%H%M%S%f')}-{random()}"              self.__gui._send_ws_id(id)          self.__scopes.create_scope(id)          return id, create        def _new_scopes(self):          self.__scopes = _DataScopes()        def _get_data_scope(self):          return self.__scopes.get_scope(self.__gui._get_client_id())        def _get_all_scopes(self):          return self.__scopes.get_all_scopes()


import re  import typing as t  from types import FrameType    from ._locals_context import _LocalsContext  from .get_imported_var import _get_imported_var  from .get_module_name import _get_module_name_from_frame, _get_module_name_from_imported_var      class _VariableDirectory:      def __init__(self, locals_context: _LocalsContext):          self._locals_context = locals_context          self._default_module = ""          self._var_dir: t.Dict[str, t.Dict] = {}          self._var_head: t.Dict[str, t.List[t.Tuple[str, str]]] = {}          self._imported_var_dir: t.Dict[str, t.List[t.Tuple[str, str, str]]] = {}        def set_default(self, frame: FrameType) -> None:          self._default_module = _get_module_name_from_frame(frame)          self.add_frame(frame)        def add_frame(self, frame: t.Optional[FrameType]) -> None:          if frame is None:              return          module_name = _get_module_name_from_frame(frame)          if module_name not in self._imported_var_dir:              imported_var_list = _get_imported_var(frame)              self._imported_var_dir[module_name] = imported_var_list        def pre_process_module_import_all(self) -> None:          for imported_dir in self._imported_var_dir.values():              additional_var_list: t.List[t.Tuple[str, str, str]] = []              for name, asname, module in imported_dir:                  if name != "*" or asname != "*":                      continue                  if module not in self._locals_context._locals_map.keys():                      continue                  with self._locals_context.set_locals_context(module):                      additional_var_list.extend(                          (v, v, module) for v in self._locals_context.get_locals().keys() if not v.startswith("_")                      )              imported_dir.extend(additional_var_list)        def process_imported_var(self) -> None:          self.pre_process_module_import_all()          default_imported_dir = self._imported_var_dir[self._default_module]          with self._locals_context.set_locals_context(self._default_module):              for name, asname, module in default_imported_dir:                  if name == "*" and asname == "*":                      continue                  imported_module_name = _get_module_name_from_imported_var(                      name, self._locals_context.get_locals().get(asname, None), module                  )                  temp_var_name = self.add_var(asname, self._default_module)                  self.add_var(name, imported_module_name, temp_var_name)            for k, v in self._imported_var_dir.items():              with self._locals_context.set_locals_context(k):                  for name, asname, module in v:                      if name == "*" and asname == "*":                          continue                      imported_module_name = _get_module_name_from_imported_var(                          name, self._locals_context.get_locals().get(asname, None), module                      )                      var_name = self.get_var(name, imported_module_name)                      var_asname = self.get_var(asname, k)                      if var_name is None and var_asname is None:                          temp_var_name = self.add_var(asname, k)                          self.add_var(name, imported_module_name, temp_var_name)                      elif var_name is not None:                          self.add_var(asname, k, var_name)                      else:                          self.add_var(name, imported_module_name, var_asname)        def add_var(self, name: str, module: t.Optional[str], var_name: t.Optional[str] = None) -> str:          if module is None:              module = self._default_module          if gv := self.get_var(name, module):              return gv          var_encode = _variable_encode(name, module) if module != self._default_module else name          if var_name is None:              var_name = var_encode          self.__add_var_head(name, module, var_name)          if var_encode != var_name:              var_name_decode, module_decode = _variable_decode(var_name)              if module_decode is None:                  module_decode = self._default_module              self.__add_var_head(var_name_decode, module_decode, var_encode)          if name not in self._var_dir:              self._var_dir[name] = {module: var_name}          else:              self._var_dir[name][module] = var_name          return var_name        def __add_var_head(self, name: str, module: str, var_head: str) -> None:          if var_head not in self._var_head:              self._var_head[var_head] = [(name, module)]          else:              self._var_head[var_head].append((name, module))        def get_var(self, name: str, module: str) -> t.Optional[str]:          if name in self._var_dir and module in self._var_dir[name]:              return self._var_dir[name][module]          return None      _MODULE_NAME_MAP: t.List[str] = []  _MODULE_ID = "_TPMDL_"  _RE_TPMDL_DECODE = re.compile(r"(.*?)" + _MODULE_ID + r"(\d+)$")      def _variable_encode(var_name: str, module_name: t.Optional[str]):      if module_name is None:          return var_name      if module_name not in _MODULE_NAME_MAP:          _MODULE_NAME_MAP.append(module_name)      return f"{var_name}{_MODULE_ID}{_MODULE_NAME_MAP.index(module_name)}"      def _variable_decode(var_name: str):      from ._evaluator import _Evaluator        if result := _RE_TPMDL_DECODE.match(var_name):          return _Evaluator._expr_decode(str(result[1])), _MODULE_NAME_MAP[int(result[2])]      return _Evaluator._expr_decode(var_name), None      def _reset_name_map():      _MODULE_NAME_MAP.clear()


from typing import Dict      class _Singleton(type):      _instances: Dict = {}        def __call__(self, *args, **kwargs):          if self not in self._instances:              self._instances[self] = super(_Singleton, self).__call__(*args, **kwargs)          return self._instances[self]


import re    import pandas as pd      def _get_data_type(value):      if pd.api.types.is_bool_dtype(value):          return "bool"      elif pd.api.types.is_integer_dtype(value):          return "int"      elif pd.api.types.is_float_dtype(value):          return "float"      return re.match(r"^<class '(.*\.)?(.*?)(\d\d)?'>", str(type(value))).group(2)


import ast  import inspect  import typing as t  from types import FrameType      def _get_imported_var(frame: FrameType) -> t.List[t.Tuple[str, str, str]]:      st = ast.parse(inspect.getsource(frame))      var_list: t.List[t.Tuple[str, str, str]] = []      for node in ast.walk(st):          if isinstance(node, ast.ImportFrom):              # get the imported element as (name, asname, module)              # ex: from module1 import a as x --> ("a", "x", "module1")              var_list.extend(                  (                      child_node.name,                      child_node.asname if child_node.asname is not None else child_node.name,                      node.module or "",                  )                  for child_node in node.names              )      return var_list


import re  import typing as t  from datetime import date, datetime, time    from dateutil import parser  from pytz import utc    from .._warnings import _warn      def _date_to_string(date_val: t.Union[datetime, date, time]) -> str:      if isinstance(date_val, datetime):          # return date.isoformat() + 'Z', if possible          try:              return date_val.astimezone(utc).isoformat()          except Exception as e:              # astimezone() fails on Windows for pre-epoch times              # See https://bugs.python.org/issue36759              _warn("Exception raised converting date to ISO 8601", e)      return date_val.isoformat()      def _string_to_date(date_str: str) -> t.Union[datetime, date]:      # return datetime.strptime(date_str, '%Y-%m-%dT%H:%M:%S.%fZ')      # return datetime.fromisoformat(date_str)      date = parser.parse(date_str)      date_regex = r"^[A-Z][a-z]{2} (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{2} \d{4}$"      return date.date() if re.match(date_regex, date_str) else date


from importlib import util      def _is_in_notebook():  # pragma: no cover      try:          if not util.find_spec("IPython"):              return False            from IPython import get_ipython            ipython = get_ipython()            if ipython is None or "IPKernelApp" not in ipython.config:              return False      except (ImportError, AttributeError):          return False      return True


import typing as t  from pathlib import Path      def _get_non_existent_file_path(dir_path: Path, file_name: str) -> Path:      if not file_name:          file_name = "taipy_file.bin"      file_path = dir_path / file_name      index = 0      file_stem = file_path.stem      file_suffix = file_path.suffix      while file_path.exists():          file_path = dir_path / f"{file_stem}.{index}{file_suffix}"          index += 1      return file_path


import re  import typing as t    _RE_PD_TYPE = re.compile(r"^([^\s\d\[]+)(\d+)(\[(.*,\s(\S+))\])?")      def _get_date_col_str_name(columns: t.List[str], col: str) -> str:      suffix = "_str"      while col + suffix in columns:          suffix += "_"      return col + suffix


import typing as t    import numpy  import pandas as pd    from ..gui import Gui  from .data_format import _DataFormat  from .pandas_data_accessor import _PandasDataAccessor      class _NumpyDataAccessor(_PandasDataAccessor):      __types = (numpy.ndarray,)        @staticmethod      def get_supported_classes() -> t.List[str]:          return [t.__name__ for t in _NumpyDataAccessor.__types]  # type: ignore        def __get_dataframe(self, value: t.Any) -> pd.DataFrame:          return pd.DataFrame(value)        def get_col_types(self, var_name: str, value: t.Any) -> t.Union[None, t.Dict[str, str]]:  # type: ignore          if isinstance(value, _NumpyDataAccessor.__types):  # type: ignore              return super().get_col_types(var_name, self.__get_dataframe(value))          return None        def get_data(  # noqa: C901          self, guiApp: Gui, var_name: str, value: t.Any, payload: t.Dict[str, t.Any], data_format: _DataFormat      ) -> t.Dict[str, t.Any]:          if isinstance(value, _NumpyDataAccessor.__types):  # type: ignore              return super().get_data(guiApp, var_name, self.__get_dataframe(value), payload, data_format)          return {}


import typing as t    import pandas as pd    from ..gui import Gui  from ..utils import _MapDict  from .data_format import _DataFormat  from .pandas_data_accessor import _PandasDataAccessor      class _ArrayDictDataAccessor(_PandasDataAccessor):      __types = (dict, list, tuple, _MapDict)        @staticmethod      def get_supported_classes() -> t.List[str]:          return [t.__name__ for t in _ArrayDictDataAccessor.__types]  # type: ignore        def __get_dataframe(self, value: t.Any) -> t.Union[t.List[pd.DataFrame], pd.DataFrame]:          if isinstance(value, list):              if not value or isinstance(value[0], (str, int, float, bool)):                  return pd.DataFrame({"0": value})              types = {type(x) for x in value}              if len(types) == 1:                  type_elt = next(iter(types), None)                  if type_elt == list:                      lengths = {len(x) for x in value}                      return (                          pd.DataFrame(value)                          if len(lengths) == 1                          else [pd.DataFrame({f"{i}/0": v}) for i, v in enumerate(value)]                      )                  elif type_elt == dict:                      return [pd.DataFrame(v) for v in value]                  elif type_elt == _MapDict:                      return [pd.DataFrame(v._dict) for v in value]                  elif type_elt == pd.DataFrame:                      return value                elif len(types) == 2 and list in types and pd.DataFrame in types:                  return [v if isinstance(v, pd.DataFrame) else pd.DataFrame({f"{i}/0": v}) for i, v in enumerate(value)]          elif isinstance(value, _MapDict):              return pd.DataFrame(value._dict)          return pd.DataFrame(value)        def get_col_types(self, var_name: str, value: t.Any) -> t.Union[None, t.Dict[str, str]]:  # type: ignore          if isinstance(value, _ArrayDictDataAccessor.__types):  # type: ignore              return super().get_col_types(var_name, self.__get_dataframe(value))          return None        def get_data(  # noqa: C901          self, guiApp: Gui, var_name: str, value: t.Any, payload: t.Dict[str, t.Any], data_format: _DataFormat      ) -> t.Dict[str, t.Any]:          if isinstance(value, _ArrayDictDataAccessor.__types):  # type: ignore              return super().get_data(guiApp, var_name, self.__get_dataframe(value), payload, data_format)          return {}


from .data_accessor import _DataAccessor  from .decimator import LTTB, RDP, MinMaxDecimator, ScatterDecimator  from .utils import Decimator


import inspect  import typing as t  from abc import ABC, abstractmethod    from .._warnings import _warn  from ..utils import _TaipyData  from .data_format import _DataFormat      class _DataAccessor(ABC):      _WS_DATE_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ"        @staticmethod      @abstractmethod      def get_supported_classes() -> t.List[str]:          pass        @abstractmethod      def get_data(          self, guiApp: t.Any, var_name: str, value: t.Any, payload: t.Dict[str, t.Any], data_format: _DataFormat      ) -> t.Dict[str, t.Any]:          pass        @abstractmethod      def get_col_types(self, var_name: str, value: t.Any) -> t.Dict[str, str]:          pass      class _InvalidDataAccessor(_DataAccessor):      @staticmethod      def get_supported_classes() -> t.List[str]:          return [type(None).__name__]        def get_data(          self, guiApp: t.Any, var_name: str, value: t.Any, payload: t.Dict[str, t.Any], data_format: _DataFormat      ) -> t.Dict[str, t.Any]:          return {}        def get_col_types(self, var_name: str, value: t.Any) -> t.Dict[str, str]:          return {}      class _DataAccessors(object):      def __init__(self) -> None:          self.__access_4_type: t.Dict[str, _DataAccessor] = {}            self.__invalid_data_accessor = _InvalidDataAccessor()            self.__data_format = _DataFormat.JSON            from .array_dict_data_accessor import _ArrayDictDataAccessor          from .numpy_data_accessor import _NumpyDataAccessor          from .pandas_data_accessor import _PandasDataAccessor            self._register(_PandasDataAccessor)          self._register(_ArrayDictDataAccessor)          self._register(_NumpyDataAccessor)        def _register(self, cls: t.Type[_DataAccessor]) -> None:          if not inspect.isclass(cls):              raise AttributeError("The argument of 'DataAccessors.register' should be a class")          if not issubclass(cls, _DataAccessor):              raise TypeError(f"Class {cls.__name__} is not a subclass of DataAccessor")          names = cls.get_supported_classes()          if not names:              raise TypeError(f"method {cls.__name__}.get_supported_classes returned an invalid value")          # check existence          inst: t.Optional[_DataAccessor] = None          for name in names:              inst = self.__access_4_type.get(name)              if inst:                  break          if inst is None:              try:                  inst = cls()              except Exception as e:                  raise TypeError(f"Class {cls.__name__} cannot be instanciated") from e              if inst:                  for name in names:                      self.__access_4_type[name] = inst  # type: ignore        def __get_instance(self, value: _TaipyData) -> _DataAccessor:  # type: ignore          value = value.get()          access = self.__access_4_type.get(type(value).__name__)          if access is None:              _warn(f"Can't find Data Accessor for type {type(value).__name__}.")              return self.__invalid_data_accessor          return access        def _get_data(          self, guiApp: t.Any, var_name: str, value: _TaipyData, payload: t.Dict[str, t.Any]      ) -> t.Dict[str, t.Any]:          return self.__get_instance(value).get_data(guiApp, var_name, value.get(), payload, self.__data_format)        def _get_col_types(self, var_name: str, value: _TaipyData) -> t.Dict[str, str]:          return self.__get_instance(value).get_col_types(var_name, value.get())        def _set_data_format(self, data_format: _DataFormat):          self.__data_format = data_format


from __future__ import annotations    import typing as t  from abc import ABC, abstractmethod    import numpy as np    from .._warnings import _warn    if t.TYPE_CHECKING:      import pandas as pd      class Decimator(ABC):      """Base class for decimating chart data.        *Decimating* is the term used to name the process of reducing the number of      data points displayed in charts while retaining the overall shape of the traces.      `Decimator` is a base class that does decimation on data sets.        Taipy GUI comes out-of-the-box with several implementation of this class for      different use cases.      """        _CHART_MODES: t.List[str] = []        def __init__(self, threshold: t.Optional[int], zoom: t.Optional[bool]) -> None:          """Initialize a new `Decimator`.            Arguments:              threshold (Optional[int]): The minimum amount of data points before the                  decimator class is applied.              zoom (Optional[bool]): set to True to reapply the decimation                  when zoom or re-layout events are triggered.          """          super().__init__()          self.threshold = threshold          self._zoom = zoom if zoom is not None else True        def _is_applicable(self, data: t.Any, nb_rows_max: int, chart_mode: str):          if chart_mode not in self._CHART_MODES:              _warn(f"{type(self).__name__} is only applicable for {' '.join(self._CHART_MODES)}.")              return False          if self.threshold is None:              if nb_rows_max < len(data):                  return True          elif self.threshold < len(data):              return True          return False        @abstractmethod      def decimate(self, data: np.ndarray, payload: t.Dict[str, t.Any]) -> np.ndarray:          """Decimate function.            This method is executed when the appropriate conditions specified in the          constructor are met. This function implements the algorithm that determines          which data points are kept or dropped.            Arguments:              data (numpy.array): An array containing all the data points represented as                  tuples.              payload (Dict[str, any]): additional information on charts that is provided                  at runtime.            Returns:              An array of Boolean mask values. The array should set True or False for each                  of its indexes where True indicates that the corresponding data point                  from *data* should be preserved, or False requires that this                  data point be dropped.          """          return NotImplementedError  # type: ignore      def _df_data_filter(      dataframe: pd.DataFrame,      x_column_name: t.Optional[str],      y_column_name: str,      z_column_name: str,      decimator: Decimator,      payload: t.Dict[str, t.Any],      is_copied: bool,  ):      df = dataframe.copy() if not is_copied else dataframe      if not x_column_name:          index = 0          while f"tAiPy_index_{index}" in df.columns:              index += 1          x_column_name = f"tAiPy_index_{index}"          df[x_column_name] = df.index      column_list = [x_column_name, y_column_name, z_column_name] if z_column_name else [x_column_name, y_column_name]      points = df[column_list].to_numpy()      mask = decimator.decimate(points, payload)      return df[mask], is_copied      def _df_relayout(      dataframe: pd.DataFrame,      x_column: t.Optional[str],      y_column: str,      chart_mode: str,      x0: t.Optional[float],      x1: t.Optional[float],      y0: t.Optional[float],      y1: t.Optional[float],      is_copied: bool,  ):      if chart_mode not in ["lines+markers", "markers"]:          return dataframe, is_copied      # if chart data is invalid      if x0 is None or x1 is None or y0 is None or y1 is None:          return dataframe, is_copied      df = dataframe.copy() if not is_copied else dataframe      is_copied = True      has_x_col = True        if not x_column:          index = 0          while f"tAiPy_index_{index}" in df.columns:              index += 1          x_column = f"tAiPy_index_{index}"          df[x_column] = df.index          has_x_col = False        # if chart_mode is empty      if chart_mode == "lines+markers":          # only filter by x column          df = df.loc[(df[x_column] > x0) & (df[x_column] < x1)]      else:          # filter by both x and y columns          df = df.loc[(df[x_column] > x0) & (df[x_column] < x1) & (df[y_column] > y0) & (df[y_column] < y1)]  # noqa      if not has_x_col:          df.drop(x_column, axis=1, inplace=True)      return df, is_copied


from enum import Enum      class _DataFormat(Enum):      JSON = "JSON"      APACHE_ARROW = "ARROW"


import base64  import pathlib  import tempfile  import typing as t  import urllib.parse  from importlib import util  from pathlib import Path  from sys import getsizeof    from .._warnings import _warn  from ..utils import _get_non_existent_file_path, _variable_decode    _has_magic_module = False    if util.find_spec("magic"):      import magic        _has_magic_module = True      class _ContentAccessor:      def __init__(self, data_url_max_size: int) -> None:          self.__content_paths: t.Dict[str, pathlib.Path] = {}          self.__url_is_image: t.Dict[str, bool] = {}          self.__paths: t.Dict[pathlib.Path, str] = {}          self.__data_url_max_size = data_url_max_size          self.__temp_dir_path = Path(tempfile.gettempdir())        def get_path(self, path: pathlib.Path) -> str:          url_path = self.__paths.get(path)          if url_path is None:              self.__paths[path] = url_path = "taipyStatic" + str(len(self.__paths))          return url_path        def get_content_path(          self, url_path: str, file_name: str, bypass: t.Optional[str]      ) -> t.Tuple[t.Union[pathlib.Path, None], bool]:          content_path = self.__content_paths.get(url_path)          if not content_path:              return (None, True)          return (content_path, bypass is not None or self.__url_is_image.get(f"{url_path}/{file_name}", False))        def __get_mime_from_file(self, path: pathlib.Path):          if _has_magic_module:              try:                  return magic.from_file(str(path), mime=True)              except Exception as e:                  _warn(f"Exception reading mime type in '{path}'", e)          return None        def __get_display_name(self, var_name: str) -> str:          if not isinstance(var_name, str):              return var_name          if var_name.startswith("_tpC_"):              var_name = var_name[5:]          if var_name.startswith("tpec_"):              var_name = var_name[5:]          return _variable_decode(var_name)[0]        def get_info(self, var_name: str, value: t.Any, image: bool) -> t.Union[str, t.Tuple[str], t.Any]:  # noqa: C901          if value is None:              return ""          newvalue = value          mime = None          if not isinstance(newvalue, (str, pathlib.Path)) and (              getsizeof(newvalue) > self.__data_url_max_size or not _has_magic_module          ):              # write data to file              file_name = "TaiPyContent.bin"              if _has_magic_module:                  try:                      mime = magic.from_buffer(value, mime=True)                      file_name = "TaiPyContent." + mime.split("/")[-1]                  except Exception as e:                      _warn(f"{self.__get_display_name(var_name)} ({type(value)}) cannot be typed", e)              file_path = _get_non_existent_file_path(self.__temp_dir_path, file_name)              try:                  with open(file_path, "wb") as temp_file:                      temp_file.write(value)              except Exception as e:                  _warn(f"{self.__get_display_name(var_name)} ({type(value)}) cannot be written to file {file_path}", e)              newvalue = file_path          if isinstance(newvalue, (str, pathlib.Path)):              path = pathlib.Path(newvalue) if isinstance(newvalue, str) else newvalue              if not path.is_file():                  if (                      var_name != "Gui.download"                      and not str(path).startswith("http")                      and not str(path).startswith("/")                      and not str(path).strip().lower().startswith("<svg")                  ):                      _warn(f"{self.__get_display_name(var_name)}: file '{value}' does not exist.")                  return str(value)              if image:                  if not mime:                      mime = self.__get_mime_from_file(path)                  if mime and not mime.startswith("image"):                      _warn(f"{self.__get_display_name(var_name)}: file '{path}' mime type ({mime}) is not an image.")                      return f"Invalid content: {mime}"              dir_path = path.resolve().parent              url_path = self.get_path(dir_path)              self.__content_paths[url_path] = dir_path              file_url = f"{url_path}/{path.name}"              self.__url_is_image[file_url] = image              return (urllib.parse.quote_plus(file_url, safe="/"),)          elif _has_magic_module:              try:                  mime = magic.from_buffer(value, mime=True)                  if not image or mime.startswith("image"):                      return f"data:{mime};base64," + str(base64.b64encode(value), "utf-8")                  _warn(f"{self.__get_display_name(var_name)}: ({type(value)}) does not have an image mime type: {mime}.")                  return f"Invalid content: {mime}"              except Exception as e:                  _warn(f"{self.__get_display_name(var_name)}: ({type(value)}) cannot be base64 encoded", e)                  return "Cannot be base64 encoded"          else:              _warn(                  "python-magic (and python-magic-bin on Windows) packages need to be installed if you want to process content as an array of bytes."              )              return "Cannot guess content type"


from __future__ import annotations    import typing as t  from types import SimpleNamespace    from .._warnings import _warn      class _DataScopes:      _GLOBAL_ID = "global"        def __init__(self) -> None:          self.__scopes: t.Dict[str, SimpleNamespace] = {_DataScopes._GLOBAL_ID: SimpleNamespace()}          self.__single_client = True        def set_single_client(self, value: bool) -> None:          self.__single_client = value        def is_single_client(self) -> bool:          return self.__single_client        def get_scope(self, client_id: t.Optional[str]) -> SimpleNamespace:          if self.__single_client:              return self.__scopes[_DataScopes._GLOBAL_ID]          # global context in case request is not registered or client_id is not available (such as in the context of running tests)          if not client_id:              _warn("Empty session id, using global scope instead.")              return self.__scopes[_DataScopes._GLOBAL_ID]          if client_id not in self.__scopes:              _warn(                  f"Session id {client_id} not found in data scope. Taipy will automatically create a scope for this session id but you may have to reload your page."              )              self.create_scope(client_id)          return self.__scopes[client_id]        def get_all_scopes(self) -> t.Dict[str, SimpleNamespace]:          return self.__scopes        def create_scope(self, id: str) -> None:          if self.__single_client:              return          if id is None:              _warn("Empty session id, might be due to unestablished WebSocket connection.")              return          if id not in self.__scopes:              self.__scopes[id] = SimpleNamespace()        def delete_scope(self, id: str) -> None:  # pragma: no cover          if self.__single_client:              return          if id is None:              _warn("Empty session id, might be due to unestablished WebSocket connection.")              return          if id in self.__scopes:              del self.__scopes[id]


import typing as t    import numpy as np    from ..utils import Decimator      class ScatterDecimator(Decimator):      """A decimator designed for scatter charts.        This algorithm fits the data points into a grid. If multiple points are in the same grid      cell, depending on the chart configuration, some points are removed to reduce the number      points being displayed.        This class can only be used with scatter charts.      """        _CHART_MODES = ["markers"]        def __init__(          self,          binning_ratio: t.Optional[float] = None,          max_overlap_points: t.Optional[int] = None,          threshold: t.Optional[int] = None,          zoom: t.Optional[bool] = True,      ):          """Initialize a new `ScatterDecimator`.            Arguments:              binning_ratio (Optional[float]): the size of the data grid for the algorithm.                  The higher the value, the smaller the grid size.              max_overlap_points (Optional(int)): the maximum number of points for a single cell                  within the data grid within the algorithm. This dictates how dense a single                  grid cell can be.              threshold (Optional[int]): The minimum amount of data points before the                  decimation is applied.              zoom (Optional[bool]): set to True to reapply the decimation                  when zoom or re-layout events are triggered.          """          super().__init__(threshold, zoom)          binning_ratio = binning_ratio if binning_ratio is not None else 1          self._binning_ratio = binning_ratio if binning_ratio > 0 else 1          self._max_overlap_points = max_overlap_points if max_overlap_points is not None else 3        def decimate(self, data: np.ndarray, payload: t.Dict[str, t.Any]) -> np.ndarray:          n_rows = data.shape[0]          mask = np.empty(n_rows, dtype=bool)          width = payload.get("width", None)          height = payload.get("height", None)          if width is None or height is None:              mask.fill(True)              return mask          mask.fill(False)          grid_x, grid_y = round(width / self._binning_ratio), round(height / self._binning_ratio)          x_col, y_col = data[:, 0], data[:, 1]          min_x, max_x = np.amin(x_col), np.amax(x_col)          min_y, max_y = np.amin(y_col), np.amax(y_col)          min_max_x_diff, min_max_y_diff = max_x - min_x, max_y - min_y          x_grid_map = np.rint((x_col - min_x) * grid_x / min_max_x_diff).astype(int)          y_grid_map = np.rint((y_col - min_y) * grid_y / min_max_y_diff).astype(int)          z_grid_map = None          grid_shape = (grid_x + 1, grid_y + 1)          if len(data[0]) == 3:              grid_z = grid_x              grid_shape = (grid_x + 1, grid_y + 1, grid_z + 1)  # type: ignore              z_col = data[:, 2]              min_z, max_z = np.amin(z_col), np.amax(z_col)              min_max_z_diff = max_z - min_z              z_grid_map = np.rint((z_col - min_z) * grid_z / min_max_z_diff).astype(int)          grid = np.empty(grid_shape, dtype=int)          grid.fill(0)          if z_grid_map is not None:              for i in np.arange(n_rows):                  if grid[x_grid_map[i], y_grid_map[i], z_grid_map[i]] < self._max_overlap_points:                      grid[x_grid_map[i], y_grid_map[i], z_grid_map[i]] += 1                      mask[i] = True          else:              for i in np.arange(n_rows):                  if grid[x_grid_map[i], y_grid_map[i]] < self._max_overlap_points:                      grid[x_grid_map[i], y_grid_map[i]] += 1                      mask[i] = True          return mask


from .lttb import LTTB  from .minmax import MinMaxDecimator  from .rdp import RDP  from .scatter_decimator import ScatterDecimator


import typing as t    import numpy as np    from ..utils import Decimator      class MinMaxDecimator(Decimator):      """A decimator using the MinMax algorithm.        The MinMax algorithm is an efficient algorithm that preserves the peaks within the data. It      can work very well with noisy signal data where data peeks need to be highlighted.        This class can only be used with line charts.      """        _CHART_MODES = ["lines+markers"]        def __init__(self, n_out: int, threshold: t.Optional[int] = None, zoom: t.Optional[bool] = True):          """Initialize a new `MinMaxDecimator`.            Arguments:              n_out (int): The maximum number of points that will be displayed after decimation.              threshold (Optional[int]): The minimum amount of data points before the                  decimation is applied.              zoom (Optional[bool]): set to True to reapply the decimation                  when zoom or re-layout events are triggered.          """          super().__init__(threshold, zoom)          self._n_out = n_out // 2        def decimate(self, data: np.ndarray, payload: t.Dict[str, t.Any]) -> np.ndarray:          if self._n_out >= data.shape[0]:              return np.full(len(data), False)          # Create a boolean mask          x = data[:, 0]          y = data[:, 1]          num_bins = self._n_out          pts_per_bin = x.size // num_bins          # Create temp to hold the reshaped & slightly cropped y          y_temp = y[: num_bins * pts_per_bin].reshape((num_bins, pts_per_bin))          # use argmax/min to get column locations          cc_max = np.argmax(y_temp, axis=1)          cc_min = np.argmin(y_temp, axis=1)          rr = np.arange(0, num_bins)          # compute the flat index to where these are          flat_max = cc_max + rr * pts_per_bin          flat_min = cc_min + rr * pts_per_bin          mm_mask = np.full((x.size,), False)          mm_mask[flat_max] = True          mm_mask[flat_min] = True          return mm_mask


import typing as t    import numpy as np    from ..utils import Decimator      class LTTB(Decimator):      """A decimator using the LTTB algorithm.        The LTTB algorithm is an high performance algorithm that significantly reduces the number of      data points. It can work very well with time-series data to show trends using by using only      a few data points.        This class can only be used with line charts.      """        _CHART_MODES = ["lines+markers"]        def __init__(self, n_out: int, threshold: t.Optional[int] = None, zoom: t.Optional[bool] = True) -> None:          """Initialize a new `LTTB`.            Arguments:              n_out (int): The maximum number of points that will be displayed after decimation.              threshold (Optional[int]): The minimum amount of data points before the                  decimation is applied.              zoom (Optional[bool]): set to True to reapply the decimation                  when zoom or re-layout events are triggered.          """          super().__init__(threshold, zoom)          self._n_out = n_out        @staticmethod      def _areas_of_triangles(a, bs, c):          bs_minus_a = bs - a          a_minus_bs = a - bs          return 0.5 * abs((a[0] - c[0]) * (bs_minus_a[:, 1]) - (a_minus_bs[:, 0]) * (c[1] - a[1]))        def decimate(self, data: np.ndarray, payload: t.Dict[str, t.Any]) -> np.ndarray:          n_out = self._n_out          if n_out >= data.shape[0]:              return np.full(len(data), True)            if n_out < 3:              raise ValueError("Can only down-sample to a minimum of 3 points")            # Split data into bins          n_bins = n_out - 2          data_bins = np.array_split(data[1:-1], n_bins)            prev_a = data[0]          start_pos = 0            # Prepare output mask array          # First and last points are the same as in the input.          out_mask = np.full(len(data), False)          out_mask[0] = True          out_mask[len(data) - 1] = True            # Largest Triangle Three Buckets (LTTB):          # In each bin, find the point that makes the largest triangle          # with the point saved in the previous bin          # and the centroid of the points in the next bin.          for i in range(len(data_bins)):              this_bin = data_bins[i]              next_bin = data_bins[i + 1] if i < n_bins - 1 else data[-1:]              a = prev_a              bs = this_bin              c = next_bin.mean(axis=0)                areas = LTTB._areas_of_triangles(a, bs, c)              bs_pos = np.argmax(areas)              prev_a = bs[bs_pos]              out_mask[start_pos + bs_pos] = True              start_pos += len(this_bin)            return out_mask


import typing as t    import numpy as np    from ..utils import Decimator      class RDP(Decimator):      """A decimator using the RDP algorithm.        The RDP algorithm reduces a shape made of line segments into a similar shape with      less points. This algorithm should be used if the final visual representation is      prioritized over the performance of the application.        This class can only be used with line charts.      """        _CHART_MODES = ["lines+markers"]        def __init__(          self,          epsilon: t.Optional[int] = None,          n_out: t.Optional[int] = None,          threshold: t.Optional[int] = None,          zoom: t.Optional[bool] = True,      ):          """Initialize a new `RDP`.            Arguments:              epsilon (Optional[int]): The epsilon value for the RDP algorithm. If this value                  is being used, the *n_out* argument is ignored.              n_out (Optional(int)): The maximum number of points that are displayed after                  decimation. This value is ignored if the epsilon value is used.<br/>                  This process is not very efficient so consider using `LTTB` or `MinMaxDecimator`                  if the provided data has more than 100.000 data points.              threshold (Optional[int]): The minimum amount of data points before the                  decimation is applied.              zoom (Optional[bool]): set to True to reapply the decimation                  when zoom or re-layout events are triggered.          """          super().__init__(threshold, zoom)          self._epsilon = epsilon          self._n_out = n_out        @staticmethod      def dsquared_line_points(P1, P2, points):          """          Calculate only squared distance, only needed for comparison          """          xdiff = P2[0] - P1[0]          ydiff = P2[1] - P1[1]          nom = (ydiff * points[:, 0] - xdiff * points[:, 1] + P2[0] * P1[1] - P2[1] * P1[0]) ** 2          denom = ydiff**2 + xdiff**2          return np.divide(nom, denom)        @staticmethod      def __rdp_epsilon(data, epsilon: int):          # initiate mask array          # same amount of points          mask = np.empty(data.shape[0], dtype=bool)            # Assume all points are valid and falsify those which are found          mask.fill(True)            # The stack to select start and end index          stack: t.List[t.Tuple[int, int]] = [(0, data.shape[0] - 1)]  # type: ignore            while stack:              # Pop the last item              (start, end) = stack.pop()                # nothing to calculate if no points in between              if end - start <= 1:                  continue                # Calculate distance to points              P1 = data[start]              P2 = data[end]              points = data[start + 1 : end]              dsq = RDP.dsquared_line_points(P1, P2, points)                mask_eps = dsq > epsilon**2                if mask_eps.any():                  # max point outside eps                  # Include index that was sliced out                  # Also include the start index to get absolute index                  # And not relative                  mid = np.argmax(dsq) + 1 + start                  stack.append((start, mid))  # type: ignore                  stack.append((mid, end))  # type: ignore                else:                  # Points in between are redundant                  mask[start + 1 : end] = False            return mask        @staticmethod      def __rdp_points(M, n_out):          M_len = M.shape[0]            if M_len <= n_out:              mask = np.empty(M_len, dtype=bool)              mask.fill(True)              return mask            weights = np.empty(M_len)          # weights.fill(0)          weights[0] = float("inf")          weights[M_len - 1] = float("inf")            stack = [(0, M_len - 1)]            while stack:              (start, end) = stack.pop()              if end - start <= 1:                  continue              dsq = RDP.dsquared_line_points(M[start], M[end], M[start + 1 : end])              max_dist_index = np.argmax(dsq) + start + 1              weights[max_dist_index] = np.amax(dsq)              stack.append((start, max_dist_index))              stack.append((max_dist_index, end))            maxTolerance = np.sort(weights)[M_len - n_out]            return weights >= maxTolerance        def decimate(self, data: np.ndarray, payload: t.Dict[str, t.Any]) -> np.ndarray:          if self._epsilon:              return RDP.__rdp_epsilon(data, self._epsilon)          elif self._n_out:              return RDP.__rdp_points(data, self._n_out)          raise RuntimeError("RDP Decimator failed to run. Fill in either 'epsilon' or 'n_out' value")


import typing as t    from ..utils.singleton import _Singleton    if t.TYPE_CHECKING:      from ._element import _Block      class _BuilderContextManager(object, metaclass=_Singleton):      def __init__(self):          self.__blocks: t.List["_Block"] = []        def push(self, element: "_Block") -> None:          self.__blocks.append(element)        def pop(self) -> t.Optional["_Block"]:          return self.__blocks.pop() if self.__blocks else None        def peek(self) -> t.Optional["_Block"]:          return self.__blocks[-1] if self.__blocks else None


from ._api_generator import _ElementApiGenerator  from ._element import html    # separate import for "Page" class so stubgen can properly generate pyi file  from .page import Page    _ElementApiGenerator().add_default()


import typing as t    from .._renderers import _Renderer  from ._context_manager import _BuilderContextManager  from ._element import _Block, _DefaultBlock, _Element      class Page(_Renderer):      """Page generator for the Builder API.        This class is used to create a page created with the Builder API.
      Instance of this class can be added to the application using `Gui.add_page()^`.        This class is typically be used as a Python Context Manager to add the elements.
      Here is how you can create a single-page application, creating the elements with code:      ```py      from taipy.gui import Gui      from taipy.gui.builder import Page, button        def do_something(state):          pass        with Page() as page:          button(label="Press me", on_action=do_something)        Gui(page).run()      ```      """        def __init__(self, element: t.Optional[_Element] = None, **kwargs) -> None:          """Initialize a new page.            Arguments:              element (*Element*): An optional element, defined in the `taipy.gui.builder` module,                  that is created in the page.
                  The default creates a `part` where several elements can be stored.          """          if element is None:              element = _DefaultBlock()          kwargs["content"] = element          super().__init__(**kwargs)        # Generate JSX from Element Object      def render(self, gui) -> str:          if self._base_element is None:              return "
No Base Element found for Page
"          return self._base_element._render(gui)        def add(self, *elements: _Element):          if not isinstance(self._base_element, _Block):              raise RuntimeError("Can't add child element to non-block element")          for element in elements:              if element not in self._base_element._children:                  self._base_element._children.append(element)          return self        def __enter__(self):          if self._base_element is None:              raise RuntimeError("Can't use context manager with missing block element for Page")          if not isinstance(self._base_element, _Block):              raise RuntimeError("Can't add child element to non-block element")          _BuilderContextManager().push(self._base_element)          return self        def __exit__(self, exc_type, exc_value, traceback):          _BuilderContextManager().pop()


import typing as t    from .._renderers.factory import _Factory      class _BuilderFactory(_Factory):      @staticmethod      def create_element(gui, element_type: str, properties: t.Dict[str, t.Any]) -> t.Tuple[str, str]:          builder_html = _Factory.call_builder(gui, element_type, properties, True)          if builder_html is None:              return f"<div>INVALID SYNTAX - Element is '{element_type}'", "div"          return builder_html  # type: ignore


from __future__ import annotations    import copy  import typing as t  from abc import ABC, abstractmethod  from collections.abc import Iterable    from ._context_manager import _BuilderContextManager  from ._factory import _BuilderFactory    if t.TYPE_CHECKING:      from ..gui import Gui      class _Element(ABC):      """NOT DOCUMENTED"""        _ELEMENT_NAME = ""      _DEFAULT_PROPERTY = ""        def __new__(cls, *args, **kwargs):          obj = super(_Element, cls).__new__(cls)          parent = _BuilderContextManager().peek()          if parent is not None:              parent.add(obj)          return obj        def __init__(self, *args, **kwargs):          self._properties: t.Dict[str, t.Any] = {}          if args and self._DEFAULT_PROPERTY != "":              self._properties = {self._DEFAULT_PROPERTY: args[0]}          self._properties.update(kwargs)          self.parse_properties()        def update(self, **kwargs):          self._properties.update(kwargs)          self.parse_properties()        # Convert property value to string      def parse_properties(self):          self._properties = {k: _Element._parse_property(v) for k, v in self._properties.items()}        # Get a deepcopy version of the properties      def _deepcopy_properties(self):          return copy.deepcopy(self._properties)        @staticmethod      def _parse_property(value: t.Any) -> t.Any:          if isinstance(value, (str, dict, Iterable)):              return value          if hasattr(value, "__name__"):              return str(getattr(value, "__name__"))          return str(value)        @abstractmethod      def _render(self, gui: "Gui") -> str:          pass      class _Block(_Element):      """NOT DOCUMENTED"""        def __init__(self, *args, **kwargs):          super().__init__(*args, **kwargs)          self._children: t.List[_Element] = []        def add(self, *elements: _Element):          for element in elements:              if element not in self._children:                  self._children.append(element)          return self        def __enter__(self):          _BuilderContextManager().push(self)          return self        def __exit__(self, exc_type, exc_value, traceback):          _BuilderContextManager().pop()        def _render(self, gui: "Gui") -> str:          el = _BuilderFactory.create_element(gui, self._ELEMENT_NAME, self._deepcopy_properties())          return f"{el[0]}{self._render_children(gui)}</{el[1]}>"        def _render_children(self, gui: "Gui") -> str:          return "\n".join([child._render(gui) for child in self._children])      class _DefaultBlock(_Block):      _ELEMENT_NAME = "part"        def __init__(self, *args, **kwargs):          super().__init__(*args, **kwargs)      class html(_Block):      """A visual element defined as an HTML tag.        Use this class to integrate raw HTML to your page.        This element can be used as a block element.      """        def __init__(self, *args, **kwargs):          """Create a new `html` block.            Arguments:              args (any[]): A list of one or two unnamed arguments:                    - *args[0]* is the HTML tag name. If empty or None, this represents an HTML text                    node.                  - *args[1]* (optional) is the text of this element.
                    Note that special HTML characters (such as '<' or '&') do not need to be protected.              kwargs (dict[str, any]): the HTML attributes for this element.
                  These should be valid attribute names, with valid attribute values.            Examples:              - To generate `<br/>`, use:                 ```                 html("br")                 ```              - To generate `<h1>My page title</h1>`, use:                 ```                 html("h1", "My page title")                 ```              - To generate `<h1 id="page-title">My page title</h1>`, use:                 ```                 html("h1", "My page title", id="page-title")                 ```              - To generate `<p>This is a <b>Taipy GUI</b> element.</p>`, use:                 ```                 with html("p"):                     html(None, "This is a ")                     html("b", "Taipy GUI")                     html(None, " element.")                 ```          """          super().__init__(*args, **kwargs)          if not args:              raise RuntimeError("Can't render html element. Missing html tag name.")          self._ELEMENT_NAME = args[0] if args[0] else None          self._content = args[1] if len(args) > 1 else ""        def _render(self, gui: "Gui") -> str:          if self._ELEMENT_NAME:              attrs = ""              if self._properties:                  attrs = " " + " ".join([f'{k}="{str(v)}"' for k, v in self._properties.items()])              return f"<{self._ELEMENT_NAME}{attrs}>{self._content}{self._render_children(gui)}</{self._ELEMENT_NAME}>"          else:              return self._content      class _Control(_Element):      """NOT DOCUMENTED"""        def __init__(self, *args, **kwargs):          super().__init__(*args, **kwargs)        def _render(self, gui: "Gui") -> str:          el = _BuilderFactory.create_element(gui, self._ELEMENT_NAME, self._deepcopy_properties())          return (              f"
{el[0]}</{el[1]}>
"              if f"<{el[1]}" in el[0] and f"</{el[1]}" not in el[0]              else f"
{el[0]}
"          )        def __enter__(self):          raise RuntimeError(f"Can't use Context Manager for control type '{self._ELEMENT_NAME}'")        def __exit__(self, exc_type, exc_value, traceback):          raise RuntimeError(f"Can't use Context Manager for control type '{self._ELEMENT_NAME}'")


import inspect  import json  import os  import sys  import types  import typing as t    from taipy.logger._taipy_logger import _TaipyLogger    from ..utils.singleton import _Singleton  from ._element import _Block, _Control    if t.TYPE_CHECKING:      from ..extension.library import ElementLibrary      class _ElementApiGenerator(object, metaclass=_Singleton):      def __init__(self):          self.__module: t.Optional[types.ModuleType] = None        @staticmethod      def find_default_property(property_list: t.List[t.Dict[str, t.Any]]) -> str:          for property in property_list:              if "default_property" in property and property["default_property"] is True:                  return property["name"]          return ""        def add_default(self):          current_frame = inspect.currentframe()          error_message = "Cannot generate elements API for the current module"          if current_frame is None:              raise RuntimeError(f"{error_message}: No frame found.")          if current_frame.f_back is None:              raise RuntimeError(f"{error_message}: taipy-gui module not found.")          module_name = current_frame.f_back.f_globals["__name__"]          self.__module = module = sys.modules[module_name]          with open(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "viselements.json"))) as viselements:              data = json.load(viselements)              if "blocks" not in data or "controls" not in data:                  raise RuntimeError(f"{error_message}: Invalid viselements.json file.")              for blockElement in data["blocks"]:                  default_property = _ElementApiGenerator.find_default_property(blockElement[1]["properties"])                  setattr(                      module,                      blockElement[0],                      _ElementApiGenerator.create_block_api(blockElement[0], blockElement[0], default_property),                  )              for controlElement in data["controls"]:                  default_property = _ElementApiGenerator.find_default_property(controlElement[1]["properties"])                  setattr(                      module,                      controlElement[0],                      _ElementApiGenerator.create_control_api(controlElement[0], controlElement[0], default_property),                  )        def add_library(self, library: "ElementLibrary"):          library_name = library.get_name()          if self.__module is None:              _TaipyLogger._get_logger().info(                  f"Python API for extension library '{library_name}' is not available. To fix this, import 'taipy.gui.builder' before importing the extension library."              )              return          library_module = getattr(self.__module, library_name, None)          if library_module is None:              library_module = types.ModuleType(library_name)              setattr(self.__module, library_name, library_module)          for element_name, element in library.get_elements().items():              setattr(                  library_module,                  element_name,                  _ElementApiGenerator().create_control_api(                      element_name, f"{library_name}.{element_name}", element.default_attribute                  ),              )        @staticmethod      def create_block_api(          classname: str,          element_name: str,          default_property: str,      ):          return _ElementApiGenerator.create_element_api(classname, element_name, default_property, _Block)        @staticmethod      def create_control_api(          classname: str,          element_name: str,          default_property: str,      ):          return _ElementApiGenerator.create_element_api(classname, element_name, default_property, _Control)        @staticmethod      def create_element_api(          classname: str,          element_name: str,          default_property: str,          ElementBaseClass: t.Union[t.Type[_Block], t.Type[_Control]],      ):          return type(              classname,              (ElementBaseClass,),              {                  "__init__": lambda self, *args, **kwargs: ElementBaseClass.__init__(self, *args, **kwargs),                  "_ELEMENT_NAME": element_name,                  "_DEFAULT_PROPERTY": default_property,              },          )


import typing as t  from abc import ABC, abstractmethod  from os import path    from ..page import Page  from ..utils import _is_in_notebook, _varname_from_content  from ._html import _TaipyHTMLParser    if t.TYPE_CHECKING:      from ..builder._element import _Element      from ..gui import Gui      class _Renderer(Page, ABC):      def __init__(self, **kwargs) -> None:          """NOT DOCUMENTED          Initialize a new _Renderer with the indicated content.            Arguments:              content (str): The text content or the path to the file holding the text to be transformed.            If *content* is a path to a readable file, the file is read entirely as the text template.          """          from ..builder._element import _Element            super().__init__(**kwargs)          content: t.Optional[t.Union[str, _Element]] = kwargs.get("content", None)          if content is None:              raise ValueError("'content' argument is missing for class '_Renderer'")          self._content = ""          self._base_element: t.Optional[_Element] = None          self._filepath = ""          if isinstance(content, str):              self.__process_content(content)          elif isinstance(content, _Element):              self._base_element = content          else:              raise ValueError(                  f"'content' argument has incorrect type '{type(content).__name__}'. This must be a string or an Builder element."              )        def __process_content(self, content: str) -> None:          if path.exists(content) and path.isfile(content):              return self.__parse_file_content(content)          if self._frame is not None:              frame_dir_path = path.dirname(path.abspath(self._frame.f_code.co_filename))              content_path = path.join(frame_dir_path, content)              if path.exists(content_path) and path.isfile(content_path):                  return self.__parse_file_content(content_path)          self._content = content        def __parse_file_content(self, content):          with open(t.cast(str, content), "r") as f:              self._content = f.read()              # Save file path for error handling              self._filepath = content        def set_content(self, content: str) -> None:          """Set a new page content.            Reads the new page content and reinitializes the `Page^` instance to reflect the change.            !!! important              This function can only be used in an IPython notebook context.            Arguments:              content (str): The text content or the path to the file holding the text to be transformed.                  If *content* is a path to a readable file, the file is read entirely as the text                  template.            Exceptions:              RuntimeError: If this method is called outside an IPython notebook context.          """          if not _is_in_notebook():              raise RuntimeError("'set_content()' must be used in an IPython notebook context")          self.__process_content(content)        def _get_content_detail(self, gui: "Gui") -> str:          if self._filepath:              return f"in file '{self._filepath}'"          if varname := _varname_from_content(gui, self._content):              return f"in variable '{varname}'"          return ""        @abstractmethod      def render(self, gui: "Gui") -> str:          pass      class _EmptyPage(_Renderer):      def __init__(self) -> None:          super().__init__(content="<PageContent />")        def render(self, gui: "Gui") -> str:          return self._content      class Markdown(_Renderer):      """Page generator for *Markdown* text.        Taipy can use Markdown text to create pages that are the base of      user interfaces.        You can find details on the Taipy Markdown-specific syntax and how to add      Taipy Visual Elements in the [section on HTML](../gui/pages/index.md#using-markdown)      of the User Manual.      """        def __init__(self, content: str, **kwargs) -> None:          """Initialize a new `Markdown` page.            Arguments:              content (str): The text content or the path to the file holding the Markdown text                  to be transformed.
                  If _content_ is a path to a readable file, the file is read as the Markdown                  template content.          """          kwargs["content"] = content          super().__init__(**kwargs)        # Generate JSX from Markdown      def render(self, gui: "Gui") -> str:          return gui._markdown.convert(self._content)      class Html(_Renderer):      """Page generator for *HTML* text.        Taipy can use HTML code to create pages that are the base of      user interfaces.        You can find details on HTML-specific constructs and how to add      Taipy Visual Elements in the [section on HTML](../gui/pages/index.md#using-html)      of the User Manual.      """        def __init__(self, content: str, **kwargs) -> None:          """Initialize a new `Html` page.            Arguments:              content (str): The text content or the path to the file holding the HTML text to                  be transformed.
                  If *content* is a path to a readable file, the file is read as the HTML                  template content.          """          kwargs["content"] = content          super().__init__(**kwargs)          self.head = None        # Modify path routes      def modify_taipy_base_url(self, base_url):          self._content = self._content.replace("{{taipy_base_url}}", f"{base_url}")        # Generate JSX from HTML      def render(self, gui: "Gui") -> str:          parser = _TaipyHTMLParser(gui)          parser.feed_data(self._content)          self.head = parser.head          return parser.get_jsx()


import typing as t    from .._warnings import _warn  from ..types import NumberTypes  from ..utils import _RE_PD_TYPE, _get_date_col_str_name, _MapDict      def _add_to_dict_and_get(dico: t.Dict[str, t.Any], key: str, value: t.Any) -> t.Any:      if key not in dico.keys():          dico[key] = value      return dico[key]      def _get_tuple_val(attr: tuple, index: int, default_val: t.Any) -> t.Any:      return attr[index] if len(attr) > index else default_val      def _get_columns_dict_from_list(      col_list: t.Union[t.List[str], t.Tuple[str]], col_types_keys: t.List[str], value: t.Any  ):      col_dict = {}      idx = 0      for col in col_list:          if col in col_types_keys:              col_dict[col] = {"index": idx}              idx += 1          elif col:              _warn(                  f'Error column "{col}" is not present in the Dataframe "{value.head(0) if hasattr(value, "head") else value}".'              )      return col_dict      def _get_columns_dict(  # noqa: C901      value: t.Any,      columns: t.Union[str, t.List[str], t.Tuple[str], t.Dict[str, t.Any], _MapDict],      col_types: t.Optional[t.Dict[str, str]] = None,      date_format: t.Optional[str] = None,      number_format: t.Optional[str] = None,      opt_columns: t.Optional[t.Set[str]] = None,  ):      if col_types is None:          return None      col_dict: t.Optional[dict] = None      if isinstance(columns, str):          col_dict = _get_columns_dict_from_list([s.strip() for s in columns.split(";")], col_types_keys, value)      elif isinstance(columns, (list, tuple)):          col_dict = _get_columns_dict_from_list(columns, col_types_keys, value)      elif isinstance(columns, _MapDict):          col_dict = columns._dict.copy()      elif isinstance(columns, dict):          col_dict = columns.copy()      if not isinstance(col_dict, dict):          _warn("Error: columns attributes should be a string, a list, a tuple or a dict.")          col_dict = {}      nb_cols = len(col_dict)      if nb_cols == 0:          for col in col_types_keys:              col_dict[col] = {"index": nb_cols}              nb_cols += 1      else:          col_dict = {str(k): v for k, v in col_dict.items()}          if opt_columns:              for col in opt_columns:                  if col in col_types_keys and col not in col_dict:                      col_dict[col] = {"index": nb_cols}                      nb_cols += 1      idx = 0      for col, ctype in col_types.items():          col = str(col)          if col in col_dict:              re_type = _RE_PD_TYPE.match(ctype)              grps = re_type.groups() if re_type else ()              ctype = grps[0] if grps else ctype              col_dict[col]["type"] = ctype              col_dict[col]["dfid"] = col              if len(grps) > 4 and grps[4]:                  col_dict[col]["tz"] = grps[4]              idx = _add_to_dict_and_get(col_dict[col], "index", idx) + 1              if ctype == "datetime":                  if date_format:                      _add_to_dict_and_get(col_dict[col], "format", date_format)                  col_dict[_get_date_col_str_name(col_types.keys(), col)] = col_dict.pop(col)  # type: ignore              elif number_format and ctype in NumberTypes:                  _add_to_dict_and_get(col_dict[col], "format", number_format)      return col_dict


#  # 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 __future__ import annotations    from datetime import date, datetime, time  from json import JSONEncoder  from pathlib import Path    from flask.json.provider import DefaultJSONProvider    from .._warnings import _warn  from ..icon import Icon  from ..utils import _date_to_string, _MapDict, _TaipyBase      def _default(o):      if isinstance(o, Icon):          return o._to_dict()      if isinstance(o, _MapDict):          return o._dict      if isinstance(o, _TaipyBase):          return o.get()      if isinstance(o, (datetime, date, time)):          return _date_to_string(o)      if isinstance(o, Path):          return str(o)      try:          raise TypeError(f"Object of type {o.__class__.__name__} is not JSON serializable")      except Exception as e:          _warn("Exception in JSONEncoder", e)          return None      class _TaipyJsonEncoder(JSONEncoder):      def default(self, o):          return _default(o)      class _TaipyJsonProvider(DefaultJSONProvider):      default = staticmethod(_default)  # type: ignore      sort_keys = False


from markdown.treeprocessors import Treeprocessor    from ..builder import _Builder      class _Postprocessor(Treeprocessor):      @staticmethod      def extend(md, gui, priority):          instance = _Postprocessor(md)          md.treeprocessors.register(instance, "taipy", priority)          instance._gui = gui        def run(self, root):          MD_PARA_CLASSNAME = "md-para"          for p in root.iter():              if p.tag == "p":                  classes = p.get("class")                  classes = f"{MD_PARA_CLASSNAME} {classes}" if classes else MD_PARA_CLASSNAME                  p.set("class", classes)                  p.tag = "div"              if p != root:                  p.set("key", _Builder._get_key(p.tag))          return root


from markdown.inlinepatterns import InlineProcessor    from .factory import _MarkdownFactory      class _ControlPattern(InlineProcessor):      __PATTERN = _MarkdownFactory._TAIPY_START + r"([a-zA-Z][\.a-zA-Z_$0-9]*)(.*?)" + _MarkdownFactory._TAIPY_END        @staticmethod      def extend(md, gui, priority):          instance = _ControlPattern(_ControlPattern.__PATTERN, md)          md.inlinePatterns.register(instance, "taipy", priority)          instance._gui = gui        def handleMatch(self, m, data):          return _MarkdownFactory.create_element(self._gui, m.group(1), m.group(2)), m.start(0), m.end(0)


import re    from markdown.blockprocessors import BlockProcessor    from .factory import _MarkdownFactory      class _StartBlockProcessor(BlockProcessor):      __RE_FENCE_START = re.compile(          _MarkdownFactory._TAIPY_START + r"([a-zA-Z][\.a-zA-Z_$0-9]*)\.start(.*?)" + _MarkdownFactory._TAIPY_END      )  # start line      __RE_OTHER_FENCE = re.compile(          _MarkdownFactory._TAIPY_START + r"([a-zA-Z][\.a-zA-Z_$0-9]*)\.(start|end)(.*?)" + _MarkdownFactory._TAIPY_END      )  # start or end tag        @staticmethod      def extend(md, gui, priority):          instance = _StartBlockProcessor(md.parser)          md.parser.blockprocessors.register(instance, "taipy", priority)          instance._gui = gui        def test(self, parent, block):          return re.match(_StartBlockProcessor.__RE_FENCE_START, block)        def run(self, parent, blocks):          original_block = blocks[0]          original_match = re.search(_StartBlockProcessor.__RE_FENCE_START, original_block)          blocks[0] = re.sub(_StartBlockProcessor.__RE_FENCE_START, "", blocks[0], 1)          tag = original_match.group(1)          queue = [tag]          # Find block with ending fence          for block_num, block in enumerate(blocks):              matches = re.findall(_StartBlockProcessor.__RE_OTHER_FENCE, block)              for match in matches:                  if queue[-1] == match[0] and match[1] == "end":                      queue.pop()                  elif match[1] == "start":                      queue.append(match[0])              if not queue:                  # remove end fence                  blocks[block_num] = re.sub(                      _MarkdownFactory._TAIPY_START + tag + r"\.end(.*?)" + _MarkdownFactory._TAIPY_END,                      "",                      block,                      1,                  )                  # render fenced area inside a new div                  e = _MarkdownFactory.create_element(self._gui, original_match.group(1), original_match.group(2))                  parent.append(e)                  # parse inside blocks                  self.parser.parseBlocks(e, blocks[: block_num + 1])                  # remove used blocks                  del blocks[: block_num + 1]                  return True  # or could have had no return statement          # No closing marker!  Restore and do nothing          blocks[0] = original_block          return False  # equivalent to our test() routine returning False


from typing import Any    from markdown.extensions import Extension    from .blocproc import _StartBlockProcessor  from .control import _ControlPattern  from .postproc import _Postprocessor  from .preproc import _Preprocessor      class _TaipyMarkdownExtension(Extension):      config = {"gui": ["", "Gui object for extension"]}        def extendMarkdown(self, md):          from ...gui import Gui            gui = self.config["gui"][0]          if not isinstance(gui, Gui):              raise RuntimeError("Gui instance is not bound to Markdown Extension")          md.registerExtension(self)          _Preprocessor.extend(md, gui, 210)          _ControlPattern.extend(md, gui, 205)          _StartBlockProcessor.extend(md, gui, 175)          _Postprocessor.extend(md, gui, 200)


import typing as t    from ..factory import _Factory      class _MarkdownFactory(_Factory):      # Taipy Markdown tags      _TAIPY_START = "TaIpY:"      _TAIPY_END = ":tAiPy"        _TAIPY_BLOCK_TAGS = ["layout", "part", "expandable", "dialog", "pane"]        @staticmethod      def create_element(gui, control_type: str, all_properties: str) -> t.Union[t.Any, str]:          # Create properties dict from all_properties          property_pairs = _Factory._PROPERTY_RE.findall(all_properties)          properties = {property[0]: property[1] for property in property_pairs}          builder_md = _Factory.call_builder(gui, control_type, properties)          if builder_md is None:              return f"<|INVALID SYNTAX - Control is '{control_type}'|>"          return builder_md


from .parser import _TaipyHTMLParser


import typing as t    from ..factory import _Factory      class _HtmlFactory(_Factory):      @staticmethod      def create_element(gui, namespace: str, control_type: str, all_properties: t.Dict[str, str]) -> t.Tuple[str, str]:          builder_html = _Factory.call_builder(gui, f"{namespace}.{control_type}", all_properties, True)          if builder_html is None:              return f"
INVALID SYNTAX - Control is '{namespace}:{control_type}'
", "div"          return builder_html  # type: ignore


import re  import typing as t  from html.parser import HTMLParser    from ..._warnings import _warn  from .factory import _HtmlFactory      class _TaipyHTMLParser(HTMLParser):      __TAIPY_NAMESPACE_RE = re.compile(r"([a-zA-Z\_]+):([a-zA-Z\_]*)")        def __init__(self, gui):          super().__init__()          self._gui = gui          self.body = ""          self.head = []          self.taipy_tag = None          self.tag_mapping = {}          self.is_body = True          self.head_tag = None          self._line_count = 0          self._tag_queue = []        # @override      def handle_starttag(self, tag, props) -> None:          self._tag_queue.append((tag, self._line_count))          if tag == "html":              return          if self.head_tag is not None:              self.head.append(self.head_tag)              self.head_tag = None          if self.taipy_tag is not None:              self.parse_taipy_tag()          if tag == "head":              self.is_body = False          elif tag == "body":              self.is_body = True          elif m := self.__TAIPY_NAMESPACE_RE.match(tag):              self.taipy_tag = _TaipyTag(m.group(1), m.group(2), props)          elif not self.is_body:              head_props = {prop[0]: prop[1] for prop in props}              self.head_tag = {"tag": tag, "props": head_props, "content": ""}          else:              self.append_data(str(self.get_starttag_text()))        # @override      def handle_data(self, data: str) -> None:          data = data.strip()          if data and self.taipy_tag is not None and self.taipy_tag.set_value(data):              self.parse_taipy_tag()          elif not self.is_body and self.head_tag is not None:              self.head_tag["content"] = data          else:              self.append_data(data)        # @override      def handle_endtag(self, tag) -> None:          if not self._tag_queue:              _warn(f"Closing '{tag}' at line {self._line_count} is missing an opening tag.")          else:              opening_tag, opening_tag_line = self._tag_queue.pop()              if opening_tag != tag:                  _warn(                      f"Opening tag '{opening_tag}' at line {opening_tag_line} has no matching closing tag '{tag}' at line {self._line_count}."                  )          if tag in ["head", "body", "html"]:              return          if self.taipy_tag is not None:              self.parse_taipy_tag()          if not self.is_body:              self.head.append(self.head_tag)              self.head_tag = None          elif tag in self.tag_mapping:              self.append_data(f"</{self.tag_mapping[tag]}>")          else:              self.append_data(f"</{tag}>")        def append_data(self, data: str) -> None:          if self.is_body:              self.body += data        def parse_taipy_tag(self) -> None:          tp_string, tp_element_name = self.taipy_tag.parse(self._gui)          self.append_data(tp_string)          self.tag_mapping[f"{self.taipy_tag.namespace}:{self.taipy_tag.control_type}"] = tp_element_name          self.taipy_tag = None        def get_jsx(self) -> str:          return self.body        def feed_data(self, data: str):          data_lines = data.split("\n")          for line, data_line in enumerate(data_lines):              self._line_count = line + 1              self.feed(data_line)          while self._tag_queue:              opening_tag, opening_tag_line = self._tag_queue.pop()              _warn(f"Opening tag '{opening_tag}' at line {opening_tag_line} has no matching closing tag.")      class _TaipyTag(object):      def __init__(self, namespace: str, tag_name: str, properties: t.List[t.Tuple[str, str]]) -> None:          self.namespace = namespace          self.control_type = tag_name          self.properties = {prop[0]: prop[1] for prop in properties}          self.has_set_value = False        def set_value(self, value: str) -> bool:          if self.has_set_value:              return False          property_name = _HtmlFactory.get_default_property_name(f"{self.namespace}.{self.control_type}")          # Set property only if it is not already defined          if property_name and property_name not in self.properties.keys():              self.properties[property_name] = value          self.has_set_value = True          return True        def parse(self, gui) -> t.Tuple[str, str]:          for k, v in self.properties.items():              self.properties[k] = v if v is not None else "true"          # allow usage of 'class' property in html taipy tag          if "class" in self.properties and "class_name" not in self.properties:              self.properties["class_name"] = self.properties["class"]          return _HtmlFactory.create_element(gui, self.namespace, self.control_type, self.properties)


import pandas as pd  from taipy import Gui    # ---- READ EXCEL ----  df = pd.read_excel(      io="data/supermarkt_sales.xlsx",      engine="openpyxl",      sheet_name="Sales",      skiprows=3,      usecols="B:R",      nrows=1000,  )  # Add 'hour' column to dataframe  df["hour"] = pd.to_datetime(df["Time"], format="%H:%M:%S").dt.hour      # initialization of variables  cities = list(df["City"].unique())  types = list(df["Customer_type"].unique())  genders = list(df["Gender"].unique())  city = cities  customer_type = types  gender = genders    layout = {"margin": {"l": 220}}    # Markdown for the entire page  ## NOTE: {: .orange} references a color from main.css use to style my text  ## <text|  ## |text>  ## "text" here is just a name given to my part/my section  ## it has no meaning in the code  page = """<|toggle|theme|>    <|layout|columns=20 80|gap=30px|  <sidebar|  ## Please **filter**{: .orange} here:    <|{city}|selector|lov={cities}|multiple|label=Select the City|dropdown|on_change=on_filter|width=100%|>    <|{customer_type}|selector|lov={types}|multiple|label=Select the Customer Type|dropdown|on_change=on_filter|width=100%|>    <|{gender}|selector|lov={genders}|multiple|label=Select the Gender|dropdown|on_change=on_filter|width=100%|>  |sidebar>    <main_page|  # 📊 **Sales**{: .orange} Dashboard    <|layout|columns=1 1 1|  <total_sales|  ## **Total**{: .orange} sales:  ### US $ <|{int(df_selection["Total"].sum())}|>  |total_sales>    <average_rating|  ## **Average**{: .orange} Rating:  ### <|{round(df_selection["Rating"].mean(), 1)}|> <|{"⭐" * int(round(round(df_selection["Rating"].mean(), 1), 0))}|>  |average_rating>    <average_sale|  ## Average Sales Per **Transaction**{: .orange}:  ### US $ <|{round(df_selection["Total"].mean(), 2)}|>  |average_sale>  |>    <br/>    Display df_selection in an expandable  <|Sales Table|expandable|expanded=False|  <|{df_selection}|table|width=100%|page_size=5|rebuild|class_name=table|>  |>    <charts|  <|{sales_by_hour}|chart|x=Hour|y=Total|type=bar|title=Sales by Hour|color=#ff462b|>    <|{sales_by_product_line}|chart|x=Total|y=Product|type=bar|orientation=h|title=Sales by Product|layout={layout}|color=#ff462b|>  |charts>  |main_page>  |>    Code from [Coding is Fun](https://github.com/Sven-Bo)    Get the Taipy Code [here](https://github.com/Avaiga/demo-sales-dashboard) and the original code [here](https://github.com/Sven-Bo/streamlit-sales-dashboard)  """      def filter(city, customer_type, gender):      df_selection = df[          df["City"].isin(city)          & df["Customer_type"].isin(customer_type)          & df["Gender"].isin(gender)      ]        # SALES BY PRODUCT LINE [BAR CHART]      sales_by_product_line = (          df_selection[["Product line", "Total"]]          .groupby(by=["Product line"])          .sum()[["Total"]]          .sort_values(by="Total")      )      sales_by_product_line["Product"] = sales_by_product_line.index        # SALES BY HOUR [BAR CHART]      sales_by_hour = (          df_selection[["hour", "Total"]].groupby(by=["hour"]).sum()[["Total"]]      )      sales_by_hour["Hour"] = sales_by_hour.index      return df_selection, sales_by_product_line, sales_by_hour      def on_filter(state):      state.df_selection, state.sales_by_product_line, state.sales_by_hour = filter(          state.city, state.customer_type, state.gender      )      if __name__ == "__main__":      # initialize dataframes      df_selection, sales_by_product_line, sales_by_hour = filter(          city, customer_type, gender      )        # run the app      Gui(page).run()


from taipy.gui import Markdown  import numpy as np    import json    from data.data import data      type_selector = ['Absolute', 'Relative']  selected_type = type_selector[0]      def initialize_world(data):      data_world = data.groupby(["Country/Region",                                      'Date'])\                              .sum()\                              .reset_index()        with open("data/pop.json","r") as f:                              pop = json.load(f)            data_world['Population'] = data_world['Country/Region'].map(lambda x: pop.get(x, [None, 0])[1])        data_world = data_world.dropna()\                              .reset_index()      data_world['Deaths/100k'] = data_world.loc[:,'Deaths']/data_world.loc[:,'Population']*100000            data_world_pie_absolute = data_world[['Country/Region', 'Deaths', 'Recovered', 'Confirmed']].groupby(["Country/Region"])\                                          .max()\                                          .sort_values(by='Deaths', ascending=False)[:20]\                                          .reset_index()                                        data_world_pie_relative = data_world[['Country/Region', 'Deaths/100k']].groupby(["Country/Region"])\                                          .max()\                                          .sort_values(by='Deaths/100k', ascending=False)[:20]\                                          .reset_index()            country_absolute = data_world_pie_absolute['Country/Region'].unique().tolist()      country_relative = data_world_pie_relative.loc[:,'Country/Region'].unique().tolist()                           data_world_evolution_absolute = data_world[data_world['Country/Region'].str.contains('|'.join(country_absolute),regex=True)]      data_world_evolution_absolute = data_world_evolution_absolute.pivot(index='Date', columns='Country/Region', values='Deaths')\                                       .reset_index()            data_world_evolution_relative = data_world[data_world['Country/Region'].str.contains('|'.join(country_relative),regex=True)]      data_world_evolution_relative = data_world_evolution_relative.pivot(index='Date', columns='Country/Region', values='Deaths/100k')\                                       .reset_index()      return data_world, data_world_pie_absolute, data_world_pie_relative, data_world_evolution_absolute, data_world_evolution_relative        data_world,\  data_world_pie_absolute, data_world_pie_relative,\  data_world_evolution_absolute, data_world_evolution_relative = initialize_world(data)          data_world_evolution_absolute_properties = {"x":"Date"}  cols = [col for col in data_world_evolution_absolute.columns if col != "Date"]  for i in range(len(cols)):      data_world_evolution_absolute_properties[f'y[{i}]'] = cols[i]      data_world_evolution_relative_properties = {"x":"Date"}  cols = [col for col in data_world_evolution_relative.columns if col != "Date"]  for i in range(len(cols)):      data_world_evolution_relative_properties[f'y[{i}]'] = cols[i]              world_md = Markdown("pages/world/world.md")


from taipy.gui import Markdown, notify  import datetime as dt      selected_data_node = None  selected_scenario = None  selected_date = None  default_result = {"Date": [dt.datetime(2020,10,1)], "Deaths": [0], "ARIMA": [0], "Linear Regression": [0]}      def on_submission_change(state, submitable, details):      if details['submission_status'] == 'COMPLETED':          state.refresh('selected_scenario')          notify(state, "success", "Predictions ready!")          print("Predictions ready!")      elif details['submission_status'] == 'FAILED':          notify(state, "error", "Submission failed!")          print("Submission failed!")      else:          notify(state, "info", "In progress...")          print("In progress...")      def on_change_params(state):      if state.selected_date.year < 2020 or state.selected_date.year > 2021:          notify(state, "error", "Invalid date! Must be between 2020 and 2021")          state.selected_date = dt.datetime(2020,10,1)          return            state.selected_scenario.date.write(state.selected_date.replace(tzinfo=None))      state.selected_scenario.country.write(state.selected_country)      notify(state, "success", "Scenario parameters changed!")        state['Country'].on_change_country(state)      def on_change(state, var_name, var_value):      if var_name == 'selected_scenario' and var_value:          state.selected_date = state.selected_scenario.date.read()          state.selected_country = state.selected_scenario.country.read()      predictions_md = Markdown("pages/predictions/predictions.md")


from taipy.gui import Gui  from math import cos, exp    value = 10    page = """  Markdown  # Taipy *Demo*    Value: <|{value}|text|>    <|{value}|slider|on_change=on_slider|>    <|{data}|chart|>  """    def compute_data(decay:int)->list:      return [cos(i/6) * exp(-i*decay/600) for i in range(100)]    def on_slider(state):      state.data = compute_data(state.value)    data = compute_data(value)    Gui(page).run(use_reloader=True, port=5002)


from taipy.gui import Gui  import taipy as tp    from pages.country.country import country_md  from pages.world.world import world_md  from pages.map.map import map_md  from pages.predictions.predictions import predictions_md, selected_scenario  from pages.root import root, selected_country, selector_country    from config.config import Config    pages = {      '/':root,      "Country":country_md,      "World":world_md,      "Map":map_md,      "Predictions":predictions_md  }      gui_multi_pages = Gui(pages=pages)    if __name__ == '__main__':      tp.Core().run()            gui_multi_pages.run(title="Covid Dashboard")


import yfinance as yf  from taipy.gui import Gui  from taipy.gui.data.decimator import MinMaxDecimator, RDP, LTTB      df_AAPL = yf.Ticker("AAPL").history(interval="1d", period="100Y")  df_AAPL["DATE"] = df_AAPL.index.astype("int64").astype(float)    n_out = 500  decimator_instance = MinMaxDecimator(n_out=n_out)    decimate_data_count = len(df_AAPL)    page = """  # Decimator    From a data length of <|{len(df_AAPL)}|> to <|{n_out}|>    ## Without decimator    <|{df_AAPL}|chart|x=DATE|y=Open|>    ## With decimator    <|{df_AAPL}|chart|x=DATE|y=Open|decimator=decimator_instance|>  """    gui = Gui(page)  gui.run(port=5026)


# Create an app to upload a csv and display it in a table  from taipy.gui import Gui  import pandas as pd    data = []  data_path = ""      def data_upload(state):      state.data = pd.read_csv(state.data_path)      page = """  <|{data_path}|file_selector|on_action=data_upload|>  <|{data}|table|>  """    Gui(page).run()


import socket  import pickle  import math  from threading import Thread  from taipy.gui import Gui, State, invoke_callback, get_state_id  import numpy as np  import pandas as pd    init_lat = 49.247  init_long = 1.377    factory_lat = 49.246  factory_long = 1.369    diff_lat = abs(init_lat - factory_lat) * 15  diff_long = abs(init_long - factory_long) * 15    lats_unique = np.arange(init_lat - diff_lat, init_lat + diff_lat, 0.001)  longs_unique = np.arange(init_long - diff_long, init_long + diff_long, 0.001)    countdown = 20  periods = 0  line_data = pd.DataFrame({"Time": [], "Max AQI": []})    drone_data = pd.DataFrame(      {          "Drone ID": [43, 234, 32, 23, 5, 323, 12, 238, 21, 84],          "Battery Level": [              "86%",              "56%",              "45%",              "12%",              "85%",              "67%",              "34%",              "78%",              "90%",              "100%",          ],          "AQI": [40, 34, 24, 22, 33, 45, 23, 34, 23, 34],          "Status": [              "Moving",              "Measuring",              "Measuring",              "Stopped",              "Measuring",              "Moving",              "Moving",              "Measuring",              "Measuring",              "Measuring",          ],      }  )    HOST = "127.0.0.1"  PORT = 65432    layout_map = {      "mapbox": {          "style": "open-street-map",          "center": {"lat": init_lat, "lon": init_long},          "zoom": 13,      },      "dragmode": "false",      "margin": {"l": 0, "r": 0, "b": 0, "t": 0},  }    layout_line = {      "title": "Max Measured AQI over Time",      "yaxis": {"range": [0, 150]},  }    options = {      "opacity": 0.8,      "colorscale": "Bluered",      "zmin": 0,      "zmax": 140,      "colorbar": {"title": "AQI"},      "hoverinfo": "none",  }    config = {"scrollZoom": False, "displayModeBar": False}      def pollution(lat: float, long: float):      """      Return pollution level in percentage      Pollution should be centered around the factory      Pollution should decrease with distance to factory      Pollution should have an added random component        Args:          - lat: latitude          - long: longitude        Returns:          - pollution level      """      global countdown      return 80 * (0.5 + 0.5 * math.sin(countdown / 20)) * math.exp(          -(0.8 * (lat - factory_lat) ** 2 + 0.2 * (long - factory_long) ** 2) / 0.00005      ) + np.random.randint(0, 50)      lats = []  longs = []  pollutions = []  times = []  max_pollutions = []    for lat in lats_unique:      for long in longs_unique:          lats.append(lat)          longs.append(long)          pollutions.append(pollution(lat, long))    data_province_displayed = pd.DataFrame(      {          "Latitude": lats,          "Longitude": longs,          "Pollution": pollutions,      }  )    max_pollution = data_province_displayed["Pollution"].max()      # Socket handler  def client_handler(gui: Gui, state_id_list: list):      s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)      s.bind((HOST, PORT))      s.listen()      conn, _ = s.accept()      while True:          if data := conn.recv(1024 * 1024):              pollutions = pickle.loads(data)              print(f"Data received: {pollutions[:5]}")              if hasattr(gui, "_server") and state_id_list:                  invoke_callback(                      gui,                      state_id_list[0],                      update_pollutions,                      [pollutions],                  )          else:              print("Connection closed")              break      # Gui declaration  state_id_list = []    Gui.add_shared_variable("pollutions")      def on_init(state: State):      state_id = get_state_id(state)      if (state_id := get_state_id(state)) is not None and state_id != "":          state_id_list.append(state_id)      update_pollutions(state, pollutions)      def update_pollutions(state: State, val):      state.pollutions = val      state.data_province_displayed = pd.DataFrame(          {              "Latitude": lats,              "Longitude": longs,              "Pollution": state.pollutions,          }      )      # Add an hour to the time      state.periods = state.periods + 1      state.max_pollutions = state.max_pollutions + [max(state.pollutions)]      state.times = pd.date_range(          "2020-11-04", periods=len(state.max_pollutions), freq="H"      )      state.line_data = pd.DataFrame(          {              "Time": state.times,              "Max AQI": state.max_pollutions,          }      )      page = """  <|{data_province_displayed}|chart|type=densitymapbox|plot_config={config}|options={options}|lat=Latitude|lon=Longitude|layout={layout_map}|z=Pollution|mode=markers|class_name=map|height=40vh|>  <|layout|columns=1 2 2|  <|part|class_name=card|  **Max Measured AQI:**

  <|{int(data_province_displayed["Pollution"].max())}|indicator|value={int(data_province_displayed["Pollution"].max())}|min=140|max=0|>

  **Average Measured AQI:**

  <|{int(data_province_displayed["Pollution"].mean())}|indicator|value={int(data_province_displayed["Pollution"].mean())}|min=140|max=0|>  |>    <|part|class_name=card|  <|{drone_data}|table|show_all=True|>  |>    <|part|class_name=card|  <|{line_data[-30:]}|chart|type=lines|x=Time|y=Max AQI|layout={layout_line}|height=40vh|>  |>  |>  """  gui = Gui(page=page)    t = Thread(      target=client_handler,      args=(          gui,          state_id_list,      ),  )  t.start()  gui.run(run_browser=False)