streamlit-nightly 1.32.3.dev20240325__py2.py3-none-any.whl → 1.32.3.dev20240328__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. streamlit/__init__.py +4 -2
  2. streamlit/components/v1/__init__.py +3 -17
  3. streamlit/components/v1/{custom_component.py → components.py} +159 -11
  4. streamlit/delta_generator.py +3 -0
  5. streamlit/elements/media.py +52 -4
  6. streamlit/elements/widgets/time_widgets.py +5 -21
  7. streamlit/errors.py +0 -6
  8. streamlit/proto/AutoRerun_pb2.py +25 -0
  9. streamlit/proto/AutoRerun_pb2.pyi +48 -0
  10. streamlit/proto/ClientState_pb2.py +3 -3
  11. streamlit/proto/ClientState_pb2.pyi +4 -1
  12. streamlit/proto/Delta_pb2.py +2 -2
  13. streamlit/proto/Delta_pb2.pyi +4 -1
  14. streamlit/proto/ForwardMsg_pb2.py +10 -9
  15. streamlit/proto/ForwardMsg_pb2.pyi +12 -3
  16. streamlit/proto/NewSession_pb2.py +24 -24
  17. streamlit/proto/NewSession_pb2.pyi +8 -1
  18. streamlit/proto/PageProfile_pb2.py +6 -6
  19. streamlit/proto/PageProfile_pb2.pyi +4 -1
  20. streamlit/runtime/app_session.py +67 -24
  21. streamlit/runtime/caching/cache_data_api.py +3 -3
  22. streamlit/runtime/caching/cache_errors.py +0 -11
  23. streamlit/runtime/caching/cache_resource_api.py +2 -2
  24. streamlit/runtime/caching/cache_utils.py +1 -43
  25. streamlit/runtime/fragment.py +239 -0
  26. streamlit/runtime/metrics_util.py +17 -9
  27. streamlit/runtime/runtime.py +6 -12
  28. streamlit/runtime/runtime_util.py +54 -2
  29. streamlit/runtime/scriptrunner/script_requests.py +53 -37
  30. streamlit/runtime/scriptrunner/script_run_context.py +15 -2
  31. streamlit/runtime/scriptrunner/script_runner.py +63 -14
  32. streamlit/runtime/state/common.py +2 -0
  33. streamlit/runtime/state/session_state.py +51 -7
  34. streamlit/runtime/state/widgets.py +10 -2
  35. streamlit/static/asset-manifest.json +19 -19
  36. streamlit/static/index.html +1 -1
  37. streamlit/static/static/js/1074.73973756.chunk.js +1 -0
  38. streamlit/static/static/js/1451.3b0a3e31.chunk.js +1 -0
  39. streamlit/static/static/js/1792.b8efa879.chunk.js +1 -0
  40. streamlit/static/static/js/{3092.3d4df25e.chunk.js → 3092.ad569cc8.chunk.js} +1 -1
  41. streamlit/static/static/js/3513.e3e7300a.chunk.js +1 -0
  42. streamlit/static/static/js/4177.69f9f18d.chunk.js +1 -0
  43. streamlit/static/static/js/4319.a6745434.chunk.js +1 -0
  44. streamlit/static/static/js/{4477.2555c11a.chunk.js → 4477.e10e4373.chunk.js} +1 -1
  45. streamlit/static/static/js/{4666.99f3abc3.chunk.js → 4666.b694c5a9.chunk.js} +1 -1
  46. streamlit/static/static/js/5106.44f0ff51.chunk.js +1 -0
  47. streamlit/static/static/js/5379.6571574f.chunk.js +1 -0
  48. streamlit/static/static/js/6013.8e80e091.chunk.js +1 -0
  49. streamlit/static/static/js/6718.802da17e.chunk.js +1 -0
  50. streamlit/static/static/js/7175.be4076bc.chunk.js +1 -0
  51. streamlit/static/static/js/{7602.f0420392.chunk.js → 7602.6175e969.chunk.js} +1 -1
  52. streamlit/static/static/js/{8492.e6dab83f.chunk.js → 8492.f56c9d4c.chunk.js} +1 -1
  53. streamlit/static/static/js/8691.9ccf7f89.chunk.js +1 -0
  54. streamlit/static/static/js/main.722453f0.js +2 -0
  55. streamlit/testing/v1/local_script_runner.py +2 -0
  56. streamlit/time_util.py +88 -0
  57. streamlit/watcher/local_sources_watcher.py +2 -1
  58. streamlit/web/server/component_request_handler.py +2 -2
  59. streamlit/web/server/server.py +2 -1
  60. {streamlit_nightly-1.32.3.dev20240325.dist-info → streamlit_nightly-1.32.3.dev20240328.dist-info}/METADATA +1 -1
  61. {streamlit_nightly-1.32.3.dev20240325.dist-info → streamlit_nightly-1.32.3.dev20240328.dist-info}/RECORD +66 -68
  62. streamlit/components/lib/__init__.py +0 -13
  63. streamlit/components/lib/local_component_registry.py +0 -82
  64. streamlit/components/types/__init__.py +0 -13
  65. streamlit/components/types/base_component_registry.py +0 -98
  66. streamlit/components/types/base_custom_component.py +0 -137
  67. streamlit/components/v1/component_registry.py +0 -103
  68. streamlit/static/static/js/1074.71719df6.chunk.js +0 -1
  69. streamlit/static/static/js/1451.e3be1711.chunk.js +0 -1
  70. streamlit/static/static/js/1792.16c16498.chunk.js +0 -1
  71. streamlit/static/static/js/3513.57cff89c.chunk.js +0 -1
  72. streamlit/static/static/js/4177.ab9a7aa1.chunk.js +0 -1
  73. streamlit/static/static/js/4319.213fc321.chunk.js +0 -1
  74. streamlit/static/static/js/5106.22187bfc.chunk.js +0 -1
  75. streamlit/static/static/js/5379.e466522d.chunk.js +0 -1
  76. streamlit/static/static/js/6013.75c92264.chunk.js +0 -1
  77. streamlit/static/static/js/6718.97945fc6.chunk.js +0 -1
  78. streamlit/static/static/js/7175.8c1b4d38.chunk.js +0 -1
  79. streamlit/static/static/js/8691.24a5792f.chunk.js +0 -1
  80. streamlit/static/static/js/main.7fde7092.js +0 -2
  81. /streamlit/static/static/js/{main.7fde7092.js.LICENSE.txt → main.722453f0.js.LICENSE.txt} +0 -0
  82. {streamlit_nightly-1.32.3.dev20240325.data → streamlit_nightly-1.32.3.dev20240328.data}/scripts/streamlit.cmd +0 -0
  83. {streamlit_nightly-1.32.3.dev20240325.dist-info → streamlit_nightly-1.32.3.dev20240328.dist-info}/WHEEL +0 -0
  84. {streamlit_nightly-1.32.3.dev20240325.dist-info → streamlit_nightly-1.32.3.dev20240328.dist-info}/entry_points.txt +0 -0
  85. {streamlit_nightly-1.32.3.dev20240325.dist-info → streamlit_nightly-1.32.3.dev20240328.dist-info}/top_level.txt +0 -0
