streamlit-nightly 1.43.3.dev20250311__py3-none-any.whl → 1.43.3.dev20250312__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 (83) hide show
  1. streamlit/__init__.py +1 -0
  2. streamlit/elements/markdown.py +98 -2
  3. streamlit/errors.py +7 -0
  4. streamlit/runtime/secrets.py +24 -29
  5. streamlit/static/index.html +1 -1
  6. streamlit/static/static/js/{FileDownload.esm.B-R2xJ_2.js → FileDownload.esm.C9csNfwR.js} +1 -1
  7. streamlit/static/static/js/{FileHelper.Dpame4Yy.js → FileHelper.CTWNHaVI.js} +1 -1
  8. streamlit/static/static/js/{FormClearHelper.CJtgEcyv.js → FormClearHelper.1VkFJY3v.js} +1 -1
  9. streamlit/static/static/js/{Hooks.eMU4yP9C.js → Hooks.vPqq3xQ5.js} +1 -1
  10. streamlit/static/static/js/{InputInstructions.Bt5nMAh-.js → InputInstructions.7jABRwB0.js} +1 -1
  11. streamlit/static/static/js/{ProgressBar.CRfY498S.js → ProgressBar.BWY8ITDS.js} +1 -1
  12. streamlit/static/static/js/{RenderInPortalIfExists.CjsBZs42.js → RenderInPortalIfExists.CP_sn1OG.js} +1 -1
  13. streamlit/static/static/js/{Toolbar.CBmSHKas.js → Toolbar.DzqMcgvB.js} +1 -1
  14. streamlit/static/static/js/{base-input.pwi2uHY4.js → base-input.DjuthXF0.js} +1 -1
  15. streamlit/static/static/js/{checkbox.BRMCIUrT.js → checkbox.BddRUN3_.js} +1 -1
  16. streamlit/static/static/js/{createSuper.BT2FfU2u.js → createSuper.BAGgahBq.js} +1 -1
  17. streamlit/static/static/js/{data-grid-overlay-editor.DR231PaH.js → data-grid-overlay-editor.Bscjz8_-.js} +1 -1
  18. streamlit/static/static/js/{downloader.Cwh9Q8n3.js → downloader.BgDSv-Ig.js} +1 -1
  19. streamlit/static/static/js/{es6.DXFo1lzk.js → es6.3kVHyEdR.js} +2 -2
  20. streamlit/static/static/js/{iframeResizer.contentWindow.BqHH3gN-.js → iframeResizer.contentWindow.n2oqEwdf.js} +1 -1
  21. streamlit/static/static/js/{index.ClCou1d2.js → index.0JqsAt5p.js} +1 -1
  22. streamlit/static/static/js/{index.DbtNEUBr.js → index.3k9e_sFT.js} +1 -1
  23. streamlit/static/static/js/{index.DzJ-K9FH.js → index.B1ZLFKil.js} +1 -1
  24. streamlit/static/static/js/{index.BhhnIkTX.js → index.B8IuPu4x.js} +1 -1
  25. streamlit/static/static/js/{index.pfdwKIIK.js → index.BNTyamf9.js} +1 -1
  26. streamlit/static/static/js/{index.B71BDPil.js → index.BPcgpI5G.js} +1 -1
  27. streamlit/static/static/js/{index.BtaSeLy3.js → index.BQXOwXQG.js} +1 -1
  28. streamlit/static/static/js/{index.DC7tm9ca.js → index.BaYVwylD.js} +1 -1
  29. streamlit/static/static/js/{index.CKLHvpe_.js → index.Bd5GUMH8.js} +1 -1
  30. streamlit/static/static/js/index.BfTunuGf.js +1 -0
  31. streamlit/static/static/js/{index.eHde7unb.js → index.C28BRw13.js} +1 -1
  32. streamlit/static/static/js/{index.SGdFItlP.js → index.C8ZHYetm.js} +1 -1
  33. streamlit/static/static/js/index.CFbiFnmq.js +1 -0
  34. streamlit/static/static/js/{index.E4BOW70b.js → index.CYrF9jN2.js} +1 -1
  35. streamlit/static/static/js/{index.B9ftDzXT.js → index.ChDimwy6.js} +1 -1
  36. streamlit/static/static/js/{index.7mbSZESp.js → index.Cj7yHfOR.js} +1 -1
  37. streamlit/static/static/js/{index.C8ZQWk_P.js → index.CrZncPLs.js} +1 -1
  38. streamlit/static/static/js/{index.DIxz2WrU.js → index.CrjCtGqg.js} +1 -1
  39. streamlit/static/static/js/{index.DBAW0l2y.js → index.D3EE2F77.js} +1 -1
  40. streamlit/static/static/js/{index.Y1Qnwm4b.js → index.D3uVQMaA.js} +1 -1
  41. streamlit/static/static/js/{index.DGe1v1i2.js → index.D7k3QVrz.js} +1 -1
  42. streamlit/static/static/js/{index.BtuGy7By.js → index.D8rVyQy1.js} +2 -2
  43. streamlit/static/static/js/{index.CtDd3Kvg.js → index.DAAc9Gb3.js} +1 -1
  44. streamlit/static/static/js/{index.DTC2KQEB.js → index.DAghU1FB.js} +1 -1
  45. streamlit/static/static/js/{index.DJZrR-yh.js → index.DbI6X421.js} +1 -1
  46. streamlit/static/static/js/{index.Bt4_I4Hr.js → index.DlXteNnv.js} +1 -1
  47. streamlit/static/static/js/{index.BAQ_1jSz.js → index.Dv6XiWKs.js} +1 -1
  48. streamlit/static/static/js/{index._HJ2bgYb.js → index.FJszpQ-y.js} +6 -6
  49. streamlit/static/static/js/{index.oH2t20_d.js → index.N6CP_9Qh.js} +1 -1
  50. streamlit/static/static/js/{index.BN2fMHzp.js → index.OtBp-Blq.js} +1 -1
  51. streamlit/static/static/js/{index.DklFRDjI.js → index.S_LaABz9.js} +1 -1
  52. streamlit/static/static/js/{index.-J5N3GRT.js → index.UJT9uVs_.js} +1 -1
  53. streamlit/static/static/js/{index.Cqy-AKUq.js → index.j6cgFK9c.js} +1 -1
  54. streamlit/static/static/js/index.k2DDVmzp.js +1 -0
  55. streamlit/static/static/js/{index.DAIPHdqL.js → index.mMuChmJi.js} +1 -1
  56. streamlit/static/static/js/{index.BiPCWEUM.js → index.pEU90S1o.js} +45 -45
  57. streamlit/static/static/js/index.svH5ea22.js +1 -0
  58. streamlit/static/static/js/index.zrNj-omI.js +1 -0
  59. streamlit/static/static/js/{input.Rf6xGN5X.js → input.A7Xel5Mz.js} +1 -1
  60. streamlit/static/static/js/{memory.D5NLCYdA.js → memory.DKAi1aOw.js} +1 -1
  61. streamlit/static/static/js/{mergeWith.Bcdwg8Ac.js → mergeWith.BOXngkwE.js} +1 -1
  62. streamlit/static/static/js/{number-overlay-editor.CCjfRIEO.js → number-overlay-editor.Dr9nZLr4.js} +1 -1
  63. streamlit/static/static/js/{possibleConstructorReturn.B8bXiVQj.js → possibleConstructorReturn.Dmq70n5Q.js} +1 -1
  64. streamlit/static/static/js/{sandbox.lrrkbqxh.js → sandbox.OiNVhKVk.js} +1 -1
  65. streamlit/static/static/js/{textarea.DCEYRe9D.js → textarea.BvcErhuX.js} +1 -1
  66. streamlit/static/static/js/{timepicker.DpQ3WAC_.js → timepicker.BndxQ_56.js} +1 -1
  67. streamlit/static/static/js/{toConsumableArray.EduObuzm.js → toConsumableArray.Bvyh5k2t.js} +1 -1
  68. streamlit/static/static/js/{uniqueId.qyd-2U_A.js → uniqueId.BJXawxf6.js} +1 -1
  69. streamlit/static/static/js/{useBasicWidgetState.B0zc_tpZ.js → useBasicWidgetState.-z6NaxAe.js} +1 -1
  70. streamlit/static/static/js/{useOnInputChange.tzktvOeD.js → useOnInputChange.DvBUKld6.js} +1 -1
  71. streamlit/static/static/js/{withFullScreenWrapper.TezXOJ_z.js → withFullScreenWrapper.CubK7zml.js} +1 -1
  72. streamlit/web/cli.py +42 -0
  73. {streamlit_nightly-1.43.3.dev20250311.dist-info → streamlit_nightly-1.43.3.dev20250312.dist-info}/METADATA +1 -1
  74. {streamlit_nightly-1.43.3.dev20250311.dist-info → streamlit_nightly-1.43.3.dev20250312.dist-info}/RECORD +78 -78
  75. streamlit/static/static/js/index.BMcgy3Eb.js +0 -1
  76. streamlit/static/static/js/index.COJ2HeaK.js +0 -1
  77. streamlit/static/static/js/index.D6iEZATu.js +0 -1
  78. streamlit/static/static/js/index.DuXQiNfC.js +0 -1
  79. streamlit/static/static/js/index.Fi_0UKZA.js +0 -1
  80. {streamlit_nightly-1.43.3.dev20250311.data → streamlit_nightly-1.43.3.dev20250312.data}/scripts/streamlit.cmd +0 -0
  81. {streamlit_nightly-1.43.3.dev20250311.dist-info → streamlit_nightly-1.43.3.dev20250312.dist-info}/WHEEL +0 -0
  82. {streamlit_nightly-1.43.3.dev20250311.dist-info → streamlit_nightly-1.43.3.dev20250312.dist-info}/entry_points.txt +0 -0
  83. {streamlit_nightly-1.43.3.dev20250311.dist-info → streamlit_nightly-1.43.3.dev20250312.dist-info}/top_level.txt +0 -0
