Spaces:
Running
Running
Upload folder using huggingface_hub
Browse files- README.md +129 -51
- app.py +260 -225
- space.py +71 -35
- src/README.md +129 -51
- src/assets/gradio_logo_white.png +0 -0
- src/backend/gradio_creditspanel/creditspanel.py +116 -148
- src/backend/gradio_creditspanel/templates/component/index.js +0 -0
- src/backend/gradio_creditspanel/templates/component/style.css +1 -1
- src/demo/app.py +67 -32
- src/demo/space.py +71 -35
- src/frontend/Index.svelte +13 -0
- src/frontend/shared/MatrixEffect.svelte +21 -0
- src/frontend/shared/ScrollEffect.svelte +25 -2
- src/frontend/shared/StarWarsEffect.svelte +22 -0
- src/pyproject.toml +1 -1
README.md
CHANGED
|
@@ -10,7 +10,8 @@ app_file: space.py
|
|
| 10 |
---
|
| 11 |
|
| 12 |
# `gradio_creditspanel`
|
| 13 |
-
<
|
|
|
|
| 14 |
|
| 15 |
Credits Panel for Gradio UI
|
| 16 |
|
|
@@ -43,7 +44,7 @@ def setup_demo_files():
|
|
| 43 |
with open("./assets/logo.webp", "w") as f:
|
| 44 |
f.write("Placeholder WebP logo")
|
| 45 |
|
| 46 |
-
# ---
|
| 47 |
credits_list = [
|
| 48 |
{"section_title": "Project Leadership"},
|
| 49 |
{"title": "Project Manager", "name": "Emma Thompson"},
|
|
@@ -72,6 +73,8 @@ DEFAULT_SPEEDS = {
|
|
| 72 |
"starwars": 70.0,
|
| 73 |
"matrix": 40.0
|
| 74 |
}
|
|
|
|
|
|
|
| 75 |
|
| 76 |
def update_panel(
|
| 77 |
effect: str,
|
|
@@ -89,39 +92,52 @@ def update_panel(
|
|
| 89 |
logo_height: str | None,
|
| 90 |
scroll_background_color: str | None,
|
| 91 |
scroll_title_color: str | None,
|
|
|
|
| 92 |
scroll_name_color: str | None,
|
| 93 |
layout_style: str,
|
| 94 |
title_uppercase: bool,
|
| 95 |
name_uppercase: bool,
|
| 96 |
section_title_uppercase: bool,
|
| 97 |
-
swap_font_sizes: bool
|
|
|
|
|
|
|
| 98 |
) -> dict:
|
| 99 |
"""Callback function that updates all properties of the CreditsPanel component."""
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
|
| 126 |
def update_ui_on_effect_change(effect: str) -> tuple[float, float]:
|
| 127 |
"""Updates sliders to sensible defaults when the animation effect is changed."""
|
|
@@ -163,6 +179,14 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 163 |
name_uppercase_checkbox = gr.Checkbox(label="Name Uppercase", value=False)
|
| 164 |
section_title_uppercase_checkbox = gr.Checkbox(label="Section Uppercase", value=True)
|
| 165 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
gr.Markdown("### Intro Text")
|
| 167 |
intro_title_input = gr.Textbox(label="Intro Title", value="Gradio")
|
| 168 |
intro_subtitle_input = gr.Textbox(label="Intro Subtitle", value="The best UI framework")
|
|
@@ -182,19 +206,20 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 182 |
gr.Markdown("### Color Settings (Scroll Effect)")
|
| 183 |
scroll_background_color = gr.ColorPicker(label="Background Color", value="#000000")
|
| 184 |
scroll_title_color = gr.ColorPicker(label="Title Color", value="#FFFFFF")
|
|
|
|
| 185 |
scroll_name_color = gr.ColorPicker(label="Name Color", value="#FFFFFF")
|
| 186 |
|
| 187 |
-
panel = CreditsPanel(
|
|
|
|
| 188 |
credits=credits_list,
|
| 189 |
licenses=license_paths,
|
| 190 |
effect="scroll",
|
| 191 |
-
height=500,
|
| 192 |
speed=DEFAULT_SPEEDS["scroll"],
|
| 193 |
base_font_size=1.5,
|
| 194 |
intro_title="Gradio",
|
| 195 |
intro_subtitle="The best UI framework",
|
| 196 |
sidebar_position="right",
|
| 197 |
-
logo_path=
|
| 198 |
show_logo=True,
|
| 199 |
show_licenses=True,
|
| 200 |
show_credits=True,
|
|
@@ -205,11 +230,14 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 205 |
scroll_background_color="#000000",
|
| 206 |
scroll_title_color="#FFFFFF",
|
| 207 |
scroll_name_color="#FFFFFF",
|
|
|
|
| 208 |
layout_style="stacked",
|
| 209 |
title_uppercase=False,
|
| 210 |
name_uppercase=False,
|
| 211 |
section_title_uppercase=True,
|
| 212 |
swap_font_sizes_on_two_column=False,
|
|
|
|
|
|
|
| 213 |
)
|
| 214 |
|
| 215 |
inputs = [
|
|
@@ -227,15 +255,23 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 227 |
logo_width_input,
|
| 228 |
logo_height_input,
|
| 229 |
scroll_background_color,
|
| 230 |
-
scroll_title_color,
|
|
|
|
| 231 |
scroll_name_color,
|
| 232 |
layout_style_radio,
|
| 233 |
title_uppercase_checkbox,
|
| 234 |
name_uppercase_checkbox,
|
| 235 |
section_title_uppercase_checkbox,
|
| 236 |
-
swap_sizes_checkbox
|
|
|
|
|
|
|
| 237 |
]
|
| 238 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 239 |
layout_style_radio.change(
|
| 240 |
fn=toggle_swap_checkbox_visibility,
|
| 241 |
inputs=layout_style_radio,
|
|
@@ -270,7 +306,9 @@ if __name__ == "__main__":
|
|
| 270 |
<td align="left" style="width: 25%;">
|
| 271 |
|
| 272 |
```python
|
| 273 |
-
Any
|
|
|
|
|
|
|
| 274 |
```
|
| 275 |
|
| 276 |
</td>
|
|
@@ -279,21 +317,11 @@ Any
|
|
| 279 |
</tr>
|
| 280 |
|
| 281 |
<tr>
|
| 282 |
-
<td align="left"><code>
|
| 283 |
<td align="left" style="width: 25%;">
|
| 284 |
|
| 285 |
```python
|
| 286 |
-
|
| 287 |
-
typing.List[typing.Dict[str, str]],
|
| 288 |
-
typing.Callable,
|
| 289 |
-
NoneType,
|
| 290 |
-
][
|
| 291 |
-
typing.List[typing.Dict[str, str]][
|
| 292 |
-
typing.Dict[str, str][str, str]
|
| 293 |
-
],
|
| 294 |
-
Callable,
|
| 295 |
-
None,
|
| 296 |
-
]
|
| 297 |
```
|
| 298 |
|
| 299 |
</td>
|
|
@@ -302,7 +330,7 @@ typing.Union[
|
|
| 302 |
</tr>
|
| 303 |
|
| 304 |
<tr>
|
| 305 |
-
<td align="left"><code>
|
| 306 |
<td align="left" style="width: 25%;">
|
| 307 |
|
| 308 |
```python
|
|
@@ -315,11 +343,21 @@ int | str | None
|
|
| 315 |
</tr>
|
| 316 |
|
| 317 |
<tr>
|
| 318 |
-
<td align="left"><code>
|
| 319 |
<td align="left" style="width: 25%;">
|
| 320 |
|
| 321 |
```python
|
| 322 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 323 |
```
|
| 324 |
|
| 325 |
</td>
|
|
@@ -566,6 +604,19 @@ str | None
|
|
| 566 |
<td align="left">None</td>
|
| 567 |
</tr>
|
| 568 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 569 |
<tr>
|
| 570 |
<td align="left"><code>layout_style</code></td>
|
| 571 |
<td align="left" style="width: 25%;">
|
|
@@ -631,6 +682,32 @@ bool
|
|
| 631 |
<td align="left">None</td>
|
| 632 |
</tr>
|
| 633 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 634 |
<tr>
|
| 635 |
<td align="left"><code>label</code></td>
|
| 636 |
<td align="left" style="width: 25%;">
|
|
@@ -844,7 +921,6 @@ The impact on the users predict function varies depending on whether the compone
|
|
| 844 |
|
| 845 |
The code snippet below is accurate in cases where the component is used as both an input and an output.
|
| 846 |
|
| 847 |
-
- **As output:** Is passed, dict[str, Any] | None: The input payload, returned unchanged.
|
| 848 |
|
| 849 |
|
| 850 |
```python
|
|
@@ -852,7 +928,9 @@ The code snippet below is accurate in cases where the component is used as both
|
|
| 852 |
value: typing.Optional[typing.Dict[str, typing.Any]][
|
| 853 |
typing.Dict[str, typing.Any][str, Any], None
|
| 854 |
]
|
| 855 |
-
) -> Any
|
|
|
|
|
|
|
| 856 |
return value
|
| 857 |
```
|
| 858 |
|
|
|
|
| 10 |
---
|
| 11 |
|
| 12 |
# `gradio_creditspanel`
|
| 13 |
+
<img alt="Static Badge" src="https://img.shields.io/badge/version%20-%200.0.4%20-%20blue"> <a href="https://huggingface.co/spaces/elismasilva/gradio_creditspanel"><img src="https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Demo-blue"></a><p><span>💻 <a href='https://github.com/DEVAIEXP/gradio_component_creditspanel'>Component GitHub Code</a></span></p>
|
| 14 |
+
|
| 15 |
|
| 16 |
Credits Panel for Gradio UI
|
| 17 |
|
|
|
|
| 44 |
with open("./assets/logo.webp", "w") as f:
|
| 45 |
f.write("Placeholder WebP logo")
|
| 46 |
|
| 47 |
+
# --- Credits list with sections ---
|
| 48 |
credits_list = [
|
| 49 |
{"section_title": "Project Leadership"},
|
| 50 |
{"title": "Project Manager", "name": "Emma Thompson"},
|
|
|
|
| 73 |
"starwars": 70.0,
|
| 74 |
"matrix": 40.0
|
| 75 |
}
|
| 76 |
+
SCROLL_LOGO_PATH = "./assets/gradio_logo_white.png"
|
| 77 |
+
LOGO_PATH="./assets/logo.webp"
|
| 78 |
|
| 79 |
def update_panel(
|
| 80 |
effect: str,
|
|
|
|
| 92 |
logo_height: str | None,
|
| 93 |
scroll_background_color: str | None,
|
| 94 |
scroll_title_color: str | None,
|
| 95 |
+
scroll_section_title_color: str | None,
|
| 96 |
scroll_name_color: str | None,
|
| 97 |
layout_style: str,
|
| 98 |
title_uppercase: bool,
|
| 99 |
name_uppercase: bool,
|
| 100 |
section_title_uppercase: bool,
|
| 101 |
+
swap_font_sizes: bool,
|
| 102 |
+
show_scroll_logo: bool,
|
| 103 |
+
scroll_logo_height: str | None
|
| 104 |
) -> dict:
|
| 105 |
"""Callback function that updates all properties of the CreditsPanel component."""
|
| 106 |
+
|
| 107 |
+
scroll_logo_path = SCROLL_LOGO_PATH if show_scroll_logo else None
|
| 108 |
+
|
| 109 |
+
if not scroll_logo_height:
|
| 110 |
+
scroll_logo_height = "120px"
|
| 111 |
+
|
| 112 |
+
return {
|
| 113 |
+
"credits": credits_list,
|
| 114 |
+
"licenses": license_paths,
|
| 115 |
+
"effect": effect,
|
| 116 |
+
"speed": speed,
|
| 117 |
+
"base_font_size": base_font_size,
|
| 118 |
+
"intro_title": intro_title,
|
| 119 |
+
"intro_subtitle": intro_subtitle,
|
| 120 |
+
"sidebar_position": sidebar_position,
|
| 121 |
+
"logo_path": LOGO_PATH,
|
| 122 |
+
"show_logo": show_logo,
|
| 123 |
+
"show_licenses": show_licenses,
|
| 124 |
+
"show_credits": show_credits,
|
| 125 |
+
"logo_position": logo_position,
|
| 126 |
+
"logo_sizing": logo_sizing,
|
| 127 |
+
"logo_width": logo_width,
|
| 128 |
+
"logo_height": logo_height,
|
| 129 |
+
"scroll_background_color": scroll_background_color,
|
| 130 |
+
"scroll_title_color": scroll_title_color,
|
| 131 |
+
"scroll_name_color": scroll_name_color,
|
| 132 |
+
"scroll_section_title_color": scroll_section_title_color,
|
| 133 |
+
"layout_style": layout_style,
|
| 134 |
+
"title_uppercase": title_uppercase,
|
| 135 |
+
"name_uppercase": name_uppercase,
|
| 136 |
+
"section_title_uppercase": section_title_uppercase,
|
| 137 |
+
"swap_font_sizes_on_two_column": swap_font_sizes,
|
| 138 |
+
"scroll_logo_path": scroll_logo_path,
|
| 139 |
+
"scroll_logo_height": scroll_logo_height,
|
| 140 |
+
}
|
| 141 |
|
| 142 |
def update_ui_on_effect_change(effect: str) -> tuple[float, float]:
|
| 143 |
"""Updates sliders to sensible defaults when the animation effect is changed."""
|
|
|
|
| 179 |
name_uppercase_checkbox = gr.Checkbox(label="Name Uppercase", value=False)
|
| 180 |
section_title_uppercase_checkbox = gr.Checkbox(label="Section Uppercase", value=True)
|
| 181 |
|
| 182 |
+
gr.Markdown("### Scrolling Logo")
|
| 183 |
+
show_scroll_logo_checkbox = gr.Checkbox(
|
| 184 |
+
label="Show Logo in Credits Roll",
|
| 185 |
+
value=True,
|
| 186 |
+
info="Toggles the logo above the intro text."
|
| 187 |
+
)
|
| 188 |
+
scroll_logo_height_input = gr.Textbox(label="Scrolling Logo Height", value="100px")
|
| 189 |
+
|
| 190 |
gr.Markdown("### Intro Text")
|
| 191 |
intro_title_input = gr.Textbox(label="Intro Title", value="Gradio")
|
| 192 |
intro_subtitle_input = gr.Textbox(label="Intro Subtitle", value="The best UI framework")
|
|
|
|
| 206 |
gr.Markdown("### Color Settings (Scroll Effect)")
|
| 207 |
scroll_background_color = gr.ColorPicker(label="Background Color", value="#000000")
|
| 208 |
scroll_title_color = gr.ColorPicker(label="Title Color", value="#FFFFFF")
|
| 209 |
+
scroll_section_title_color = gr.ColorPicker(label="Section Title Color", value="#FFFFFF")
|
| 210 |
scroll_name_color = gr.ColorPicker(label="Name Color", value="#FFFFFF")
|
| 211 |
|
| 212 |
+
panel = CreditsPanel(
|
| 213 |
+
height=500,
|
| 214 |
credits=credits_list,
|
| 215 |
licenses=license_paths,
|
| 216 |
effect="scroll",
|
|
|
|
| 217 |
speed=DEFAULT_SPEEDS["scroll"],
|
| 218 |
base_font_size=1.5,
|
| 219 |
intro_title="Gradio",
|
| 220 |
intro_subtitle="The best UI framework",
|
| 221 |
sidebar_position="right",
|
| 222 |
+
logo_path=LOGO_PATH,
|
| 223 |
show_logo=True,
|
| 224 |
show_licenses=True,
|
| 225 |
show_credits=True,
|
|
|
|
| 230 |
scroll_background_color="#000000",
|
| 231 |
scroll_title_color="#FFFFFF",
|
| 232 |
scroll_name_color="#FFFFFF",
|
| 233 |
+
scroll_section_title_color="#FFFFFF",
|
| 234 |
layout_style="stacked",
|
| 235 |
title_uppercase=False,
|
| 236 |
name_uppercase=False,
|
| 237 |
section_title_uppercase=True,
|
| 238 |
swap_font_sizes_on_two_column=False,
|
| 239 |
+
scroll_logo_path=SCROLL_LOGO_PATH,
|
| 240 |
+
scroll_logo_height="100px",
|
| 241 |
)
|
| 242 |
|
| 243 |
inputs = [
|
|
|
|
| 255 |
logo_width_input,
|
| 256 |
logo_height_input,
|
| 257 |
scroll_background_color,
|
| 258 |
+
scroll_title_color,
|
| 259 |
+
scroll_section_title_color,
|
| 260 |
scroll_name_color,
|
| 261 |
layout_style_radio,
|
| 262 |
title_uppercase_checkbox,
|
| 263 |
name_uppercase_checkbox,
|
| 264 |
section_title_uppercase_checkbox,
|
| 265 |
+
swap_sizes_checkbox,
|
| 266 |
+
show_scroll_logo_checkbox,
|
| 267 |
+
scroll_logo_height_input
|
| 268 |
]
|
| 269 |
|
| 270 |
+
demo.load(
|
| 271 |
+
fn=update_panel,
|
| 272 |
+
inputs=inputs,
|
| 273 |
+
outputs=panel
|
| 274 |
+
)
|
| 275 |
layout_style_radio.change(
|
| 276 |
fn=toggle_swap_checkbox_visibility,
|
| 277 |
inputs=layout_style_radio,
|
|
|
|
| 306 |
<td align="left" style="width: 25%;">
|
| 307 |
|
| 308 |
```python
|
| 309 |
+
typing.Optional[typing.Dict[str, typing.Any]][
|
| 310 |
+
typing.Dict[str, typing.Any][str, Any], None
|
| 311 |
+
]
|
| 312 |
```
|
| 313 |
|
| 314 |
</td>
|
|
|
|
| 317 |
</tr>
|
| 318 |
|
| 319 |
<tr>
|
| 320 |
+
<td align="left"><code>height</code></td>
|
| 321 |
<td align="left" style="width: 25%;">
|
| 322 |
|
| 323 |
```python
|
| 324 |
+
int | str | None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 325 |
```
|
| 326 |
|
| 327 |
</td>
|
|
|
|
| 330 |
</tr>
|
| 331 |
|
| 332 |
<tr>
|
| 333 |
+
<td align="left"><code>width</code></td>
|
| 334 |
<td align="left" style="width: 25%;">
|
| 335 |
|
| 336 |
```python
|
|
|
|
| 343 |
</tr>
|
| 344 |
|
| 345 |
<tr>
|
| 346 |
+
<td align="left"><code>credits</code></td>
|
| 347 |
<td align="left" style="width: 25%;">
|
| 348 |
|
| 349 |
```python
|
| 350 |
+
typing.Union[
|
| 351 |
+
typing.List[typing.Dict[str, str]],
|
| 352 |
+
typing.Callable,
|
| 353 |
+
NoneType,
|
| 354 |
+
][
|
| 355 |
+
typing.List[typing.Dict[str, str]][
|
| 356 |
+
typing.Dict[str, str][str, str]
|
| 357 |
+
],
|
| 358 |
+
Callable,
|
| 359 |
+
None,
|
| 360 |
+
]
|
| 361 |
```
|
| 362 |
|
| 363 |
</td>
|
|
|
|
| 604 |
<td align="left">None</td>
|
| 605 |
</tr>
|
| 606 |
|
| 607 |
+
<tr>
|
| 608 |
+
<td align="left"><code>scroll_section_title_color</code></td>
|
| 609 |
+
<td align="left" style="width: 25%;">
|
| 610 |
+
|
| 611 |
+
```python
|
| 612 |
+
str | None
|
| 613 |
+
```
|
| 614 |
+
|
| 615 |
+
</td>
|
| 616 |
+
<td align="left"><code>None</code></td>
|
| 617 |
+
<td align="left">None</td>
|
| 618 |
+
</tr>
|
| 619 |
+
|
| 620 |
<tr>
|
| 621 |
<td align="left"><code>layout_style</code></td>
|
| 622 |
<td align="left" style="width: 25%;">
|
|
|
|
| 682 |
<td align="left">None</td>
|
| 683 |
</tr>
|
| 684 |
|
| 685 |
+
<tr>
|
| 686 |
+
<td align="left"><code>scroll_logo_path</code></td>
|
| 687 |
+
<td align="left" style="width: 25%;">
|
| 688 |
+
|
| 689 |
+
```python
|
| 690 |
+
str | pathlib.Path | None
|
| 691 |
+
```
|
| 692 |
+
|
| 693 |
+
</td>
|
| 694 |
+
<td align="left"><code>None</code></td>
|
| 695 |
+
<td align="left">None</td>
|
| 696 |
+
</tr>
|
| 697 |
+
|
| 698 |
+
<tr>
|
| 699 |
+
<td align="left"><code>scroll_logo_height</code></td>
|
| 700 |
+
<td align="left" style="width: 25%;">
|
| 701 |
+
|
| 702 |
+
```python
|
| 703 |
+
str
|
| 704 |
+
```
|
| 705 |
+
|
| 706 |
+
</td>
|
| 707 |
+
<td align="left"><code>"120px"</code></td>
|
| 708 |
+
<td align="left">None</td>
|
| 709 |
+
</tr>
|
| 710 |
+
|
| 711 |
<tr>
|
| 712 |
<td align="left"><code>label</code></td>
|
| 713 |
<td align="left" style="width: 25%;">
|
|
|
|
| 921 |
|
| 922 |
The code snippet below is accurate in cases where the component is used as both an input and an output.
|
| 923 |
|
|
|
|
| 924 |
|
| 925 |
|
| 926 |
```python
|
|
|
|
| 928 |
value: typing.Optional[typing.Dict[str, typing.Any]][
|
| 929 |
typing.Dict[str, typing.Any][str, Any], None
|
| 930 |
]
|
| 931 |
+
) -> typing.Optional[typing.Dict[str, typing.Any]][
|
| 932 |
+
typing.Dict[str, typing.Any][str, Any], None
|
| 933 |
+
]:
|
| 934 |
return value
|
| 935 |
```
|
| 936 |
|
app.py
CHANGED
|
@@ -1,226 +1,261 @@
|
|
| 1 |
-
# app.py
|
| 2 |
-
|
| 3 |
-
import gradio as gr
|
| 4 |
-
from gradio_creditspanel import CreditsPanel
|
| 5 |
-
import os
|
| 6 |
-
|
| 7 |
-
def setup_demo_files():
|
| 8 |
-
"""Creates necessary directories and dummy files for the demo."""
|
| 9 |
-
os.makedirs("
|
| 10 |
-
if not os.path.exists("
|
| 11 |
-
with open("
|
| 12 |
-
f.write("Apache License\nVersion 2.0, January 2004...")
|
| 13 |
-
if not os.path.exists("
|
| 14 |
-
with open("
|
| 15 |
-
f.write("MIT License\nCopyright (c) 2025 Author...")
|
| 16 |
-
os.makedirs("
|
| 17 |
-
if not os.path.exists("
|
| 18 |
-
with open("
|
| 19 |
-
f.write("Placeholder WebP logo")
|
| 20 |
-
|
| 21 |
-
# --- Credits list with sections ---
|
| 22 |
-
credits_list = [
|
| 23 |
-
{"section_title": "Project Leadership"},
|
| 24 |
-
{"title": "Project Manager", "name": "Emma Thompson"},
|
| 25 |
-
{"title": "Scrum Master", "name": "Ava Rodriguez"},
|
| 26 |
-
|
| 27 |
-
{"section_title": "Development Team"},
|
| 28 |
-
{"title": "Lead Developer", "name": "John Doe"},
|
| 29 |
-
{"title": "Senior Backend Engineer", "name": "Michael Chen"},
|
| 30 |
-
{"title": "Frontend Developer", "name": "Sarah Johnson"},
|
| 31 |
-
{"title": "UI/UX Designer", "name": "Jane Smith"},
|
| 32 |
-
{"title": "Database Architect", "name": "Alex Ray"},
|
| 33 |
-
|
| 34 |
-
{"section_title": "Quality & Operations"},
|
| 35 |
-
{"title": "DevOps Engineer", "name": "Liam Patel"},
|
| 36 |
-
{"title": "Quality Assurance Lead", "name": "Sam Wilson"},
|
| 37 |
-
{"title": "Test Automation Engineer", "name": "Olivia Brown"},
|
| 38 |
-
]
|
| 39 |
-
|
| 40 |
-
license_paths = {
|
| 41 |
-
"Gradio Framework": "
|
| 42 |
-
"This Component": "
|
| 43 |
-
}
|
| 44 |
-
|
| 45 |
-
DEFAULT_SPEEDS = {
|
| 46 |
-
"scroll": 40.0,
|
| 47 |
-
"starwars": 70.0,
|
| 48 |
-
"matrix": 40.0
|
| 49 |
-
}
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
gr.
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
scroll_background_color,
|
| 205 |
-
scroll_title_color,
|
| 206 |
-
scroll_name_color,
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 226 |
demo.launch()
|
|
|
|
| 1 |
+
# app.py
|
| 2 |
+
|
| 3 |
+
import gradio as gr
|
| 4 |
+
from gradio_creditspanel import CreditsPanel
|
| 5 |
+
import os
|
| 6 |
+
|
| 7 |
+
def setup_demo_files():
|
| 8 |
+
"""Creates necessary directories and dummy files for the demo."""
|
| 9 |
+
os.makedirs("LICENSES", exist_ok=True)
|
| 10 |
+
if not os.path.exists("LICENSES/Apache.txt"):
|
| 11 |
+
with open("LICENSES/Apache.txt", "w") as f:
|
| 12 |
+
f.write("Apache License\nVersion 2.0, January 2004...")
|
| 13 |
+
if not os.path.exists("LICENSES/MIT.txt"):
|
| 14 |
+
with open("LICENSES/MIT.txt", "w") as f:
|
| 15 |
+
f.write("MIT License\nCopyright (c) 2025 Author...")
|
| 16 |
+
os.makedirs("assets", exist_ok=True)
|
| 17 |
+
if not os.path.exists("./assets/logo.webp"):
|
| 18 |
+
with open("./assets/logo.webp", "w") as f:
|
| 19 |
+
f.write("Placeholder WebP logo")
|
| 20 |
+
|
| 21 |
+
# --- Credits list with sections ---
|
| 22 |
+
credits_list = [
|
| 23 |
+
{"section_title": "Project Leadership"},
|
| 24 |
+
{"title": "Project Manager", "name": "Emma Thompson"},
|
| 25 |
+
{"title": "Scrum Master", "name": "Ava Rodriguez"},
|
| 26 |
+
|
| 27 |
+
{"section_title": "Development Team"},
|
| 28 |
+
{"title": "Lead Developer", "name": "John Doe"},
|
| 29 |
+
{"title": "Senior Backend Engineer", "name": "Michael Chen"},
|
| 30 |
+
{"title": "Frontend Developer", "name": "Sarah Johnson"},
|
| 31 |
+
{"title": "UI/UX Designer", "name": "Jane Smith"},
|
| 32 |
+
{"title": "Database Architect", "name": "Alex Ray"},
|
| 33 |
+
|
| 34 |
+
{"section_title": "Quality & Operations"},
|
| 35 |
+
{"title": "DevOps Engineer", "name": "Liam Patel"},
|
| 36 |
+
{"title": "Quality Assurance Lead", "name": "Sam Wilson"},
|
| 37 |
+
{"title": "Test Automation Engineer", "name": "Olivia Brown"},
|
| 38 |
+
]
|
| 39 |
+
|
| 40 |
+
license_paths = {
|
| 41 |
+
"Gradio Framework": "./LICENSES/Apache.txt",
|
| 42 |
+
"This Component": "./LICENSES/MIT.txt"
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
DEFAULT_SPEEDS = {
|
| 46 |
+
"scroll": 40.0,
|
| 47 |
+
"starwars": 70.0,
|
| 48 |
+
"matrix": 40.0
|
| 49 |
+
}
|
| 50 |
+
SCROLL_LOGO_PATH = "./assets/gradio_logo_white.png"
|
| 51 |
+
LOGO_PATH="./assets/logo.webp"
|
| 52 |
+
|
| 53 |
+
def update_panel(
|
| 54 |
+
effect: str,
|
| 55 |
+
speed: float,
|
| 56 |
+
base_font_size: float,
|
| 57 |
+
intro_title: str,
|
| 58 |
+
intro_subtitle: str,
|
| 59 |
+
sidebar_position: str,
|
| 60 |
+
show_logo: bool,
|
| 61 |
+
show_licenses: bool,
|
| 62 |
+
show_credits: bool,
|
| 63 |
+
logo_position: str,
|
| 64 |
+
logo_sizing: str,
|
| 65 |
+
logo_width: str | None,
|
| 66 |
+
logo_height: str | None,
|
| 67 |
+
scroll_background_color: str | None,
|
| 68 |
+
scroll_title_color: str | None,
|
| 69 |
+
scroll_section_title_color: str | None,
|
| 70 |
+
scroll_name_color: str | None,
|
| 71 |
+
layout_style: str,
|
| 72 |
+
title_uppercase: bool,
|
| 73 |
+
name_uppercase: bool,
|
| 74 |
+
section_title_uppercase: bool,
|
| 75 |
+
swap_font_sizes: bool,
|
| 76 |
+
show_scroll_logo: bool,
|
| 77 |
+
scroll_logo_height: str | None
|
| 78 |
+
) -> dict:
|
| 79 |
+
"""Callback function that updates all properties of the CreditsPanel component."""
|
| 80 |
+
|
| 81 |
+
scroll_logo_path = SCROLL_LOGO_PATH if show_scroll_logo else None
|
| 82 |
+
|
| 83 |
+
if not scroll_logo_height:
|
| 84 |
+
scroll_logo_height = "120px"
|
| 85 |
+
|
| 86 |
+
return {
|
| 87 |
+
"credits": credits_list,
|
| 88 |
+
"licenses": license_paths,
|
| 89 |
+
"effect": effect,
|
| 90 |
+
"speed": speed,
|
| 91 |
+
"base_font_size": base_font_size,
|
| 92 |
+
"intro_title": intro_title,
|
| 93 |
+
"intro_subtitle": intro_subtitle,
|
| 94 |
+
"sidebar_position": sidebar_position,
|
| 95 |
+
"logo_path": LOGO_PATH,
|
| 96 |
+
"show_logo": show_logo,
|
| 97 |
+
"show_licenses": show_licenses,
|
| 98 |
+
"show_credits": show_credits,
|
| 99 |
+
"logo_position": logo_position,
|
| 100 |
+
"logo_sizing": logo_sizing,
|
| 101 |
+
"logo_width": logo_width,
|
| 102 |
+
"logo_height": logo_height,
|
| 103 |
+
"scroll_background_color": scroll_background_color,
|
| 104 |
+
"scroll_title_color": scroll_title_color,
|
| 105 |
+
"scroll_name_color": scroll_name_color,
|
| 106 |
+
"scroll_section_title_color": scroll_section_title_color,
|
| 107 |
+
"layout_style": layout_style,
|
| 108 |
+
"title_uppercase": title_uppercase,
|
| 109 |
+
"name_uppercase": name_uppercase,
|
| 110 |
+
"section_title_uppercase": section_title_uppercase,
|
| 111 |
+
"swap_font_sizes_on_two_column": swap_font_sizes,
|
| 112 |
+
"scroll_logo_path": scroll_logo_path,
|
| 113 |
+
"scroll_logo_height": scroll_logo_height,
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
def update_ui_on_effect_change(effect: str) -> tuple[float, float]:
|
| 117 |
+
"""Updates sliders to sensible defaults when the animation effect is changed."""
|
| 118 |
+
font_size = 1.5
|
| 119 |
+
if effect == "starwars":
|
| 120 |
+
font_size = 3.8
|
| 121 |
+
speed = DEFAULT_SPEEDS.get(effect, 40.0)
|
| 122 |
+
return speed, font_size
|
| 123 |
+
|
| 124 |
+
def toggle_swap_checkbox_visibility(layout: str) -> dict:
|
| 125 |
+
"""Show the swap checkbox only for the two-column layout."""
|
| 126 |
+
return gr.update(visible=(layout == 'two-column'))
|
| 127 |
+
|
| 128 |
+
with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
| 129 |
+
gr.Markdown(
|
| 130 |
+
"""
|
| 131 |
+
# Interactive CreditsPanel Demo
|
| 132 |
+
Use the sidebar controls to customize the `CreditsPanel` component in real-time.
|
| 133 |
+
"""
|
| 134 |
+
)
|
| 135 |
+
|
| 136 |
+
with gr.Sidebar(position="right"):
|
| 137 |
+
gr.Markdown("### Effects Settings")
|
| 138 |
+
effect_radio = gr.Radio(["scroll", "starwars", "matrix"], label="Animation Effect", value="scroll")
|
| 139 |
+
speed_slider = gr.Slider(minimum=5.0, maximum=100.0, step=1.0, value=DEFAULT_SPEEDS["scroll"], label="Animation Speed")
|
| 140 |
+
font_size_slider = gr.Slider(minimum=1.0, maximum=10.0, step=0.1, value=1.5, label="Base Font Size")
|
| 141 |
+
|
| 142 |
+
gr.Markdown("### Credits Layout Settings")
|
| 143 |
+
layout_style_radio = gr.Radio(
|
| 144 |
+
["stacked", "two-column"], label="Layout Style", value="stacked",
|
| 145 |
+
info="How to display titles and names."
|
| 146 |
+
)
|
| 147 |
+
swap_sizes_checkbox = gr.Checkbox(
|
| 148 |
+
label="Swap Title/Name Font Sizes", value=False,
|
| 149 |
+
info="Emphasize name over title in two-column layout.",
|
| 150 |
+
visible=False
|
| 151 |
+
)
|
| 152 |
+
title_uppercase_checkbox = gr.Checkbox(label="Title Uppercase", value=False)
|
| 153 |
+
name_uppercase_checkbox = gr.Checkbox(label="Name Uppercase", value=False)
|
| 154 |
+
section_title_uppercase_checkbox = gr.Checkbox(label="Section Uppercase", value=True)
|
| 155 |
+
|
| 156 |
+
gr.Markdown("### Scrolling Logo")
|
| 157 |
+
show_scroll_logo_checkbox = gr.Checkbox(
|
| 158 |
+
label="Show Logo in Credits Roll",
|
| 159 |
+
value=True,
|
| 160 |
+
info="Toggles the logo above the intro text."
|
| 161 |
+
)
|
| 162 |
+
scroll_logo_height_input = gr.Textbox(label="Scrolling Logo Height", value="100px")
|
| 163 |
+
|
| 164 |
+
gr.Markdown("### Intro Text")
|
| 165 |
+
intro_title_input = gr.Textbox(label="Intro Title", value="Gradio")
|
| 166 |
+
intro_subtitle_input = gr.Textbox(label="Intro Subtitle", value="The best UI framework")
|
| 167 |
+
|
| 168 |
+
gr.Markdown("### Layout & Visibility")
|
| 169 |
+
sidebar_position_radio = gr.Radio(["right", "bottom"], label="Sidebar Position", value="right")
|
| 170 |
+
show_logo_checkbox = gr.Checkbox(label="Show Logo", value=True)
|
| 171 |
+
show_licenses_checkbox = gr.Checkbox(label="Show Licenses", value=True)
|
| 172 |
+
show_credits_checkbox = gr.Checkbox(label="Show Credits", value=True)
|
| 173 |
+
|
| 174 |
+
gr.Markdown("### Logo Customization")
|
| 175 |
+
logo_position_radio = gr.Radio(["left", "center", "right"], label="Logo Position", value="center")
|
| 176 |
+
logo_sizing_radio = gr.Radio(["stretch", "crop", "resize"], label="Logo Sizing", value="resize")
|
| 177 |
+
logo_width_input = gr.Textbox(label="Logo Width", value="200px")
|
| 178 |
+
logo_height_input = gr.Textbox(label="Logo Height", value="100px")
|
| 179 |
+
|
| 180 |
+
gr.Markdown("### Color Settings (Scroll Effect)")
|
| 181 |
+
scroll_background_color = gr.ColorPicker(label="Background Color", value="#000000")
|
| 182 |
+
scroll_title_color = gr.ColorPicker(label="Title Color", value="#FFFFFF")
|
| 183 |
+
scroll_section_title_color = gr.ColorPicker(label="Section Title Color", value="#FFFFFF")
|
| 184 |
+
scroll_name_color = gr.ColorPicker(label="Name Color", value="#FFFFFF")
|
| 185 |
+
|
| 186 |
+
panel = CreditsPanel(
|
| 187 |
+
height=500,
|
| 188 |
+
credits=credits_list,
|
| 189 |
+
licenses=license_paths,
|
| 190 |
+
effect="scroll",
|
| 191 |
+
speed=DEFAULT_SPEEDS["scroll"],
|
| 192 |
+
base_font_size=1.5,
|
| 193 |
+
intro_title="Gradio",
|
| 194 |
+
intro_subtitle="The best UI framework",
|
| 195 |
+
sidebar_position="right",
|
| 196 |
+
logo_path=LOGO_PATH,
|
| 197 |
+
show_logo=True,
|
| 198 |
+
show_licenses=True,
|
| 199 |
+
show_credits=True,
|
| 200 |
+
logo_position="center",
|
| 201 |
+
logo_sizing="resize",
|
| 202 |
+
logo_width="200px",
|
| 203 |
+
logo_height="100px",
|
| 204 |
+
scroll_background_color="#000000",
|
| 205 |
+
scroll_title_color="#FFFFFF",
|
| 206 |
+
scroll_name_color="#FFFFFF",
|
| 207 |
+
scroll_section_title_color="#FFFFFF",
|
| 208 |
+
layout_style="stacked",
|
| 209 |
+
title_uppercase=False,
|
| 210 |
+
name_uppercase=False,
|
| 211 |
+
section_title_uppercase=True,
|
| 212 |
+
swap_font_sizes_on_two_column=False,
|
| 213 |
+
scroll_logo_path=SCROLL_LOGO_PATH,
|
| 214 |
+
scroll_logo_height="100px",
|
| 215 |
+
)
|
| 216 |
+
|
| 217 |
+
inputs = [
|
| 218 |
+
effect_radio,
|
| 219 |
+
speed_slider,
|
| 220 |
+
font_size_slider,
|
| 221 |
+
intro_title_input,
|
| 222 |
+
intro_subtitle_input,
|
| 223 |
+
sidebar_position_radio,
|
| 224 |
+
show_logo_checkbox,
|
| 225 |
+
show_licenses_checkbox,
|
| 226 |
+
show_credits_checkbox,
|
| 227 |
+
logo_position_radio,
|
| 228 |
+
logo_sizing_radio,
|
| 229 |
+
logo_width_input,
|
| 230 |
+
logo_height_input,
|
| 231 |
+
scroll_background_color,
|
| 232 |
+
scroll_title_color,
|
| 233 |
+
scroll_section_title_color,
|
| 234 |
+
scroll_name_color,
|
| 235 |
+
layout_style_radio,
|
| 236 |
+
title_uppercase_checkbox,
|
| 237 |
+
name_uppercase_checkbox,
|
| 238 |
+
section_title_uppercase_checkbox,
|
| 239 |
+
swap_sizes_checkbox,
|
| 240 |
+
show_scroll_logo_checkbox,
|
| 241 |
+
scroll_logo_height_input
|
| 242 |
+
]
|
| 243 |
+
|
| 244 |
+
demo.load(
|
| 245 |
+
fn=update_panel,
|
| 246 |
+
inputs=inputs,
|
| 247 |
+
outputs=panel
|
| 248 |
+
)
|
| 249 |
+
layout_style_radio.change(
|
| 250 |
+
fn=toggle_swap_checkbox_visibility,
|
| 251 |
+
inputs=layout_style_radio,
|
| 252 |
+
outputs=swap_sizes_checkbox
|
| 253 |
+
)
|
| 254 |
+
effect_radio.change(fn=update_ui_on_effect_change, inputs=effect_radio, outputs=[speed_slider, font_size_slider])
|
| 255 |
+
|
| 256 |
+
for input_component in inputs:
|
| 257 |
+
input_component.change(fn=update_panel, inputs=inputs, outputs=panel)
|
| 258 |
+
|
| 259 |
+
if __name__ == "__main__":
|
| 260 |
+
setup_demo_files()
|
| 261 |
demo.launch()
|
space.py
CHANGED
|
@@ -3,7 +3,7 @@ import gradio as gr
|
|
| 3 |
from app import demo as app
|
| 4 |
import os
|
| 5 |
|
| 6 |
-
_docs = {'CreditsPanel': {'description': 'A Gradio component for displaying credits with customizable visual effects, such as scrolling or Star Wars-style animations.\
|
| 7 |
|
| 8 |
abs_path = os.path.join(os.path.dirname(__file__), "css.css")
|
| 9 |
|
|
@@ -58,7 +58,7 @@ def setup_demo_files():
|
|
| 58 |
with open("./assets/logo.webp", "w") as f:
|
| 59 |
f.write("Placeholder WebP logo")
|
| 60 |
|
| 61 |
-
# ---
|
| 62 |
credits_list = [
|
| 63 |
{"section_title": "Project Leadership"},
|
| 64 |
{"title": "Project Manager", "name": "Emma Thompson"},
|
|
@@ -87,6 +87,8 @@ DEFAULT_SPEEDS = {
|
|
| 87 |
"starwars": 70.0,
|
| 88 |
"matrix": 40.0
|
| 89 |
}
|
|
|
|
|
|
|
| 90 |
|
| 91 |
def update_panel(
|
| 92 |
effect: str,
|
|
@@ -104,39 +106,52 @@ def update_panel(
|
|
| 104 |
logo_height: str | None,
|
| 105 |
scroll_background_color: str | None,
|
| 106 |
scroll_title_color: str | None,
|
|
|
|
| 107 |
scroll_name_color: str | None,
|
| 108 |
layout_style: str,
|
| 109 |
title_uppercase: bool,
|
| 110 |
name_uppercase: bool,
|
| 111 |
section_title_uppercase: bool,
|
| 112 |
-
swap_font_sizes: bool
|
|
|
|
|
|
|
| 113 |
) -> dict:
|
| 114 |
\"\"\"Callback function that updates all properties of the CreditsPanel component.\"\"\"
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
|
| 141 |
def update_ui_on_effect_change(effect: str) -> tuple[float, float]:
|
| 142 |
\"\"\"Updates sliders to sensible defaults when the animation effect is changed.\"\"\"
|
|
@@ -178,6 +193,14 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 178 |
name_uppercase_checkbox = gr.Checkbox(label="Name Uppercase", value=False)
|
| 179 |
section_title_uppercase_checkbox = gr.Checkbox(label="Section Uppercase", value=True)
|
| 180 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 181 |
gr.Markdown("### Intro Text")
|
| 182 |
intro_title_input = gr.Textbox(label="Intro Title", value="Gradio")
|
| 183 |
intro_subtitle_input = gr.Textbox(label="Intro Subtitle", value="The best UI framework")
|
|
@@ -197,19 +220,20 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 197 |
gr.Markdown("### Color Settings (Scroll Effect)")
|
| 198 |
scroll_background_color = gr.ColorPicker(label="Background Color", value="#000000")
|
| 199 |
scroll_title_color = gr.ColorPicker(label="Title Color", value="#FFFFFF")
|
|
|
|
| 200 |
scroll_name_color = gr.ColorPicker(label="Name Color", value="#FFFFFF")
|
| 201 |
|
| 202 |
-
panel = CreditsPanel(
|
|
|
|
| 203 |
credits=credits_list,
|
| 204 |
licenses=license_paths,
|
| 205 |
effect="scroll",
|
| 206 |
-
height=500,
|
| 207 |
speed=DEFAULT_SPEEDS["scroll"],
|
| 208 |
base_font_size=1.5,
|
| 209 |
intro_title="Gradio",
|
| 210 |
intro_subtitle="The best UI framework",
|
| 211 |
sidebar_position="right",
|
| 212 |
-
logo_path=
|
| 213 |
show_logo=True,
|
| 214 |
show_licenses=True,
|
| 215 |
show_credits=True,
|
|
@@ -220,11 +244,14 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 220 |
scroll_background_color="#000000",
|
| 221 |
scroll_title_color="#FFFFFF",
|
| 222 |
scroll_name_color="#FFFFFF",
|
|
|
|
| 223 |
layout_style="stacked",
|
| 224 |
title_uppercase=False,
|
| 225 |
name_uppercase=False,
|
| 226 |
section_title_uppercase=True,
|
| 227 |
swap_font_sizes_on_two_column=False,
|
|
|
|
|
|
|
| 228 |
)
|
| 229 |
|
| 230 |
inputs = [
|
|
@@ -242,15 +269,23 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 242 |
logo_width_input,
|
| 243 |
logo_height_input,
|
| 244 |
scroll_background_color,
|
| 245 |
-
scroll_title_color,
|
|
|
|
| 246 |
scroll_name_color,
|
| 247 |
layout_style_radio,
|
| 248 |
title_uppercase_checkbox,
|
| 249 |
name_uppercase_checkbox,
|
| 250 |
section_title_uppercase_checkbox,
|
| 251 |
-
swap_sizes_checkbox
|
|
|
|
|
|
|
| 252 |
]
|
| 253 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 254 |
layout_style_radio.change(
|
| 255 |
fn=toggle_swap_checkbox_visibility,
|
| 256 |
inputs=layout_style_radio,
|
|
@@ -294,7 +329,6 @@ The impact on the users predict function varies depending on whether the compone
|
|
| 294 |
|
| 295 |
The code snippet below is accurate in cases where the component is used as both an input and an output.
|
| 296 |
|
| 297 |
-
- **As input:** Is passed, dict[str, Any] | None: The input payload, returned unchanged.
|
| 298 |
|
| 299 |
|
| 300 |
```python
|
|
@@ -302,7 +336,9 @@ def predict(
|
|
| 302 |
value: typing.Optional[typing.Dict[str, typing.Any]][
|
| 303 |
typing.Dict[str, typing.Any][str, Any], None
|
| 304 |
]
|
| 305 |
-
) -> Any
|
|
|
|
|
|
|
| 306 |
return value
|
| 307 |
```
|
| 308 |
""", elem_classes=["md-custom", "CreditsPanel-user-fn"], header_links=True)
|
|
|
|
| 3 |
from app import demo as app
|
| 4 |
import os
|
| 5 |
|
| 6 |
+
_docs = {'CreditsPanel': {'description': 'A Gradio component for displaying credits with customizable visual effects, such as scrolling or Star Wars-style animations.\nThis component is configured via a single dictionary `value` that holds all settings.\nIt supports displaying a logo, licenses, sections, and various text styling options.\n\n EVENTS (list): Supported events for the component, currently only `change`.', 'members': {'__init__': {'value': {'type': 'typing.Optional[typing.Dict[str, typing.Any]][\n typing.Dict[str, typing.Any][str, Any], None\n]', 'default': 'None', 'description': None}, 'height': {'type': 'int | str | None', 'default': 'None', 'description': None}, 'width': {'type': 'int | str | None', 'default': 'None', 'description': None}, 'credits': {'type': 'typing.Union[\n typing.List[typing.Dict[str, str]],\n typing.Callable,\n NoneType,\n][\n typing.List[typing.Dict[str, str]][\n typing.Dict[str, str][str, str]\n ],\n Callable,\n None,\n]', 'default': 'None', 'description': None}, 'licenses': {'type': 'typing.Optional[typing.Dict[str, str | pathlib.Path]][\n typing.Dict[str, str | pathlib.Path][\n str, str | pathlib.Path\n ],\n None,\n]', 'default': 'None', 'description': None}, 'effect': {'type': '"scroll" | "starwars" | "matrix"', 'default': '"scroll"', 'description': None}, 'speed': {'type': 'float', 'default': '40.0', 'description': None}, 'base_font_size': {'type': 'float', 'default': '1.5', 'description': None}, 'intro_title': {'type': 'str | None', 'default': 'None', 'description': None}, 'intro_subtitle': {'type': 'str | None', 'default': 'None', 'description': None}, 'sidebar_position': {'type': '"right" | "bottom"', 'default': '"right"', 'description': None}, 'logo_path': {'type': 'str | pathlib.Path | None', 'default': 'None', 'description': None}, 'show_logo': {'type': 'bool', 'default': 'True', 'description': None}, 'show_licenses': {'type': 'bool', 'default': 'True', 'description': None}, 'show_credits': {'type': 'bool', 'default': 'True', 'description': None}, 'logo_position': {'type': '"center" | "left" | "right"', 'default': '"center"', 'description': None}, 'logo_sizing': {'type': '"stretch" | "crop" | "resize"', 'default': '"resize"', 'description': None}, 'logo_width': {'type': 'int | str | None', 'default': 'None', 'description': None}, 'logo_height': {'type': 'int | str | None', 'default': 'None', 'description': None}, 'scroll_background_color': {'type': 'str | None', 'default': 'None', 'description': None}, 'scroll_title_color': {'type': 'str | None', 'default': 'None', 'description': None}, 'scroll_name_color': {'type': 'str | None', 'default': 'None', 'description': None}, 'scroll_section_title_color': {'type': 'str | None', 'default': 'None', 'description': None}, 'layout_style': {'type': '"stacked" | "two-column"', 'default': '"stacked"', 'description': None}, 'title_uppercase': {'type': 'bool', 'default': 'False', 'description': None}, 'name_uppercase': {'type': 'bool', 'default': 'False', 'description': None}, 'section_title_uppercase': {'type': 'bool', 'default': 'True', 'description': None}, 'swap_font_sizes_on_two_column': {'type': 'bool', 'default': 'False', 'description': None}, 'scroll_logo_path': {'type': 'str | pathlib.Path | None', 'default': 'None', 'description': None}, 'scroll_logo_height': {'type': 'str', 'default': '"120px"', 'description': None}, 'label': {'type': 'str | gradio.i18n.I18nData | None', 'default': 'None', 'description': None}, 'every': {'type': 'float | None', 'default': 'None', 'description': None}, 'inputs': {'type': 'typing.Union[\n gradio.components.base.Component,\n typing.Sequence[gradio.components.base.Component],\n set[gradio.components.base.Component],\n NoneType,\n][\n gradio.components.base.Component,\n typing.Sequence[gradio.components.base.Component][\n gradio.components.base.Component\n ],\n set[gradio.components.base.Component],\n None,\n]', 'default': 'None', 'description': None}, 'show_label': {'type': 'bool', 'default': 'False', 'description': None}, 'container': {'type': 'bool', 'default': 'True', 'description': None}, 'scale': {'type': 'int | None', 'default': 'None', 'description': None}, 'min_width': {'type': 'int', 'default': '160', 'description': None}, 'interactive': {'type': 'bool | None', 'default': 'None', 'description': None}, 'visible': {'type': 'bool', 'default': 'True', 'description': None}, 'elem_id': {'type': 'str | None', 'default': 'None', 'description': None}, 'elem_classes': {'type': 'list[str] | str | None', 'default': 'None', 'description': None}, 'render': {'type': 'bool', 'default': 'True', 'description': None}, 'key': {'type': 'int | str | tuple[int | str, Ellipsis] | None', 'default': 'None', 'description': None}, 'preserved_by_key': {'type': 'list[str] | str | None', 'default': '"value"', 'description': None}}, 'postprocess': {'value': {'type': 'typing.Optional[typing.Dict[str, typing.Any]][\n typing.Dict[str, typing.Any][str, Any], None\n]', 'description': None}}, 'preprocess': {'return': {'type': 'typing.Optional[typing.Dict[str, typing.Any]][\n typing.Dict[str, typing.Any][str, Any], None\n]', 'description': None}, 'value': None}}, 'events': {'change': {'type': None, 'default': None, 'description': 'Triggered when the value of the CreditsPanel changes either because of user input (e.g. a user types in a textbox) OR because of a function update (e.g. an image receives a value from the output of an event trigger). See `.input()` for a listener that is only triggered by user input.'}}}, '__meta__': {'additional_interfaces': {}, 'user_fn_refs': {'CreditsPanel': []}}}
|
| 7 |
|
| 8 |
abs_path = os.path.join(os.path.dirname(__file__), "css.css")
|
| 9 |
|
|
|
|
| 58 |
with open("./assets/logo.webp", "w") as f:
|
| 59 |
f.write("Placeholder WebP logo")
|
| 60 |
|
| 61 |
+
# --- Credits list with sections ---
|
| 62 |
credits_list = [
|
| 63 |
{"section_title": "Project Leadership"},
|
| 64 |
{"title": "Project Manager", "name": "Emma Thompson"},
|
|
|
|
| 87 |
"starwars": 70.0,
|
| 88 |
"matrix": 40.0
|
| 89 |
}
|
| 90 |
+
SCROLL_LOGO_PATH = "./assets/gradio_logo_white.png"
|
| 91 |
+
LOGO_PATH="./assets/logo.webp"
|
| 92 |
|
| 93 |
def update_panel(
|
| 94 |
effect: str,
|
|
|
|
| 106 |
logo_height: str | None,
|
| 107 |
scroll_background_color: str | None,
|
| 108 |
scroll_title_color: str | None,
|
| 109 |
+
scroll_section_title_color: str | None,
|
| 110 |
scroll_name_color: str | None,
|
| 111 |
layout_style: str,
|
| 112 |
title_uppercase: bool,
|
| 113 |
name_uppercase: bool,
|
| 114 |
section_title_uppercase: bool,
|
| 115 |
+
swap_font_sizes: bool,
|
| 116 |
+
show_scroll_logo: bool,
|
| 117 |
+
scroll_logo_height: str | None
|
| 118 |
) -> dict:
|
| 119 |
\"\"\"Callback function that updates all properties of the CreditsPanel component.\"\"\"
|
| 120 |
+
|
| 121 |
+
scroll_logo_path = SCROLL_LOGO_PATH if show_scroll_logo else None
|
| 122 |
+
|
| 123 |
+
if not scroll_logo_height:
|
| 124 |
+
scroll_logo_height = "120px"
|
| 125 |
+
|
| 126 |
+
return {
|
| 127 |
+
"credits": credits_list,
|
| 128 |
+
"licenses": license_paths,
|
| 129 |
+
"effect": effect,
|
| 130 |
+
"speed": speed,
|
| 131 |
+
"base_font_size": base_font_size,
|
| 132 |
+
"intro_title": intro_title,
|
| 133 |
+
"intro_subtitle": intro_subtitle,
|
| 134 |
+
"sidebar_position": sidebar_position,
|
| 135 |
+
"logo_path": LOGO_PATH,
|
| 136 |
+
"show_logo": show_logo,
|
| 137 |
+
"show_licenses": show_licenses,
|
| 138 |
+
"show_credits": show_credits,
|
| 139 |
+
"logo_position": logo_position,
|
| 140 |
+
"logo_sizing": logo_sizing,
|
| 141 |
+
"logo_width": logo_width,
|
| 142 |
+
"logo_height": logo_height,
|
| 143 |
+
"scroll_background_color": scroll_background_color,
|
| 144 |
+
"scroll_title_color": scroll_title_color,
|
| 145 |
+
"scroll_name_color": scroll_name_color,
|
| 146 |
+
"scroll_section_title_color": scroll_section_title_color,
|
| 147 |
+
"layout_style": layout_style,
|
| 148 |
+
"title_uppercase": title_uppercase,
|
| 149 |
+
"name_uppercase": name_uppercase,
|
| 150 |
+
"section_title_uppercase": section_title_uppercase,
|
| 151 |
+
"swap_font_sizes_on_two_column": swap_font_sizes,
|
| 152 |
+
"scroll_logo_path": scroll_logo_path,
|
| 153 |
+
"scroll_logo_height": scroll_logo_height,
|
| 154 |
+
}
|
| 155 |
|
| 156 |
def update_ui_on_effect_change(effect: str) -> tuple[float, float]:
|
| 157 |
\"\"\"Updates sliders to sensible defaults when the animation effect is changed.\"\"\"
|
|
|
|
| 193 |
name_uppercase_checkbox = gr.Checkbox(label="Name Uppercase", value=False)
|
| 194 |
section_title_uppercase_checkbox = gr.Checkbox(label="Section Uppercase", value=True)
|
| 195 |
|
| 196 |
+
gr.Markdown("### Scrolling Logo")
|
| 197 |
+
show_scroll_logo_checkbox = gr.Checkbox(
|
| 198 |
+
label="Show Logo in Credits Roll",
|
| 199 |
+
value=True,
|
| 200 |
+
info="Toggles the logo above the intro text."
|
| 201 |
+
)
|
| 202 |
+
scroll_logo_height_input = gr.Textbox(label="Scrolling Logo Height", value="100px")
|
| 203 |
+
|
| 204 |
gr.Markdown("### Intro Text")
|
| 205 |
intro_title_input = gr.Textbox(label="Intro Title", value="Gradio")
|
| 206 |
intro_subtitle_input = gr.Textbox(label="Intro Subtitle", value="The best UI framework")
|
|
|
|
| 220 |
gr.Markdown("### Color Settings (Scroll Effect)")
|
| 221 |
scroll_background_color = gr.ColorPicker(label="Background Color", value="#000000")
|
| 222 |
scroll_title_color = gr.ColorPicker(label="Title Color", value="#FFFFFF")
|
| 223 |
+
scroll_section_title_color = gr.ColorPicker(label="Section Title Color", value="#FFFFFF")
|
| 224 |
scroll_name_color = gr.ColorPicker(label="Name Color", value="#FFFFFF")
|
| 225 |
|
| 226 |
+
panel = CreditsPanel(
|
| 227 |
+
height=500,
|
| 228 |
credits=credits_list,
|
| 229 |
licenses=license_paths,
|
| 230 |
effect="scroll",
|
|
|
|
| 231 |
speed=DEFAULT_SPEEDS["scroll"],
|
| 232 |
base_font_size=1.5,
|
| 233 |
intro_title="Gradio",
|
| 234 |
intro_subtitle="The best UI framework",
|
| 235 |
sidebar_position="right",
|
| 236 |
+
logo_path=LOGO_PATH,
|
| 237 |
show_logo=True,
|
| 238 |
show_licenses=True,
|
| 239 |
show_credits=True,
|
|
|
|
| 244 |
scroll_background_color="#000000",
|
| 245 |
scroll_title_color="#FFFFFF",
|
| 246 |
scroll_name_color="#FFFFFF",
|
| 247 |
+
scroll_section_title_color="#FFFFFF",
|
| 248 |
layout_style="stacked",
|
| 249 |
title_uppercase=False,
|
| 250 |
name_uppercase=False,
|
| 251 |
section_title_uppercase=True,
|
| 252 |
swap_font_sizes_on_two_column=False,
|
| 253 |
+
scroll_logo_path=SCROLL_LOGO_PATH,
|
| 254 |
+
scroll_logo_height="100px",
|
| 255 |
)
|
| 256 |
|
| 257 |
inputs = [
|
|
|
|
| 269 |
logo_width_input,
|
| 270 |
logo_height_input,
|
| 271 |
scroll_background_color,
|
| 272 |
+
scroll_title_color,
|
| 273 |
+
scroll_section_title_color,
|
| 274 |
scroll_name_color,
|
| 275 |
layout_style_radio,
|
| 276 |
title_uppercase_checkbox,
|
| 277 |
name_uppercase_checkbox,
|
| 278 |
section_title_uppercase_checkbox,
|
| 279 |
+
swap_sizes_checkbox,
|
| 280 |
+
show_scroll_logo_checkbox,
|
| 281 |
+
scroll_logo_height_input
|
| 282 |
]
|
| 283 |
|
| 284 |
+
demo.load(
|
| 285 |
+
fn=update_panel,
|
| 286 |
+
inputs=inputs,
|
| 287 |
+
outputs=panel
|
| 288 |
+
)
|
| 289 |
layout_style_radio.change(
|
| 290 |
fn=toggle_swap_checkbox_visibility,
|
| 291 |
inputs=layout_style_radio,
|
|
|
|
| 329 |
|
| 330 |
The code snippet below is accurate in cases where the component is used as both an input and an output.
|
| 331 |
|
|
|
|
| 332 |
|
| 333 |
|
| 334 |
```python
|
|
|
|
| 336 |
value: typing.Optional[typing.Dict[str, typing.Any]][
|
| 337 |
typing.Dict[str, typing.Any][str, Any], None
|
| 338 |
]
|
| 339 |
+
) -> typing.Optional[typing.Dict[str, typing.Any]][
|
| 340 |
+
typing.Dict[str, typing.Any][str, Any], None
|
| 341 |
+
]:
|
| 342 |
return value
|
| 343 |
```
|
| 344 |
""", elem_classes=["md-custom", "CreditsPanel-user-fn"], header_links=True)
|
src/README.md
CHANGED
|
@@ -10,7 +10,8 @@ app_file: space.py
|
|
| 10 |
---
|
| 11 |
|
| 12 |
# `gradio_creditspanel`
|
| 13 |
-
<
|
|
|
|
| 14 |
|
| 15 |
Credits Panel for Gradio UI
|
| 16 |
|
|
@@ -43,7 +44,7 @@ def setup_demo_files():
|
|
| 43 |
with open("./assets/logo.webp", "w") as f:
|
| 44 |
f.write("Placeholder WebP logo")
|
| 45 |
|
| 46 |
-
# ---
|
| 47 |
credits_list = [
|
| 48 |
{"section_title": "Project Leadership"},
|
| 49 |
{"title": "Project Manager", "name": "Emma Thompson"},
|
|
@@ -72,6 +73,8 @@ DEFAULT_SPEEDS = {
|
|
| 72 |
"starwars": 70.0,
|
| 73 |
"matrix": 40.0
|
| 74 |
}
|
|
|
|
|
|
|
| 75 |
|
| 76 |
def update_panel(
|
| 77 |
effect: str,
|
|
@@ -89,39 +92,52 @@ def update_panel(
|
|
| 89 |
logo_height: str | None,
|
| 90 |
scroll_background_color: str | None,
|
| 91 |
scroll_title_color: str | None,
|
|
|
|
| 92 |
scroll_name_color: str | None,
|
| 93 |
layout_style: str,
|
| 94 |
title_uppercase: bool,
|
| 95 |
name_uppercase: bool,
|
| 96 |
section_title_uppercase: bool,
|
| 97 |
-
swap_font_sizes: bool
|
|
|
|
|
|
|
| 98 |
) -> dict:
|
| 99 |
"""Callback function that updates all properties of the CreditsPanel component."""
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
|
| 126 |
def update_ui_on_effect_change(effect: str) -> tuple[float, float]:
|
| 127 |
"""Updates sliders to sensible defaults when the animation effect is changed."""
|
|
@@ -163,6 +179,14 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 163 |
name_uppercase_checkbox = gr.Checkbox(label="Name Uppercase", value=False)
|
| 164 |
section_title_uppercase_checkbox = gr.Checkbox(label="Section Uppercase", value=True)
|
| 165 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
gr.Markdown("### Intro Text")
|
| 167 |
intro_title_input = gr.Textbox(label="Intro Title", value="Gradio")
|
| 168 |
intro_subtitle_input = gr.Textbox(label="Intro Subtitle", value="The best UI framework")
|
|
@@ -182,19 +206,20 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 182 |
gr.Markdown("### Color Settings (Scroll Effect)")
|
| 183 |
scroll_background_color = gr.ColorPicker(label="Background Color", value="#000000")
|
| 184 |
scroll_title_color = gr.ColorPicker(label="Title Color", value="#FFFFFF")
|
|
|
|
| 185 |
scroll_name_color = gr.ColorPicker(label="Name Color", value="#FFFFFF")
|
| 186 |
|
| 187 |
-
panel = CreditsPanel(
|
|
|
|
| 188 |
credits=credits_list,
|
| 189 |
licenses=license_paths,
|
| 190 |
effect="scroll",
|
| 191 |
-
height=500,
|
| 192 |
speed=DEFAULT_SPEEDS["scroll"],
|
| 193 |
base_font_size=1.5,
|
| 194 |
intro_title="Gradio",
|
| 195 |
intro_subtitle="The best UI framework",
|
| 196 |
sidebar_position="right",
|
| 197 |
-
logo_path=
|
| 198 |
show_logo=True,
|
| 199 |
show_licenses=True,
|
| 200 |
show_credits=True,
|
|
@@ -205,11 +230,14 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 205 |
scroll_background_color="#000000",
|
| 206 |
scroll_title_color="#FFFFFF",
|
| 207 |
scroll_name_color="#FFFFFF",
|
|
|
|
| 208 |
layout_style="stacked",
|
| 209 |
title_uppercase=False,
|
| 210 |
name_uppercase=False,
|
| 211 |
section_title_uppercase=True,
|
| 212 |
swap_font_sizes_on_two_column=False,
|
|
|
|
|
|
|
| 213 |
)
|
| 214 |
|
| 215 |
inputs = [
|
|
@@ -227,15 +255,23 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 227 |
logo_width_input,
|
| 228 |
logo_height_input,
|
| 229 |
scroll_background_color,
|
| 230 |
-
scroll_title_color,
|
|
|
|
| 231 |
scroll_name_color,
|
| 232 |
layout_style_radio,
|
| 233 |
title_uppercase_checkbox,
|
| 234 |
name_uppercase_checkbox,
|
| 235 |
section_title_uppercase_checkbox,
|
| 236 |
-
swap_sizes_checkbox
|
|
|
|
|
|
|
| 237 |
]
|
| 238 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 239 |
layout_style_radio.change(
|
| 240 |
fn=toggle_swap_checkbox_visibility,
|
| 241 |
inputs=layout_style_radio,
|
|
@@ -270,7 +306,9 @@ if __name__ == "__main__":
|
|
| 270 |
<td align="left" style="width: 25%;">
|
| 271 |
|
| 272 |
```python
|
| 273 |
-
Any
|
|
|
|
|
|
|
| 274 |
```
|
| 275 |
|
| 276 |
</td>
|
|
@@ -279,21 +317,11 @@ Any
|
|
| 279 |
</tr>
|
| 280 |
|
| 281 |
<tr>
|
| 282 |
-
<td align="left"><code>
|
| 283 |
<td align="left" style="width: 25%;">
|
| 284 |
|
| 285 |
```python
|
| 286 |
-
|
| 287 |
-
typing.List[typing.Dict[str, str]],
|
| 288 |
-
typing.Callable,
|
| 289 |
-
NoneType,
|
| 290 |
-
][
|
| 291 |
-
typing.List[typing.Dict[str, str]][
|
| 292 |
-
typing.Dict[str, str][str, str]
|
| 293 |
-
],
|
| 294 |
-
Callable,
|
| 295 |
-
None,
|
| 296 |
-
]
|
| 297 |
```
|
| 298 |
|
| 299 |
</td>
|
|
@@ -302,7 +330,7 @@ typing.Union[
|
|
| 302 |
</tr>
|
| 303 |
|
| 304 |
<tr>
|
| 305 |
-
<td align="left"><code>
|
| 306 |
<td align="left" style="width: 25%;">
|
| 307 |
|
| 308 |
```python
|
|
@@ -315,11 +343,21 @@ int | str | None
|
|
| 315 |
</tr>
|
| 316 |
|
| 317 |
<tr>
|
| 318 |
-
<td align="left"><code>
|
| 319 |
<td align="left" style="width: 25%;">
|
| 320 |
|
| 321 |
```python
|
| 322 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 323 |
```
|
| 324 |
|
| 325 |
</td>
|
|
@@ -566,6 +604,19 @@ str | None
|
|
| 566 |
<td align="left">None</td>
|
| 567 |
</tr>
|
| 568 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 569 |
<tr>
|
| 570 |
<td align="left"><code>layout_style</code></td>
|
| 571 |
<td align="left" style="width: 25%;">
|
|
@@ -631,6 +682,32 @@ bool
|
|
| 631 |
<td align="left">None</td>
|
| 632 |
</tr>
|
| 633 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 634 |
<tr>
|
| 635 |
<td align="left"><code>label</code></td>
|
| 636 |
<td align="left" style="width: 25%;">
|
|
@@ -844,7 +921,6 @@ The impact on the users predict function varies depending on whether the compone
|
|
| 844 |
|
| 845 |
The code snippet below is accurate in cases where the component is used as both an input and an output.
|
| 846 |
|
| 847 |
-
- **As output:** Is passed, dict[str, Any] | None: The input payload, returned unchanged.
|
| 848 |
|
| 849 |
|
| 850 |
```python
|
|
@@ -852,7 +928,9 @@ The code snippet below is accurate in cases where the component is used as both
|
|
| 852 |
value: typing.Optional[typing.Dict[str, typing.Any]][
|
| 853 |
typing.Dict[str, typing.Any][str, Any], None
|
| 854 |
]
|
| 855 |
-
) -> Any
|
|
|
|
|
|
|
| 856 |
return value
|
| 857 |
```
|
| 858 |
|
|
|
|
| 10 |
---
|
| 11 |
|
| 12 |
# `gradio_creditspanel`
|
| 13 |
+
<img alt="Static Badge" src="https://img.shields.io/badge/version%20-%200.0.4%20-%20blue"> <a href="https://huggingface.co/spaces/elismasilva/gradio_creditspanel"><img src="https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Demo-blue"></a><p><span>💻 <a href='https://github.com/DEVAIEXP/gradio_component_creditspanel'>Component GitHub Code</a></span></p>
|
| 14 |
+
|
| 15 |
|
| 16 |
Credits Panel for Gradio UI
|
| 17 |
|
|
|
|
| 44 |
with open("./assets/logo.webp", "w") as f:
|
| 45 |
f.write("Placeholder WebP logo")
|
| 46 |
|
| 47 |
+
# --- Credits list with sections ---
|
| 48 |
credits_list = [
|
| 49 |
{"section_title": "Project Leadership"},
|
| 50 |
{"title": "Project Manager", "name": "Emma Thompson"},
|
|
|
|
| 73 |
"starwars": 70.0,
|
| 74 |
"matrix": 40.0
|
| 75 |
}
|
| 76 |
+
SCROLL_LOGO_PATH = "./assets/gradio_logo_white.png"
|
| 77 |
+
LOGO_PATH="./assets/logo.webp"
|
| 78 |
|
| 79 |
def update_panel(
|
| 80 |
effect: str,
|
|
|
|
| 92 |
logo_height: str | None,
|
| 93 |
scroll_background_color: str | None,
|
| 94 |
scroll_title_color: str | None,
|
| 95 |
+
scroll_section_title_color: str | None,
|
| 96 |
scroll_name_color: str | None,
|
| 97 |
layout_style: str,
|
| 98 |
title_uppercase: bool,
|
| 99 |
name_uppercase: bool,
|
| 100 |
section_title_uppercase: bool,
|
| 101 |
+
swap_font_sizes: bool,
|
| 102 |
+
show_scroll_logo: bool,
|
| 103 |
+
scroll_logo_height: str | None
|
| 104 |
) -> dict:
|
| 105 |
"""Callback function that updates all properties of the CreditsPanel component."""
|
| 106 |
+
|
| 107 |
+
scroll_logo_path = SCROLL_LOGO_PATH if show_scroll_logo else None
|
| 108 |
+
|
| 109 |
+
if not scroll_logo_height:
|
| 110 |
+
scroll_logo_height = "120px"
|
| 111 |
+
|
| 112 |
+
return {
|
| 113 |
+
"credits": credits_list,
|
| 114 |
+
"licenses": license_paths,
|
| 115 |
+
"effect": effect,
|
| 116 |
+
"speed": speed,
|
| 117 |
+
"base_font_size": base_font_size,
|
| 118 |
+
"intro_title": intro_title,
|
| 119 |
+
"intro_subtitle": intro_subtitle,
|
| 120 |
+
"sidebar_position": sidebar_position,
|
| 121 |
+
"logo_path": LOGO_PATH,
|
| 122 |
+
"show_logo": show_logo,
|
| 123 |
+
"show_licenses": show_licenses,
|
| 124 |
+
"show_credits": show_credits,
|
| 125 |
+
"logo_position": logo_position,
|
| 126 |
+
"logo_sizing": logo_sizing,
|
| 127 |
+
"logo_width": logo_width,
|
| 128 |
+
"logo_height": logo_height,
|
| 129 |
+
"scroll_background_color": scroll_background_color,
|
| 130 |
+
"scroll_title_color": scroll_title_color,
|
| 131 |
+
"scroll_name_color": scroll_name_color,
|
| 132 |
+
"scroll_section_title_color": scroll_section_title_color,
|
| 133 |
+
"layout_style": layout_style,
|
| 134 |
+
"title_uppercase": title_uppercase,
|
| 135 |
+
"name_uppercase": name_uppercase,
|
| 136 |
+
"section_title_uppercase": section_title_uppercase,
|
| 137 |
+
"swap_font_sizes_on_two_column": swap_font_sizes,
|
| 138 |
+
"scroll_logo_path": scroll_logo_path,
|
| 139 |
+
"scroll_logo_height": scroll_logo_height,
|
| 140 |
+
}
|
| 141 |
|
| 142 |
def update_ui_on_effect_change(effect: str) -> tuple[float, float]:
|
| 143 |
"""Updates sliders to sensible defaults when the animation effect is changed."""
|
|
|
|
| 179 |
name_uppercase_checkbox = gr.Checkbox(label="Name Uppercase", value=False)
|
| 180 |
section_title_uppercase_checkbox = gr.Checkbox(label="Section Uppercase", value=True)
|
| 181 |
|
| 182 |
+
gr.Markdown("### Scrolling Logo")
|
| 183 |
+
show_scroll_logo_checkbox = gr.Checkbox(
|
| 184 |
+
label="Show Logo in Credits Roll",
|
| 185 |
+
value=True,
|
| 186 |
+
info="Toggles the logo above the intro text."
|
| 187 |
+
)
|
| 188 |
+
scroll_logo_height_input = gr.Textbox(label="Scrolling Logo Height", value="100px")
|
| 189 |
+
|
| 190 |
gr.Markdown("### Intro Text")
|
| 191 |
intro_title_input = gr.Textbox(label="Intro Title", value="Gradio")
|
| 192 |
intro_subtitle_input = gr.Textbox(label="Intro Subtitle", value="The best UI framework")
|
|
|
|
| 206 |
gr.Markdown("### Color Settings (Scroll Effect)")
|
| 207 |
scroll_background_color = gr.ColorPicker(label="Background Color", value="#000000")
|
| 208 |
scroll_title_color = gr.ColorPicker(label="Title Color", value="#FFFFFF")
|
| 209 |
+
scroll_section_title_color = gr.ColorPicker(label="Section Title Color", value="#FFFFFF")
|
| 210 |
scroll_name_color = gr.ColorPicker(label="Name Color", value="#FFFFFF")
|
| 211 |
|
| 212 |
+
panel = CreditsPanel(
|
| 213 |
+
height=500,
|
| 214 |
credits=credits_list,
|
| 215 |
licenses=license_paths,
|
| 216 |
effect="scroll",
|
|
|
|
| 217 |
speed=DEFAULT_SPEEDS["scroll"],
|
| 218 |
base_font_size=1.5,
|
| 219 |
intro_title="Gradio",
|
| 220 |
intro_subtitle="The best UI framework",
|
| 221 |
sidebar_position="right",
|
| 222 |
+
logo_path=LOGO_PATH,
|
| 223 |
show_logo=True,
|
| 224 |
show_licenses=True,
|
| 225 |
show_credits=True,
|
|
|
|
| 230 |
scroll_background_color="#000000",
|
| 231 |
scroll_title_color="#FFFFFF",
|
| 232 |
scroll_name_color="#FFFFFF",
|
| 233 |
+
scroll_section_title_color="#FFFFFF",
|
| 234 |
layout_style="stacked",
|
| 235 |
title_uppercase=False,
|
| 236 |
name_uppercase=False,
|
| 237 |
section_title_uppercase=True,
|
| 238 |
swap_font_sizes_on_two_column=False,
|
| 239 |
+
scroll_logo_path=SCROLL_LOGO_PATH,
|
| 240 |
+
scroll_logo_height="100px",
|
| 241 |
)
|
| 242 |
|
| 243 |
inputs = [
|
|
|
|
| 255 |
logo_width_input,
|
| 256 |
logo_height_input,
|
| 257 |
scroll_background_color,
|
| 258 |
+
scroll_title_color,
|
| 259 |
+
scroll_section_title_color,
|
| 260 |
scroll_name_color,
|
| 261 |
layout_style_radio,
|
| 262 |
title_uppercase_checkbox,
|
| 263 |
name_uppercase_checkbox,
|
| 264 |
section_title_uppercase_checkbox,
|
| 265 |
+
swap_sizes_checkbox,
|
| 266 |
+
show_scroll_logo_checkbox,
|
| 267 |
+
scroll_logo_height_input
|
| 268 |
]
|
| 269 |
|
| 270 |
+
demo.load(
|
| 271 |
+
fn=update_panel,
|
| 272 |
+
inputs=inputs,
|
| 273 |
+
outputs=panel
|
| 274 |
+
)
|
| 275 |
layout_style_radio.change(
|
| 276 |
fn=toggle_swap_checkbox_visibility,
|
| 277 |
inputs=layout_style_radio,
|
|
|
|
| 306 |
<td align="left" style="width: 25%;">
|
| 307 |
|
| 308 |
```python
|
| 309 |
+
typing.Optional[typing.Dict[str, typing.Any]][
|
| 310 |
+
typing.Dict[str, typing.Any][str, Any], None
|
| 311 |
+
]
|
| 312 |
```
|
| 313 |
|
| 314 |
</td>
|
|
|
|
| 317 |
</tr>
|
| 318 |
|
| 319 |
<tr>
|
| 320 |
+
<td align="left"><code>height</code></td>
|
| 321 |
<td align="left" style="width: 25%;">
|
| 322 |
|
| 323 |
```python
|
| 324 |
+
int | str | None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 325 |
```
|
| 326 |
|
| 327 |
</td>
|
|
|
|
| 330 |
</tr>
|
| 331 |
|
| 332 |
<tr>
|
| 333 |
+
<td align="left"><code>width</code></td>
|
| 334 |
<td align="left" style="width: 25%;">
|
| 335 |
|
| 336 |
```python
|
|
|
|
| 343 |
</tr>
|
| 344 |
|
| 345 |
<tr>
|
| 346 |
+
<td align="left"><code>credits</code></td>
|
| 347 |
<td align="left" style="width: 25%;">
|
| 348 |
|
| 349 |
```python
|
| 350 |
+
typing.Union[
|
| 351 |
+
typing.List[typing.Dict[str, str]],
|
| 352 |
+
typing.Callable,
|
| 353 |
+
NoneType,
|
| 354 |
+
][
|
| 355 |
+
typing.List[typing.Dict[str, str]][
|
| 356 |
+
typing.Dict[str, str][str, str]
|
| 357 |
+
],
|
| 358 |
+
Callable,
|
| 359 |
+
None,
|
| 360 |
+
]
|
| 361 |
```
|
| 362 |
|
| 363 |
</td>
|
|
|
|
| 604 |
<td align="left">None</td>
|
| 605 |
</tr>
|
| 606 |
|
| 607 |
+
<tr>
|
| 608 |
+
<td align="left"><code>scroll_section_title_color</code></td>
|
| 609 |
+
<td align="left" style="width: 25%;">
|
| 610 |
+
|
| 611 |
+
```python
|
| 612 |
+
str | None
|
| 613 |
+
```
|
| 614 |
+
|
| 615 |
+
</td>
|
| 616 |
+
<td align="left"><code>None</code></td>
|
| 617 |
+
<td align="left">None</td>
|
| 618 |
+
</tr>
|
| 619 |
+
|
| 620 |
<tr>
|
| 621 |
<td align="left"><code>layout_style</code></td>
|
| 622 |
<td align="left" style="width: 25%;">
|
|
|
|
| 682 |
<td align="left">None</td>
|
| 683 |
</tr>
|
| 684 |
|
| 685 |
+
<tr>
|
| 686 |
+
<td align="left"><code>scroll_logo_path</code></td>
|
| 687 |
+
<td align="left" style="width: 25%;">
|
| 688 |
+
|
| 689 |
+
```python
|
| 690 |
+
str | pathlib.Path | None
|
| 691 |
+
```
|
| 692 |
+
|
| 693 |
+
</td>
|
| 694 |
+
<td align="left"><code>None</code></td>
|
| 695 |
+
<td align="left">None</td>
|
| 696 |
+
</tr>
|
| 697 |
+
|
| 698 |
+
<tr>
|
| 699 |
+
<td align="left"><code>scroll_logo_height</code></td>
|
| 700 |
+
<td align="left" style="width: 25%;">
|
| 701 |
+
|
| 702 |
+
```python
|
| 703 |
+
str
|
| 704 |
+
```
|
| 705 |
+
|
| 706 |
+
</td>
|
| 707 |
+
<td align="left"><code>"120px"</code></td>
|
| 708 |
+
<td align="left">None</td>
|
| 709 |
+
</tr>
|
| 710 |
+
|
| 711 |
<tr>
|
| 712 |
<td align="left"><code>label</code></td>
|
| 713 |
<td align="left" style="width: 25%;">
|
|
|
|
| 921 |
|
| 922 |
The code snippet below is accurate in cases where the component is used as both an input and an output.
|
| 923 |
|
|
|
|
| 924 |
|
| 925 |
|
| 926 |
```python
|
|
|
|
| 928 |
value: typing.Optional[typing.Dict[str, typing.Any]][
|
| 929 |
typing.Dict[str, typing.Any][str, Any], None
|
| 930 |
]
|
| 931 |
+
) -> typing.Optional[typing.Dict[str, typing.Any]][
|
| 932 |
+
typing.Dict[str, typing.Any][str, Any], None
|
| 933 |
+
]:
|
| 934 |
return value
|
| 935 |
```
|
| 936 |
|
src/assets/gradio_logo_white.png
ADDED
|
src/backend/gradio_creditspanel/creditspanel.py
CHANGED
|
@@ -13,7 +13,8 @@ import os
|
|
| 13 |
class CreditsPanel(Component):
|
| 14 |
"""
|
| 15 |
A Gradio component for displaying credits with customizable visual effects, such as scrolling or Star Wars-style animations.
|
| 16 |
-
|
|
|
|
| 17 |
|
| 18 |
Attributes:
|
| 19 |
EVENTS (list): Supported events for the component, currently only `change`.
|
|
@@ -23,11 +24,13 @@ class CreditsPanel(Component):
|
|
| 23 |
|
| 24 |
def __init__(
|
| 25 |
self,
|
| 26 |
-
value: Any = None,
|
| 27 |
-
credits: List[Dict[str, str]] | Callable | None = None,
|
| 28 |
*,
|
|
|
|
| 29 |
height: int | str | None = None,
|
| 30 |
width: int | str | None = None,
|
|
|
|
|
|
|
| 31 |
licenses: Dict[str, str | Path] | None = None,
|
| 32 |
effect: Literal["scroll", "starwars", "matrix"] = "scroll",
|
| 33 |
speed: float = 40.0,
|
|
@@ -46,11 +49,15 @@ class CreditsPanel(Component):
|
|
| 46 |
scroll_background_color: str | None = None,
|
| 47 |
scroll_title_color: str | None = None,
|
| 48 |
scroll_name_color: str | None = None,
|
|
|
|
| 49 |
layout_style: Literal["stacked", "two-column"] = "stacked",
|
| 50 |
title_uppercase: bool = False,
|
| 51 |
name_uppercase: bool = False,
|
| 52 |
section_title_uppercase: bool = True,
|
| 53 |
swap_font_sizes_on_two_column: bool = False,
|
|
|
|
|
|
|
|
|
|
| 54 |
label: str | I18nData | None = None,
|
| 55 |
every: float | None = None,
|
| 56 |
inputs: Component | Sequence[Component] | set[Component] | None = None,
|
|
@@ -70,74 +77,77 @@ class CreditsPanel(Component):
|
|
| 70 |
Initialize the CreditsPanel component.
|
| 71 |
|
| 72 |
Args:
|
| 73 |
-
value (Any, optional):
|
| 74 |
-
|
| 75 |
-
height (int | str | None, optional):
|
| 76 |
-
width (int | str | None, optional):
|
| 77 |
-
|
| 78 |
-
|
|
|
|
| 79 |
speed (float, optional): Animation speed in seconds. Defaults to 40.0.
|
| 80 |
-
base_font_size (float, optional): Base font size in rem
|
| 81 |
-
intro_title (str | None, optional): Title for the intro
|
| 82 |
-
intro_subtitle (str | None, optional): Subtitle for the intro
|
| 83 |
sidebar_position (Literal["right", "bottom"], optional): Position of the licenses sidebar. Defaults to "right".
|
| 84 |
-
logo_path (str | Path | None, optional): Path or URL to the logo
|
| 85 |
-
show_logo (bool, optional): Whether to display the logo. Defaults to True.
|
| 86 |
show_licenses (bool, optional): Whether to display licenses. Defaults to True.
|
| 87 |
-
show_credits (bool, optional): Whether to display the credits. Defaults to True.
|
| 88 |
-
logo_position (Literal["center", "left", "right"], optional):
|
| 89 |
-
logo_sizing (Literal["stretch", "crop", "resize"], optional):
|
| 90 |
-
logo_width (int | str | None, optional):
|
| 91 |
-
logo_height (int | str | None, optional):
|
| 92 |
-
scroll_background_color (str | None, optional): Background color for scroll effect.
|
| 93 |
scroll_title_color (str | None, optional): Color for credit titles.
|
| 94 |
scroll_name_color (str | None, optional): Color for credit names.
|
| 95 |
-
|
|
|
|
| 96 |
title_uppercase (bool, optional): Whether to display titles in uppercase. Defaults to False.
|
| 97 |
-
name_uppercase (bool, optional): Whether to display names in uppercase. Defaults to False.
|
| 98 |
section_title_uppercase (bool, optional): Whether to display section titles in uppercase. Defaults to True.
|
| 99 |
-
swap_font_sizes_on_two_column (bool, optional):
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
show_label (bool, optional): Whether to show the label. Defaults to False.
|
| 104 |
-
container (bool, optional): Whether to render in a container. Defaults to True.
|
| 105 |
-
scale (int | None, optional): Scaling factor for the component.
|
| 106 |
-
min_width (int, optional): Minimum width in pixels. Defaults to 160.
|
| 107 |
-
interactive (bool | None, optional): Whether the component is interactive.
|
| 108 |
-
visible (bool, optional): Whether the component is visible. Defaults to True.
|
| 109 |
-
elem_id (str | None, optional): Custom HTML element ID.
|
| 110 |
-
elem_classes (list[str] | str | None, optional): CSS classes for the component.
|
| 111 |
-
render (bool, optional): Whether to render the component. Defaults to True.
|
| 112 |
-
key (int | str | tuple[int | str, ...] | None, optional): Component key for state preservation.
|
| 113 |
-
preserved_by_key (list[str] | str | None, optional): Properties preserved by key. Defaults to "value".
|
| 114 |
"""
|
|
|
|
| 115 |
self.height = height
|
| 116 |
self.width = width
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
self.
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
|
| 142 |
super().__init__(
|
| 143 |
label=label,
|
|
@@ -154,35 +164,14 @@ class CreditsPanel(Component):
|
|
| 154 |
key=key,
|
| 155 |
visible=visible,
|
| 156 |
preserved_by_key=preserved_by_key,
|
| 157 |
-
value=
|
| 158 |
)
|
| 159 |
|
| 160 |
-
def
|
| 161 |
-
"""
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
Returns:
|
| 165 |
-
Dict[str, str]: Dictionary mapping license names to their content or error messages if loading fails.
|
| 166 |
-
"""
|
| 167 |
-
processed = {}
|
| 168 |
-
for name, path in self.licenses_paths.items():
|
| 169 |
-
try:
|
| 170 |
-
with open(path, "r", encoding="utf-8") as f:
|
| 171 |
-
processed[name] = f.read()
|
| 172 |
-
except Exception as e:
|
| 173 |
-
processed[name] = f"Error loading license file '{path}':\n{e}"
|
| 174 |
-
return processed
|
| 175 |
-
|
| 176 |
-
def _process_logo_path(self) -> Dict[str, Any] | None:
|
| 177 |
-
"""
|
| 178 |
-
Process the logo path, handling both local files and URLs.
|
| 179 |
-
|
| 180 |
-
Returns:
|
| 181 |
-
Dict[str, Any] | None: Dictionary with logo details (path, url, orig_name, mime_type) or None if no logo_path is provided or the file is not found.
|
| 182 |
-
"""
|
| 183 |
-
if not self.logo_path:
|
| 184 |
return None
|
| 185 |
-
path = str(
|
| 186 |
if is_http_url_like(path):
|
| 187 |
return {"path": None, "url": path, "orig_name": Path(path).name, "mime_type": None}
|
| 188 |
if os.path.exists(path):
|
|
@@ -191,75 +180,55 @@ class CreditsPanel(Component):
|
|
| 191 |
|
| 192 |
def preprocess(self, payload: Dict[str, Any] | None) -> Dict[str, Any] | None:
|
| 193 |
"""
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
Args:
|
| 197 |
-
payload (Dict[str, Any] | None): Input data to preprocess.
|
| 198 |
-
|
| 199 |
-
Returns:
|
| 200 |
-
Dict[str, Any] | None: The input payload, returned unchanged.
|
| 201 |
"""
|
| 202 |
return payload
|
| 203 |
|
| 204 |
-
def postprocess(self, value: Any) -> Dict[str, Any] | None:
|
| 205 |
"""
|
| 206 |
-
|
| 207 |
-
|
|
|
|
| 208 |
Args:
|
| 209 |
-
value (Any):
|
| 210 |
|
| 211 |
Returns:
|
| 212 |
-
Dict[str, Any] | None:
|
| 213 |
"""
|
| 214 |
-
|
| 215 |
-
if not credits_source and not self.licenses_paths:
|
| 216 |
return None
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
"logo_width": self.logo_width,
|
| 233 |
-
"logo_height": self.logo_height,
|
| 234 |
-
"scroll_background_color": self.scroll_background_color,
|
| 235 |
-
"scroll_title_color": self.scroll_title_color,
|
| 236 |
-
"scroll_name_color": self.scroll_name_color,
|
| 237 |
-
"layout_style": self.layout_style,
|
| 238 |
-
"title_uppercase": self.title_uppercase,
|
| 239 |
-
"name_uppercase": self.name_uppercase,
|
| 240 |
-
"section_title_uppercase": self.section_title_uppercase,
|
| 241 |
-
"swap_font_sizes_on_two_column": self.swap_font_sizes_on_two_column,
|
| 242 |
-
}
|
| 243 |
|
| 244 |
-
|
| 245 |
-
"""
|
| 246 |
-
|
| 247 |
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
|
|
|
| 251 |
return {"type": "object"}
|
| 252 |
|
| 253 |
def example_payload(self) -> Any:
|
| 254 |
-
"""
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
Returns:
|
| 258 |
-
Dict[str, Any]: Example data structure for the component's payload.
|
| 259 |
-
"""
|
| 260 |
return {
|
| 261 |
-
"credits": [{"title": "Example", "name": "Credit"}],
|
| 262 |
-
"licenses": {},
|
| 263 |
"effect": "scroll",
|
| 264 |
"speed": 20,
|
| 265 |
"sidebar_position": "right",
|
|
@@ -274,18 +243,17 @@ class CreditsPanel(Component):
|
|
| 274 |
"scroll_background_color": None,
|
| 275 |
"scroll_title_color": None,
|
| 276 |
"scroll_name_color": None,
|
|
|
|
| 277 |
"layout_style": "stacked",
|
| 278 |
"title_uppercase": False,
|
| 279 |
"name_uppercase": False,
|
| 280 |
"section_title_uppercase": True,
|
| 281 |
"swap_font_sizes_on_two_column": False,
|
|
|
|
|
|
|
| 282 |
}
|
| 283 |
|
| 284 |
def example_value(self) -> Any:
|
| 285 |
-
"""
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
Returns:
|
| 289 |
-
List[Dict[str, str]]: Example list of credits.
|
| 290 |
-
"""
|
| 291 |
-
return [{"title": "Example", "name": "Credit"}]
|
|
|
|
| 13 |
class CreditsPanel(Component):
|
| 14 |
"""
|
| 15 |
A Gradio component for displaying credits with customizable visual effects, such as scrolling or Star Wars-style animations.
|
| 16 |
+
This component is configured via a single dictionary `value` that holds all settings.
|
| 17 |
+
It supports displaying a logo, licenses, sections, and various text styling options.
|
| 18 |
|
| 19 |
Attributes:
|
| 20 |
EVENTS (list): Supported events for the component, currently only `change`.
|
|
|
|
| 24 |
|
| 25 |
def __init__(
|
| 26 |
self,
|
| 27 |
+
value: Dict[str, Any] | None = None,
|
|
|
|
| 28 |
*,
|
| 29 |
+
# Structural parameters
|
| 30 |
height: int | str | None = None,
|
| 31 |
width: int | str | None = None,
|
| 32 |
+
# Configuration parameters (will be part of the `value` dictionary)
|
| 33 |
+
credits: List[Dict[str, str]] | Callable | None = None,
|
| 34 |
licenses: Dict[str, str | Path] | None = None,
|
| 35 |
effect: Literal["scroll", "starwars", "matrix"] = "scroll",
|
| 36 |
speed: float = 40.0,
|
|
|
|
| 49 |
scroll_background_color: str | None = None,
|
| 50 |
scroll_title_color: str | None = None,
|
| 51 |
scroll_name_color: str | None = None,
|
| 52 |
+
scroll_section_title_color: str | None = None,
|
| 53 |
layout_style: Literal["stacked", "two-column"] = "stacked",
|
| 54 |
title_uppercase: bool = False,
|
| 55 |
name_uppercase: bool = False,
|
| 56 |
section_title_uppercase: bool = True,
|
| 57 |
swap_font_sizes_on_two_column: bool = False,
|
| 58 |
+
scroll_logo_path: str | Path | None = None,
|
| 59 |
+
scroll_logo_height: str = "120px",
|
| 60 |
+
# Standard Gradio parameters
|
| 61 |
label: str | I18nData | None = None,
|
| 62 |
every: float | None = None,
|
| 63 |
inputs: Component | Sequence[Component] | set[Component] | None = None,
|
|
|
|
| 77 |
Initialize the CreditsPanel component.
|
| 78 |
|
| 79 |
Args:
|
| 80 |
+
value (Dict[str, Any], optional): The dictionary containing the component's full configuration.
|
| 81 |
+
If provided, it overrides all other configuration parameters.
|
| 82 |
+
height (int | str | None, optional): The structural height of the component.
|
| 83 |
+
width (int | str | None, optional): The structural width of the component.
|
| 84 |
+
credits (List[Dict[str, str]] | Callable | None, optional): List of credits, can include section headers.
|
| 85 |
+
licenses (Dict[str, str | Path] | None, optional): Dictionary mapping license names to file paths.
|
| 86 |
+
effect (Literal["scroll", "starwars", "matrix"], optional): Visual effect for the credits. Defaults to "scroll".
|
| 87 |
speed (float, optional): Animation speed in seconds. Defaults to 40.0.
|
| 88 |
+
base_font_size (float, optional): Base font size in rem. Defaults to 1.5.
|
| 89 |
+
intro_title (str | None, optional): Title for the intro sequence.
|
| 90 |
+
intro_subtitle (str | None, optional): Subtitle for the intro sequence.
|
| 91 |
sidebar_position (Literal["right", "bottom"], optional): Position of the licenses sidebar. Defaults to "right".
|
| 92 |
+
logo_path (str | Path | None, optional): Path or URL to the main static logo.
|
| 93 |
+
show_logo (bool, optional): Whether to display the main logo. Defaults to True.
|
| 94 |
show_licenses (bool, optional): Whether to display licenses. Defaults to True.
|
| 95 |
+
show_credits (bool, optional): Whether to display the credits panel. Defaults to True.
|
| 96 |
+
logo_position (Literal["center", "left", "right"], optional): Main logo alignment. Defaults to "center".
|
| 97 |
+
logo_sizing (Literal["stretch", "crop", "resize"], optional): Main logo sizing mode. Defaults to "resize".
|
| 98 |
+
logo_width (int | str | None, optional): Main logo width.
|
| 99 |
+
logo_height (int | str | None, optional): Main logo height.
|
| 100 |
+
scroll_background_color (str | None, optional): Background color for the scroll effect.
|
| 101 |
scroll_title_color (str | None, optional): Color for credit titles.
|
| 102 |
scroll_name_color (str | None, optional): Color for credit names.
|
| 103 |
+
scroll_section_title_color (str | None, optional): Color for section titles in the scroll effect.
|
| 104 |
+
layout_style (Literal["stacked", "two-column"], optional): Layout for credits. Defaults to "stacked".
|
| 105 |
title_uppercase (bool, optional): Whether to display titles in uppercase. Defaults to False.
|
| 106 |
+
name_uppercase (bool, optional): Whether to display names in uppercase. Defaults to False.
|
| 107 |
section_title_uppercase (bool, optional): Whether to display section titles in uppercase. Defaults to True.
|
| 108 |
+
swap_font_sizes_on_two_column (bool, optional): Swaps title and name font sizes in two-column layout. Defaults to False.
|
| 109 |
+
scroll_logo_path (str | Path | None, optional): Path or URL to a logo inside the scrolling credits.
|
| 110 |
+
scroll_logo_height (str, optional): The height of the scrolling logo. Defaults to "120px".
|
| 111 |
+
(Other standard Gradio arguments)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
"""
|
| 113 |
+
# Structural parameters are stored directly on self.
|
| 114 |
self.height = height
|
| 115 |
self.width = width
|
| 116 |
+
|
| 117 |
+
# All other configuration parameters are bundled into a dictionary.
|
| 118 |
+
# This dictionary is the component's main `value`.
|
| 119 |
+
self._config = {
|
| 120 |
+
"credits": credits if credits is not None else [],
|
| 121 |
+
"licenses": licenses or {},
|
| 122 |
+
"effect": effect,
|
| 123 |
+
"speed": speed,
|
| 124 |
+
"base_font_size": base_font_size,
|
| 125 |
+
"intro_title": intro_title,
|
| 126 |
+
"intro_subtitle": intro_subtitle,
|
| 127 |
+
"sidebar_position": sidebar_position,
|
| 128 |
+
"logo_path": logo_path,
|
| 129 |
+
"show_logo": show_logo,
|
| 130 |
+
"show_licenses": show_licenses,
|
| 131 |
+
"show_credits": show_credits,
|
| 132 |
+
"logo_position": logo_position,
|
| 133 |
+
"logo_sizing": logo_sizing,
|
| 134 |
+
"logo_width": logo_width,
|
| 135 |
+
"logo_height": logo_height,
|
| 136 |
+
"scroll_background_color": scroll_background_color,
|
| 137 |
+
"scroll_title_color": scroll_title_color,
|
| 138 |
+
"scroll_name_color": scroll_name_color,
|
| 139 |
+
"scroll_section_title_color": scroll_section_title_color,
|
| 140 |
+
"layout_style": layout_style,
|
| 141 |
+
"title_uppercase": title_uppercase,
|
| 142 |
+
"name_uppercase": name_uppercase,
|
| 143 |
+
"section_title_uppercase": section_title_uppercase,
|
| 144 |
+
"swap_font_sizes_on_two_column": swap_font_sizes_on_two_column,
|
| 145 |
+
"scroll_logo_path": scroll_logo_path,
|
| 146 |
+
"scroll_logo_height": scroll_logo_height,
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
# If a `value` dictionary is passed directly, it overrides the individual parameters.
|
| 150 |
+
initial_value = value if value is not None else self._config
|
| 151 |
|
| 152 |
super().__init__(
|
| 153 |
label=label,
|
|
|
|
| 164 |
key=key,
|
| 165 |
visible=visible,
|
| 166 |
preserved_by_key=preserved_by_key,
|
| 167 |
+
value=initial_value, # The component's state is its configuration dictionary.
|
| 168 |
)
|
| 169 |
|
| 170 |
+
def _process_image_path(self, image_path: str | Path | None) -> Dict[str, Any] | None:
|
| 171 |
+
"""Helper function to process an image path, handling local files and URLs."""
|
| 172 |
+
if not image_path:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
return None
|
| 174 |
+
path = str(image_path)
|
| 175 |
if is_http_url_like(path):
|
| 176 |
return {"path": None, "url": path, "orig_name": Path(path).name, "mime_type": None}
|
| 177 |
if os.path.exists(path):
|
|
|
|
| 180 |
|
| 181 |
def preprocess(self, payload: Dict[str, Any] | None) -> Dict[str, Any] | None:
|
| 182 |
"""
|
| 183 |
+
Passes the payload from the frontend through, unmodified.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
"""
|
| 185 |
return payload
|
| 186 |
|
| 187 |
+
def postprocess(self, value: Dict[str, Any] | None) -> Dict[str, Any] | None:
|
| 188 |
"""
|
| 189 |
+
Processes the component's `value` dictionary to prepare data for the frontend.
|
| 190 |
+
This involves resolving file paths for licenses and images.
|
| 191 |
+
|
| 192 |
Args:
|
| 193 |
+
value (Dict[str, Any] | None): The component's configuration dictionary.
|
| 194 |
|
| 195 |
Returns:
|
| 196 |
+
Dict[str, Any] | None: The processed dictionary ready to be sent to the frontend.
|
| 197 |
"""
|
| 198 |
+
if not value:
|
|
|
|
| 199 |
return None
|
| 200 |
+
|
| 201 |
+
processed_value = value.copy()
|
| 202 |
+
|
| 203 |
+
# Process license file paths from the 'licenses' dictionary
|
| 204 |
+
license_paths = processed_value.get("licenses", {})
|
| 205 |
+
processed_licenses = {}
|
| 206 |
+
if isinstance(license_paths, dict): # Check if licenses are in the expected format
|
| 207 |
+
for name, path in license_paths.items():
|
| 208 |
+
try:
|
| 209 |
+
with open(path, "r", encoding="utf-8") as f:
|
| 210 |
+
processed_licenses[name] = f.read()
|
| 211 |
+
except Exception as e:
|
| 212 |
+
# Silently fail or log, to avoid crashing the app for a missing license file
|
| 213 |
+
processed_licenses[name] = f"Error loading license file '{path}':\n{e}"
|
| 214 |
+
processed_value["licenses"] = processed_licenses
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
|
| 216 |
+
# Process image paths
|
| 217 |
+
processed_value["logo_path"] = self._process_image_path(processed_value.get("logo_path"))
|
| 218 |
+
processed_value["scroll_logo_path"] = self._process_image_path(processed_value.get("scroll_logo_path"))
|
| 219 |
|
| 220 |
+
return processed_value
|
| 221 |
+
|
| 222 |
+
def api_info(self) -> Dict[str, Any]:
|
| 223 |
+
"""Returns API info for the component."""
|
| 224 |
return {"type": "object"}
|
| 225 |
|
| 226 |
def example_payload(self) -> Any:
|
| 227 |
+
"""Returns an example payload for the component's API."""
|
| 228 |
+
# This now directly returns a dictionary matching the `value` structure.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 229 |
return {
|
| 230 |
+
"credits": [{"title": "API Example", "name": "Credit"}],
|
| 231 |
+
"licenses": {"MIT": "MIT License text..."},
|
| 232 |
"effect": "scroll",
|
| 233 |
"speed": 20,
|
| 234 |
"sidebar_position": "right",
|
|
|
|
| 243 |
"scroll_background_color": None,
|
| 244 |
"scroll_title_color": None,
|
| 245 |
"scroll_name_color": None,
|
| 246 |
+
"scroll_section_title_color": None,
|
| 247 |
"layout_style": "stacked",
|
| 248 |
"title_uppercase": False,
|
| 249 |
"name_uppercase": False,
|
| 250 |
"section_title_uppercase": True,
|
| 251 |
"swap_font_sizes_on_two_column": False,
|
| 252 |
+
"scroll_logo_path": None,
|
| 253 |
+
"scroll_logo_height": "120px",
|
| 254 |
}
|
| 255 |
|
| 256 |
def example_value(self) -> Any:
|
| 257 |
+
"""Returns an example value for the component."""
|
| 258 |
+
# The example value is now the entire configuration dictionary.
|
| 259 |
+
return self.example_payload()
|
|
|
|
|
|
|
|
|
|
|
|
src/backend/gradio_creditspanel/templates/component/index.js
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
src/backend/gradio_creditspanel/templates/component/style.css
CHANGED
|
@@ -1 +1 @@
|
|
| 1 |
-
.block.svelte-239wnu{position:relative;margin:0;box-shadow:var(--block-shadow);border-width:var(--block-border-width);border-color:var(--block-border-color);border-radius:var(--block-radius);background:var(--block-background-fill);width:100%;line-height:var(--line-sm)}.block.fullscreen.svelte-239wnu{border-radius:0}.auto-margin.svelte-239wnu{margin-left:auto;margin-right:auto}.block.border_focus.svelte-239wnu{border-color:var(--color-accent)}.block.border_contrast.svelte-239wnu{border-color:var(--body-text-color)}.padded.svelte-239wnu{padding:var(--block-padding)}.hidden.svelte-239wnu{display:none}.flex.svelte-239wnu{display:flex;flex-direction:column}.hide-container.svelte-239wnu:not(.fullscreen){margin:0;box-shadow:none;--block-border-width:0;background:transparent;padding:0;overflow:visible}.resize-handle.svelte-239wnu{position:absolute;bottom:0;right:0;width:10px;height:10px;fill:var(--block-border-color);cursor:nwse-resize}.fullscreen.svelte-239wnu{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:1000;overflow:auto}.animating.svelte-239wnu{animation:svelte-239wnu-pop-out .1s ease-out forwards}@keyframes svelte-239wnu-pop-out{0%{position:fixed;top:var(--start-top);left:var(--start-left);width:var(--start-width);height:var(--start-height);z-index:100}to{position:fixed;top:0vh;left:0vw;width:100vw;height:100vh;z-index:1000}}.placeholder.svelte-239wnu{border-radius:var(--block-radius);border-width:var(--block-border-width);border-color:var(--block-border-color);border-style:dashed}Tables */ table,tr,td,th{margin-top:var(--spacing-sm);margin-bottom:var(--spacing-sm);padding:var(--spacing-xl)}.md code,.md pre{background:none;font-family:var(--font-mono);font-size:var(--text-sm);text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:2;tab-size:2;-webkit-hyphens:none;hyphens:none}.md pre[class*=language-]::selection,.md pre[class*=language-] ::selection,.md code[class*=language-]::selection,.md code[class*=language-] ::selection{text-shadow:none;background:#b3d4fc}.md pre{padding:1em;margin:.5em 0;overflow:auto;position:relative;margin-top:var(--spacing-sm);margin-bottom:var(--spacing-sm);box-shadow:none;border:none;border-radius:var(--radius-md);background:var(--code-background-fill);padding:var(--spacing-xxl);font-family:var(--font-mono);text-shadow:none;border-radius:var(--radius-sm);white-space:nowrap;display:block;white-space:pre}.md :not(pre)>code{padding:.1em;border-radius:var(--radius-xs);white-space:normal;background:var(--code-background-fill);border:1px solid var(--panel-border-color);padding:var(--spacing-xxs) var(--spacing-xs)}.md .token.comment,.md .token.prolog,.md .token.doctype,.md .token.cdata{color:#708090}.md .token.punctuation{color:#999}.md .token.namespace{opacity:.7}.md .token.property,.md .token.tag,.md .token.boolean,.md .token.number,.md .token.constant,.md .token.symbol,.md .token.deleted{color:#905}.md .token.selector,.md .token.attr-name,.md .token.string,.md .token.char,.md .token.builtin,.md .token.inserted{color:#690}.md .token.atrule,.md .token.attr-value,.md .token.keyword{color:#07a}.md .token.function,.md .token.class-name{color:#dd4a68}.md .token.regex,.md .token.important,.md .token.variable{color:#e90}.md .token.important,.md .token.bold{font-weight:700}.md .token.italic{font-style:italic}.md .token.entity{cursor:help}.dark .md .token.comment,.dark .md .token.prolog,.dark .md .token.cdata{color:#5c6370}.dark .md .token.doctype,.dark .md .token.punctuation,.dark .md .token.entity{color:#abb2bf}.dark .md .token.attr-name,.dark .md .token.class-name,.dark .md .token.boolean,.dark .md .token.constant,.dark .md .token.number,.dark .md .token.atrule{color:#d19a66}.dark .md .token.keyword{color:#c678dd}.dark .md .token.property,.dark .md .token.tag,.dark .md .token.symbol,.dark .md .token.deleted,.dark .md .token.important{color:#e06c75}.dark .md .token.selector,.dark .md .token.string,.dark .md .token.char,.dark .md .token.builtin,.dark .md .token.inserted,.dark .md .token.regex,.dark .md .token.attr-value,.dark .md .token.attr-value>.token.punctuation{color:#98c379}.dark .md .token.variable,.dark .md .token.operator,.dark .md .token.function{color:#61afef}.dark .md .token.url{color:#56b6c2}span.svelte-1m32c2s div[class*=code_wrap]{position:relative}span.svelte-1m32c2s span.katex{font-size:var(--text-lg);direction:ltr}span.svelte-1m32c2s div[class*=code_wrap]>button{z-index:1;cursor:pointer;border-bottom-left-radius:var(--radius-sm);padding:var(--spacing-md);width:25px;height:25px;position:absolute;right:0}span.svelte-1m32c2s .check{opacity:0;z-index:var(--layer-top);transition:opacity .2s;background:var(--code-background-fill);color:var(--body-text-color);position:absolute;top:var(--size-1-5);left:var(--size-1-5)}span.svelte-1m32c2s p:not(:first-child){margin-top:var(--spacing-xxl)}span.svelte-1m32c2s .md-header-anchor{margin-left:-25px;padding-right:8px;line-height:1;color:var(--body-text-color-subdued);opacity:0}span.svelte-1m32c2s h1:hover .md-header-anchor,span.svelte-1m32c2s h2:hover .md-header-anchor,span.svelte-1m32c2s h3:hover .md-header-anchor,span.svelte-1m32c2s h4:hover .md-header-anchor,span.svelte-1m32c2s h5:hover .md-header-anchor,span.svelte-1m32c2s h6:hover .md-header-anchor{opacity:1}span.md.svelte-1m32c2s .md-header-anchor>svg{color:var(--body-text-color-subdued)}span.svelte-1m32c2s table{word-break:break-word}div.svelte-17qq50w>.md.prose{font-weight:var(--block-info-text-weight);font-size:var(--block-info-text-size);line-height:var(--line-sm)}div.svelte-17qq50w>.md.prose *{color:var(--block-info-text-color)}div.svelte-17qq50w{margin-bottom:var(--spacing-md)}span.has-info.svelte-zgrq3{margin-bottom:var(--spacing-xs)}span.svelte-zgrq3:not(.has-info){margin-bottom:var(--spacing-lg)}span.svelte-zgrq3{display:inline-block;position:relative;z-index:var(--layer-4);border:solid var(--block-title-border-width) var(--block-title-border-color);border-radius:var(--block-title-radius);background:var(--block-title-background-fill);padding:var(--block-title-padding);color:var(--block-title-text-color);font-weight:var(--block-title-text-weight);font-size:var(--block-title-text-size);line-height:var(--line-sm)}span[dir=rtl].svelte-zgrq3{display:block}.hide.svelte-zgrq3{margin:0;height:0}label.svelte-13ao5pu.svelte-13ao5pu{display:inline-flex;align-items:center;z-index:var(--layer-2);box-shadow:var(--block-label-shadow);border:var(--block-label-border-width) solid var(--block-label-border-color);border-top:none;border-left:none;border-radius:var(--block-label-radius);background:var(--block-label-background-fill);padding:var(--block-label-padding);pointer-events:none;color:var(--block-label-text-color);font-weight:var(--block-label-text-weight);font-size:var(--block-label-text-size);line-height:var(--line-sm)}.gr-group label.svelte-13ao5pu.svelte-13ao5pu{border-top-left-radius:0}label.float.svelte-13ao5pu.svelte-13ao5pu{position:absolute;top:var(--block-label-margin);left:var(--block-label-margin)}label.svelte-13ao5pu.svelte-13ao5pu:not(.float){position:static;margin-top:var(--block-label-margin);margin-left:var(--block-label-margin)}.hide.svelte-13ao5pu.svelte-13ao5pu{height:0}span.svelte-13ao5pu.svelte-13ao5pu{opacity:.8;margin-right:var(--size-2);width:calc(var(--block-label-text-size) - 1px);height:calc(var(--block-label-text-size) - 1px)}.hide-label.svelte-13ao5pu.svelte-13ao5pu{box-shadow:none;border-width:0;background:transparent;overflow:visible}label[dir=rtl].svelte-13ao5pu.svelte-13ao5pu{border:var(--block-label-border-width) solid var(--block-label-border-color);border-top:none;border-right:none;border-bottom-left-radius:var(--block-radius);border-bottom-right-radius:var(--block-label-radius);border-top-left-radius:var(--block-label-radius)}label[dir=rtl].svelte-13ao5pu span.svelte-13ao5pu{margin-left:var(--size-2);margin-right:0}button.svelte-qgco6m{display:flex;justify-content:center;align-items:center;gap:1px;z-index:var(--layer-2);border-radius:var(--radius-xs);color:var(--block-label-text-color);border:1px solid transparent;padding:var(--spacing-xxs)}button.svelte-qgco6m:hover{background-color:var(--background-fill-secondary)}button[disabled].svelte-qgco6m{opacity:.5;box-shadow:none}button[disabled].svelte-qgco6m:hover{cursor:not-allowed}.padded.svelte-qgco6m{background:var(--bg-color)}button.svelte-qgco6m:hover,button.highlight.svelte-qgco6m{cursor:pointer;color:var(--color-accent)}.padded.svelte-qgco6m:hover{color:var(--block-label-text-color)}span.svelte-qgco6m{padding:0 1px;font-size:10px}div.svelte-qgco6m{display:flex;align-items:center;justify-content:center;transition:filter .2s ease-in-out}.x-small.svelte-qgco6m{width:10px;height:10px}.small.svelte-qgco6m{width:14px;height:14px}.medium.svelte-qgco6m{width:20px;height:20px}.large.svelte-qgco6m{width:22px;height:22px}.pending.svelte-qgco6m{animation:svelte-qgco6m-flash .5s infinite}@keyframes svelte-qgco6m-flash{0%{opacity:.5}50%{opacity:1}to{opacity:.5}}.transparent.svelte-qgco6m{background:transparent;border:none;box-shadow:none}.empty.svelte-3w3rth{display:flex;justify-content:center;align-items:center;margin-top:calc(0px - var(--size-6));height:var(--size-full)}.icon.svelte-3w3rth{opacity:.5;height:var(--size-5);color:var(--body-text-color)}.small.svelte-3w3rth{min-height:calc(var(--size-32) - 20px)}.large.svelte-3w3rth{min-height:calc(var(--size-64) - 20px)}.unpadded_box.svelte-3w3rth{margin-top:0}.small_parent.svelte-3w3rth{min-height:100%!important}.dropdown-arrow.svelte-145leq6,.dropdown-arrow.svelte-ihhdbf{fill:currentColor}.circle.svelte-ihhdbf{fill:currentColor;opacity:.1}svg.svelte-pb9pol{animation:svelte-pb9pol-spin 1.5s linear infinite}@keyframes svelte-pb9pol-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}h2.svelte-1xg7h5n{font-size:var(--text-xl)!important}p.svelte-1xg7h5n,h2.svelte-1xg7h5n{white-space:pre-line}.wrap.svelte-1xg7h5n{display:flex;flex-direction:column;justify-content:center;align-items:center;min-height:var(--size-60);color:var(--block-label-text-color);line-height:var(--line-md);height:100%;padding-top:var(--size-3);text-align:center;margin:auto var(--spacing-lg)}.or.svelte-1xg7h5n{color:var(--body-text-color-subdued);display:flex}.icon-wrap.svelte-1xg7h5n{width:30px;margin-bottom:var(--spacing-lg)}@media (--screen-md){.wrap.svelte-1xg7h5n{font-size:var(--text-lg)}}.hovered.svelte-1xg7h5n{color:var(--color-accent)}div.svelte-q32hvf{border-top:1px solid transparent;display:flex;max-height:100%;justify-content:center;align-items:center;gap:var(--spacing-sm);height:auto;align-items:flex-end;color:var(--block-label-text-color);flex-shrink:0}.show_border.svelte-q32hvf{border-top:1px solid var(--block-border-color);margin-top:var(--spacing-xxl);box-shadow:var(--shadow-drop)}.source-selection.svelte-15ls1gu{display:flex;align-items:center;justify-content:center;border-top:1px solid var(--border-color-primary);width:100%;margin-left:auto;margin-right:auto;height:var(--size-10)}.icon.svelte-15ls1gu{width:22px;height:22px;margin:var(--spacing-lg) var(--spacing-xs);padding:var(--spacing-xs);color:var(--neutral-400);border-radius:var(--radius-md)}.selected.svelte-15ls1gu{color:var(--color-accent)}.icon.svelte-15ls1gu:hover,.icon.svelte-15ls1gu:focus{color:var(--color-accent)}.icon-button-wrapper.svelte-1h0hs6p{display:flex;flex-direction:row;align-items:center;justify-content:center;z-index:var(--layer-2);gap:var(--spacing-sm);box-shadow:var(--shadow-drop);border:1px solid var(--border-color-primary);background:var(--block-background-fill);padding:var(--spacing-xxs)}.icon-button-wrapper.hide-top-corner.svelte-1h0hs6p{border-top:none;border-right:none;border-radius:var(--block-label-right-radius)}.icon-button-wrapper.display-top-corner.svelte-1h0hs6p{border-radius:var(--radius-sm) 0 0 var(--radius-sm);top:var(--spacing-sm);right:-1px}.icon-button-wrapper.svelte-1h0hs6p:not(.top-panel){border:1px solid var(--border-color-primary);border-radius:var(--radius-sm)}.top-panel.svelte-1h0hs6p{position:absolute;top:var(--block-label-margin);right:var(--block-label-margin);margin:0}.icon-button-wrapper.svelte-1h0hs6p button{margin:var(--spacing-xxs);border-radius:var(--radius-xs);position:relative}.icon-button-wrapper.svelte-1h0hs6p a.download-link:not(:last-child),.icon-button-wrapper.svelte-1h0hs6p button:not(:last-child){margin-right:var(--spacing-xxs)}.icon-button-wrapper.svelte-1h0hs6p a.download-link:not(:last-child):not(.no-border *):after,.icon-button-wrapper.svelte-1h0hs6p button:not(:last-child):not(.no-border *):after{content:"";position:absolute;right:-4.5px;top:15%;height:70%;width:1px;background-color:var(--border-color-primary)}.icon-button-wrapper.svelte-1h0hs6p>*{height:100%}svg.svelte-43sxxs.svelte-43sxxs{width:var(--size-20);height:var(--size-20)}svg.svelte-43sxxs path.svelte-43sxxs{fill:var(--loader-color)}div.svelte-43sxxs.svelte-43sxxs{z-index:var(--layer-2)}.margin.svelte-43sxxs.svelte-43sxxs{margin:var(--size-4)}.wrap.svelte-17v219f.svelte-17v219f{display:flex;flex-direction:column;justify-content:center;align-items:center;z-index:var(--layer-2);transition:opacity .1s ease-in-out;border-radius:var(--block-radius);background:var(--block-background-fill);padding:0 var(--size-6);max-height:var(--size-screen-h);overflow:hidden}.wrap.center.svelte-17v219f.svelte-17v219f{top:0;right:0;left:0}.wrap.default.svelte-17v219f.svelte-17v219f{top:0;right:0;bottom:0;left:0}.hide.svelte-17v219f.svelte-17v219f{opacity:0;pointer-events:none}.generating.svelte-17v219f.svelte-17v219f{animation:svelte-17v219f-pulseStart 1s cubic-bezier(.4,0,.6,1),svelte-17v219f-pulse 2s cubic-bezier(.4,0,.6,1) 1s infinite;border:2px solid var(--color-accent);background:transparent;z-index:var(--layer-1);pointer-events:none}.translucent.svelte-17v219f.svelte-17v219f{background:none}@keyframes svelte-17v219f-pulseStart{0%{opacity:0}to{opacity:1}}@keyframes svelte-17v219f-pulse{0%,to{opacity:1}50%{opacity:.5}}.loading.svelte-17v219f.svelte-17v219f{z-index:var(--layer-2);color:var(--body-text-color)}.eta-bar.svelte-17v219f.svelte-17v219f{position:absolute;top:0;right:0;bottom:0;left:0;transform-origin:left;opacity:.8;z-index:var(--layer-1);transition:10ms;background:var(--background-fill-secondary)}.progress-bar-wrap.svelte-17v219f.svelte-17v219f{border:1px solid var(--border-color-primary);background:var(--background-fill-primary);width:55.5%;height:var(--size-4)}.progress-bar.svelte-17v219f.svelte-17v219f{transform-origin:left;background-color:var(--loader-color);width:var(--size-full);height:var(--size-full)}.progress-level.svelte-17v219f.svelte-17v219f{display:flex;flex-direction:column;align-items:center;gap:1;z-index:var(--layer-2);width:var(--size-full)}.progress-level-inner.svelte-17v219f.svelte-17v219f{margin:var(--size-2) auto;color:var(--body-text-color);font-size:var(--text-sm);font-family:var(--font-mono)}.meta-text.svelte-17v219f.svelte-17v219f{position:absolute;bottom:0;right:0;z-index:var(--layer-2);padding:var(--size-1) var(--size-2);font-size:var(--text-sm);font-family:var(--font-mono)}.meta-text-center.svelte-17v219f.svelte-17v219f{display:flex;position:absolute;top:0;right:0;justify-content:center;align-items:center;transform:translateY(var(--size-6));z-index:var(--layer-2);padding:var(--size-1) var(--size-2);font-size:var(--text-sm);font-family:var(--font-mono);text-align:center}.error.svelte-17v219f.svelte-17v219f{box-shadow:var(--shadow-drop);border:solid 1px var(--error-border-color);border-radius:var(--radius-full);background:var(--error-background-fill);padding-right:var(--size-4);padding-left:var(--size-4);color:var(--error-text-color);font-weight:var(--weight-semibold);font-size:var(--text-lg);line-height:var(--line-lg);font-family:var(--font)}.minimal.svelte-17v219f.svelte-17v219f{pointer-events:none}.minimal.svelte-17v219f .progress-text.svelte-17v219f{background:var(--block-background-fill)}.border.svelte-17v219f.svelte-17v219f{border:1px solid var(--border-color-primary)}.clear-status.svelte-17v219f.svelte-17v219f{position:absolute;display:flex;top:var(--size-2);right:var(--size-2);justify-content:flex-end;gap:var(--spacing-sm);z-index:var(--layer-1)}.toast-body.svelte-syezpc{display:flex;position:relative;right:0;left:0;align-items:center;margin:var(--size-6) var(--size-4);margin:auto;border-radius:var(--container-radius);overflow:hidden;pointer-events:auto}.toast-body.error.svelte-syezpc{border:1px solid var(--color-red-700);background:var(--color-red-50)}.dark .toast-body.error.svelte-syezpc{border:1px solid var(--color-red-500);background-color:var(--color-grey-950)}.toast-body.warning.svelte-syezpc{border:1px solid var(--color-yellow-700);background:var(--color-yellow-50)}.dark .toast-body.warning.svelte-syezpc{border:1px solid var(--color-yellow-500);background-color:var(--color-grey-950)}.toast-body.info.svelte-syezpc{border:1px solid var(--color-grey-700);background:var(--color-grey-50)}.dark .toast-body.info.svelte-syezpc{border:1px solid var(--color-grey-500);background-color:var(--color-grey-950)}.toast-body.success.svelte-syezpc{border:1px solid var(--color-green-700);background:var(--color-green-50)}.dark .toast-body.success.svelte-syezpc{border:1px solid var(--color-green-500);background-color:var(--color-grey-950)}.toast-title.svelte-syezpc{display:flex;align-items:center;font-weight:var(--weight-bold);font-size:var(--text-lg);line-height:var(--line-sm)}.toast-title.error.svelte-syezpc{color:var(--color-red-700)}.dark .toast-title.error.svelte-syezpc{color:var(--color-red-50)}.toast-title.warning.svelte-syezpc{color:var(--color-yellow-700)}.dark .toast-title.warning.svelte-syezpc{color:var(--color-yellow-50)}.toast-title.info.svelte-syezpc{color:var(--color-grey-700)}.dark .toast-title.info.svelte-syezpc{color:var(--color-grey-50)}.toast-title.success.svelte-syezpc{color:var(--color-green-700)}.dark .toast-title.success.svelte-syezpc{color:var(--color-green-50)}.toast-close.svelte-syezpc{margin:0 var(--size-3);border-radius:var(--size-3);padding:0px var(--size-1-5);font-size:var(--size-5);line-height:var(--size-5)}.toast-close.error.svelte-syezpc{color:var(--color-red-700)}.dark .toast-close.error.svelte-syezpc{color:var(--color-red-500)}.toast-close.warning.svelte-syezpc{color:var(--color-yellow-700)}.dark .toast-close.warning.svelte-syezpc{color:var(--color-yellow-500)}.toast-close.info.svelte-syezpc{color:var(--color-grey-700)}.dark .toast-close.info.svelte-syezpc{color:var(--color-grey-500)}.toast-close.success.svelte-syezpc{color:var(--color-green-700)}.dark .toast-close.success.svelte-syezpc{color:var(--color-green-500)}.toast-text.svelte-syezpc{font-size:var(--text-lg);word-wrap:break-word;overflow-wrap:break-word;word-break:break-word}.toast-text.error.svelte-syezpc{color:var(--color-red-700)}.dark .toast-text.error.svelte-syezpc{color:var(--color-red-50)}.toast-text.warning.svelte-syezpc{color:var(--color-yellow-700)}.dark .toast-text.warning.svelte-syezpc{color:var(--color-yellow-50)}.toast-text.info.svelte-syezpc{color:var(--color-grey-700)}.dark .toast-text.info.svelte-syezpc{color:var(--color-grey-50)}.toast-text.success.svelte-syezpc{color:var(--color-green-700)}.dark .toast-text.success.svelte-syezpc{color:var(--color-green-50)}.toast-details.svelte-syezpc{margin:var(--size-3) var(--size-3) var(--size-3) 0;width:100%}.toast-icon.svelte-syezpc{display:flex;position:absolute;position:relative;flex-shrink:0;justify-content:center;align-items:center;margin:var(--size-2);border-radius:var(--radius-full);padding:var(--size-1);padding-left:calc(var(--size-1) - 1px);width:35px;height:35px}.toast-icon.error.svelte-syezpc{color:var(--color-red-700)}.dark .toast-icon.error.svelte-syezpc{color:var(--color-red-500)}.toast-icon.warning.svelte-syezpc{color:var(--color-yellow-700)}.dark .toast-icon.warning.svelte-syezpc{color:var(--color-yellow-500)}.toast-icon.info.svelte-syezpc{color:var(--color-grey-700)}.dark .toast-icon.info.svelte-syezpc{color:var(--color-grey-500)}.toast-icon.success.svelte-syezpc{color:var(--color-green-700)}.dark .toast-icon.success.svelte-syezpc{color:var(--color-green-500)}@keyframes svelte-syezpc-countdown{0%{transform:scaleX(1)}to{transform:scaleX(0)}}.timer.svelte-syezpc{position:absolute;bottom:0;left:0;transform-origin:0 0;animation:svelte-syezpc-countdown 10s linear forwards;width:100%;height:var(--size-1)}.timer.error.svelte-syezpc{background:var(--color-red-700)}.dark .timer.error.svelte-syezpc{background:var(--color-red-500)}.timer.warning.svelte-syezpc{background:var(--color-yellow-700)}.dark .timer.warning.svelte-syezpc{background:var(--color-yellow-500)}.timer.info.svelte-syezpc{background:var(--color-grey-700)}.dark .timer.info.svelte-syezpc{background:var(--color-grey-500)}.timer.success.svelte-syezpc{background:var(--color-green-700)}.dark .timer.success.svelte-syezpc{background:var(--color-green-500)}.hidden.svelte-syezpc{display:none}.toast-text.svelte-syezpc a{text-decoration:underline}.toast-wrap.svelte-gatr8h{display:flex;position:fixed;top:var(--size-4);right:var(--size-4);flex-direction:column;align-items:end;gap:var(--size-2);z-index:var(--layer-top);width:calc(100% - var(--size-8))}@media (--screen-sm){.toast-wrap.svelte-gatr8h{width:calc(var(--size-96) + var(--size-10))}}.streaming-bar.svelte-ga0jj6{position:absolute;bottom:0;left:0;right:0;height:4px;background-color:var(--primary-600);animation:svelte-ga0jj6-countdown linear forwards;z-index:1}@keyframes svelte-ga0jj6-countdown{0%{transform:translate(0)}to{transform:translate(-100%)}}.wrapper.svelte-1t8lt48.svelte-1t8lt48{width:100%;height:100%;overflow:hidden;position:relative;font-family:sans-serif}.credits-container.svelte-1t8lt48.svelte-1t8lt48{position:absolute;bottom:0;transform:translateY(100%);width:100%;text-align:center;animation:svelte-1t8lt48-scroll var(--animation-duration) linear infinite;padding:0 2rem;box-sizing:border-box}.section-title.svelte-1t8lt48.svelte-1t8lt48{margin-top:4rem;margin-bottom:2.5rem;font-weight:700}.credit.intro-block.svelte-1t8lt48.svelte-1t8lt48{margin-bottom:5rem}.credit.svelte-1t8lt48.svelte-1t8lt48{margin-bottom:2rem}.credit.svelte-1t8lt48 h2.svelte-1t8lt48,.credit.svelte-1t8lt48 p.svelte-1t8lt48{margin:.5rem 0;font-family:sans-serif}.credit-two-column.svelte-1t8lt48.svelte-1t8lt48{display:flex;justify-content:space-between;align-items:baseline;text-align:left;margin:.8rem auto;max-width:80%;gap:1rem}.credit-two-column.svelte-1t8lt48 .title.svelte-1t8lt48{flex:1;text-align:right;padding-right:1rem}.credit-two-column.svelte-1t8lt48 .name.svelte-1t8lt48{flex:1;text-align:left;padding-left:1rem}.uppercase.svelte-1t8lt48.svelte-1t8lt48{text-transform:uppercase}@keyframes svelte-1t8lt48-scroll{0%{transform:translateY(100%)}to{transform:translateY(-100%)}}.viewport.svelte-upsott.svelte-upsott{width:100%;height:100%;position:relative;overflow:hidden;perspective:400px;-webkit-mask-image:linear-gradient(to bottom,black 60%,transparent 100%);mask-image:linear-gradient(to bottom,black 60%,transparent 100%);font-family:Droid Sans,sans-serif;font-weight:700}.stars.svelte-upsott.svelte-upsott{position:absolute;top:0;left:0;width:1px;height:1px;background:transparent;z-index:0;animation:svelte-upsott-twinkle 10s linear infinite}.stars.small.svelte-upsott.svelte-upsott{animation-duration:10s}.stars.medium.svelte-upsott.svelte-upsott{animation-duration:15s}.stars.large.svelte-upsott.svelte-upsott{animation-duration:20s}@keyframes svelte-upsott-twinkle{0%{opacity:.6}50%{opacity:1}to{opacity:.6}}.crawl.svelte-upsott.svelte-upsott{position:absolute;width:100%;bottom:0;transform-origin:50% 100%;animation:svelte-upsott-crawl-animation var(--animation-duration) linear infinite;z-index:1;text-align:center}@keyframes svelte-upsott-crawl-animation{0%{transform:rotateX(60deg) translateY(100%) translateZ(100px)}to{transform:rotateX(60deg) translateY(-150%) translateZ(-1200px)}}.uppercase.svelte-upsott.svelte-upsott{text-transform:uppercase}.section-title.svelte-upsott.svelte-upsott{margin-top:5rem;margin-bottom:3rem;font-weight:700}.credit.intro-block.svelte-upsott.svelte-upsott{margin-bottom:5rem}.credit.svelte-upsott.svelte-upsott{margin-bottom:2rem}.credit.svelte-upsott h2.svelte-upsott,.credit.svelte-upsott p.svelte-upsott{margin:.5rem 0;padding:0;white-space:nowrap}.credit-two-column.svelte-upsott.svelte-upsott{display:flex;justify-content:space-between;align-items:baseline;margin:.8rem auto;width:90%;white-space:nowrap}.credit-two-column.svelte-upsott .spacer.svelte-upsott{flex-grow:1;border-bottom:1px dotted rgba(254,218,74,.3);margin:0 1em;transform:translateY(-.5em)}.matrix-container.svelte-1851m15.svelte-1851m15{width:100%;height:100%;position:relative;overflow:hidden}canvas.svelte-1851m15.svelte-1851m15{display:block;position:absolute;top:0;left:0;width:100%;height:100%;z-index:1}.credits-scroll-overlay.svelte-1851m15.svelte-1851m15{position:absolute;top:0;left:0;width:100%;height:100%;z-index:2;color:#fff;font-family:monospace;text-align:center;-webkit-mask-image:linear-gradient(transparent,black 20%,black 80%,transparent);mask-image:linear-gradient(transparent,black 20%,black 80%,transparent)}.credits-content.svelte-1851m15.svelte-1851m15{position:absolute;width:100%;bottom:0;transform:translateY(100%);animation:svelte-1851m15-scroll-from-bottom var(--animation-duration) linear infinite;padding:0 2rem;box-sizing:border-box}@keyframes svelte-1851m15-scroll-from-bottom{0%{transform:translateY(100%)}to{transform:translateY(-100%)}}.uppercase.svelte-1851m15.svelte-1851m15{text-transform:uppercase}.section-title.svelte-1851m15.svelte-1851m15{margin-top:4rem;margin-bottom:2.5rem;font-weight:700;color:#5f5;text-shadow:0 0 8px #0f0}.credit-block.intro-block.svelte-1851m15.svelte-1851m15{margin-bottom:5rem}.credit-block.svelte-1851m15.svelte-1851m15{margin-bottom:2.5em}.title.svelte-1851m15.svelte-1851m15{color:#0f0;opacity:.8}.name.svelte-1851m15.svelte-1851m15{font-weight:700;color:#5f5;text-shadow:0 0 5px #0f0}.credit-two-column.svelte-1851m15.svelte-1851m15{display:flex;justify-content:space-between;align-items:baseline;text-align:left;margin:.8em auto;max-width:80%;gap:1em}.credit-two-column.svelte-1851m15 .title.svelte-1851m15{flex:1;text-align:right;padding-right:1em}.credit-two-column.svelte-1851m15 .name.svelte-1851m15{flex:1;text-align:left;padding-left:1em}.unstyled-link.svelte-151nsdd{all:unset;cursor:pointer}img.svelte-kxeri3{object-fit:cover}.image-container.svelte-x2tujq.svelte-x2tujq{height:100%;position:relative;min-width:var(--size-20)}.image-container.svelte-x2tujq button.svelte-x2tujq{width:var(--size-full);height:var(--size-full);border-radius:var(--radius-lg);display:flex;align-items:center;justify-content:center}.image-frame.svelte-x2tujq img{width:var(--size-full);height:var(--size-full);object-fit:scale-down}.selectable.svelte-x2tujq.svelte-x2tujq{cursor:crosshair}.fullscreen-controls svg{position:relative;top:0}.image-container:fullscreen{background-color:#000;display:flex;justify-content:center;align-items:center}.image-container:fullscreen img{max-width:90vw;max-height:90vh;object-fit:scale-down}.image-frame.svelte-x2tujq.svelte-x2tujq{width:auto;height:100%;display:flex;align-items:center;justify-content:center}.block{border:none!important;box-shadow:none!important;border-style:none!important}.outer-logo-wrapper.svelte-1hawtr7.svelte-1hawtr7,.outer-credits-wrapper.svelte-1hawtr7.svelte-1hawtr7{display:flex;flex-direction:column;width:100%;border:none}.logo-panel.svelte-1hawtr7.svelte-1hawtr7{background:var(--background-fill-primary);border:none;display:flex!important;align-items:center;justify-content:var(--logo-justify, center);padding:0 0 20px;width:100%}.credits-panel-wrapper.svelte-1hawtr7.svelte-1hawtr7{display:flex;flex-direction:var(--panel-direction, row);min-height:var(--size-full, 500px);width:100%;background:var(--background-fill-primary);border:1px solid var(--border-color-primary);border-radius:var(--radius-lg);overflow:hidden}.main-credits-panel.svelte-1hawtr7.svelte-1hawtr7{flex-grow:1;flex-shrink:1;min-width:200px;background:#000;overflow:hidden;position:relative}.licenses-sidebar.svelte-1hawtr7.svelte-1hawtr7{width:calc(100% - var(--main-panel-width, 400px));max-width:100%;max-height:var(--sidebar-max-height, none);flex-shrink:1;flex-grow:1;background:var(--background-fill-secondary);overflow-y:auto;border-left:var(--border-left, 1px solid var(--border-color-primary));border-top:var(--border-top, none)}.licenses-sidebar.svelte-1hawtr7 h3.svelte-1hawtr7{margin:var(--spacing-lg);font-size:var(--text-lg)}.licenses-sidebar.svelte-1hawtr7 li.svelte-1hawtr7{padding:0;margin:0;cursor:default;border-bottom:1px solid var(--border-color-primary)}.licenses-sidebar.svelte-1hawtr7 li button.svelte-1hawtr7{background:none;border:none;font:inherit;color:inherit;text-align:left;width:100%;cursor:pointer;padding:var(--spacing-md) var(--spacing-lg);transition:background-color .2s}.licenses-sidebar.svelte-1hawtr7 li button.svelte-1hawtr7:hover{background-color:var(--background-fill-primary)}.licenses-sidebar.svelte-1hawtr7 li button.svelte-1hawtr7:focus-visible{outline:2px solid var(--color-accent);outline-offset:-2px}.licenses-sidebar.svelte-1hawtr7 li button.selected.svelte-1hawtr7{background-color:var(--color-accent);color:#fff;font-weight:700}.license-display.svelte-1hawtr7.svelte-1hawtr7{padding:var(--spacing-lg);overflow-y:auto;flex-grow:1;border-top:1px solid var(--border-color-primary);background:var(--background-fill-primary)}.license-display.svelte-1hawtr7 h4.svelte-1hawtr7{margin-top:0}.license-display.svelte-1hawtr7 pre.svelte-1hawtr7{white-space:pre-wrap;word-break:break-word;font-size:var(--text-sm);color:var(--body-text-color-subdued)}
|
|
|
|
| 1 |
+
.block.svelte-239wnu{position:relative;margin:0;box-shadow:var(--block-shadow);border-width:var(--block-border-width);border-color:var(--block-border-color);border-radius:var(--block-radius);background:var(--block-background-fill);width:100%;line-height:var(--line-sm)}.block.fullscreen.svelte-239wnu{border-radius:0}.auto-margin.svelte-239wnu{margin-left:auto;margin-right:auto}.block.border_focus.svelte-239wnu{border-color:var(--color-accent)}.block.border_contrast.svelte-239wnu{border-color:var(--body-text-color)}.padded.svelte-239wnu{padding:var(--block-padding)}.hidden.svelte-239wnu{display:none}.flex.svelte-239wnu{display:flex;flex-direction:column}.hide-container.svelte-239wnu:not(.fullscreen){margin:0;box-shadow:none;--block-border-width:0;background:transparent;padding:0;overflow:visible}.resize-handle.svelte-239wnu{position:absolute;bottom:0;right:0;width:10px;height:10px;fill:var(--block-border-color);cursor:nwse-resize}.fullscreen.svelte-239wnu{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:1000;overflow:auto}.animating.svelte-239wnu{animation:svelte-239wnu-pop-out .1s ease-out forwards}@keyframes svelte-239wnu-pop-out{0%{position:fixed;top:var(--start-top);left:var(--start-left);width:var(--start-width);height:var(--start-height);z-index:100}to{position:fixed;top:0vh;left:0vw;width:100vw;height:100vh;z-index:1000}}.placeholder.svelte-239wnu{border-radius:var(--block-radius);border-width:var(--block-border-width);border-color:var(--block-border-color);border-style:dashed}Tables */ table,tr,td,th{margin-top:var(--spacing-sm);margin-bottom:var(--spacing-sm);padding:var(--spacing-xl)}.md code,.md pre{background:none;font-family:var(--font-mono);font-size:var(--text-sm);text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:2;tab-size:2;-webkit-hyphens:none;hyphens:none}.md pre[class*=language-]::selection,.md pre[class*=language-] ::selection,.md code[class*=language-]::selection,.md code[class*=language-] ::selection{text-shadow:none;background:#b3d4fc}.md pre{padding:1em;margin:.5em 0;overflow:auto;position:relative;margin-top:var(--spacing-sm);margin-bottom:var(--spacing-sm);box-shadow:none;border:none;border-radius:var(--radius-md);background:var(--code-background-fill);padding:var(--spacing-xxl);font-family:var(--font-mono);text-shadow:none;border-radius:var(--radius-sm);white-space:nowrap;display:block;white-space:pre}.md :not(pre)>code{padding:.1em;border-radius:var(--radius-xs);white-space:normal;background:var(--code-background-fill);border:1px solid var(--panel-border-color);padding:var(--spacing-xxs) var(--spacing-xs)}.md .token.comment,.md .token.prolog,.md .token.doctype,.md .token.cdata{color:#708090}.md .token.punctuation{color:#999}.md .token.namespace{opacity:.7}.md .token.property,.md .token.tag,.md .token.boolean,.md .token.number,.md .token.constant,.md .token.symbol,.md .token.deleted{color:#905}.md .token.selector,.md .token.attr-name,.md .token.string,.md .token.char,.md .token.builtin,.md .token.inserted{color:#690}.md .token.atrule,.md .token.attr-value,.md .token.keyword{color:#07a}.md .token.function,.md .token.class-name{color:#dd4a68}.md .token.regex,.md .token.important,.md .token.variable{color:#e90}.md .token.important,.md .token.bold{font-weight:700}.md .token.italic{font-style:italic}.md .token.entity{cursor:help}.dark .md .token.comment,.dark .md .token.prolog,.dark .md .token.cdata{color:#5c6370}.dark .md .token.doctype,.dark .md .token.punctuation,.dark .md .token.entity{color:#abb2bf}.dark .md .token.attr-name,.dark .md .token.class-name,.dark .md .token.boolean,.dark .md .token.constant,.dark .md .token.number,.dark .md .token.atrule{color:#d19a66}.dark .md .token.keyword{color:#c678dd}.dark .md .token.property,.dark .md .token.tag,.dark .md .token.symbol,.dark .md .token.deleted,.dark .md .token.important{color:#e06c75}.dark .md .token.selector,.dark .md .token.string,.dark .md .token.char,.dark .md .token.builtin,.dark .md .token.inserted,.dark .md .token.regex,.dark .md .token.attr-value,.dark .md .token.attr-value>.token.punctuation{color:#98c379}.dark .md .token.variable,.dark .md .token.operator,.dark .md .token.function{color:#61afef}.dark .md .token.url{color:#56b6c2}span.svelte-1m32c2s div[class*=code_wrap]{position:relative}span.svelte-1m32c2s span.katex{font-size:var(--text-lg);direction:ltr}span.svelte-1m32c2s div[class*=code_wrap]>button{z-index:1;cursor:pointer;border-bottom-left-radius:var(--radius-sm);padding:var(--spacing-md);width:25px;height:25px;position:absolute;right:0}span.svelte-1m32c2s .check{opacity:0;z-index:var(--layer-top);transition:opacity .2s;background:var(--code-background-fill);color:var(--body-text-color);position:absolute;top:var(--size-1-5);left:var(--size-1-5)}span.svelte-1m32c2s p:not(:first-child){margin-top:var(--spacing-xxl)}span.svelte-1m32c2s .md-header-anchor{margin-left:-25px;padding-right:8px;line-height:1;color:var(--body-text-color-subdued);opacity:0}span.svelte-1m32c2s h1:hover .md-header-anchor,span.svelte-1m32c2s h2:hover .md-header-anchor,span.svelte-1m32c2s h3:hover .md-header-anchor,span.svelte-1m32c2s h4:hover .md-header-anchor,span.svelte-1m32c2s h5:hover .md-header-anchor,span.svelte-1m32c2s h6:hover .md-header-anchor{opacity:1}span.md.svelte-1m32c2s .md-header-anchor>svg{color:var(--body-text-color-subdued)}span.svelte-1m32c2s table{word-break:break-word}div.svelte-17qq50w>.md.prose{font-weight:var(--block-info-text-weight);font-size:var(--block-info-text-size);line-height:var(--line-sm)}div.svelte-17qq50w>.md.prose *{color:var(--block-info-text-color)}div.svelte-17qq50w{margin-bottom:var(--spacing-md)}span.has-info.svelte-zgrq3{margin-bottom:var(--spacing-xs)}span.svelte-zgrq3:not(.has-info){margin-bottom:var(--spacing-lg)}span.svelte-zgrq3{display:inline-block;position:relative;z-index:var(--layer-4);border:solid var(--block-title-border-width) var(--block-title-border-color);border-radius:var(--block-title-radius);background:var(--block-title-background-fill);padding:var(--block-title-padding);color:var(--block-title-text-color);font-weight:var(--block-title-text-weight);font-size:var(--block-title-text-size);line-height:var(--line-sm)}span[dir=rtl].svelte-zgrq3{display:block}.hide.svelte-zgrq3{margin:0;height:0}label.svelte-13ao5pu.svelte-13ao5pu{display:inline-flex;align-items:center;z-index:var(--layer-2);box-shadow:var(--block-label-shadow);border:var(--block-label-border-width) solid var(--block-label-border-color);border-top:none;border-left:none;border-radius:var(--block-label-radius);background:var(--block-label-background-fill);padding:var(--block-label-padding);pointer-events:none;color:var(--block-label-text-color);font-weight:var(--block-label-text-weight);font-size:var(--block-label-text-size);line-height:var(--line-sm)}.gr-group label.svelte-13ao5pu.svelte-13ao5pu{border-top-left-radius:0}label.float.svelte-13ao5pu.svelte-13ao5pu{position:absolute;top:var(--block-label-margin);left:var(--block-label-margin)}label.svelte-13ao5pu.svelte-13ao5pu:not(.float){position:static;margin-top:var(--block-label-margin);margin-left:var(--block-label-margin)}.hide.svelte-13ao5pu.svelte-13ao5pu{height:0}span.svelte-13ao5pu.svelte-13ao5pu{opacity:.8;margin-right:var(--size-2);width:calc(var(--block-label-text-size) - 1px);height:calc(var(--block-label-text-size) - 1px)}.hide-label.svelte-13ao5pu.svelte-13ao5pu{box-shadow:none;border-width:0;background:transparent;overflow:visible}label[dir=rtl].svelte-13ao5pu.svelte-13ao5pu{border:var(--block-label-border-width) solid var(--block-label-border-color);border-top:none;border-right:none;border-bottom-left-radius:var(--block-radius);border-bottom-right-radius:var(--block-label-radius);border-top-left-radius:var(--block-label-radius)}label[dir=rtl].svelte-13ao5pu span.svelte-13ao5pu{margin-left:var(--size-2);margin-right:0}button.svelte-qgco6m{display:flex;justify-content:center;align-items:center;gap:1px;z-index:var(--layer-2);border-radius:var(--radius-xs);color:var(--block-label-text-color);border:1px solid transparent;padding:var(--spacing-xxs)}button.svelte-qgco6m:hover{background-color:var(--background-fill-secondary)}button[disabled].svelte-qgco6m{opacity:.5;box-shadow:none}button[disabled].svelte-qgco6m:hover{cursor:not-allowed}.padded.svelte-qgco6m{background:var(--bg-color)}button.svelte-qgco6m:hover,button.highlight.svelte-qgco6m{cursor:pointer;color:var(--color-accent)}.padded.svelte-qgco6m:hover{color:var(--block-label-text-color)}span.svelte-qgco6m{padding:0 1px;font-size:10px}div.svelte-qgco6m{display:flex;align-items:center;justify-content:center;transition:filter .2s ease-in-out}.x-small.svelte-qgco6m{width:10px;height:10px}.small.svelte-qgco6m{width:14px;height:14px}.medium.svelte-qgco6m{width:20px;height:20px}.large.svelte-qgco6m{width:22px;height:22px}.pending.svelte-qgco6m{animation:svelte-qgco6m-flash .5s infinite}@keyframes svelte-qgco6m-flash{0%{opacity:.5}50%{opacity:1}to{opacity:.5}}.transparent.svelte-qgco6m{background:transparent;border:none;box-shadow:none}.empty.svelte-3w3rth{display:flex;justify-content:center;align-items:center;margin-top:calc(0px - var(--size-6));height:var(--size-full)}.icon.svelte-3w3rth{opacity:.5;height:var(--size-5);color:var(--body-text-color)}.small.svelte-3w3rth{min-height:calc(var(--size-32) - 20px)}.large.svelte-3w3rth{min-height:calc(var(--size-64) - 20px)}.unpadded_box.svelte-3w3rth{margin-top:0}.small_parent.svelte-3w3rth{min-height:100%!important}.dropdown-arrow.svelte-145leq6,.dropdown-arrow.svelte-ihhdbf{fill:currentColor}.circle.svelte-ihhdbf{fill:currentColor;opacity:.1}svg.svelte-pb9pol{animation:svelte-pb9pol-spin 1.5s linear infinite}@keyframes svelte-pb9pol-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}h2.svelte-1xg7h5n{font-size:var(--text-xl)!important}p.svelte-1xg7h5n,h2.svelte-1xg7h5n{white-space:pre-line}.wrap.svelte-1xg7h5n{display:flex;flex-direction:column;justify-content:center;align-items:center;min-height:var(--size-60);color:var(--block-label-text-color);line-height:var(--line-md);height:100%;padding-top:var(--size-3);text-align:center;margin:auto var(--spacing-lg)}.or.svelte-1xg7h5n{color:var(--body-text-color-subdued);display:flex}.icon-wrap.svelte-1xg7h5n{width:30px;margin-bottom:var(--spacing-lg)}@media (--screen-md){.wrap.svelte-1xg7h5n{font-size:var(--text-lg)}}.hovered.svelte-1xg7h5n{color:var(--color-accent)}div.svelte-q32hvf{border-top:1px solid transparent;display:flex;max-height:100%;justify-content:center;align-items:center;gap:var(--spacing-sm);height:auto;align-items:flex-end;color:var(--block-label-text-color);flex-shrink:0}.show_border.svelte-q32hvf{border-top:1px solid var(--block-border-color);margin-top:var(--spacing-xxl);box-shadow:var(--shadow-drop)}.source-selection.svelte-15ls1gu{display:flex;align-items:center;justify-content:center;border-top:1px solid var(--border-color-primary);width:100%;margin-left:auto;margin-right:auto;height:var(--size-10)}.icon.svelte-15ls1gu{width:22px;height:22px;margin:var(--spacing-lg) var(--spacing-xs);padding:var(--spacing-xs);color:var(--neutral-400);border-radius:var(--radius-md)}.selected.svelte-15ls1gu{color:var(--color-accent)}.icon.svelte-15ls1gu:hover,.icon.svelte-15ls1gu:focus{color:var(--color-accent)}.icon-button-wrapper.svelte-1h0hs6p{display:flex;flex-direction:row;align-items:center;justify-content:center;z-index:var(--layer-2);gap:var(--spacing-sm);box-shadow:var(--shadow-drop);border:1px solid var(--border-color-primary);background:var(--block-background-fill);padding:var(--spacing-xxs)}.icon-button-wrapper.hide-top-corner.svelte-1h0hs6p{border-top:none;border-right:none;border-radius:var(--block-label-right-radius)}.icon-button-wrapper.display-top-corner.svelte-1h0hs6p{border-radius:var(--radius-sm) 0 0 var(--radius-sm);top:var(--spacing-sm);right:-1px}.icon-button-wrapper.svelte-1h0hs6p:not(.top-panel){border:1px solid var(--border-color-primary);border-radius:var(--radius-sm)}.top-panel.svelte-1h0hs6p{position:absolute;top:var(--block-label-margin);right:var(--block-label-margin);margin:0}.icon-button-wrapper.svelte-1h0hs6p button{margin:var(--spacing-xxs);border-radius:var(--radius-xs);position:relative}.icon-button-wrapper.svelte-1h0hs6p a.download-link:not(:last-child),.icon-button-wrapper.svelte-1h0hs6p button:not(:last-child){margin-right:var(--spacing-xxs)}.icon-button-wrapper.svelte-1h0hs6p a.download-link:not(:last-child):not(.no-border *):after,.icon-button-wrapper.svelte-1h0hs6p button:not(:last-child):not(.no-border *):after{content:"";position:absolute;right:-4.5px;top:15%;height:70%;width:1px;background-color:var(--border-color-primary)}.icon-button-wrapper.svelte-1h0hs6p>*{height:100%}svg.svelte-43sxxs.svelte-43sxxs{width:var(--size-20);height:var(--size-20)}svg.svelte-43sxxs path.svelte-43sxxs{fill:var(--loader-color)}div.svelte-43sxxs.svelte-43sxxs{z-index:var(--layer-2)}.margin.svelte-43sxxs.svelte-43sxxs{margin:var(--size-4)}.wrap.svelte-17v219f.svelte-17v219f{display:flex;flex-direction:column;justify-content:center;align-items:center;z-index:var(--layer-2);transition:opacity .1s ease-in-out;border-radius:var(--block-radius);background:var(--block-background-fill);padding:0 var(--size-6);max-height:var(--size-screen-h);overflow:hidden}.wrap.center.svelte-17v219f.svelte-17v219f{top:0;right:0;left:0}.wrap.default.svelte-17v219f.svelte-17v219f{top:0;right:0;bottom:0;left:0}.hide.svelte-17v219f.svelte-17v219f{opacity:0;pointer-events:none}.generating.svelte-17v219f.svelte-17v219f{animation:svelte-17v219f-pulseStart 1s cubic-bezier(.4,0,.6,1),svelte-17v219f-pulse 2s cubic-bezier(.4,0,.6,1) 1s infinite;border:2px solid var(--color-accent);background:transparent;z-index:var(--layer-1);pointer-events:none}.translucent.svelte-17v219f.svelte-17v219f{background:none}@keyframes svelte-17v219f-pulseStart{0%{opacity:0}to{opacity:1}}@keyframes svelte-17v219f-pulse{0%,to{opacity:1}50%{opacity:.5}}.loading.svelte-17v219f.svelte-17v219f{z-index:var(--layer-2);color:var(--body-text-color)}.eta-bar.svelte-17v219f.svelte-17v219f{position:absolute;top:0;right:0;bottom:0;left:0;transform-origin:left;opacity:.8;z-index:var(--layer-1);transition:10ms;background:var(--background-fill-secondary)}.progress-bar-wrap.svelte-17v219f.svelte-17v219f{border:1px solid var(--border-color-primary);background:var(--background-fill-primary);width:55.5%;height:var(--size-4)}.progress-bar.svelte-17v219f.svelte-17v219f{transform-origin:left;background-color:var(--loader-color);width:var(--size-full);height:var(--size-full)}.progress-level.svelte-17v219f.svelte-17v219f{display:flex;flex-direction:column;align-items:center;gap:1;z-index:var(--layer-2);width:var(--size-full)}.progress-level-inner.svelte-17v219f.svelte-17v219f{margin:var(--size-2) auto;color:var(--body-text-color);font-size:var(--text-sm);font-family:var(--font-mono)}.meta-text.svelte-17v219f.svelte-17v219f{position:absolute;bottom:0;right:0;z-index:var(--layer-2);padding:var(--size-1) var(--size-2);font-size:var(--text-sm);font-family:var(--font-mono)}.meta-text-center.svelte-17v219f.svelte-17v219f{display:flex;position:absolute;top:0;right:0;justify-content:center;align-items:center;transform:translateY(var(--size-6));z-index:var(--layer-2);padding:var(--size-1) var(--size-2);font-size:var(--text-sm);font-family:var(--font-mono);text-align:center}.error.svelte-17v219f.svelte-17v219f{box-shadow:var(--shadow-drop);border:solid 1px var(--error-border-color);border-radius:var(--radius-full);background:var(--error-background-fill);padding-right:var(--size-4);padding-left:var(--size-4);color:var(--error-text-color);font-weight:var(--weight-semibold);font-size:var(--text-lg);line-height:var(--line-lg);font-family:var(--font)}.minimal.svelte-17v219f.svelte-17v219f{pointer-events:none}.minimal.svelte-17v219f .progress-text.svelte-17v219f{background:var(--block-background-fill)}.border.svelte-17v219f.svelte-17v219f{border:1px solid var(--border-color-primary)}.clear-status.svelte-17v219f.svelte-17v219f{position:absolute;display:flex;top:var(--size-2);right:var(--size-2);justify-content:flex-end;gap:var(--spacing-sm);z-index:var(--layer-1)}.toast-body.svelte-syezpc{display:flex;position:relative;right:0;left:0;align-items:center;margin:var(--size-6) var(--size-4);margin:auto;border-radius:var(--container-radius);overflow:hidden;pointer-events:auto}.toast-body.error.svelte-syezpc{border:1px solid var(--color-red-700);background:var(--color-red-50)}.dark .toast-body.error.svelte-syezpc{border:1px solid var(--color-red-500);background-color:var(--color-grey-950)}.toast-body.warning.svelte-syezpc{border:1px solid var(--color-yellow-700);background:var(--color-yellow-50)}.dark .toast-body.warning.svelte-syezpc{border:1px solid var(--color-yellow-500);background-color:var(--color-grey-950)}.toast-body.info.svelte-syezpc{border:1px solid var(--color-grey-700);background:var(--color-grey-50)}.dark .toast-body.info.svelte-syezpc{border:1px solid var(--color-grey-500);background-color:var(--color-grey-950)}.toast-body.success.svelte-syezpc{border:1px solid var(--color-green-700);background:var(--color-green-50)}.dark .toast-body.success.svelte-syezpc{border:1px solid var(--color-green-500);background-color:var(--color-grey-950)}.toast-title.svelte-syezpc{display:flex;align-items:center;font-weight:var(--weight-bold);font-size:var(--text-lg);line-height:var(--line-sm)}.toast-title.error.svelte-syezpc{color:var(--color-red-700)}.dark .toast-title.error.svelte-syezpc{color:var(--color-red-50)}.toast-title.warning.svelte-syezpc{color:var(--color-yellow-700)}.dark .toast-title.warning.svelte-syezpc{color:var(--color-yellow-50)}.toast-title.info.svelte-syezpc{color:var(--color-grey-700)}.dark .toast-title.info.svelte-syezpc{color:var(--color-grey-50)}.toast-title.success.svelte-syezpc{color:var(--color-green-700)}.dark .toast-title.success.svelte-syezpc{color:var(--color-green-50)}.toast-close.svelte-syezpc{margin:0 var(--size-3);border-radius:var(--size-3);padding:0px var(--size-1-5);font-size:var(--size-5);line-height:var(--size-5)}.toast-close.error.svelte-syezpc{color:var(--color-red-700)}.dark .toast-close.error.svelte-syezpc{color:var(--color-red-500)}.toast-close.warning.svelte-syezpc{color:var(--color-yellow-700)}.dark .toast-close.warning.svelte-syezpc{color:var(--color-yellow-500)}.toast-close.info.svelte-syezpc{color:var(--color-grey-700)}.dark .toast-close.info.svelte-syezpc{color:var(--color-grey-500)}.toast-close.success.svelte-syezpc{color:var(--color-green-700)}.dark .toast-close.success.svelte-syezpc{color:var(--color-green-500)}.toast-text.svelte-syezpc{font-size:var(--text-lg);word-wrap:break-word;overflow-wrap:break-word;word-break:break-word}.toast-text.error.svelte-syezpc{color:var(--color-red-700)}.dark .toast-text.error.svelte-syezpc{color:var(--color-red-50)}.toast-text.warning.svelte-syezpc{color:var(--color-yellow-700)}.dark .toast-text.warning.svelte-syezpc{color:var(--color-yellow-50)}.toast-text.info.svelte-syezpc{color:var(--color-grey-700)}.dark .toast-text.info.svelte-syezpc{color:var(--color-grey-50)}.toast-text.success.svelte-syezpc{color:var(--color-green-700)}.dark .toast-text.success.svelte-syezpc{color:var(--color-green-50)}.toast-details.svelte-syezpc{margin:var(--size-3) var(--size-3) var(--size-3) 0;width:100%}.toast-icon.svelte-syezpc{display:flex;position:absolute;position:relative;flex-shrink:0;justify-content:center;align-items:center;margin:var(--size-2);border-radius:var(--radius-full);padding:var(--size-1);padding-left:calc(var(--size-1) - 1px);width:35px;height:35px}.toast-icon.error.svelte-syezpc{color:var(--color-red-700)}.dark .toast-icon.error.svelte-syezpc{color:var(--color-red-500)}.toast-icon.warning.svelte-syezpc{color:var(--color-yellow-700)}.dark .toast-icon.warning.svelte-syezpc{color:var(--color-yellow-500)}.toast-icon.info.svelte-syezpc{color:var(--color-grey-700)}.dark .toast-icon.info.svelte-syezpc{color:var(--color-grey-500)}.toast-icon.success.svelte-syezpc{color:var(--color-green-700)}.dark .toast-icon.success.svelte-syezpc{color:var(--color-green-500)}@keyframes svelte-syezpc-countdown{0%{transform:scaleX(1)}to{transform:scaleX(0)}}.timer.svelte-syezpc{position:absolute;bottom:0;left:0;transform-origin:0 0;animation:svelte-syezpc-countdown 10s linear forwards;width:100%;height:var(--size-1)}.timer.error.svelte-syezpc{background:var(--color-red-700)}.dark .timer.error.svelte-syezpc{background:var(--color-red-500)}.timer.warning.svelte-syezpc{background:var(--color-yellow-700)}.dark .timer.warning.svelte-syezpc{background:var(--color-yellow-500)}.timer.info.svelte-syezpc{background:var(--color-grey-700)}.dark .timer.info.svelte-syezpc{background:var(--color-grey-500)}.timer.success.svelte-syezpc{background:var(--color-green-700)}.dark .timer.success.svelte-syezpc{background:var(--color-green-500)}.hidden.svelte-syezpc{display:none}.toast-text.svelte-syezpc a{text-decoration:underline}.toast-wrap.svelte-gatr8h{display:flex;position:fixed;top:var(--size-4);right:var(--size-4);flex-direction:column;align-items:end;gap:var(--size-2);z-index:var(--layer-top);width:calc(100% - var(--size-8))}@media (--screen-sm){.toast-wrap.svelte-gatr8h{width:calc(var(--size-96) + var(--size-10))}}.streaming-bar.svelte-ga0jj6{position:absolute;bottom:0;left:0;right:0;height:4px;background-color:var(--primary-600);animation:svelte-ga0jj6-countdown linear forwards;z-index:1}@keyframes svelte-ga0jj6-countdown{0%{transform:translate(0)}to{transform:translate(-100%)}}.wrapper.svelte-1nrfbo6.svelte-1nrfbo6{width:100%;height:100%;overflow:hidden;position:relative;font-family:sans-serif}.scroll-logo-container.svelte-1nrfbo6.svelte-1nrfbo6{text-align:center;margin-bottom:2rem}.scroll-logo-container.svelte-1nrfbo6 img.svelte-1nrfbo6{display:block;margin-left:auto;margin-right:auto;max-width:80%;object-fit:contain}.credits-container.svelte-1nrfbo6.svelte-1nrfbo6{position:absolute;bottom:0;transform:translateY(100%);width:100%;text-align:center;animation:svelte-1nrfbo6-scroll var(--animation-duration) linear infinite;padding:0 2rem;box-sizing:border-box}.section-title.svelte-1nrfbo6.svelte-1nrfbo6{margin-top:4rem;margin-bottom:2.5rem;font-weight:700}.credit.intro-block.svelte-1nrfbo6.svelte-1nrfbo6{margin-bottom:5rem}.credit.svelte-1nrfbo6.svelte-1nrfbo6{margin-bottom:2rem}.credit.svelte-1nrfbo6 h2.svelte-1nrfbo6,.credit.svelte-1nrfbo6 p.svelte-1nrfbo6{margin:.5rem 0;font-family:sans-serif}.credit-two-column.svelte-1nrfbo6.svelte-1nrfbo6{display:flex;justify-content:space-between;align-items:baseline;text-align:left;margin:.8rem auto;max-width:80%;gap:1rem}.credit-two-column.svelte-1nrfbo6 .title.svelte-1nrfbo6{flex:1;text-align:right;padding-right:1rem}.credit-two-column.svelte-1nrfbo6 .name.svelte-1nrfbo6{flex:1;text-align:left;padding-left:1rem}.uppercase.svelte-1nrfbo6.svelte-1nrfbo6{text-transform:uppercase}@keyframes svelte-1nrfbo6-scroll{0%{transform:translateY(100%)}to{transform:translateY(-100%)}}.viewport.svelte-1hia40q.svelte-1hia40q{width:100%;height:100%;position:relative;overflow:hidden;perspective:400px;-webkit-mask-image:linear-gradient(to bottom,black 60%,transparent 100%);mask-image:linear-gradient(to bottom,black 60%,transparent 100%);font-family:Droid Sans,sans-serif;font-weight:700}.stars.svelte-1hia40q.svelte-1hia40q{position:absolute;top:0;left:0;width:1px;height:1px;background:transparent;z-index:0;animation:svelte-1hia40q-twinkle 10s linear infinite}.stars.small.svelte-1hia40q.svelte-1hia40q{animation-duration:10s}.stars.medium.svelte-1hia40q.svelte-1hia40q{animation-duration:15s}.stars.large.svelte-1hia40q.svelte-1hia40q{animation-duration:20s}@keyframes svelte-1hia40q-twinkle{0%{opacity:.6}50%{opacity:1}to{opacity:.6}}.crawl.svelte-1hia40q.svelte-1hia40q{position:absolute;width:100%;bottom:0;transform-origin:50% 100%;animation:svelte-1hia40q-crawl-animation var(--animation-duration) linear infinite;z-index:1;text-align:center}@keyframes svelte-1hia40q-crawl-animation{0%{transform:rotateX(60deg) translateY(100%) translateZ(100px)}to{transform:rotateX(60deg) translateY(-150%) translateZ(-1200px)}}.scroll-logo-container.svelte-1hia40q.svelte-1hia40q{text-align:center;margin-bottom:2rem}.scroll-logo-container.svelte-1hia40q img.svelte-1hia40q{display:block;margin-left:auto;margin-right:auto;max-width:70%;object-fit:contain;filter:grayscale(1) sepia(100%) hue-rotate(15deg) saturate(8) brightness(1.2)}.uppercase.svelte-1hia40q.svelte-1hia40q{text-transform:uppercase}.section-title.svelte-1hia40q.svelte-1hia40q{margin-top:5rem;margin-bottom:3rem;font-weight:700}.credit.intro-block.svelte-1hia40q.svelte-1hia40q{margin-bottom:5rem}.credit.svelte-1hia40q.svelte-1hia40q{margin-bottom:2rem}.credit.svelte-1hia40q h2.svelte-1hia40q,.credit.svelte-1hia40q p.svelte-1hia40q{margin:.5rem 0;padding:0;white-space:nowrap}.credit-two-column.svelte-1hia40q.svelte-1hia40q{display:flex;justify-content:space-between;align-items:baseline;margin:.8rem auto;width:90%;white-space:nowrap}.credit-two-column.svelte-1hia40q .spacer.svelte-1hia40q{flex-grow:1;border-bottom:1px dotted rgba(254,218,74,.3);margin:0 1em;transform:translateY(-.5em)}.matrix-container.svelte-1bt5wt2.svelte-1bt5wt2{width:100%;height:100%;position:relative;overflow:hidden}canvas.svelte-1bt5wt2.svelte-1bt5wt2{display:block;position:absolute;top:0;left:0;width:100%;height:100%;z-index:1}.credits-scroll-overlay.svelte-1bt5wt2.svelte-1bt5wt2{position:absolute;top:0;left:0;width:100%;height:100%;z-index:2;color:#fff;font-family:monospace;text-align:center;-webkit-mask-image:linear-gradient(transparent,black 20%,black 80%,transparent);mask-image:linear-gradient(transparent,black 20%,black 80%,transparent)}.credits-content.svelte-1bt5wt2.svelte-1bt5wt2{position:absolute;width:100%;bottom:0;transform:translateY(100%);animation:svelte-1bt5wt2-scroll-from-bottom var(--animation-duration) linear infinite;padding:0 2rem;box-sizing:border-box}@keyframes svelte-1bt5wt2-scroll-from-bottom{0%{transform:translateY(100%)}to{transform:translateY(-100%)}}.uppercase.svelte-1bt5wt2.svelte-1bt5wt2{text-transform:uppercase}.section-title.svelte-1bt5wt2.svelte-1bt5wt2{margin-top:4rem;margin-bottom:2.5rem;font-weight:700;color:#5f5;text-shadow:0 0 8px #0f0}.credit-block.intro-block.svelte-1bt5wt2.svelte-1bt5wt2{margin-bottom:5rem}.credit-block.svelte-1bt5wt2.svelte-1bt5wt2{margin-bottom:2.5em}.title.svelte-1bt5wt2.svelte-1bt5wt2{color:#0f0;opacity:.8}.name.svelte-1bt5wt2.svelte-1bt5wt2{font-weight:700;color:#5f5;text-shadow:0 0 5px #0f0}.credit-two-column.svelte-1bt5wt2.svelte-1bt5wt2{display:flex;justify-content:space-between;align-items:baseline;text-align:left;margin:.8em auto;max-width:80%;gap:1em}.credit-two-column.svelte-1bt5wt2 .title.svelte-1bt5wt2{flex:1;text-align:right;padding-right:1em}.credit-two-column.svelte-1bt5wt2 .name.svelte-1bt5wt2{flex:1;text-align:left;padding-left:1em}.scroll-logo-container.svelte-1bt5wt2.svelte-1bt5wt2{text-align:center;margin-bottom:2rem}.scroll-logo-container.svelte-1bt5wt2 img.svelte-1bt5wt2{display:block;margin-left:auto;margin-right:auto;max-width:80%;object-fit:contain;filter:grayscale(1) brightness(.5) sepia(100%) hue-rotate(50deg) saturate(500%)}.unstyled-link.svelte-151nsdd{all:unset;cursor:pointer}img.svelte-kxeri3{object-fit:cover}.image-container.svelte-x2tujq.svelte-x2tujq{height:100%;position:relative;min-width:var(--size-20)}.image-container.svelte-x2tujq button.svelte-x2tujq{width:var(--size-full);height:var(--size-full);border-radius:var(--radius-lg);display:flex;align-items:center;justify-content:center}.image-frame.svelte-x2tujq img{width:var(--size-full);height:var(--size-full);object-fit:scale-down}.selectable.svelte-x2tujq.svelte-x2tujq{cursor:crosshair}.fullscreen-controls svg{position:relative;top:0}.image-container:fullscreen{background-color:#000;display:flex;justify-content:center;align-items:center}.image-container:fullscreen img{max-width:90vw;max-height:90vh;object-fit:scale-down}.image-frame.svelte-x2tujq.svelte-x2tujq{width:auto;height:100%;display:flex;align-items:center;justify-content:center}.block{border:none!important;box-shadow:none!important;border-style:none!important}.outer-logo-wrapper.svelte-1hawtr7.svelte-1hawtr7,.outer-credits-wrapper.svelte-1hawtr7.svelte-1hawtr7{display:flex;flex-direction:column;width:100%;border:none}.logo-panel.svelte-1hawtr7.svelte-1hawtr7{background:var(--background-fill-primary);border:none;display:flex!important;align-items:center;justify-content:var(--logo-justify, center);padding:0 0 20px;width:100%}.credits-panel-wrapper.svelte-1hawtr7.svelte-1hawtr7{display:flex;flex-direction:var(--panel-direction, row);min-height:var(--size-full, 500px);width:100%;background:var(--background-fill-primary);border:1px solid var(--border-color-primary);border-radius:var(--radius-lg);overflow:hidden}.main-credits-panel.svelte-1hawtr7.svelte-1hawtr7{flex-grow:1;flex-shrink:1;min-width:200px;background:#000;overflow:hidden;position:relative}.licenses-sidebar.svelte-1hawtr7.svelte-1hawtr7{width:calc(100% - var(--main-panel-width, 400px));max-width:100%;max-height:var(--sidebar-max-height, none);flex-shrink:1;flex-grow:1;background:var(--background-fill-secondary);overflow-y:auto;border-left:var(--border-left, 1px solid var(--border-color-primary));border-top:var(--border-top, none)}.licenses-sidebar.svelte-1hawtr7 h3.svelte-1hawtr7{margin:var(--spacing-lg);font-size:var(--text-lg)}.licenses-sidebar.svelte-1hawtr7 li.svelte-1hawtr7{padding:0;margin:0;cursor:default;border-bottom:1px solid var(--border-color-primary)}.licenses-sidebar.svelte-1hawtr7 li button.svelte-1hawtr7{background:none;border:none;font:inherit;color:inherit;text-align:left;width:100%;cursor:pointer;padding:var(--spacing-md) var(--spacing-lg);transition:background-color .2s}.licenses-sidebar.svelte-1hawtr7 li button.svelte-1hawtr7:hover{background-color:var(--background-fill-primary)}.licenses-sidebar.svelte-1hawtr7 li button.svelte-1hawtr7:focus-visible{outline:2px solid var(--color-accent);outline-offset:-2px}.licenses-sidebar.svelte-1hawtr7 li button.selected.svelte-1hawtr7{background-color:var(--color-accent);color:#fff;font-weight:700}.license-display.svelte-1hawtr7.svelte-1hawtr7{padding:var(--spacing-lg);overflow-y:auto;flex-grow:1;border-top:1px solid var(--border-color-primary);background:var(--background-fill-primary)}.license-display.svelte-1hawtr7 h4.svelte-1hawtr7{margin-top:0}.license-display.svelte-1hawtr7 pre.svelte-1hawtr7{white-space:pre-wrap;word-break:break-word;font-size:var(--text-sm);color:var(--body-text-color-subdued)}
|
src/demo/app.py
CHANGED
|
@@ -18,7 +18,7 @@ def setup_demo_files():
|
|
| 18 |
with open("./assets/logo.webp", "w") as f:
|
| 19 |
f.write("Placeholder WebP logo")
|
| 20 |
|
| 21 |
-
# ---
|
| 22 |
credits_list = [
|
| 23 |
{"section_title": "Project Leadership"},
|
| 24 |
{"title": "Project Manager", "name": "Emma Thompson"},
|
|
@@ -47,6 +47,8 @@ DEFAULT_SPEEDS = {
|
|
| 47 |
"starwars": 70.0,
|
| 48 |
"matrix": 40.0
|
| 49 |
}
|
|
|
|
|
|
|
| 50 |
|
| 51 |
def update_panel(
|
| 52 |
effect: str,
|
|
@@ -64,39 +66,52 @@ def update_panel(
|
|
| 64 |
logo_height: str | None,
|
| 65 |
scroll_background_color: str | None,
|
| 66 |
scroll_title_color: str | None,
|
|
|
|
| 67 |
scroll_name_color: str | None,
|
| 68 |
layout_style: str,
|
| 69 |
title_uppercase: bool,
|
| 70 |
name_uppercase: bool,
|
| 71 |
section_title_uppercase: bool,
|
| 72 |
-
swap_font_sizes: bool
|
|
|
|
|
|
|
| 73 |
) -> dict:
|
| 74 |
"""Callback function that updates all properties of the CreditsPanel component."""
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
|
| 101 |
def update_ui_on_effect_change(effect: str) -> tuple[float, float]:
|
| 102 |
"""Updates sliders to sensible defaults when the animation effect is changed."""
|
|
@@ -138,6 +153,14 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 138 |
name_uppercase_checkbox = gr.Checkbox(label="Name Uppercase", value=False)
|
| 139 |
section_title_uppercase_checkbox = gr.Checkbox(label="Section Uppercase", value=True)
|
| 140 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
gr.Markdown("### Intro Text")
|
| 142 |
intro_title_input = gr.Textbox(label="Intro Title", value="Gradio")
|
| 143 |
intro_subtitle_input = gr.Textbox(label="Intro Subtitle", value="The best UI framework")
|
|
@@ -157,19 +180,20 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 157 |
gr.Markdown("### Color Settings (Scroll Effect)")
|
| 158 |
scroll_background_color = gr.ColorPicker(label="Background Color", value="#000000")
|
| 159 |
scroll_title_color = gr.ColorPicker(label="Title Color", value="#FFFFFF")
|
|
|
|
| 160 |
scroll_name_color = gr.ColorPicker(label="Name Color", value="#FFFFFF")
|
| 161 |
|
| 162 |
-
panel = CreditsPanel(
|
|
|
|
| 163 |
credits=credits_list,
|
| 164 |
licenses=license_paths,
|
| 165 |
effect="scroll",
|
| 166 |
-
height=500,
|
| 167 |
speed=DEFAULT_SPEEDS["scroll"],
|
| 168 |
base_font_size=1.5,
|
| 169 |
intro_title="Gradio",
|
| 170 |
intro_subtitle="The best UI framework",
|
| 171 |
sidebar_position="right",
|
| 172 |
-
logo_path=
|
| 173 |
show_logo=True,
|
| 174 |
show_licenses=True,
|
| 175 |
show_credits=True,
|
|
@@ -180,11 +204,14 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 180 |
scroll_background_color="#000000",
|
| 181 |
scroll_title_color="#FFFFFF",
|
| 182 |
scroll_name_color="#FFFFFF",
|
|
|
|
| 183 |
layout_style="stacked",
|
| 184 |
title_uppercase=False,
|
| 185 |
name_uppercase=False,
|
| 186 |
section_title_uppercase=True,
|
| 187 |
swap_font_sizes_on_two_column=False,
|
|
|
|
|
|
|
| 188 |
)
|
| 189 |
|
| 190 |
inputs = [
|
|
@@ -202,15 +229,23 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 202 |
logo_width_input,
|
| 203 |
logo_height_input,
|
| 204 |
scroll_background_color,
|
| 205 |
-
scroll_title_color,
|
|
|
|
| 206 |
scroll_name_color,
|
| 207 |
layout_style_radio,
|
| 208 |
title_uppercase_checkbox,
|
| 209 |
name_uppercase_checkbox,
|
| 210 |
section_title_uppercase_checkbox,
|
| 211 |
-
swap_sizes_checkbox
|
|
|
|
|
|
|
| 212 |
]
|
| 213 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 214 |
layout_style_radio.change(
|
| 215 |
fn=toggle_swap_checkbox_visibility,
|
| 216 |
inputs=layout_style_radio,
|
|
|
|
| 18 |
with open("./assets/logo.webp", "w") as f:
|
| 19 |
f.write("Placeholder WebP logo")
|
| 20 |
|
| 21 |
+
# --- Credits list with sections ---
|
| 22 |
credits_list = [
|
| 23 |
{"section_title": "Project Leadership"},
|
| 24 |
{"title": "Project Manager", "name": "Emma Thompson"},
|
|
|
|
| 47 |
"starwars": 70.0,
|
| 48 |
"matrix": 40.0
|
| 49 |
}
|
| 50 |
+
SCROLL_LOGO_PATH = "./assets/gradio_logo_white.png"
|
| 51 |
+
LOGO_PATH="./assets/logo.webp"
|
| 52 |
|
| 53 |
def update_panel(
|
| 54 |
effect: str,
|
|
|
|
| 66 |
logo_height: str | None,
|
| 67 |
scroll_background_color: str | None,
|
| 68 |
scroll_title_color: str | None,
|
| 69 |
+
scroll_section_title_color: str | None,
|
| 70 |
scroll_name_color: str | None,
|
| 71 |
layout_style: str,
|
| 72 |
title_uppercase: bool,
|
| 73 |
name_uppercase: bool,
|
| 74 |
section_title_uppercase: bool,
|
| 75 |
+
swap_font_sizes: bool,
|
| 76 |
+
show_scroll_logo: bool,
|
| 77 |
+
scroll_logo_height: str | None
|
| 78 |
) -> dict:
|
| 79 |
"""Callback function that updates all properties of the CreditsPanel component."""
|
| 80 |
+
|
| 81 |
+
scroll_logo_path = SCROLL_LOGO_PATH if show_scroll_logo else None
|
| 82 |
+
|
| 83 |
+
if not scroll_logo_height:
|
| 84 |
+
scroll_logo_height = "120px"
|
| 85 |
+
|
| 86 |
+
return {
|
| 87 |
+
"credits": credits_list,
|
| 88 |
+
"licenses": license_paths,
|
| 89 |
+
"effect": effect,
|
| 90 |
+
"speed": speed,
|
| 91 |
+
"base_font_size": base_font_size,
|
| 92 |
+
"intro_title": intro_title,
|
| 93 |
+
"intro_subtitle": intro_subtitle,
|
| 94 |
+
"sidebar_position": sidebar_position,
|
| 95 |
+
"logo_path": LOGO_PATH,
|
| 96 |
+
"show_logo": show_logo,
|
| 97 |
+
"show_licenses": show_licenses,
|
| 98 |
+
"show_credits": show_credits,
|
| 99 |
+
"logo_position": logo_position,
|
| 100 |
+
"logo_sizing": logo_sizing,
|
| 101 |
+
"logo_width": logo_width,
|
| 102 |
+
"logo_height": logo_height,
|
| 103 |
+
"scroll_background_color": scroll_background_color,
|
| 104 |
+
"scroll_title_color": scroll_title_color,
|
| 105 |
+
"scroll_name_color": scroll_name_color,
|
| 106 |
+
"scroll_section_title_color": scroll_section_title_color,
|
| 107 |
+
"layout_style": layout_style,
|
| 108 |
+
"title_uppercase": title_uppercase,
|
| 109 |
+
"name_uppercase": name_uppercase,
|
| 110 |
+
"section_title_uppercase": section_title_uppercase,
|
| 111 |
+
"swap_font_sizes_on_two_column": swap_font_sizes,
|
| 112 |
+
"scroll_logo_path": scroll_logo_path,
|
| 113 |
+
"scroll_logo_height": scroll_logo_height,
|
| 114 |
+
}
|
| 115 |
|
| 116 |
def update_ui_on_effect_change(effect: str) -> tuple[float, float]:
|
| 117 |
"""Updates sliders to sensible defaults when the animation effect is changed."""
|
|
|
|
| 153 |
name_uppercase_checkbox = gr.Checkbox(label="Name Uppercase", value=False)
|
| 154 |
section_title_uppercase_checkbox = gr.Checkbox(label="Section Uppercase", value=True)
|
| 155 |
|
| 156 |
+
gr.Markdown("### Scrolling Logo")
|
| 157 |
+
show_scroll_logo_checkbox = gr.Checkbox(
|
| 158 |
+
label="Show Logo in Credits Roll",
|
| 159 |
+
value=True,
|
| 160 |
+
info="Toggles the logo above the intro text."
|
| 161 |
+
)
|
| 162 |
+
scroll_logo_height_input = gr.Textbox(label="Scrolling Logo Height", value="100px")
|
| 163 |
+
|
| 164 |
gr.Markdown("### Intro Text")
|
| 165 |
intro_title_input = gr.Textbox(label="Intro Title", value="Gradio")
|
| 166 |
intro_subtitle_input = gr.Textbox(label="Intro Subtitle", value="The best UI framework")
|
|
|
|
| 180 |
gr.Markdown("### Color Settings (Scroll Effect)")
|
| 181 |
scroll_background_color = gr.ColorPicker(label="Background Color", value="#000000")
|
| 182 |
scroll_title_color = gr.ColorPicker(label="Title Color", value="#FFFFFF")
|
| 183 |
+
scroll_section_title_color = gr.ColorPicker(label="Section Title Color", value="#FFFFFF")
|
| 184 |
scroll_name_color = gr.ColorPicker(label="Name Color", value="#FFFFFF")
|
| 185 |
|
| 186 |
+
panel = CreditsPanel(
|
| 187 |
+
height=500,
|
| 188 |
credits=credits_list,
|
| 189 |
licenses=license_paths,
|
| 190 |
effect="scroll",
|
|
|
|
| 191 |
speed=DEFAULT_SPEEDS["scroll"],
|
| 192 |
base_font_size=1.5,
|
| 193 |
intro_title="Gradio",
|
| 194 |
intro_subtitle="The best UI framework",
|
| 195 |
sidebar_position="right",
|
| 196 |
+
logo_path=LOGO_PATH,
|
| 197 |
show_logo=True,
|
| 198 |
show_licenses=True,
|
| 199 |
show_credits=True,
|
|
|
|
| 204 |
scroll_background_color="#000000",
|
| 205 |
scroll_title_color="#FFFFFF",
|
| 206 |
scroll_name_color="#FFFFFF",
|
| 207 |
+
scroll_section_title_color="#FFFFFF",
|
| 208 |
layout_style="stacked",
|
| 209 |
title_uppercase=False,
|
| 210 |
name_uppercase=False,
|
| 211 |
section_title_uppercase=True,
|
| 212 |
swap_font_sizes_on_two_column=False,
|
| 213 |
+
scroll_logo_path=SCROLL_LOGO_PATH,
|
| 214 |
+
scroll_logo_height="100px",
|
| 215 |
)
|
| 216 |
|
| 217 |
inputs = [
|
|
|
|
| 229 |
logo_width_input,
|
| 230 |
logo_height_input,
|
| 231 |
scroll_background_color,
|
| 232 |
+
scroll_title_color,
|
| 233 |
+
scroll_section_title_color,
|
| 234 |
scroll_name_color,
|
| 235 |
layout_style_radio,
|
| 236 |
title_uppercase_checkbox,
|
| 237 |
name_uppercase_checkbox,
|
| 238 |
section_title_uppercase_checkbox,
|
| 239 |
+
swap_sizes_checkbox,
|
| 240 |
+
show_scroll_logo_checkbox,
|
| 241 |
+
scroll_logo_height_input
|
| 242 |
]
|
| 243 |
|
| 244 |
+
demo.load(
|
| 245 |
+
fn=update_panel,
|
| 246 |
+
inputs=inputs,
|
| 247 |
+
outputs=panel
|
| 248 |
+
)
|
| 249 |
layout_style_radio.change(
|
| 250 |
fn=toggle_swap_checkbox_visibility,
|
| 251 |
inputs=layout_style_radio,
|
src/demo/space.py
CHANGED
|
@@ -3,7 +3,7 @@ import gradio as gr
|
|
| 3 |
from app import demo as app
|
| 4 |
import os
|
| 5 |
|
| 6 |
-
_docs = {'CreditsPanel': {'description': 'A Gradio component for displaying credits with customizable visual effects, such as scrolling or Star Wars-style animations.\
|
| 7 |
|
| 8 |
abs_path = os.path.join(os.path.dirname(__file__), "css.css")
|
| 9 |
|
|
@@ -58,7 +58,7 @@ def setup_demo_files():
|
|
| 58 |
with open("./assets/logo.webp", "w") as f:
|
| 59 |
f.write("Placeholder WebP logo")
|
| 60 |
|
| 61 |
-
# ---
|
| 62 |
credits_list = [
|
| 63 |
{"section_title": "Project Leadership"},
|
| 64 |
{"title": "Project Manager", "name": "Emma Thompson"},
|
|
@@ -87,6 +87,8 @@ DEFAULT_SPEEDS = {
|
|
| 87 |
"starwars": 70.0,
|
| 88 |
"matrix": 40.0
|
| 89 |
}
|
|
|
|
|
|
|
| 90 |
|
| 91 |
def update_panel(
|
| 92 |
effect: str,
|
|
@@ -104,39 +106,52 @@ def update_panel(
|
|
| 104 |
logo_height: str | None,
|
| 105 |
scroll_background_color: str | None,
|
| 106 |
scroll_title_color: str | None,
|
|
|
|
| 107 |
scroll_name_color: str | None,
|
| 108 |
layout_style: str,
|
| 109 |
title_uppercase: bool,
|
| 110 |
name_uppercase: bool,
|
| 111 |
section_title_uppercase: bool,
|
| 112 |
-
swap_font_sizes: bool
|
|
|
|
|
|
|
| 113 |
) -> dict:
|
| 114 |
\"\"\"Callback function that updates all properties of the CreditsPanel component.\"\"\"
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
|
| 141 |
def update_ui_on_effect_change(effect: str) -> tuple[float, float]:
|
| 142 |
\"\"\"Updates sliders to sensible defaults when the animation effect is changed.\"\"\"
|
|
@@ -178,6 +193,14 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 178 |
name_uppercase_checkbox = gr.Checkbox(label="Name Uppercase", value=False)
|
| 179 |
section_title_uppercase_checkbox = gr.Checkbox(label="Section Uppercase", value=True)
|
| 180 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 181 |
gr.Markdown("### Intro Text")
|
| 182 |
intro_title_input = gr.Textbox(label="Intro Title", value="Gradio")
|
| 183 |
intro_subtitle_input = gr.Textbox(label="Intro Subtitle", value="The best UI framework")
|
|
@@ -197,19 +220,20 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 197 |
gr.Markdown("### Color Settings (Scroll Effect)")
|
| 198 |
scroll_background_color = gr.ColorPicker(label="Background Color", value="#000000")
|
| 199 |
scroll_title_color = gr.ColorPicker(label="Title Color", value="#FFFFFF")
|
|
|
|
| 200 |
scroll_name_color = gr.ColorPicker(label="Name Color", value="#FFFFFF")
|
| 201 |
|
| 202 |
-
panel = CreditsPanel(
|
|
|
|
| 203 |
credits=credits_list,
|
| 204 |
licenses=license_paths,
|
| 205 |
effect="scroll",
|
| 206 |
-
height=500,
|
| 207 |
speed=DEFAULT_SPEEDS["scroll"],
|
| 208 |
base_font_size=1.5,
|
| 209 |
intro_title="Gradio",
|
| 210 |
intro_subtitle="The best UI framework",
|
| 211 |
sidebar_position="right",
|
| 212 |
-
logo_path=
|
| 213 |
show_logo=True,
|
| 214 |
show_licenses=True,
|
| 215 |
show_credits=True,
|
|
@@ -220,11 +244,14 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 220 |
scroll_background_color="#000000",
|
| 221 |
scroll_title_color="#FFFFFF",
|
| 222 |
scroll_name_color="#FFFFFF",
|
|
|
|
| 223 |
layout_style="stacked",
|
| 224 |
title_uppercase=False,
|
| 225 |
name_uppercase=False,
|
| 226 |
section_title_uppercase=True,
|
| 227 |
swap_font_sizes_on_two_column=False,
|
|
|
|
|
|
|
| 228 |
)
|
| 229 |
|
| 230 |
inputs = [
|
|
@@ -242,15 +269,23 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="CreditsPanel Demo") as demo:
|
|
| 242 |
logo_width_input,
|
| 243 |
logo_height_input,
|
| 244 |
scroll_background_color,
|
| 245 |
-
scroll_title_color,
|
|
|
|
| 246 |
scroll_name_color,
|
| 247 |
layout_style_radio,
|
| 248 |
title_uppercase_checkbox,
|
| 249 |
name_uppercase_checkbox,
|
| 250 |
section_title_uppercase_checkbox,
|
| 251 |
-
swap_sizes_checkbox
|
|
|
|
|
|
|
| 252 |
]
|
| 253 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 254 |
layout_style_radio.change(
|
| 255 |
fn=toggle_swap_checkbox_visibility,
|
| 256 |
inputs=layout_style_radio,
|
|
@@ -294,7 +329,6 @@ The impact on the users predict function varies depending on whether the compone
|
|
| 294 |
|
| 295 |
The code snippet below is accurate in cases where the component is used as both an input and an output.
|
| 296 |
|
| 297 |
-
- **As input:** Is passed, dict[str, Any] | None: The input payload, returned unchanged.
|
| 298 |
|
| 299 |
|
| 300 |
```python
|
|
@@ -302,7 +336,9 @@ def predict(
|
|
| 302 |
value: typing.Optional[typing.Dict[str, typing.Any]][
|
| 303 |
typing.Dict[str, typing.Any][str, Any], None
|
| 304 |
]
|
| 305 |
-
) -> Any
|
|
|
|
|
|
|
| 306 |
return value
|
| 307 |
```
|
| 308 |
""", elem_classes=["md-custom", "CreditsPanel-user-fn"], header_links=True)
|
|
|
|
| 3 |
from app import demo as app
|
| 4 |
import os
|
| 5 |
|
| 6 |
+
_docs = {'CreditsPanel': {'description': 'A Gradio component for displaying credits with customizable visual effects, such as scrolling or Star Wars-style animations.\nThis component is configured via a single dictionary `value` that holds all settings.\nIt supports displaying a logo, licenses, sections, and various text styling options.\n\n EVENTS (list): Supported events for the component, currently only `change`.', 'members': {'__init__': {'value': {'type': 'typing.Optional[typing.Dict[str, typing.Any]][\n typing.Dict[str, typing.Any][str, Any], None\n]', 'default': 'None', 'description': None}, 'height': {'type': 'int | str | None', 'default': 'None', 'description': None}, 'width': {'type': 'int | str | None', 'default': 'None', 'description': None}, 'credits': {'type': 'typing.Union[\n typing.List[typing.Dict[str, str]],\n typing.Callable,\n NoneType,\n][\n typing.List[typing.Dict[str, str]][\n typing.Dict[str, str][str, str]\n ],\n Callable,\n None,\n]', 'default': 'None', 'description': None}, 'licenses': {'type': 'typing.Optional[typing.Dict[str, str | pathlib.Path]][\n typing.Dict[str, str | pathlib.Path][\n str, str | pathlib.Path\n ],\n None,\n]', 'default': 'None', 'description': None}, 'effect': {'type': '"scroll" | "starwars" | "matrix"', 'default': '"scroll"', 'description': None}, 'speed': {'type': 'float', 'default': '40.0', 'description': None}, 'base_font_size': {'type': 'float', 'default': '1.5', 'description': None}, 'intro_title': {'type': 'str | None', 'default': 'None', 'description': None}, 'intro_subtitle': {'type': 'str | None', 'default': 'None', 'description': None}, 'sidebar_position': {'type': '"right" | "bottom"', 'default': '"right"', 'description': None}, 'logo_path': {'type': 'str | pathlib.Path | None', 'default': 'None', 'description': None}, 'show_logo': {'type': 'bool', 'default': 'True', 'description': None}, 'show_licenses': {'type': 'bool', 'default': 'True', 'description': None}, 'show_credits': {'type': 'bool', 'default': 'True', 'description': None}, 'logo_position': {'type': '"center" | "left" | "right"', 'default': '"center"', 'description': None}, 'logo_sizing': {'type': '"stretch" | "crop" | "resize"', 'default': '"resize"', 'description': None}, 'logo_width': {'type': 'int | str | None', 'default': 'None', 'description': None}, 'logo_height': {'type': 'int | str | None', 'default': 'None', 'description': None}, 'scroll_background_color': {'type': 'str | None', 'default': 'None', 'description': None}, 'scroll_title_color': {'type': 'str | None', 'default': 'None', 'description': None}, 'scroll_name_color': {'type': 'str | None', 'default': 'None', 'description': None}, 'scroll_section_title_color': {'type': 'str | None', 'default': 'None', 'description': None}, 'layout_style': {'type': '"stacked" | "two-column"', 'default': '"stacked"', 'description': None}, 'title_uppercase': {'type': 'bool', 'default': 'False', 'description': None}, 'name_uppercase': {'type': 'bool', 'default': 'False', 'description': None}, 'section_title_uppercase': {'type': 'bool', 'default': 'True', 'description': None}, 'swap_font_sizes_on_two_column': {'type': 'bool', 'default': 'False', 'description': None}, 'scroll_logo_path': {'type': 'str | pathlib.Path | None', 'default': 'None', 'description': None}, 'scroll_logo_height': {'type': 'str', 'default': '"120px"', 'description': None}, 'label': {'type': 'str | gradio.i18n.I18nData | None', 'default': 'None', 'description': None}, 'every': {'type': 'float | None', 'default': 'None', 'description': None}, 'inputs': {'type': 'typing.Union[\n gradio.components.base.Component,\n typing.Sequence[gradio.components.base.Component],\n set[gradio.components.base.Component],\n NoneType,\n][\n gradio.components.base.Component,\n typing.Sequence[gradio.components.base.Component][\n gradio.components.base.Component\n ],\n set[gradio.components.base.Component],\n None,\n]', 'default': 'None', 'description': None}, 'show_label': {'type': 'bool', 'default': 'False', 'description': None}, 'container': {'type': 'bool', 'default': 'True', 'description': None}, 'scale': {'type': 'int | None', 'default': 'None', 'description': None}, 'min_width': {'type': 'int', 'default': '160', 'description': None}, 'interactive': {'type': 'bool | None', 'default': 'None', 'description': None}, 'visible': {'type': 'bool', 'default': 'True', 'description': None}, 'elem_id': {'type': 'str | None', 'default': 'None', 'description': None}, 'elem_classes': {'type': 'list[str] | str | None', 'default': 'None', 'description': None}, 'render': {'type': 'bool', 'default': 'True', 'description': None}, 'key': {'type': 'int | str | tuple[int | str, Ellipsis] | None', 'default': 'None', 'description': None}, 'preserved_by_key': {'type': 'list[str] | str | None', 'default': '"value"', 'description': None}}, 'postprocess': {'value': {'type': 'typing.Optional[typing.Dict[str, typing.Any]][\n typing.Dict[str, typing.Any][str, Any], None\n]', 'description': None}}, 'preprocess': {'return': {'type': 'typing.Optional[typing.Dict[str, typing.Any]][\n typing.Dict[str, typing.Any][str, Any], None\n]', 'description': None}, 'value': None}}, 'events': {'change': {'type': None, 'default': None, 'description': 'Triggered when the value of the CreditsPanel changes either because of user input (e.g. a user types in a textbox) OR because of a function update (e.g. an image receives a value from the output of an event trigger). See `.input()` for a listener that is only triggered by user input.'}}}, '__meta__': {'additional_interfaces': {}, 'user_fn_refs': {'CreditsPanel': []}}}
|
| 7 |
|
| 8 |
abs_path = os.path.join(os.path.dirname(__file__), "css.css")
|
| 9 |
|
|
|
|
| 58 |
with open("./assets/logo.webp", "w") as f:
|
| 59 |
f.write("Placeholder WebP logo")
|
| 60 |
|
| 61 |
+
# --- Credits list with sections ---
|
| 62 |
credits_list = [
|
| 63 |
{"section_title": "Project Leadership"},
|
| 64 |
{"title": "Project Manager", "name": "Emma Thompson"},
|
|
|
|
| 87 |
"starwars": 70.0,
|
| 88 |
"matrix": 40.0
|
| 89 |
}
|
| 90 |
+
SCROLL_LOGO_PATH = "./assets/gradio_logo_white.png"
|
| 91 |
+
LOGO_PATH="./assets/logo.webp"
|
| 92 |
|
| 93 |
def update_panel(
|
| 94 |
effect: str,
|
|
|
|
| 106 |
logo_height: str | None,
|
| 107 |
scroll_background_color: str | None,
|
| 108 |
scroll_title_color: str | None,
|
| 109 |
+
scroll_section_title_color: str | None,
|
| 110 |
scroll_name_color: str | None,
|
| 111 |
layout_style: str,
|
| 112 |
title_uppercase: bool,
|
| 113 |
name_uppercase: bool,
|
| 114 |
section_title_uppercase: bool,
|
| 115 |
+
swap_font_sizes: bool,
|
| 116 |
+
show_scroll_logo: bool,
|
| 117 |
+
scroll_logo_height: str | None
|
| 118 |
) -> dict:
|
| 119 |
\"\"\"Callback function that updates all properties of the CreditsPanel component.\"\"\"
|
| 120 |
+
|
| 121 |
+
scroll_logo_path = SCROLL_LOGO_PATH if show_scroll_logo else None
|
| 122 |
+
|
| 123 |
+
if not scroll_logo_height:
|
| 124 |
+
scroll_logo_height = "120px"
|
| 125 |
+
|
| 126 |
+
return {
|
| 127 |
+
"credits": credits_list,
|
| 128 |
+
"licenses": license_paths,
|
| 129 |
+
"effect": effect,
|
| 130 |
+
"speed": speed,
|
| 131 |
+
"base_font_size": base_font_size,
|
| 132 |
+
"intro_title": intro_title,
|
| 133 |
+
"intro_subtitle": intro_subtitle,
|
| 134 |
+
"sidebar_position": sidebar_position,
|
| 135 |
+
"logo_path": LOGO_PATH,
|
| 136 |
+
"show_logo": show_logo,
|
| 137 |
+
"show_licenses": show_licenses,
|
| 138 |
+
"show_credits": show_credits,
|
| 139 |
+
"logo_position": logo_position,
|
| 140 |
+
"logo_sizing": logo_sizing,
|
| 141 |
+
"logo_width": logo_width,
|
| 142 |
+
"logo_height": logo_height,
|
| 143 |
+
"scroll_background_color": scroll_background_color,
|
| 144 |
+
"scroll_title_color": scroll_title_color,
|
| 145 |
+
"scroll_name_color": scroll_name_color,
|
| 146 |
+
"scroll_section_title_color": scroll_section_title_color,
|
| 147 |
+
"layout_style": layout_style,
|
| 148 |
+
"title_uppercase": title_uppercase,
|
| 149 |
+
"name_uppercase": name_uppercase,
|
| 150 |
+
"section_title_uppercase": section_title_uppercase,
|
| 151 |
+
"swap_font_sizes_on_two_column": swap_font_sizes,
|
| 152 |
+
"scroll_logo_path": scroll_logo_path,
|
| 153 |
+
"scroll_logo_height": scroll_logo_height,
|
| 154 |
+
}
|
| 155 |
|
| 156 |
def update_ui_on_effect_change(effect: str) -> tuple[float, float]:
|
| 157 |
\"\"\"Updates sliders to sensible defaults when the animation effect is changed.\"\"\"
|
|
|
|
| 193 |
name_uppercase_checkbox = gr.Checkbox(label="Name Uppercase", value=False)
|
| 194 |
section_title_uppercase_checkbox = gr.Checkbox(label="Section Uppercase", value=True)
|
| 195 |
|
| 196 |
+
gr.Markdown("### Scrolling Logo")
|
| 197 |
+
show_scroll_logo_checkbox = gr.Checkbox(
|
| 198 |
+
label="Show Logo in Credits Roll",
|
| 199 |
+
value=True,
|
| 200 |
+
info="Toggles the logo above the intro text."
|
| 201 |
+
)
|
| 202 |
+
scroll_logo_height_input = gr.Textbox(label="Scrolling Logo Height", value="100px")
|
| 203 |
+
|
| 204 |
gr.Markdown("### Intro Text")
|
| 205 |
intro_title_input = gr.Textbox(label="Intro Title", value="Gradio")
|
| 206 |
intro_subtitle_input = gr.Textbox(label="Intro Subtitle", value="The best UI framework")
|
|
|
|
| 220 |
gr.Markdown("### Color Settings (Scroll Effect)")
|
| 221 |
scroll_background_color = gr.ColorPicker(label="Background Color", value="#000000")
|
| 222 |
scroll_title_color = gr.ColorPicker(label="Title Color", value="#FFFFFF")
|
| 223 |
+
scroll_section_title_color = gr.ColorPicker(label="Section Title Color", value="#FFFFFF")
|
| 224 |
scroll_name_color = gr.ColorPicker(label="Name Color", value="#FFFFFF")
|
| 225 |
|
| 226 |
+
panel = CreditsPanel(
|
| 227 |
+
height=500,
|
| 228 |
credits=credits_list,
|
| 229 |
licenses=license_paths,
|
| 230 |
effect="scroll",
|
|
|
|
| 231 |
speed=DEFAULT_SPEEDS["scroll"],
|
| 232 |
base_font_size=1.5,
|
| 233 |
intro_title="Gradio",
|
| 234 |
intro_subtitle="The best UI framework",
|
| 235 |
sidebar_position="right",
|
| 236 |
+
logo_path=LOGO_PATH,
|
| 237 |
show_logo=True,
|
| 238 |
show_licenses=True,
|
| 239 |
show_credits=True,
|
|
|
|
| 244 |
scroll_background_color="#000000",
|
| 245 |
scroll_title_color="#FFFFFF",
|
| 246 |
scroll_name_color="#FFFFFF",
|
| 247 |
+
scroll_section_title_color="#FFFFFF",
|
| 248 |
layout_style="stacked",
|
| 249 |
title_uppercase=False,
|
| 250 |
name_uppercase=False,
|
| 251 |
section_title_uppercase=True,
|
| 252 |
swap_font_sizes_on_two_column=False,
|
| 253 |
+
scroll_logo_path=SCROLL_LOGO_PATH,
|
| 254 |
+
scroll_logo_height="100px",
|
| 255 |
)
|
| 256 |
|
| 257 |
inputs = [
|
|
|
|
| 269 |
logo_width_input,
|
| 270 |
logo_height_input,
|
| 271 |
scroll_background_color,
|
| 272 |
+
scroll_title_color,
|
| 273 |
+
scroll_section_title_color,
|
| 274 |
scroll_name_color,
|
| 275 |
layout_style_radio,
|
| 276 |
title_uppercase_checkbox,
|
| 277 |
name_uppercase_checkbox,
|
| 278 |
section_title_uppercase_checkbox,
|
| 279 |
+
swap_sizes_checkbox,
|
| 280 |
+
show_scroll_logo_checkbox,
|
| 281 |
+
scroll_logo_height_input
|
| 282 |
]
|
| 283 |
|
| 284 |
+
demo.load(
|
| 285 |
+
fn=update_panel,
|
| 286 |
+
inputs=inputs,
|
| 287 |
+
outputs=panel
|
| 288 |
+
)
|
| 289 |
layout_style_radio.change(
|
| 290 |
fn=toggle_swap_checkbox_visibility,
|
| 291 |
inputs=layout_style_radio,
|
|
|
|
| 329 |
|
| 330 |
The code snippet below is accurate in cases where the component is used as both an input and an output.
|
| 331 |
|
|
|
|
| 332 |
|
| 333 |
|
| 334 |
```python
|
|
|
|
| 336 |
value: typing.Optional[typing.Dict[str, typing.Any]][
|
| 337 |
typing.Dict[str, typing.Any][str, Any], None
|
| 338 |
]
|
| 339 |
+
) -> typing.Optional[typing.Dict[str, typing.Any]][
|
| 340 |
+
typing.Dict[str, typing.Any][str, Any], None
|
| 341 |
+
]:
|
| 342 |
return value
|
| 343 |
```
|
| 344 |
""", elem_classes=["md-custom", "CreditsPanel-user-fn"], header_links=True)
|
src/frontend/Index.svelte
CHANGED
|
@@ -29,6 +29,7 @@
|
|
| 29 |
* @property {number | string | null} logo_height - Logo height.
|
| 30 |
* @property {string | null} scroll_background_color - Scroll effect background color.
|
| 31 |
* @property {string | null} scroll_title_color - Credit title color.
|
|
|
|
| 32 |
* @property {string | null} scroll_name_color - Credit name color.
|
| 33 |
* @property {number} title_font_size - Title font size (unused in StarWarsEffect).
|
| 34 |
* @property {number} name_font_size - Name font size (unused in StarWarsEffect).
|
|
@@ -37,6 +38,8 @@
|
|
| 37 |
* @property {boolean} name_uppercase - Transform name to uppercase.
|
| 38 |
* @property {boolean} section_title_uppercase - Transform section title to uppercase.
|
| 39 |
* @property {boolean} swap_font_sizes_on_two_column - Swap title/name font sizes in two-column layout.
|
|
|
|
|
|
|
| 40 |
*/
|
| 41 |
export let value: Value | null = null;
|
| 42 |
export let elem_id = "";
|
|
@@ -77,12 +80,15 @@
|
|
| 77 |
logo_height: null,
|
| 78 |
scroll_background_color: null,
|
| 79 |
scroll_title_color: null,
|
|
|
|
| 80 |
scroll_name_color: null,
|
| 81 |
layout_style: "stacked",
|
| 82 |
title_uppercase: false,
|
| 83 |
name_uppercase: false,
|
| 84 |
section_title_uppercase: true,
|
| 85 |
swap_font_sizes_on_two_column: false,
|
|
|
|
|
|
|
| 86 |
};
|
| 87 |
|
| 88 |
// Tracks selected license for display
|
|
@@ -211,9 +217,12 @@
|
|
| 211 |
name_color={effectiveValue.scroll_name_color}
|
| 212 |
layout_style={effectiveValue.layout_style}
|
| 213 |
title_uppercase={effectiveValue.title_uppercase}
|
|
|
|
| 214 |
name_uppercase={effectiveValue.name_uppercase}
|
| 215 |
section_title_uppercase={effectiveValue.section_title_uppercase}
|
| 216 |
swap_font_sizes_on_two_column={effectiveValue.swap_font_sizes_on_two_column}
|
|
|
|
|
|
|
| 217 |
/>
|
| 218 |
{:else if effectiveValue.effect === "starwars"}
|
| 219 |
<StarWarsEffect
|
|
@@ -227,6 +236,8 @@
|
|
| 227 |
name_uppercase={effectiveValue.name_uppercase}
|
| 228 |
section_title_uppercase={effectiveValue.section_title_uppercase}
|
| 229 |
swap_font_sizes_on_two_column={effectiveValue.swap_font_sizes_on_two_column}
|
|
|
|
|
|
|
| 230 |
/>
|
| 231 |
{:else if effectiveValue.effect === "matrix"}
|
| 232 |
<MatrixEffect
|
|
@@ -240,6 +251,8 @@
|
|
| 240 |
name_uppercase={effectiveValue.name_uppercase}
|
| 241 |
section_title_uppercase={effectiveValue.section_title_uppercase}
|
| 242 |
swap_font_sizes_on_two_column={effectiveValue.swap_font_sizes_on_two_column}
|
|
|
|
|
|
|
| 243 |
/>
|
| 244 |
{/if}
|
| 245 |
</div>
|
|
|
|
| 29 |
* @property {number | string | null} logo_height - Logo height.
|
| 30 |
* @property {string | null} scroll_background_color - Scroll effect background color.
|
| 31 |
* @property {string | null} scroll_title_color - Credit title color.
|
| 32 |
+
* @property {string | null} scroll_section_title_color - Section title color.
|
| 33 |
* @property {string | null} scroll_name_color - Credit name color.
|
| 34 |
* @property {number} title_font_size - Title font size (unused in StarWarsEffect).
|
| 35 |
* @property {number} name_font_size - Name font size (unused in StarWarsEffect).
|
|
|
|
| 38 |
* @property {boolean} name_uppercase - Transform name to uppercase.
|
| 39 |
* @property {boolean} section_title_uppercase - Transform section title to uppercase.
|
| 40 |
* @property {boolean} swap_font_sizes_on_two_column - Swap title/name font sizes in two-column layout.
|
| 41 |
+
* @property {{path: string | null, url: string | null, ...} | null} scroll_logo_path - Logo to display inside the scroll.
|
| 42 |
+
* @property {string} scroll_logo_height - Height of the scrolling logo.
|
| 43 |
*/
|
| 44 |
export let value: Value | null = null;
|
| 45 |
export let elem_id = "";
|
|
|
|
| 80 |
logo_height: null,
|
| 81 |
scroll_background_color: null,
|
| 82 |
scroll_title_color: null,
|
| 83 |
+
scroll_section_title_color: null,
|
| 84 |
scroll_name_color: null,
|
| 85 |
layout_style: "stacked",
|
| 86 |
title_uppercase: false,
|
| 87 |
name_uppercase: false,
|
| 88 |
section_title_uppercase: true,
|
| 89 |
swap_font_sizes_on_two_column: false,
|
| 90 |
+
scroll_logo_path: null,
|
| 91 |
+
scroll_logo_height: "120px",
|
| 92 |
};
|
| 93 |
|
| 94 |
// Tracks selected license for display
|
|
|
|
| 217 |
name_color={effectiveValue.scroll_name_color}
|
| 218 |
layout_style={effectiveValue.layout_style}
|
| 219 |
title_uppercase={effectiveValue.title_uppercase}
|
| 220 |
+
scroll_section_title_color={effectiveValue.scroll_section_title_color}
|
| 221 |
name_uppercase={effectiveValue.name_uppercase}
|
| 222 |
section_title_uppercase={effectiveValue.section_title_uppercase}
|
| 223 |
swap_font_sizes_on_two_column={effectiveValue.swap_font_sizes_on_two_column}
|
| 224 |
+
scroll_logo_path={effectiveValue.scroll_logo_path}
|
| 225 |
+
scroll_logo_height={effectiveValue.scroll_logo_height}
|
| 226 |
/>
|
| 227 |
{:else if effectiveValue.effect === "starwars"}
|
| 228 |
<StarWarsEffect
|
|
|
|
| 236 |
name_uppercase={effectiveValue.name_uppercase}
|
| 237 |
section_title_uppercase={effectiveValue.section_title_uppercase}
|
| 238 |
swap_font_sizes_on_two_column={effectiveValue.swap_font_sizes_on_two_column}
|
| 239 |
+
scroll_logo_path={effectiveValue.scroll_logo_path}
|
| 240 |
+
scroll_logo_height={effectiveValue.scroll_logo_height}
|
| 241 |
/>
|
| 242 |
{:else if effectiveValue.effect === "matrix"}
|
| 243 |
<MatrixEffect
|
|
|
|
| 251 |
name_uppercase={effectiveValue.name_uppercase}
|
| 252 |
section_title_uppercase={effectiveValue.section_title_uppercase}
|
| 253 |
swap_font_sizes_on_two_column={effectiveValue.swap_font_sizes_on_two_column}
|
| 254 |
+
scroll_logo_path={effectiveValue.scroll_logo_path}
|
| 255 |
+
scroll_logo_height={effectiveValue.scroll_logo_height}
|
| 256 |
/>
|
| 257 |
{/if}
|
| 258 |
</div>
|
src/frontend/shared/MatrixEffect.svelte
CHANGED
|
@@ -14,6 +14,8 @@
|
|
| 14 |
* @property {boolean} name_uppercase - Transform name to uppercase.
|
| 15 |
* @property {boolean} section_title_uppercase - Transform section title to uppercase.
|
| 16 |
* @property {boolean} swap_font_sizes_on_two_column - Swap title/name font sizes.
|
|
|
|
|
|
|
| 17 |
*/
|
| 18 |
export let credits: Props["credits"];
|
| 19 |
export let speed: number = 20;
|
|
@@ -25,6 +27,8 @@
|
|
| 25 |
export let name_uppercase: boolean = false;
|
| 26 |
export let section_title_uppercase: boolean = true;
|
| 27 |
export let swap_font_sizes_on_two_column: boolean = false;
|
|
|
|
|
|
|
| 28 |
|
| 29 |
// Combines intro and credits for display
|
| 30 |
$: display_items = (() => {
|
|
@@ -142,6 +146,11 @@
|
|
| 142 |
bind:this={contentElement}
|
| 143 |
style="--animation-duration: {speed}s;"
|
| 144 |
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 145 |
{#each display_items as item}
|
| 146 |
<!-- Render Section Title -->
|
| 147 |
{#if item.section_title}
|
|
@@ -305,4 +314,16 @@
|
|
| 305 |
text-align: left;
|
| 306 |
padding-left: 1em;
|
| 307 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 308 |
</style>
|
|
|
|
| 14 |
* @property {boolean} name_uppercase - Transform name to uppercase.
|
| 15 |
* @property {boolean} section_title_uppercase - Transform section title to uppercase.
|
| 16 |
* @property {boolean} swap_font_sizes_on_two_column - Swap title/name font sizes.
|
| 17 |
+
* @property {{path: string | null, url: string | null, ...} | null} scroll_logo_path - Logo to display inside the scroll.
|
| 18 |
+
* @property {string} scroll_logo_height - Height of the scrolling logo.
|
| 19 |
*/
|
| 20 |
export let credits: Props["credits"];
|
| 21 |
export let speed: number = 20;
|
|
|
|
| 27 |
export let name_uppercase: boolean = false;
|
| 28 |
export let section_title_uppercase: boolean = true;
|
| 29 |
export let swap_font_sizes_on_two_column: boolean = false;
|
| 30 |
+
export let scroll_logo_path: { url: string | null } | null = null;
|
| 31 |
+
export let scroll_logo_height: string = "120px";
|
| 32 |
|
| 33 |
// Combines intro and credits for display
|
| 34 |
$: display_items = (() => {
|
|
|
|
| 146 |
bind:this={contentElement}
|
| 147 |
style="--animation-duration: {speed}s;"
|
| 148 |
>
|
| 149 |
+
{#if scroll_logo_path?.url}
|
| 150 |
+
<div class="scroll-logo-container">
|
| 151 |
+
<img src={scroll_logo_path.url} alt="Scrolling Logo" style:height={scroll_logo_height} />
|
| 152 |
+
</div>
|
| 153 |
+
{/if}
|
| 154 |
{#each display_items as item}
|
| 155 |
<!-- Render Section Title -->
|
| 156 |
{#if item.section_title}
|
|
|
|
| 314 |
text-align: left;
|
| 315 |
padding-left: 1em;
|
| 316 |
}
|
| 317 |
+
.scroll-logo-container {
|
| 318 |
+
text-align: center;
|
| 319 |
+
margin-bottom: 2rem;
|
| 320 |
+
}
|
| 321 |
+
.scroll-logo-container img {
|
| 322 |
+
display: block;
|
| 323 |
+
margin-left: auto;
|
| 324 |
+
margin-right: auto;
|
| 325 |
+
max-width: 80%;
|
| 326 |
+
object-fit: contain;
|
| 327 |
+
filter: grayscale(1) brightness(0.5) sepia(100%) hue-rotate(50deg) saturate(500%);
|
| 328 |
+
}
|
| 329 |
</style>
|
src/frontend/shared/ScrollEffect.svelte
CHANGED
|
@@ -7,6 +7,7 @@
|
|
| 7 |
* @property {number} base_font_size - Base font size in rem (default: 1.5).
|
| 8 |
* @property {string | null} background_color - Background color (default: black).
|
| 9 |
* @property {string | null} title_color - Title text color (default: white).
|
|
|
|
| 10 |
* @property {string | null} name_color - Name text color (default: white).
|
| 11 |
* @property {string | null} intro_title - Optional intro title.
|
| 12 |
* @property {string | null} intro_subtitle - Optional intro subtitle.
|
|
@@ -15,12 +16,16 @@
|
|
| 15 |
* @property {boolean} name_uppercase - Transform name to uppercase.
|
| 16 |
* @property {boolean} section_title_uppercase - Transform section title to uppercase.
|
| 17 |
* @property {boolean} swap_font_sizes_on_two_column - Swap title/name font sizes.
|
|
|
|
|
|
|
|
|
|
| 18 |
*/
|
| 19 |
export let credits: Props['credits'];
|
| 20 |
export let speed: number;
|
| 21 |
export let base_font_size: number = 1.5;
|
| 22 |
export let background_color: string | null = null;
|
| 23 |
export let title_color: string | null = null;
|
|
|
|
| 24 |
export let name_color: string | null = null;
|
| 25 |
export let intro_title: string | null = null;
|
| 26 |
export let intro_subtitle: string | null = null;
|
|
@@ -29,6 +34,8 @@
|
|
| 29 |
export let name_uppercase: boolean = false;
|
| 30 |
export let section_title_uppercase: boolean = true;
|
| 31 |
export let swap_font_sizes_on_two_column: boolean = false;
|
|
|
|
|
|
|
| 32 |
|
| 33 |
// Flag to trigger animation reset
|
| 34 |
let reset = false;
|
|
@@ -48,8 +55,8 @@
|
|
| 48 |
|
| 49 |
// Reactive styles for title and name
|
| 50 |
$: title_style = (is_intro: boolean) => `color: ${title_color || 'white'}; font-size: ${is_intro ? base_font_size * 1.5 : base_font_size}rem;`;
|
| 51 |
-
$: name_style = (is_intro: boolean) => `color: ${name_color || 'white'}; font-size: ${is_intro ? base_font_size * 0.9 : base_font_size * 0.8}rem;`;
|
| 52 |
-
$: section_title_style = `color: ${title_color || 'white'}; font-size: ${base_font_size * 1.2}rem;`;
|
| 53 |
|
| 54 |
// Reset animation on prop changes
|
| 55 |
function resetAnimation() {
|
|
@@ -64,6 +71,11 @@
|
|
| 64 |
<div class="wrapper" style:--animation-duration="{speed}s" style:background={background_color || 'black'}>
|
| 65 |
{#if !reset}
|
| 66 |
<div class="credits-container">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
{#each display_items as item}
|
| 68 |
<!-- Render Section Title -->
|
| 69 |
{#if item.section_title}
|
|
@@ -108,6 +120,17 @@
|
|
| 108 |
position: relative;
|
| 109 |
font-family: sans-serif;
|
| 110 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
|
| 112 |
/* Animated container holding all credit items */
|
| 113 |
.credits-container {
|
|
|
|
| 7 |
* @property {number} base_font_size - Base font size in rem (default: 1.5).
|
| 8 |
* @property {string | null} background_color - Background color (default: black).
|
| 9 |
* @property {string | null} title_color - Title text color (default: white).
|
| 10 |
+
* @property {string | null} scroll_section_title_color - Section title color.
|
| 11 |
* @property {string | null} name_color - Name text color (default: white).
|
| 12 |
* @property {string | null} intro_title - Optional intro title.
|
| 13 |
* @property {string | null} intro_subtitle - Optional intro subtitle.
|
|
|
|
| 16 |
* @property {boolean} name_uppercase - Transform name to uppercase.
|
| 17 |
* @property {boolean} section_title_uppercase - Transform section title to uppercase.
|
| 18 |
* @property {boolean} swap_font_sizes_on_two_column - Swap title/name font sizes.
|
| 19 |
+
* @property {{path: string | null, url: string | null, ...} | null} scroll_logo_path - Logo to display inside the scroll.
|
| 20 |
+
* @property {string} scroll_logo_height - Height of the scrolling logo.
|
| 21 |
+
*
|
| 22 |
*/
|
| 23 |
export let credits: Props['credits'];
|
| 24 |
export let speed: number;
|
| 25 |
export let base_font_size: number = 1.5;
|
| 26 |
export let background_color: string | null = null;
|
| 27 |
export let title_color: string | null = null;
|
| 28 |
+
export let scroll_section_title_color: string | null = null;
|
| 29 |
export let name_color: string | null = null;
|
| 30 |
export let intro_title: string | null = null;
|
| 31 |
export let intro_subtitle: string | null = null;
|
|
|
|
| 34 |
export let name_uppercase: boolean = false;
|
| 35 |
export let section_title_uppercase: boolean = true;
|
| 36 |
export let swap_font_sizes_on_two_column: boolean = false;
|
| 37 |
+
export let scroll_logo_path: { url: string | null } | null = null;
|
| 38 |
+
export let scroll_logo_height: string = "120px";
|
| 39 |
|
| 40 |
// Flag to trigger animation reset
|
| 41 |
let reset = false;
|
|
|
|
| 55 |
|
| 56 |
// Reactive styles for title and name
|
| 57 |
$: title_style = (is_intro: boolean) => `color: ${title_color || 'white'}; font-size: ${is_intro ? base_font_size * 1.5 : base_font_size}rem;`;
|
| 58 |
+
$: name_style = (is_intro: boolean) => `color: ${name_color || 'white'}; font-size: ${is_intro ? base_font_size * 0.9 : base_font_size * 0.8}rem;`;
|
| 59 |
+
$: section_title_style = `color: ${scroll_section_title_color || title_color || 'white'}; font-size: ${base_font_size * 1.2}rem;`;
|
| 60 |
|
| 61 |
// Reset animation on prop changes
|
| 62 |
function resetAnimation() {
|
|
|
|
| 71 |
<div class="wrapper" style:--animation-duration="{speed}s" style:background={background_color || 'black'}>
|
| 72 |
{#if !reset}
|
| 73 |
<div class="credits-container">
|
| 74 |
+
{#if scroll_logo_path?.url}
|
| 75 |
+
<div class="scroll-logo-container" style:height={scroll_logo_height}>
|
| 76 |
+
<img src={scroll_logo_path.url} alt="Scrolling Logo" style:height={scroll_logo_height} />
|
| 77 |
+
</div>
|
| 78 |
+
{/if}
|
| 79 |
{#each display_items as item}
|
| 80 |
<!-- Render Section Title -->
|
| 81 |
{#if item.section_title}
|
|
|
|
| 120 |
position: relative;
|
| 121 |
font-family: sans-serif;
|
| 122 |
}
|
| 123 |
+
.scroll-logo-container {
|
| 124 |
+
text-align: center;
|
| 125 |
+
margin-bottom: 2rem; /* Space between logo and intro text */
|
| 126 |
+
}
|
| 127 |
+
.scroll-logo-container img {
|
| 128 |
+
display: block;
|
| 129 |
+
margin-left: auto;
|
| 130 |
+
margin-right: auto;
|
| 131 |
+
max-width: 80%;
|
| 132 |
+
object-fit: contain;
|
| 133 |
+
}
|
| 134 |
|
| 135 |
/* Animated container holding all credit items */
|
| 136 |
.credits-container {
|
src/frontend/shared/StarWarsEffect.svelte
CHANGED
|
@@ -19,6 +19,8 @@
|
|
| 19 |
* @property {boolean} name_uppercase - Transform name to uppercase.
|
| 20 |
* @property {boolean} section_title_uppercase - Transform section title to uppercase.
|
| 21 |
* @property {boolean} swap_font_sizes_on_two_column - Swap title/name font sizes.
|
|
|
|
|
|
|
| 22 |
*/
|
| 23 |
export let credits: Props['credits'];
|
| 24 |
export let speed: number = 40;
|
|
@@ -33,6 +35,8 @@
|
|
| 33 |
export let name_uppercase: boolean = false;
|
| 34 |
export let section_title_uppercase: boolean = true;
|
| 35 |
export let swap_font_sizes_on_two_column: boolean = false;
|
|
|
|
|
|
|
| 36 |
|
| 37 |
// Reactive styles
|
| 38 |
$: title_style = (is_intro: boolean) => `color: ${title_color || '#feda4a'}; font-size: ${is_intro ? base_font_size * 1.5 : base_font_size}rem;`;
|
|
@@ -84,6 +88,11 @@
|
|
| 84 |
<div class="stars large" style="box-shadow: {large_stars};"></div>
|
| 85 |
|
| 86 |
<div class="crawl" bind:this={crawlElement} style="--animation-duration: {speed}s;">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
{#each display_items as item}
|
| 88 |
<!-- Render Section Title -->
|
| 89 |
{#if item.section_title}
|
|
@@ -112,6 +121,7 @@
|
|
| 112 |
</div>
|
| 113 |
|
| 114 |
<style>
|
|
|
|
| 115 |
.viewport {
|
| 116 |
width: 100%;
|
| 117 |
height: 100%;
|
|
@@ -146,6 +156,18 @@
|
|
| 146 |
}
|
| 147 |
|
| 148 |
/* STYLES */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
.uppercase { text-transform: uppercase; }
|
| 150 |
|
| 151 |
.section-title {
|
|
|
|
| 19 |
* @property {boolean} name_uppercase - Transform name to uppercase.
|
| 20 |
* @property {boolean} section_title_uppercase - Transform section title to uppercase.
|
| 21 |
* @property {boolean} swap_font_sizes_on_two_column - Swap title/name font sizes.
|
| 22 |
+
* @property {{path: string | null, url: string | null, ...} | null} scroll_logo_path - Logo to display inside the scroll.
|
| 23 |
+
* @property {string} scroll_logo_height - Height of the scrolling logo.
|
| 24 |
*/
|
| 25 |
export let credits: Props['credits'];
|
| 26 |
export let speed: number = 40;
|
|
|
|
| 35 |
export let name_uppercase: boolean = false;
|
| 36 |
export let section_title_uppercase: boolean = true;
|
| 37 |
export let swap_font_sizes_on_two_column: boolean = false;
|
| 38 |
+
export let scroll_logo_path: { url: string | null } | null = null;
|
| 39 |
+
export let scroll_logo_height: string = "120px";
|
| 40 |
|
| 41 |
// Reactive styles
|
| 42 |
$: title_style = (is_intro: boolean) => `color: ${title_color || '#feda4a'}; font-size: ${is_intro ? base_font_size * 1.5 : base_font_size}rem;`;
|
|
|
|
| 88 |
<div class="stars large" style="box-shadow: {large_stars};"></div>
|
| 89 |
|
| 90 |
<div class="crawl" bind:this={crawlElement} style="--animation-duration: {speed}s;">
|
| 91 |
+
{#if scroll_logo_path?.url}
|
| 92 |
+
<div class="scroll-logo-container">
|
| 93 |
+
<img src={scroll_logo_path.url} alt="Scrolling Logo" style:height={scroll_logo_height} />
|
| 94 |
+
</div>
|
| 95 |
+
{/if}
|
| 96 |
{#each display_items as item}
|
| 97 |
<!-- Render Section Title -->
|
| 98 |
{#if item.section_title}
|
|
|
|
| 121 |
</div>
|
| 122 |
|
| 123 |
<style>
|
| 124 |
+
|
| 125 |
.viewport {
|
| 126 |
width: 100%;
|
| 127 |
height: 100%;
|
|
|
|
| 156 |
}
|
| 157 |
|
| 158 |
/* STYLES */
|
| 159 |
+
.scroll-logo-container {
|
| 160 |
+
text-align: center;
|
| 161 |
+
margin-bottom: 2rem;
|
| 162 |
+
}
|
| 163 |
+
.scroll-logo-container img {
|
| 164 |
+
display: block;
|
| 165 |
+
margin-left: auto;
|
| 166 |
+
margin-right: auto;
|
| 167 |
+
max-width: 70%;
|
| 168 |
+
object-fit: contain;
|
| 169 |
+
filter: grayscale(1) sepia(100%) hue-rotate(15deg) saturate(8) brightness(1.2);
|
| 170 |
+
}
|
| 171 |
.uppercase { text-transform: uppercase; }
|
| 172 |
|
| 173 |
.section-title {
|
src/pyproject.toml
CHANGED
|
@@ -8,7 +8,7 @@ build-backend = "hatchling.build"
|
|
| 8 |
|
| 9 |
[project]
|
| 10 |
name = "gradio_creditspanel"
|
| 11 |
-
version = "0.0.
|
| 12 |
description = "Credits Panel for Gradio UI"
|
| 13 |
readme = "README.md"
|
| 14 |
license = "apache-2.0"
|
|
|
|
| 8 |
|
| 9 |
[project]
|
| 10 |
name = "gradio_creditspanel"
|
| 11 |
+
version = "0.0.4"
|
| 12 |
description = "Credits Panel for Gradio UI"
|
| 13 |
readme = "README.md"
|
| 14 |
license = "apache-2.0"
|