@@ -21,7 +21,7 @@ import types
21
21
  from contextlib import contextmanager
22
22
  from enum import Enum
23
23
  from timeit import default_timer as timer
24
- from typing import Callable, Final
24
+ from typing import TYPE_CHECKING, Callable, Final
25
25
 
26
26
  from blinker import Signal
27
27
 
@@ -49,6 +49,9 @@ from streamlit.runtime.state import (
49
49
  from streamlit.runtime.uploaded_file_manager import UploadedFileManager
50
50
  from streamlit.vendor.ipython.modified_sys_path import modified_sys_path
51
51
 
52
+ if TYPE_CHECKING:
53
+ from streamlit.runtime.fragment import FragmentStorage
54
+
52
55
  _LOGGER: Final = get_logger(__name__)
53
56
 
54
57
 
@@ -68,6 +71,10 @@ class ScriptRunnerEvent(Enum):
68
71
  # The script run stopped in order to start a script run with newer widget state.
69
72
  SCRIPT_STOPPED_FOR_RERUN = "SCRIPT_STOPPED_FOR_RERUN"
70
73
 
74
+ # The script run corresponding to a fragment ran to completion, or was interrupted
75
+ # by the user.
76
+ FRAGMENT_STOPPED_WITH_SUCCESS = "FRAGMENT_STOPPED_WITH_SUCCESS"
77
+
71
78
  # The ScriptRunner is done processing the ScriptEventQueue and
72
79
  # is shut down.
73
80
  SHUTDOWN = "SHUTDOWN"
@@ -106,6 +113,7 @@ class ScriptRunner:
106
113
  script_cache: ScriptCache,
107
114
  initial_rerun_data: RerunData,
108
115
  user_info: dict[str, str | None],
116
+ fragment_storage: "FragmentStorage",
109
117
  ):
110
118
  """Initialize the ScriptRunner.
111
119
 
@@ -119,12 +127,18 @@ class ScriptRunner:
119
127
  main_script_path
120
128
  Path to our main app script.
121
129
 
130
+ session_state
131
+ The AppSession's SessionState instance.
132
+
122
133
  uploaded_file_mgr
123
134
  The File manager to store the data uploaded by the file_uploader widget.
124
135
 
125
136
  script_cache
126
137
  A ScriptCache instance.
127
138
 
139
+ initial_rerun_data
140
+ RerunData to initialize this ScriptRunner with.
141
+
128
142
  user_info
129
143
  A dict that contains information about the current user. For now,
130
144
  it only contains the user's email address.
@@ -136,16 +150,18 @@ class ScriptRunner:
136
150
  Information about the current user is optionally provided when a
137
151
  websocket connection is initialized via the "X-Streamlit-User" header.
138
152
 
153
+ fragment_storage
154
+ The AppSession's FragmentStorage instance.
139
155
  """
140
156
  self._session_id = session_id
141
157
  self._main_script_path = main_script_path
142
- self._uploaded_file_mgr = uploaded_file_mgr
143
- self._script_cache = script_cache
144
- self._user_info = user_info
145
-
146
158
  self._session_state = SafeSessionState(
147
159
  session_state, yield_callback=self._maybe_handle_execution_control_request
148
160
  )
161
+ self._uploaded_file_mgr = uploaded_file_mgr
162
+ self._script_cache = script_cache
163
+ self._user_info = user_info
164
+ self._fragment_storage = fragment_storage
149
165
 
150
166
  self._requests = ScriptRequests()
151
167
  self._requests.request_rerun(initial_rerun_data)
@@ -277,6 +293,7 @@ class ScriptRunner:
277
293
  page_script_hash="",
278
294
  user_info=self._user_info,
279
295
  gather_usage_stats=bool(config.get_option("browser.gatherUsageStats")),