streamlit/__init__.py CHANGED
@@ -166,6 +166,7 @@ altair_chart = _main.altair_chart
166
166
  area_chart = _main.area_chart
167
167
  audio = _main.audio
168
168
  audio_input = _main.audio_input
169
+ badge = _main.badge
169
170
  balloons = _main.balloons
170
171
  bar_chart = _main.bar_chart
171
172
  bokeh_chart = _main.bokeh_chart
@@ -14,11 +14,11 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import TYPE_CHECKING, Final, cast
17
+ from typing import TYPE_CHECKING, Final, Literal, cast
18
18
 
19
19
  from streamlit.proto.Markdown_pb2 import Markdown as MarkdownProto
20
20
  from streamlit.runtime.metrics_util import gather_metrics
21
- from streamlit.string_util import clean_text
21
+ from streamlit.string_util import clean_text, validate_icon_or_emoji
22
22
  from streamlit.type_util import SupportsStr, is_sympy_expression
23
23
 
24
24
  if TYPE_CHECKING:
@@ -80,8 +80,14 @@ class MarkdownMixin:
80
80
  primary accent color unless you set the ``theme.primaryColor``
81
81
  configuration option.
82
82
 
83
+ - Colored badges, using the syntax ``:color-badge[text in the badge]``.
84
+ Supported colors are: blue, green, orange, red, violet, gray/grey,
85
+ or primary. For example, you can use ``:orange-badge[your text here]``
86
+ or ``:blue-badge[your text here]``.
87
+
83
88
  - Small text, using the syntax ``:small[text to show small]``.