296
+ fragment_storage=self._fragment_storage,
280
297
  )
281
298
  add_script_run_ctx(threading.current_thread(), ctx)
282
299
 
@@ -394,6 +411,9 @@ class ScriptRunner:
394
411
  The RerunData to use.
395
412
 
396
413
  """
414
+ # Avoid circular imports
415
+ from streamlit.delta_generator import dg_stack
416
+
397
417
  assert self._is_in_script_thread()
398
418
 
399
419
  # An explicit loop instead of recursion to avoid stack overflows
@@ -441,16 +461,20 @@ class ScriptRunner:
441
461
  else main_page_info["page_script_hash"]
442
462
  )
443
463
 
464
+ fragment_ids_this_run = set(rerun_data.fragment_id_queue)
465
+
444
466
  ctx = self._get_script_run_ctx()
445
467
  ctx.reset(
446
468
  query_string=rerun_data.query_string,
447
469
  page_script_hash=page_script_hash,
470
+ fragment_ids_this_run=fragment_ids_this_run,
448
471
  )
449
472
 
450
473
  self.on_event.send(
451
474
  self,
452
475
  event=ScriptRunnerEvent.SCRIPT_STARTED,
453
476
  page_script_hash=page_script_hash,
477
+ fragment_ids_this_run=fragment_ids_this_run,
454
478
  )
455
479
 
456
480
  # Compile the script. Any errors thrown here will be surfaced
@@ -497,6 +521,16 @@ class ScriptRunner:
497
521
  # is interrupted by a RerunException.
498
522
  rerun_exception_data: RerunData | None = None
499
523
 
524
+ # Saving and restoring our original cursors/dg_stack is needed
525
+ # specifically to handle the case where a RerunException is raised while
526
+ # running a fragment. In this case, we need to restore both to their states
527
+ # at the start of the script run to ensure that we write to the correct
528
+ # places in the app during the rerun (without this, ctx.cursors and dg_stack
529
+ # will still be set to the snapshots they were restored from when running
530
+ # the fragment).
531
+ original_cursors = ctx.cursors
532
+ original_dg_stack = dg_stack.get()
533
+
500
534
  # If the script stops early, we don't want to remove unseen widgets,
501
535
  # so we track this to potentially skip session state cleanup later.
502
536
  premature_stop: bool = False
@@ -504,14 +538,6 @@ class ScriptRunner:
504
538
  try:
505
539
  # Create fake module. This gives us a name global namespace to
506
540
  # execute the code in.
507
- # TODO(vdonato): Double-check that we're okay with naming the
508
- # module for every page `__main__`. I'm pretty sure this is
509
- # necessary given that people will likely often write
510
- # ```
511
- # if __name__ == "__main__":
512
- # ...
513
- # ```
514
- # in their scripts.
515
541
  module = self._new_module("__main__")
516
542
 
517
543
  # Install the fake module as the __main__ module. This allows
@@ -539,11 +565,30 @@ class ScriptRunner:
539
565
 
540
566
  ctx.on_script_start()
541
567
  prep_time = timer() - start_time
542
- exec(code, module.__dict__)
568
+
569
+ if rerun_data.fragment_id_queue:
570
+ for fragment_id in rerun_data.fragment_id_queue:
571
+ try:
572
+ wrapped_fragment = self._fragment_storage.get(
573
+ fragment_id
574
+ )
575
+ ctx.current_fragment_id = fragment_id
576
+ wrapped_fragment()
577
+
578
+ except KeyError:
579
+ raise RuntimeError(
580
+ f"Could not find fragment with id {fragment_id}"
581
+ )
582
+ else:
583
+ self._fragment_storage.clear()
584
+ exec(code, module.__dict__)
585
+
543
586
  self._session_state.maybe_check_serializable()
544
587
  self._session_state[SCRIPT_RUN_WITHOUT_ERRORS_KEY] = True
545
588
  except RerunException as e:
546
589
  rerun_exception_data = e.rerun_data
590
+ ctx.cursors = original_cursors
591
+ dg_stack.set(original_dg_stack)
547
592
  # Interruption due to a rerun is usually from `st.rerun()`, which
548
593
  # we want to count as a script completion so triggers reset.
549
594
  # It is also possible for this to happen if fast reruns is off,
@@ -563,7 +608,11 @@ class ScriptRunner:
563
608
 
564
609
  finally:
565
610
  if rerun_exception_data:
611
+ # The handling for when a full script run or a fragment is stopped early
612
+ # is the same, so we only have one ScriptRunnerEvent for this scenario.
566
613
  finished_event = ScriptRunnerEvent.SCRIPT_STOPPED_FOR_RERUN
614
+ elif rerun_data.fragment_id_queue:
615
+ finished_event = ScriptRunnerEvent.FRAGMENT_STOPPED_WITH_SUCCESS
567
616
  else:
568
617
  finished_event = ScriptRunnerEvent.SCRIPT_STOPPED_WITH_SUCCESS
569
618
 
@@ -123,6 +123,8 @@ class WidgetMetadata(Generic[T]):
123
123
  callback_args: WidgetArgs | None = None
124
124
  callback_kwargs: WidgetKwargs | None = None
125
125
 
126
+ fragment_id: str | None = None
127
+
126
128
  def __repr__(self) -> str:
127
129
  return util.repr_(self)
128
130
 
@@ -182,11 +182,21 @@ class WStates(MutableMapping[str, Any]):
182
182
  """Set a widget's metadata, overwriting any existing metadata it has."""