84
89
 
90
+
85
91
  unsafe_allow_html : bool
86
92
  Whether to render HTML within ``body``. If this is ``False``
87
93
  (default), any HTML tags found in ``body`` will be escaped and
@@ -271,6 +277,96 @@ class MarkdownMixin:
271
277
  divider_proto.element_type = MarkdownProto.Type.DIVIDER
272
278
  return self.dg._enqueue("markdown", divider_proto)
273
279
 
280
+ @gather_metrics("badge")
281
+ def badge(
282
+ self,
283
+ label: str,
284
+ *, # keyword-only arguments:
285
+ icon: str | None = None,
286
+ color: Literal[
287
+ "blue",
288
+ "green",
289
+ "orange",
290
+ "red",
291
+ "violet",
292
+ "gray",
293
+ "grey",
294
+ "rainbow",
295
+ "primary",
296
+ ] = "blue",
297
+ ) -> DeltaGenerator:
298
+ """Display a colored badge with an icon and label.
299
+
300
+ You can also insert badges directly in Markdown, e.g. via
301
+ `st.markdown(":blue-badge[Home]")`. This works in all places where Streamlit
302
+ supports Markdown, e.g. widget labels or `st.table` cells. See `st.markdown`
303
+ for more information.
304
+
305
+ Parameters
306
+ ----------
307
+ label : str
308
+ The label to display in the badge. The label can optionally contain
309
+ GitHub-flavored Markdown of the following types: Bold, Italics,
310
+ Strikethroughs, Inline Code.
311
+
312
+ See the ``body`` parameter of |st.markdown|_ for additional,
313
+ supported Markdown directives.
314
+
315
+ .. |st.markdown| replace:: ``st.markdown``
316
+ .. _st.markdown: https://docs.streamlit.io/develop/api-reference/text/st.markdown
317
+
318
+ icon : str or None
319
+ An optional emoji or icon to display next to the badge label. If
320
+ ``icon`` is ``None`` (default), no icon is displayed. If ``icon``
321
+ is a string, the following options are valid:
322
+
323
+ - A single-character emoji. For example, you can set ``icon="🚨"``
324
+ or ``icon="🔥"``. Emoji short codes are not supported.
325
+
326
+ - An icon from the Material Symbols library (rounded style) in the
327
+ format ``":material/icon_name:"`` where "icon_name" is the name
328
+ of the icon in snake case.
329
+
330
+ For example, ``icon=":material/thumb_up:"`` will display the
331
+ Thumb Up icon. Find additional icons in the `Material Symbols \
332
+ <https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
333
+ font library.
334
+
335
+ color : str
336
+ The color to use for the badge. Supported colors are: blue, green,
337
+ orange, red, violet, gray/grey, primary.
338
+ If you use "primary" for color, Streamlit will use the default
339
+ primary accent color unless you set the ``theme.primaryColor``
340
+ configuration option.
341
+
342
+ Examples
343
+ --------
344
+ >>> import streamlit as st
345
+ >>>
346
+ >>> # Simple badge
347
+ >>> st.badge("Home")
348
+ >>>
349
+ >>> # Badge with icon and color
350
+ >>> st.badge("Success", icon=":material/check:", color="green")
351
+ >>>
352
+ >>> # Multiple badges side by side in Markdown
353
+ >>> st.markdown(
354
+ ... "Here are some badges: :orange-badge[⭐️ Favorite] :blue-badge[🏠 Home] :green-badge[✅ Success]"
355
+ ... )
356
+ """
357
+ if icon is not None:
358
+ icon_str = validate_icon_or_emoji(icon) + " "
359
+ else:
360
+ icon_str = ""
361
+
362
+ # Escape [ and ] characters in the label to prevent breaking the directive syntax
363
+ escaped_label = label.replace("[", "\\[").replace("]", "\\]")
364
+
365
+ badge_proto = MarkdownProto()
366
+ badge_proto.body = f":{color}-badge[{icon_str}{escaped_label}]"
367
+ badge_proto.element_type = MarkdownProto.Type.NATIVE
368
+ return self.dg._enqueue("markdown", badge_proto)
369
+
274
370
  @property