183
183
  self.widget_metadata[widget_meta.id] = widget_meta
184
184
 
185
- def remove_stale_widgets(self, active_widget_ids: set[str]) -> None:
186
- """Remove widget state for widgets whose ids aren't in `active_widget_ids`."""
187
- # TODO(vdonato / kajarenc): Remove files corresponding to an inactive file
188
- # uploader.
189
- self.states = {k: v for k, v in self.states.items() if k in active_widget_ids}
185
+ def remove_stale_widgets(
186
+ self,
187
+ active_widget_ids: set[str],
188
+ fragment_ids_this_run: set[str] | None,
189
+ ) -> None:
190
+ """Remove widget state for stale widgets."""
191
+ self.states = {
192
+ k: v
193
+ for k, v in self.states.items()
194
+ if not _is_stale_widget(
195
+ self.widget_metadata.get(k),
196
+ active_widget_ids,
197
+ fragment_ids_this_run,
198
+ )
199
+ }
190
200
 
191
201
  def get_serialized(self, k: str) -> WidgetStateProto | None:
192
202
  """Get the serialized value of the widget with the given id.
@@ -561,14 +571,31 @@ class SessionState:
561
571
 
562
572
  def _remove_stale_widgets(self, active_widget_ids: set[str]) -> None:
563
573
  """Remove widget state for widgets whose ids aren't in `active_widget_ids`."""
564
- self._new_widget_state.remove_stale_widgets(active_widget_ids)
574
+ # Avoid circular imports.
575
+ from streamlit.runtime.scriptrunner import get_script_run_ctx
576
+
577
+ ctx = get_script_run_ctx()
578
+ if ctx is None:
579
+ return
580
+
581
+ self._new_widget_state.remove_stale_widgets(
582
+ active_widget_ids,
583
+ ctx.fragment_ids_this_run,
584
+ )
565
585
 
566
586
  # Remove entries from _old_state corresponding to
567
587
  # widgets not in widget_ids.
568
588
  self._old_state = {
569
589
  k: v
570
590
  for k, v in self._old_state.items()
571
- if (k in active_widget_ids or not is_widget_id(k))
591
+ if (
592
+ not is_widget_id(k)
593
+ or not _is_stale_widget(
594
+ self._new_widget_state.widget_metadata.get(k),
595
+ active_widget_ids,
596
+ ctx.fragment_ids_this_run,
597
+ )
598
+ )
572
599
  }
573
600
 
574
601
  def _set_widget_metadata(self, widget_metadata: WidgetMetadata[Any]) -> None:
@@ -671,6 +698,23 @@ def _is_internal_key(key: str) -> bool:
671
698
  return key.startswith(STREAMLIT_INTERNAL_KEY_PREFIX)
672
699
 
673
700
 
701
+ def _is_stale_widget(
702
+ metadata: WidgetMetadata[Any] | None,
703
+ active_widget_ids: set[str],
704
+ fragment_ids_this_run: set[str] | None,
705
+ ) -> bool:
706
+ if not metadata:
707
+ return True
708
+ elif metadata.id in active_widget_ids:
709
+ return False
710
+ # If we're running 1 or more fragments, but this widget is unrelated to any of the
711
+ # fragments that we're running, then it should not be marked as stale as its value
712
+ # may still be needed for a future fragment run or full script run.
713
+ elif fragment_ids_this_run and metadata.fragment_id not in fragment_ids_this_run:
714
+ return False
715
+ return True
716
+
717
+
674
718
  @dataclass
675
719
  class SessionStateStatProvider(CacheStatsProvider):
676
720
  _session_mgr: SessionManager
@@ -159,6 +159,7 @@ def register_widget(
159
159
  callback=on_change_handler,
160
160
  callback_args=args,
161
161
  callback_kwargs=kwargs,
162
+ fragment_id=ctx.current_fragment_id if ctx else None,
162
163
  )
163
164
  return register_widget_from_metadata(metadata, ctx, widget_func_name, element_type)
164
165
 
@@ -217,8 +218,8 @@ def register_widget_from_metadata(
217
218
 
218
219
 
219
220
  def coalesce_widget_states(
220
- old_states: WidgetStates, new_states: WidgetStates
221
- ) -> WidgetStates:
221
+ old_states: WidgetStates | None, new_states: WidgetStates | None
222
+ ) -> WidgetStates | None:
222
223
  """Coalesce an older WidgetStates into a newer one, and return a new
223
224
  WidgetStates containing the result.
224
225
 
@@ -228,6 +229,13 @@ def coalesce_widget_states(
228
229
  `old_states` will be set to True in the coalesced result, so that button
229
230
  presses don't go missing.
230
231
  """
232
+ if not old_states and not new_states:
233
+ return None
234
+ elif not old_states:
235
+ return new_states
236
+ elif not new_states:
237
+ return old_states
238
+
231
239
  states_by_id: dict[str, WidgetState] = {
232
240
  wstate.id: wstate for wstate in new_states.widgets
233
241
  }
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "files": {
3
3
  "main.css": "./static/css/main.bf304093.css",
4
- "main.js": "./static/js/main.7fde7092.js",
4
+ "main.js": "./static/js/main.722453f0.js",
5
5
  "static/js/9336.2d95d840.chunk.js": "./static/js/9336.2d95d840.chunk.js",
6
6
  "static/js/9330.d29313d4.chunk.js": "./static/js/9330.d29313d4.chunk.js",
7
7
  "static/js/7217.d970c074.chunk.js": "./static/js/7217.d970c074.chunk.js",
8
8
  "static/js/3301.1d1b10bb.chunk.js": "./static/js/3301.1d1b10bb.chunk.js",
9
9
  "static/css/3092.f719e2e6.chunk.css": "./static/css/3092.f719e2e6.chunk.css",
10
- "static/js/3092.3d4df25e.chunk.js": "./static/js/3092.3d4df25e.chunk.js",
10
+ "static/js/3092.ad569cc8.chunk.js": "./static/js/3092.ad569cc8.chunk.js",
11
11
  "static/css/43.c24b25fa.chunk.css": "./static/css/43.c24b25fa.chunk.css",
12
12
  "static/js/43.76c54963.chunk.js": "./static/js/43.76c54963.chunk.js",
13
13
  "static/js/8427.44d27448.chunk.js": "./static/js/8427.44d27448.chunk.js",
@@ -20,24 +20,24 @@
20
20
  "static/js/4113.1e7eff4d.chunk.js": "./static/js/4113.1e7eff4d.chunk.js",
21
21
  "static/js/1168.3029456a.chunk.js": "./static/js/1168.3029456a.chunk.js",
22
22
  "static/js/178.b5384fd0.chunk.js": "./static/js/178.b5384fd0.chunk.js",
23
- "static/js/1792.16c16498.chunk.js": "./static/js/1792.16c16498.chunk.js",
24
- "static/js/3513.57cff89c.chunk.js": "./static/js/3513.57cff89c.chunk.js",
25
- "static/js/7602.f0420392.chunk.js": "./static/js/7602.f0420392.chunk.js",
26
- "static/js/6013.75c92264.chunk.js": "./static/js/6013.75c92264.chunk.js",
27
- "static/js/8492.e6dab83f.chunk.js": "./static/js/8492.e6dab83f.chunk.js",
28
- "static/js/4177.ab9a7aa1.chunk.js": "./static/js/4177.ab9a7aa1.chunk.js",
29
- "static/js/1451.e3be1711.chunk.js": "./static/js/1451.e3be1711.chunk.js",
30
- "static/js/1074.71719df6.chunk.js": "./static/js/1074.71719df6.chunk.js",
23
+ "static/js/1792.b8efa879.chunk.js": "./static/js/1792.b8efa879.chunk.js",
24
+ "static/js/3513.e3e7300a.chunk.js": "./static/js/3513.e3e7300a.chunk.js",
25
+ "static/js/7602.6175e969.chunk.js": "./static/js/7602.6175e969.chunk.js",
26
+ "static/js/6013.8e80e091.chunk.js": "./static/js/6013.8e80e091.chunk.js",
27
+ "static/js/8492.f56c9d4c.chunk.js": "./static/js/8492.f56c9d4c.chunk.js",
28
+ "static/js/4177.69f9f18d.chunk.js": "./static/js/4177.69f9f18d.chunk.js",
29
+ "static/js/1451.3b0a3e31.chunk.js": "./static/js/1451.3b0a3e31.chunk.js",
30
+ "static/js/1074.73973756.chunk.js": "./static/js/1074.73973756.chunk.js",
31
31
  "static/js/8477.e948c092.chunk.js": "./static/js/8477.e948c092.chunk.js",
32
32
  "static/js/6853.d999ac75.chunk.js": "./static/js/6853.d999ac75.chunk.js",
33
- "static/js/4477.2555c11a.chunk.js": "./static/js/4477.2555c11a.chunk.js",
34
- "static/js/4319.213fc321.chunk.js": "./static/js/4319.213fc321.chunk.js",
35
- "static/js/5106.22187bfc.chunk.js": "./static/js/5106.22187bfc.chunk.js",
36
- "static/js/4666.99f3abc3.chunk.js": "./static/js/4666.99f3abc3.chunk.js",
37
- "static/js/5379.e466522d.chunk.js": "./static/js/5379.e466522d.chunk.js",
38
- "static/js/8691.24a5792f.chunk.js": "./static/js/8691.24a5792f.chunk.js",
39
- "static/js/6718.97945fc6.chunk.js": "./static/js/6718.97945fc6.chunk.js",
40
- "static/js/7175.8c1b4d38.chunk.js": "./static/js/7175.8c1b4d38.chunk.js",
33
+ "static/js/4477.e10e4373.chunk.js": "./static/js/4477.e10e4373.chunk.js",
34
+ "static/js/4319.a6745434.chunk.js": "./static/js/4319.a6745434.chunk.js",
35
+ "static/js/5106.44f0ff51.chunk.js": "./static/js/5106.44f0ff51.chunk.js",
36
+ "static/js/4666.b694c5a9.chunk.js": "./static/js/4666.b694c5a9.chunk.js",
37
+ "static/js/5379.6571574f.chunk.js": "./static/js/5379.6571574f.chunk.js",
38
+ "static/js/8691.9ccf7f89.chunk.js": "./static/js/8691.9ccf7f89.chunk.js",
39
+ "static/js/6718.802da17e.chunk.js": "./static/js/6718.802da17e.chunk.js",
40
+ "static/js/7175.be4076bc.chunk.js": "./static/js/7175.be4076bc.chunk.js",
41
41
  "static/js/5345.65c91ee7.chunk.js": "./static/js/5345.65c91ee7.chunk.js",
42
42
  "static/js/9865.fd93213d.chunk.js": "./static/js/9865.fd93213d.chunk.js",
43
43
  "static/js/6405.ac5a6f23.chunk.js": "./static/js/6405.ac5a6f23.chunk.js",
@@ -150,6 +150,6 @@
150
150
  },