275
371
  def dg(self) -> DeltaGenerator:
276
372
  """Get our DeltaGenerator."""
streamlit/errors.py CHANGED
@@ -450,3 +450,10 @@ class StreamlitBadTimeStringError(LocalizableStreamlitException):
450
450
  "`'1d2h34m'` or `2 days`, for example. Got: {time_string}",
451
451
  time_string=time_string,
452
452
  )
453
+
454
+
455
+ class StreamlitSecretNotFoundError(LocalizableStreamlitException, FileNotFoundError):
456
+ """Exception raised when a secret cannot be found or parsed in the secrets.toml file."""
457
+
458
+ def __init__(self, message: str):
459
+ super().__init__(message)
@@ -30,6 +30,7 @@ from blinker import Signal
30
30
  import streamlit as st
31
31
  import streamlit.watcher.path_watcher
32
32
  from streamlit import runtime
33
+ from streamlit.errors import StreamlitSecretNotFoundError
33
34
  from streamlit.logger import get_logger
34
35
 
35
36
  _LOGGER: Final = get_logger(__name__)
@@ -198,7 +199,6 @@ class Secrets(Mapping[str, Any]):
198
199
  self._secrets: Mapping[str, Any] | None = None
199
200
  self._lock = threading.RLock()
200
201
  self._file_watchers_installed = False
201
- self._suppress_print_error_on_exception = False
202
202
 
203
203
  self.file_change_listener = Signal(
204
204
  doc="Emitted when a `secrets.toml` file has been changed."
@@ -213,34 +213,19 @@ class Secrets(Mapping[str, Any]):
213
213
 
214
214
  Thread-safe.
215
215
  """
216
- prev_suppress_print_error_on_exception = self._suppress_print_error_on_exception
217
216
  try:
218
- # temporarily suppress printing errors on exceptions, we don't want to print errors
219
- # in this method since it only loads secrets if they exist
220
-
221
- self._suppress_print_error_on_exception = True
222
217
  self._parse()
223
218
 
224
219
  return True
225
- except FileNotFoundError:
220
+ except StreamlitSecretNotFoundError:
226
221
  # No secrets.toml files exist. That's fine.
227
222
  return False
228
- finally:
229
- self._suppress_print_error_on_exception = (
230
- prev_suppress_print_error_on_exception
231
- )
232
223
 
233
224
  def set_suppress_print_error_on_exception(
234
225
  self, suppress_print_error_on_exception: bool
235
226
  ) -> None:
236
- """Set whether exceptions should be printed when accessing secrets.
237
- For internal use, may change in future releases without notice."""
238
- self._suppress_print_error_on_exception = suppress_print_error_on_exception
239
-
240
- def _print_exception_if_not_suppressed(self, error_msg: str) -> None:
241
- """Print the given error message if exceptions are not suppressed."""
242
- if not self._suppress_print_error_on_exception:
243
- st.error(str(error_msg))
227
+ """This is left in place for compatibility with integrations until integration code can be updated."""
228
+ pass
244
229
 
245
230
  def _reset(self) -> None:
246
231
  """Clear the secrets dictionary and remove any secrets that were
@@ -275,13 +260,12 @@ class Secrets(Mapping[str, Any]):
275
260
 
276
261
  secrets.update(toml.loads(secrets_file_str))
277
262
  except (TypeError, toml.TomlDecodeError) as ex:
278
- error_msg = (
263
+ msg = (
279
264
  secret_error_messages_singleton.get_error_parsing_file_at_path_message(
280
265
  path, ex
281
266
  )
282
267
  )
283
- self._print_exception_if_not_suppressed(error_msg)
284
- raise
268
+ raise StreamlitSecretNotFoundError(msg) from ex
285
269
 
286
270
  return secrets, found_secrets_file
287
271
 
@@ -308,8 +292,7 @@ class Secrets(Mapping[str, Any]):
308
292
  error_msg = secret_error_messages_singleton.get_subfolder_path_is_not_a_folder_message(
309
293
  sub_folder_path
310
294
  )
311
- self._print_exception_if_not_suppressed(error_msg)
312
- raise ValueError(error_msg)
295
+ raise StreamlitSecretNotFoundError(error_msg)
313
296
  sub_secrets = {}
314
297
 
315
298
  for filename in os.listdir(sub_folder_path):
@@ -341,8 +324,7 @@ class Secrets(Mapping[str, Any]):
341
324
  error_msg = secret_error_messages_singleton.get_invalid_secret_path_message(
342
325
  path
343
326
  )
344
- self._print_exception_if_not_suppressed(error_msg)
345
- raise ValueError(error_msg)
327
+ raise StreamlitSecretNotFoundError(error_msg)
346
328
 
347
329
  def _parse(self) -> Mapping[str, Any]:
348
330
  """Parse our secrets.toml files if they're not already parsed.
@@ -356,7 +338,7 @@ class Secrets(Mapping[str, Any]):
356
338
 
357
339
  Raises
358
340
  ------
359
- FileNotFoundError
341
+ StreamlitSecretNotFoundError
360
342
  Raised if secrets.toml doesn't exist.
361
343
 
362
344
  """
@@ -385,8 +367,7 @@ class Secrets(Mapping[str, Any]):
385
367
  file_paths
386
368
  )
387
369
  )