151
151
  "entrypoints": [
152
152
  "static/css/main.bf304093.css",
153
- "static/js/main.7fde7092.js"
153
+ "static/js/main.722453f0.js"
154
154
  ]
155
155
  }
@@ -1 +1 @@
1
- <!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><link rel="shortcut icon" href="./favicon.png"/><link rel="preload" href="./static/media/SourceSansPro-Regular.0d69e5ff5e92ac64a0c9.woff2" as="font" type="font/woff2" crossorigin><link rel="preload" href="./static/media/SourceSansPro-SemiBold.abed79cd0df1827e18cf.woff2" as="font" type="font/woff2" crossorigin><link rel="preload" href="./static/media/SourceSansPro-Bold.118dea98980e20a81ced.woff2" as="font" type="font/woff2" crossorigin><title>Streamlit</title><script>window.prerenderReady=!1</script><script defer="defer" src="./static/js/main.7fde7092.js"></script><link href="./static/css/main.bf304093.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
1
+ <!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><link rel="shortcut icon" href="./favicon.png"/><link rel="preload" href="./static/media/SourceSansPro-Regular.0d69e5ff5e92ac64a0c9.woff2" as="font" type="font/woff2" crossorigin><link rel="preload" href="./static/media/SourceSansPro-SemiBold.abed79cd0df1827e18cf.woff2" as="font" type="font/woff2" crossorigin><link rel="preload" href="./static/media/SourceSansPro-Bold.118dea98980e20a81ced.woff2" as="font" type="font/woff2" crossorigin><title>Streamlit</title><script>window.prerenderReady=!1</script><script defer="defer" src="./static/js/main.722453f0.js"></script><link href="./static/css/main.bf304093.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_streamlit_app=self.webpackChunk_streamlit_app||[]).push([[1074],{87814:(e,t,s)=>{s.d(t,{K:()=>o});var i=s(50641);class o{constructor(){this.formClearListener=void 0,this.lastWidgetMgr=void 0,this.lastFormId=void 0}manageFormClearListener(e,t,s){null!=this.formClearListener&&this.lastWidgetMgr===e&&this.lastFormId===t||(this.disconnect(),(0,i.bM)(t)&&(this.formClearListener=e.addFormClearedListener(t,s),this.lastWidgetMgr=e,this.lastFormId=t))}disconnect(){var e;null===(e=this.formClearListener)||void 0===e||e.disconnect(),this.formClearListener=void 0,this.lastWidgetMgr=void 0,this.lastFormId=void 0}}},91074:(e,t,s)=>{s.r(t),s.d(t,{default:()=>w});var i=s(66845),o=s(91706),r=s(81810),l=s.n(r),a=s(25621),n=s(87814),d=s(90481),p=s(91034),h=s(12576),c=s(98478),m=s(86659);const u=(0,s(1515).Z)("div",{target:"e6zijwc0"})((e=>{let{theme:t}=e;return{"span[aria-disabled='true']":{background:t.colors.fadedText05}}}),"");var g=s(8879),v=s(68411),f=s(7978),b=s(97965),S=s(50641),y=s(40864);class x extends i.PureComponent{constructor(){super(...arguments),this.formClearHelper=new n.K,this.state={value:this.initialValue},this.commitWidgetValue=e=>{const{widgetMgr:t,element:s,fragmentId:i}=this.props;t.setIntArrayValue(s,this.state.value,e,i)},this.onFormCleared=()=>{this.setState(((e,t)=>({value:t.element.default})),(()=>this.commitWidgetValue({fromUi:!0})))},this.onChange=e=>{this.props.element.maxSelections&&"select"===e.type&&this.state.value.length>=this.props.element.maxSelections||this.setState(this.generateNewState(e),(()=>{this.commitWidgetValue({fromUi:!0})}))},this.filterOptions=(e,t)=>{if(this.overMaxSelections())return[];const s=e.filter((e=>!this.state.value.includes(Number(e.value))));return(0,b.HX)(s,t)}}overMaxSelections(){return this.props.element.maxSelections>0&&this.state.value.length>=this.props.element.maxSelections}getNoResultsMsg(){const{maxSelections:e}=this.props.element,{value:t}=this.state;if(0===e)return"No results";if(t.length===e){const t=1!==e?"options":"option";return"You can only select up to ".concat(e," ").concat(t,". Remove an option first.")}return"No results"}get initialValue(){const e=this.props.widgetMgr.getIntArrayValue(this.props.element);return void 0!==e?e:this.props.element.default}componentDidMount(){this.props.element.setValue?this.updateFromProtobuf():this.commitWidgetValue({fromUi:!1})}componentDidUpdate(){this.maybeUpdateFromProtobuf()}componentWillUnmount(){this.formClearHelper.disconnect()}maybeUpdateFromProtobuf(){const{setValue:e}=this.props.element;e&&this.updateFromProtobuf()}updateFromProtobuf(){const{value:e}=this.props.element;this.props.element.setValue=!1,this.setState({value:e},(()=>{this.commitWidgetValue({fromUi:!1})}))}get valueFromState(){return this.state.value.map((e=>{const t=this.props.element.options[e];return{value:e.toString(),label:t}}))}generateNewState(e){const t=()=>{var t;const s=null===(t=e.option)||void 0===t?void 0:t.value;return parseInt(s,10)};switch(e.type){case"remove":return{value:l()(this.state.value,t())};case"clear":return{value:[]};case"select":return{value:this.state.value.concat([t()])};default:throw new Error("State transition is unknown: ".concat(e.type))}}render(){var e;const{element:t,theme:s,width:i,widgetMgr:r}=this.props,l={width:i},{options:a}=t,n=0===a.length||this.props.disabled,b=0===a.length?"No options to select.":t.placeholder,x=a.map(((e,t)=>({label:e,value:t.toString()})));this.formClearHelper.manageFormClearListener(r,t.formId,this.onFormCleared);const w=a.length>10;return(0,y.jsxs)("div",{className:"row-widget stMultiSelect","data-testid":"stMultiSelect",style:l,children:[(0,y.jsx)(c.O,{label:t.label,disabled:n,labelVisibility:(0,S.iF)(null===(e=t.labelVisibility)||void 0===e?void 0:e.value),children:t.help&&(0,y.jsx)(m.dT,{children:(0,y.jsx)(g.Z,{content:t.help,placement:v.u.TOP_RIGHT})})}),(0,y.jsx)(u,{children:(0,y.jsx)(p.Z,{options:x,labelKey:"label",valueKey:"value","aria-label":t.label,placeholder:b,type:h.wD.select,multi:!0,onChange:this.onChange,value:this.valueFromState,disabled:n,size:"compact",noResultsMsg:this.getNoResultsMsg(),filterOptions:this.filterOptions,closeOnSelect:!1,overrides:{SelectArrow:{component:d.Z,props:{overrides:{Svg:{style:()=>({width:s.iconSizes.xl,height:s.iconSizes.xl})}}}},IconsContainer:{style:()=>({paddingRight:s.spacing.sm})},ControlContainer:{style:{borderLeftWidth:"1px",borderRightWidth:"1px",borderTopWidth:"1px",borderBottomWidth:"1px"}},Placeholder:{style:()=>({flex:"inherit"})},ValueContainer:{style:()=>({minHeight:"38.4px",paddingLeft:s.spacing.sm,paddingTop:0,paddingBottom:0,paddingRight:0})},ClearIcon:{props:{overrides:{Svg:{style:{color:s.colors.darkGray,transform:"scale(1.5)",width:s.spacing.twoXL,":hover":{fill:s.colors.bodyText}}}}}},SearchIcon:{style:{color:s.colors.darkGray}},Tag:{props:{overrides:{Root:{style:{borderTopLeftRadius:s.radii.md,borderTopRightRadius:s.radii.md,borderBottomRightRadius:s.radii.md,borderBottomLeftRadius:s.radii.md,fontSize:s.fontSizes.sm,paddingLeft:s.spacing.sm,marginLeft:0,marginRight:s.spacing.sm,height:"28px"}},Action:{style:{paddingLeft:0}},ActionIcon:{props:{overrides:{Svg:{style:{width:"10px",height:"10px"}}}}},Text:{style:{fontSize:s.fontSizes.md}}}}},MultiValue:{props:{overrides:{Root:{style:{fontSize:s.fontSizes.sm}}}}},Input:{props:{readOnly:o.tq&&!1===w?"readonly":null}},Dropdown:{component:f.Z}}})})]})}}const w=(0,a.b)(x)}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_streamlit_app=self.webpackChunk_streamlit_app||[]).push([[1451],{61451:(t,e,s)=>{s.r(e),s.d(e,{default:()=>C});var a=s(66845),i=s(53608),r=s.n(i),o=s(25621),n=s(15791),l=s(28278),d=s(13553),p=s(87814),m=s(98478),h=s(86659),c=s(8879),u=s(68411),g=s(50641),f=s(40864);const v="YYYY/MM/DD";function y(t){return t.map((t=>new Date(t)))}class b extends a.PureComponent{constructor(){super(...arguments),this.formClearHelper=new p.K,this.state={values:this.initialValue,isRange:this.props.element.isRange,isEmpty:!1},this.commitWidgetValue=t=>{const{widgetMgr:e,element:s,fragmentId:a}=this.props;var i;e.setStringArrayValue(s,(i=this.state.values)?i.map((t=>r()(t).format(v))):[],t,a)},this.onFormCleared=()=>{const t=y(this.props.element.default);this.setState({values:t,isEmpty:!t},(()=>this.commitWidgetValue({fromUi:!0})))},this.handleChange=t=>{let{date:e}=t;if(null===e||void 0===e)return void this.setState({values:[],isEmpty:!0});const s=[];Array.isArray(e)?e.forEach((t=>{t&&s.push(t)})):s.push(e),this.setState({values:s,isEmpty:!s},(()=>{this.state.isEmpty||this.commitWidgetValue({fromUi:!0})}))},this.handleClose=()=>{const{isEmpty:t}=this.state;t&&this.setState(((t,e)=>({values:y(e.element.default),isEmpty:!y(e.element.default)})),(()=>{this.commitWidgetValue({fromUi:!0})}))},this.getMaxDate=()=>{const{element:t}=this.props,e=t.max;return e&&e.length>0?r()(e,v).toDate():void 0}}get initialValue(){const t=this.props.widgetMgr.getStringArrayValue(this.props.element);return y(void 0!==t?t:this.props.element.default||[])}componentDidMount(){this.props.element.setValue?this.updateFromProtobuf():this.commitWidgetValue({fromUi:!1})}componentDidUpdate(){this.maybeUpdateFromProtobuf()}componentWillUnmount(){this.formClearHelper.disconnect()}maybeUpdateFromProtobuf(){const{setValue:t}=this.props.element;t&&this.updateFromProtobuf()}updateFromProtobuf(){const{value:t}=this.props.element;this.props.element.setValue=!1;const e=t.map((t=>new Date(t)));this.setState({values:e,isEmpty:!e},(()=>{this.commitWidgetValue({fromUi:!1})}))}render(){var t;const{width:e,element:s,disabled:a,theme:i,widgetMgr:o}=this.props,{values:p,isRange:y}=this.state,{colors:b,fontSizes:C,lineHeights:x}=i,D={width:e},I=r()(s.min,v).toDate(),W=this.getMaxDate(),F=0===s.default.length&&!a,V=s.format.replaceAll(/[a-zA-Z]/g,"9"),S=s.format.replaceAll("Y","y").replaceAll("D","d");return this.formClearHelper.manageFormClearListener(o,s.formId,this.onFormCleared),(0,f.jsxs)("div",{className:"stDateInput",style:D,"data-testid":"stDateInput",children:[(0,f.jsx)(m.O,{label:s.label,disabled:a,labelVisibility:(0,g.iF)(null===(t=s.labelVisibility)||void 0===t?void 0:t.value),children:s.help&&(0,f.jsx)(h.dT,{children:(0,f.jsx)(c.Z,{content:s.help,placement:u.u.TOP_RIGHT})})}),(0,f.jsx)(n.Z,{density:l.pw.high,formatString:S,mask:y?"".concat(V," \u2013 ").concat(V):V,placeholder:y?"".concat(s.format," \u2013 ").concat(s.format):s.format,disabled:a,onChange:this.handleChange,onClose:this.handleClose,overrides:{Popover:{props:{placement:d.r4.bottomLeft,overrides:{Body:{style:{border:"1px solid ".concat(b.fadedText10)}}}}},CalendarContainer:{style:{fontSize:C.sm,paddingRight:i.spacing.sm,paddingLeft:i.spacing.sm,paddingBottom:i.spacing.sm,paddingTop:i.spacing.sm}},Week:{style:{fontSize:C.sm}},Day:{style:t=>{let{$pseudoHighlighted:e,$pseudoSelected:s,$selected:a,$isHovered:i}=t;return{fontSize:C.sm,lineHeight:x.base,"::before":{backgroundColor:a||s||e||i?"".concat(b.secondaryBg," !important"):b.transparent},"::after":{borderColor:b.transparent}}}},PrevButton:{style:()=>({display:"flex",alignItems:"center",justifyContent:"center",":active":{backgroundColor:b.transparent},":focus":{backgroundColor:b.transparent,outline:0}})},NextButton:{style:{display:"flex",alignItems:"center",justifyContent:"center",":active":{backgroundColor:b.transparent},":focus":{backgroundColor:b.transparent,outline:0}}},Input:{props:{maskChar:null,overrides:{Root:{style:{borderLeftWidth:"1px",borderRightWidth:"1px",borderTopWidth:"1px",borderBottomWidth:"1px"}},ClearIcon:{props:{overrides:{Svg:{style:{color:i.colors.darkGray,transform:"scale(1.41)",width:i.spacing.twoXL,marginRight:"-8px",":hover":{fill:i.colors.bodyText}}}}}},Input:{style:{paddingRight:".5rem",paddingLeft:".5rem",paddingBottom:".5rem",paddingTop:".5rem",lineHeight:1.4},props:{"data-testid":"stDateInput-Input"}}}}}},value:p,minDate:I,maxDate:W,range:y,clearable:F})]})}}const C=(0,o.b)(b)},87814:(t,e,s)=>{s.d(e,{K:()=>i});var a=s(50641);class i{constructor(){this.formClearListener=void 0,this.lastWidgetMgr=void 0,this.lastFormId=void 0}manageFormClearListener(t,e,s){null!=this.formClearListener&&this.lastWidgetMgr===t&&this.lastFormId===e||(this.disconnect(),(0,a.bM)(e)&&(this.formClearListener=t.addFormClearedListener(e,s),this.lastWidgetMgr=t,this.lastFormId=e))}disconnect(){var t;null===(t=this.formClearListener)||void 0===t||t.disconnect(),this.formClearListener=void 0,this.lastWidgetMgr=void 0,this.lastFormId=void 0}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_streamlit_app=self.webpackChunk_streamlit_app||[]).push([[1792],{61792:(e,t,i)=>{i.r(t),i.d(t,{default:()=>n});i(66845);var s=i(81354),l=i(27446),a=i(9003),d=i(21e3),r=i(40864);const n=function(e){const{disabled:t,element:i,widgetMgr:n,width:h,fragmentId:u}=e,c={width:h},p="primary"===i.type?s.nW.PRIMARY:s.nW.SECONDARY,o=!i.help||h;return(0,r.jsx)("div",{className:"row-widget stButton","data-testid":"stButton",style:c,children:(0,r.jsx)(l.t,{help:i.help,children:(0,r.jsx)(a.ZP,{kind:p,size:s.V5.SMALL,disabled:t,fluidWidth:!!i.useContainerWidth&&o,onClick:()=>n.setTriggerValue(i,{fromUi:!0},u),children:(0,r.jsx)(d.ZP,{source:i.label,allowHTML:!1,isLabel:!0,largerLabel:!0,disableLinks:!0})})})})}}}]);