388
- self._print_exception_if_not_suppressed(error_msg)
389
- raise FileNotFoundError(error_msg)
370
+ raise StreamlitSecretNotFoundError(error_msg)
390
371
 
391
372
  for k, v in secrets.items():
392
373
  self._maybe_set_environment_variable(k, v)
@@ -492,6 +473,20 @@ class Secrets(Mapping[str, Any]):
492
473
  except KeyError:
493
474
  raise KeyError(_missing_key_error_message(key))
494
475
 
476
+ def __setattr__(self, key: str, value: Any) -> None:
477
+ # Allow internal attributes to be set
478
+ if key in {
479
+ "_secrets",
480
+ "_lock",
481
+ "_file_watchers_installed",
482
+ "_suppress_print_error_on_exception",
483
+ "file_change_listener",
484
+ "load_if_toml_exists",
485
+ }:
486
+ super().__setattr__(key, value)
487
+ else:
488
+ raise TypeError("Secrets does not support attribute assignment.")
489
+
495
490
  def __repr__(self) -> str:
496
491
  # If the runtime is NOT initialized, it is a method call outside
497
492
  # the streamlit app, so we avoid reading the secrets file as it may not exist.
@@ -51,7 +51,7 @@
51
51
  <script>
52
52
  window.prerenderReady = false
53
53
  </script>
54
- <script type="module" crossorigin src="./static/js/index.BiPCWEUM.js"></script>
54
+ <script type="module" crossorigin src="./static/js/index.pEU90S1o.js"></script>
55
55
  <link rel="stylesheet" crossorigin href="./static/css/index.DQZt7VFg.css">
56
56
  </head>
57
57
  <body>
@@ -1 +1 @@
1
- import{r as e,E as n,_ as a}from"./index.BiPCWEUM.js";var o=e.forwardRef(function(t,r){var l={fill:"currentColor",xmlns:"http://www.w3.org/2000/svg"};return e.createElement(n,a({iconAttrs:l,iconVerticalAlign:"middle",iconViewBox:"0 0 24 24"},t,{ref:r}),e.createElement("path",{fill:"none",d:"M0 0h24v24H0V0z"}),e.createElement("path",{d:"M16 9v10H8V9h8m-1.5-6h-5l-1 1H5v2h14V4h-3.5l-1-1zM18 7H6v12c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7z"}))});o.displayName="Delete";var i=e.forwardRef(function(t,r){var l={fill:"currentColor",xmlns:"http://www.w3.org/2000/svg"};return e.createElement(n,a({iconAttrs:l,iconVerticalAlign:"middle",iconViewBox:"0 0 24 24"},t,{ref:r}),e.createElement("rect",{width:24,height:24,fill:"none"}),e.createElement("path",{d:"M18 15v3H6v-3H4v3c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-3h-2zm-1-4l-1.41-1.41L13 12.17V4h-2v8.17L8.41 9.59 7 11l5 5 5-5z"}))});i.displayName="FileDownload";export{o as D,i as F};
1
+ import{r as e,E as n,_ as a}from"./index.pEU90S1o.js";var o=e.forwardRef(function(t,r){var l={fill:"currentColor",xmlns:"http://www.w3.org/2000/svg"};return e.createElement(n,a({iconAttrs:l,iconVerticalAlign:"middle",iconViewBox:"0 0 24 24"},t,{ref:r}),e.createElement("path",{fill:"none",d:"M0 0h24v24H0V0z"}),e.createElement("path",{d:"M16 9v10H8V9h8m-1.5-6h-5l-1 1H5v2h14V4h-3.5l-1-1zM18 7H6v12c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7z"}))});o.displayName="Delete";var i=e.forwardRef(function(t,r){var l={fill:"currentColor",xmlns:"http://www.w3.org/2000/svg"};return e.createElement(n,a({iconAttrs:l,iconVerticalAlign:"middle",iconViewBox:"0 0 24 24"},t,{ref:r}),e.createElement("rect",{width:24,height:24,fill:"none"}),e.createElement("path",{d:"M18 15v3H6v-3H4v3c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-3h-2zm-1-4l-1.41-1.41L13 12.17V4h-2v8.17L8.41 9.59 7 11l5 5 5-5z"}))});i.displayName="FileDownload";export{o as D,i as F};