elismasilva commited on
Commit
381625b
·
verified ·
1 Parent(s): 9e06ad8

Upload folder using huggingface_hub

Browse files
README.md CHANGED
@@ -10,7 +10,7 @@ app_file: space.py
10
  ---
11
 
12
  # `gradio_propertysheet`
13
- <img alt="Static Badge" src="https://img.shields.io/badge/version%20-%200.0.12%20-%20blue"> <a href="https://huggingface.co/spaces/elismasilva/gradio_propertysheet"><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_propertysheet'>Component GitHub Code</a></span></p>
14
 
15
  The **PropertySheet** component for Gradio allows you to automatically generate a complete and interactive settings panel from a standard Python `dataclass`. It's designed to bring the power of IDE-like property editors directly into your Gradio applications.
16
 
@@ -57,41 +57,126 @@ from gradio_htmlinjector import HTMLInjector
57
 
58
  # --- 1. Dataclass Definitions (unchanged) ---
59
  @dataclass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  class ModelSettings:
61
  model_type: Literal["SD 1.5", "SDXL", "Pony", "Custom"] = field(
62
- default="SDXL", metadata={"component": "dropdown", "label": "Base Model"}
 
 
 
 
 
63
  )
64
  custom_model_path: str = field(
65
  default="/path/to/default.safetensors",
66
  metadata={
67
  "label": "Custom Model Path",
68
  "interactive_if": {"field": "model_type", "value": "Custom"},
 
69
  },
70
  )
71
- vae_path: str = field(default="", metadata={"label": "VAE Path (optional)"})
72
-
 
 
 
 
 
73
 
74
  @dataclass
75
  class SamplingSettings:
76
  scheduler: Literal["Karras", "Simple", "Exponential"] = field(
77
  default="Karras",
78
- metadata={"component": "radio", "label": "Scheduler"}
 
 
 
 
79
  )
80
  sampler_name: Literal["Euler", "Euler a", "DPM++ 2M Karras", "UniPC"] = field(
81
  default="DPM++ 2M Karras",
82
- metadata={"component": "dropdown", "label": "Sampler"},
 
 
 
 
83
  )
84
  steps: int = field(
85
  default=25,
86
- metadata={"component": "slider", "minimum": 1, "maximum": 150, "step": 1},
 
 
 
 
 
 
 
87
  )
88
  cfg_scale: float = field(
89
  default=7.0,
90
- metadata={"component": "slider", "minimum": 1.0, "maximum": 30.0, "step": 0.5},
 
 
 
 
 
 
 
91
  )
92
  enable_advanced: bool = field(
93
  default=False,
94
- metadata={"label": "Enable Advanced Settings"}
 
 
 
95
  )
96
  advanced_option: float = field(
97
  default=0.5,
@@ -102,6 +187,7 @@ class SamplingSettings:
102
  "maximum": 1.0,
103
  "step": 0.01,
104
  "interactive_if": {"field": "enable_advanced", "value": True},
 
105
  },
106
  )
107
  temperature: float = field(
@@ -111,54 +197,106 @@ class SamplingSettings:
111
  "component": "number_float",
112
  "minimum": 0.1,
113
  "maximum": 2.0,
114
- "step": 0.1
 
115
  }
116
  )
117
 
118
  @dataclass
119
  class RenderConfig:
120
- randomize_seed: bool = field(default=True, metadata={"label": "Randomize Seed"})
 
 
 
 
 
 
 
 
 
 
121
  seed: int = field(
122
  default=-1,
123
- metadata={"component": "number_integer", "label": "Seed (-1 for random)"},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  )
125
- model: ModelSettings = field(default_factory=ModelSettings, metadata={"label": "Model Settings"})
126
- sampling: SamplingSettings = field(default_factory=SamplingSettings)
127
 
128
  @dataclass
129
  class Lighting:
130
  sun_intensity: float = field(
131
  default=1.0,
132
- metadata={"component": "slider", "minimum": 0, "maximum": 5, "step": 0.1},
 
 
 
 
 
 
 
133
  )
134
  color: str = field(
135
- default="#FFDDBB", metadata={"component": "colorpicker", "label": "Sun Color"}
 
 
 
 
 
136
  )
137
 
138
-
139
  @dataclass
140
  class EnvironmentConfig:
141
  background: Literal["Sky", "Color", "Image"] = field(
142
- default="Sky", metadata={"component": "dropdown"}
 
 
 
 
 
 
 
 
 
143
  )
144
- lighting: Lighting = field(default_factory=Lighting)
145
-
146
 
147
  @dataclass
148
  class EulerSettings:
149
  s_churn: float = field(
150
  default=0.0,
151
- metadata={"component": "slider", "minimum": 0.0, "maximum": 1.0, "step": 0.01},
 
 
 
 
 
 
 
152
  )
153
 
154
-
155
  @dataclass
156
  class DPM_Settings:
157
  karras_style: bool = field(
158
- default=True, metadata={"label": "Use Karras Sigma Schedule"}
 
 
 
 
159
  )
160
 
161
-
162
  # --- 2. Data Mappings and Initial Instances (unchanged) ---
163
  initial_render_config = RenderConfig()
164
  initial_env_config = EnvironmentConfig()
 
10
  ---
11
 
12
  # `gradio_propertysheet`
13
+ <img alt="Static Badge" src="https://img.shields.io/badge/version%20-%200.0.13%20-%20blue"> <a href="https://huggingface.co/spaces/elismasilva/gradio_propertysheet"><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_propertysheet'>Component GitHub Code</a></span></p>
14
 
15
  The **PropertySheet** component for Gradio allows you to automatically generate a complete and interactive settings panel from a standard Python `dataclass`. It's designed to bring the power of IDE-like property editors directly into your Gradio applications.
16
 
 
57
 
58
  # --- 1. Dataclass Definitions (unchanged) ---
59
  @dataclass
60
+ class APISettings:
61
+ api_key: str = field(
62
+ default="ab123cd45ef67890ghij123klmno456p",
63
+ metadata={
64
+ "label": "API Key",
65
+ "component": "password",
66
+ "help": "Your secret API key. It will not be displayed."
67
+ }
68
+ )
69
+ endpoint_url: str = field(
70
+ default="https://api.example.com",
71
+ metadata={
72
+ "label": "API Endpoint",
73
+ "component": "string", # string normal
74
+ "help": "The URL of the API server."
75
+ }
76
+ )
77
+
78
+ @dataclass
79
+ class QuantizationSettings:
80
+ quantization_method: Literal["None", "Quanto Library", "Layerwise & Bnb"] = field(
81
+ default="Layerwise & Bnb",
82
+ metadata={
83
+ "component": "radio",
84
+ "label": "Quantization Method",
85
+ "help": "Quantization mechanism to save VRAM and increase speed."
86
+ }
87
+ )
88
+ # Option 1: Literal values
89
+ quantize_mode_list: Literal["FP8", "INT8", "IN4"] = field(
90
+ default="FP8",
91
+ metadata={
92
+ "interactive_if": {"field": "quantization_method", "value": ["Quanto Library", "Layerwise & Bnb"]},
93
+ "component": "radio",
94
+ "label": "Quantization Mode (List)",
95
+ "help": "This becomes interactive if Quantization Method is 'Quanto' OR 'Layerwise'."
96
+ }
97
+ )
98
+ # Option 2: neq operand
99
+ quantize_mode_neq: Literal["FP8", "INT8", "IN4"] = field(
100
+ default="FP8",
101
+ metadata={
102
+ "interactive_if": {"field": "quantization_method", "neq": "None"},
103
+ "component": "radio",
104
+ "label": "Quantization Mode (Not Equal)",
105
+ "help": "This becomes interactive if Quantization Method is NOT 'None'."
106
+ }
107
+ )
108
+ @dataclass
109
  class ModelSettings:
110
  model_type: Literal["SD 1.5", "SDXL", "Pony", "Custom"] = field(
111
+ default="SDXL",
112
+ metadata={
113
+ "component": "dropdown",
114
+ "label": "Base Model",
115
+ "help": "Select the base diffusion model."
116
+ }
117
  )
118
  custom_model_path: str = field(
119
  default="/path/to/default.safetensors",
120
  metadata={
121
  "label": "Custom Model Path",
122
  "interactive_if": {"field": "model_type", "value": "Custom"},
123
+ "help": "Provide the local file path to your custom .safetensors or .ckpt model file. This is only active when 'Base Model' is set to 'Custom'."
124
  },
125
  )
126
+ vae_path: str = field(
127
+ default="",
128
+ metadata={
129
+ "label": "VAE Path (optional)",
130
+ "help": "Optionally, provide a path to a separate VAE file to improve color and detail."
131
+ }
132
+ )
133
 
134
  @dataclass
135
  class SamplingSettings:
136
  scheduler: Literal["Karras", "Simple", "Exponential"] = field(
137
  default="Karras",
138
+ metadata={
139
+ "component": "radio",
140
+ "label": "Scheduler",
141
+ "help": "Determines how the noise schedule is interpreted during sampling. 'Karras' is often recommended for high-quality results."
142
+ }
143
  )
144
  sampler_name: Literal["Euler", "Euler a", "DPM++ 2M Karras", "UniPC"] = field(
145
  default="DPM++ 2M Karras",
146
+ metadata={
147
+ "component": "dropdown",
148
+ "label": "Sampler",
149
+ "help": "The algorithm used to denoise the image over multiple steps. Different samplers can produce stylistically different results."
150
+ }
151
  )
152
  steps: int = field(
153
  default=25,
154
+ metadata={
155
+ "component": "slider",
156
+ "label": "Sampling Steps",
157
+ "minimum": 1,
158
+ "maximum": 150,
159
+ "step": 1,
160
+ "help": "The number of denoising steps. More steps can increase detail but also take longer. Values between 20-40 are common."
161
+ }
162
  )
163
  cfg_scale: float = field(
164
  default=7.0,
165
+ metadata={
166
+ "component": "slider",
167
+ "label": "CFG Scale",
168
+ "minimum": 1.0,
169
+ "maximum": 30.0,
170
+ "step": 0.5,
171
+ "help": "Classifier-Free Guidance Scale. Higher values make the image adhere more strictly to the prompt, while lower values allow for more creativity."
172
+ }
173
  )
174
  enable_advanced: bool = field(
175
  default=False,
176
+ metadata={
177
+ "label": "Enable Advanced Settings",
178
+ "help": "Check this box to reveal more experimental or fine-tuning options."
179
+ }
180
  )
181
  advanced_option: float = field(
182
  default=0.5,
 
187
  "maximum": 1.0,
188
  "step": 0.01,
189
  "interactive_if": {"field": "enable_advanced", "value": True},
190
+ "help": "An example of an advanced setting that is only visible when the corresponding checkbox is enabled."
191
  },
192
  )
193
  temperature: float = field(
 
197
  "component": "number_float",
198
  "minimum": 0.1,
199
  "maximum": 2.0,
200
+ "step": 0.1,
201
+ "help": "Controls the randomness of the sampling process. A value of 1.0 is standard. Higher values increase diversity at the risk of artifacts."
202
  }
203
  )
204
 
205
  @dataclass
206
  class RenderConfig:
207
+ api_settings: APISettings = field(
208
+ default_factory=APISettings,
209
+ metadata={"label": "API Settings"}
210
+ )
211
+ randomize_seed: bool = field(
212
+ default=True,
213
+ metadata={
214
+ "label": "Randomize Seed",
215
+ "help": "If checked, a new random seed will be used for each generation. Uncheck to use the specific seed value below."
216
+ }
217
+ )
218
  seed: int = field(
219
  default=-1,
220
+ metadata={
221
+ "component": "number_integer",
222
+ "label": "Seed",
223
+ "help": "The seed for the random number generator. A value of -1 means a random seed will be chosen. The same seed and settings will produce the same image."
224
+ }
225
+ )
226
+ model: ModelSettings = field(
227
+ default_factory=ModelSettings,
228
+ metadata={"label": "Model Settings"}
229
+ )
230
+ sampling: SamplingSettings = field(
231
+ default_factory=SamplingSettings,
232
+ metadata={"label": "Sampling Settings"}
233
+ )
234
+ quantization: QuantizationSettings = field(
235
+ default_factory=QuantizationSettings,
236
+ metadata={"label": "Quantization Settings"}
237
  )
 
 
238
 
239
  @dataclass
240
  class Lighting:
241
  sun_intensity: float = field(
242
  default=1.0,
243
+ metadata={
244
+ "component": "slider",
245
+ "label": "Sun Intensity",
246
+ "minimum": 0,
247
+ "maximum": 5,
248
+ "step": 0.1,
249
+ "help": "Controls the brightness of the main light source in the scene."
250
+ }
251
  )
252
  color: str = field(
253
+ default="#FFDDBB",
254
+ metadata={
255
+ "component": "colorpicker",
256
+ "label": "Sun Color",
257
+ "help": "Sets the color of the main light source."
258
+ }
259
  )
260
 
 
261
  @dataclass
262
  class EnvironmentConfig:
263
  background: Literal["Sky", "Color", "Image"] = field(
264
+ default="Sky",
265
+ metadata={
266
+ "component": "dropdown",
267
+ "label": "Background Type",
268
+ "help": "Choose the type of background for the environment."
269
+ }
270
+ )
271
+ lighting: Lighting = field(
272
+ default_factory=Lighting,
273
+ metadata={"label": "Lighting"}
274
  )
 
 
275
 
276
  @dataclass
277
  class EulerSettings:
278
  s_churn: float = field(
279
  default=0.0,
280
+ metadata={
281
+ "component": "slider",
282
+ "label": "S_Churn",
283
+ "minimum": 0.0,
284
+ "maximum": 1.0,
285
+ "step": 0.01,
286
+ "help": "Stochasticity churn factor for Euler samplers. Adds extra noise at each step, affecting diversity. 0.0 is deterministic."
287
+ }
288
  )
289
 
 
290
  @dataclass
291
  class DPM_Settings:
292
  karras_style: bool = field(
293
+ default=True,
294
+ metadata={
295
+ "label": "Use Karras Sigma Schedule",
296
+ "help": "If checked, uses the Karras noise schedule, which is often recommended for DPM++ samplers to improve image quality, especially in later steps."
297
+ }
298
  )
299
 
 
300
  # --- 2. Data Mappings and Initial Instances (unchanged) ---
301
  initial_render_config = RenderConfig()
302
  initial_env_config = EnvironmentConfig()
app.py CHANGED
@@ -9,41 +9,126 @@ from gradio_htmlinjector import HTMLInjector
9
 
10
  # --- 1. Dataclass Definitions (unchanged) ---
11
  @dataclass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  class ModelSettings:
13
  model_type: Literal["SD 1.5", "SDXL", "Pony", "Custom"] = field(
14
- default="SDXL", metadata={"component": "dropdown", "label": "Base Model"}
 
 
 
 
 
15
  )
16
  custom_model_path: str = field(
17
  default="/path/to/default.safetensors",
18
  metadata={
19
  "label": "Custom Model Path",
20
  "interactive_if": {"field": "model_type", "value": "Custom"},
 
21
  },
22
  )
23
- vae_path: str = field(default="", metadata={"label": "VAE Path (optional)"})
24
-
 
 
 
 
 
25
 
26
  @dataclass
27
  class SamplingSettings:
28
  scheduler: Literal["Karras", "Simple", "Exponential"] = field(
29
  default="Karras",
30
- metadata={"component": "radio", "label": "Scheduler"}
 
 
 
 
31
  )
32
  sampler_name: Literal["Euler", "Euler a", "DPM++ 2M Karras", "UniPC"] = field(
33
  default="DPM++ 2M Karras",
34
- metadata={"component": "dropdown", "label": "Sampler"},
 
 
 
 
35
  )
36
  steps: int = field(
37
  default=25,
38
- metadata={"component": "slider", "minimum": 1, "maximum": 150, "step": 1},
 
 
 
 
 
 
 
39
  )
40
  cfg_scale: float = field(
41
  default=7.0,
42
- metadata={"component": "slider", "minimum": 1.0, "maximum": 30.0, "step": 0.5},
 
 
 
 
 
 
 
43
  )
44
  enable_advanced: bool = field(
45
  default=False,
46
- metadata={"label": "Enable Advanced Settings"}
 
 
 
47
  )
48
  advanced_option: float = field(
49
  default=0.5,
@@ -54,6 +139,7 @@ class SamplingSettings:
54
  "maximum": 1.0,
55
  "step": 0.01,
56
  "interactive_if": {"field": "enable_advanced", "value": True},
 
57
  },
58
  )
59
  temperature: float = field(
@@ -63,54 +149,106 @@ class SamplingSettings:
63
  "component": "number_float",
64
  "minimum": 0.1,
65
  "maximum": 2.0,
66
- "step": 0.1
 
67
  }
68
  )
69
 
70
  @dataclass
71
  class RenderConfig:
72
- randomize_seed: bool = field(default=True, metadata={"label": "Randomize Seed"})
 
 
 
 
 
 
 
 
 
 
73
  seed: int = field(
74
  default=-1,
75
- metadata={"component": "number_integer", "label": "Seed (-1 for random)"},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  )
77
- model: ModelSettings = field(default_factory=ModelSettings, metadata={"label": "Model Settings"})
78
- sampling: SamplingSettings = field(default_factory=SamplingSettings)
79
 
80
  @dataclass
81
  class Lighting:
82
  sun_intensity: float = field(
83
  default=1.0,
84
- metadata={"component": "slider", "minimum": 0, "maximum": 5, "step": 0.1},
 
 
 
 
 
 
 
85
  )
86
  color: str = field(
87
- default="#FFDDBB", metadata={"component": "colorpicker", "label": "Sun Color"}
 
 
 
 
 
88
  )
89
 
90
-
91
  @dataclass
92
  class EnvironmentConfig:
93
  background: Literal["Sky", "Color", "Image"] = field(
94
- default="Sky", metadata={"component": "dropdown"}
 
 
 
 
 
 
 
 
 
95
  )
96
- lighting: Lighting = field(default_factory=Lighting)
97
-
98
 
99
  @dataclass
100
  class EulerSettings:
101
  s_churn: float = field(
102
  default=0.0,
103
- metadata={"component": "slider", "minimum": 0.0, "maximum": 1.0, "step": 0.01},
 
 
 
 
 
 
 
104
  )
105
 
106
-
107
  @dataclass
108
  class DPM_Settings:
109
  karras_style: bool = field(
110
- default=True, metadata={"label": "Use Karras Sigma Schedule"}
 
 
 
 
111
  )
112
 
113
-
114
  # --- 2. Data Mappings and Initial Instances (unchanged) ---
115
  initial_render_config = RenderConfig()
116
  initial_env_config = EnvironmentConfig()
 
9
 
10
  # --- 1. Dataclass Definitions (unchanged) ---
11
  @dataclass
12
+ class APISettings:
13
+ api_key: str = field(
14
+ default="ab123cd45ef67890ghij123klmno456p",
15
+ metadata={
16
+ "label": "API Key",
17
+ "component": "password",
18
+ "help": "Your secret API key. It will not be displayed."
19
+ }
20
+ )
21
+ endpoint_url: str = field(
22
+ default="https://api.example.com",
23
+ metadata={
24
+ "label": "API Endpoint",
25
+ "component": "string", # string normal
26
+ "help": "The URL of the API server."
27
+ }
28
+ )
29
+
30
+ @dataclass
31
+ class QuantizationSettings:
32
+ quantization_method: Literal["None", "Quanto Library", "Layerwise & Bnb"] = field(
33
+ default="Layerwise & Bnb",
34
+ metadata={
35
+ "component": "radio",
36
+ "label": "Quantization Method",
37
+ "help": "Quantization mechanism to save VRAM and increase speed."
38
+ }
39
+ )
40
+ # Option 1: Literal values
41
+ quantize_mode_list: Literal["FP8", "INT8", "IN4"] = field(
42
+ default="FP8",
43
+ metadata={
44
+ "interactive_if": {"field": "quantization_method", "value": ["Quanto Library", "Layerwise & Bnb"]},
45
+ "component": "radio",
46
+ "label": "Quantization Mode (List)",
47
+ "help": "This becomes interactive if Quantization Method is 'Quanto' OR 'Layerwise'."
48
+ }
49
+ )
50
+ # Option 2: neq operand
51
+ quantize_mode_neq: Literal["FP8", "INT8", "IN4"] = field(
52
+ default="FP8",
53
+ metadata={
54
+ "interactive_if": {"field": "quantization_method", "neq": "None"},
55
+ "component": "radio",
56
+ "label": "Quantization Mode (Not Equal)",
57
+ "help": "This becomes interactive if Quantization Method is NOT 'None'."
58
+ }
59
+ )
60
+ @dataclass
61
  class ModelSettings:
62
  model_type: Literal["SD 1.5", "SDXL", "Pony", "Custom"] = field(
63
+ default="SDXL",
64
+ metadata={
65
+ "component": "dropdown",
66
+ "label": "Base Model",
67
+ "help": "Select the base diffusion model."
68
+ }
69
  )
70
  custom_model_path: str = field(
71
  default="/path/to/default.safetensors",
72
  metadata={
73
  "label": "Custom Model Path",
74
  "interactive_if": {"field": "model_type", "value": "Custom"},
75
+ "help": "Provide the local file path to your custom .safetensors or .ckpt model file. This is only active when 'Base Model' is set to 'Custom'."
76
  },
77
  )
78
+ vae_path: str = field(
79
+ default="",
80
+ metadata={
81
+ "label": "VAE Path (optional)",
82
+ "help": "Optionally, provide a path to a separate VAE file to improve color and detail."
83
+ }
84
+ )
85
 
86
  @dataclass
87
  class SamplingSettings:
88
  scheduler: Literal["Karras", "Simple", "Exponential"] = field(
89
  default="Karras",
90
+ metadata={
91
+ "component": "radio",
92
+ "label": "Scheduler",
93
+ "help": "Determines how the noise schedule is interpreted during sampling. 'Karras' is often recommended for high-quality results."
94
+ }
95
  )
96
  sampler_name: Literal["Euler", "Euler a", "DPM++ 2M Karras", "UniPC"] = field(
97
  default="DPM++ 2M Karras",
98
+ metadata={
99
+ "component": "dropdown",
100
+ "label": "Sampler",
101
+ "help": "The algorithm used to denoise the image over multiple steps. Different samplers can produce stylistically different results."
102
+ }
103
  )
104
  steps: int = field(
105
  default=25,
106
+ metadata={
107
+ "component": "slider",
108
+ "label": "Sampling Steps",
109
+ "minimum": 1,
110
+ "maximum": 150,
111
+ "step": 1,
112
+ "help": "The number of denoising steps. More steps can increase detail but also take longer. Values between 20-40 are common."
113
+ }
114
  )
115
  cfg_scale: float = field(
116
  default=7.0,
117
+ metadata={
118
+ "component": "slider",
119
+ "label": "CFG Scale",
120
+ "minimum": 1.0,
121
+ "maximum": 30.0,
122
+ "step": 0.5,
123
+ "help": "Classifier-Free Guidance Scale. Higher values make the image adhere more strictly to the prompt, while lower values allow for more creativity."
124
+ }
125
  )
126
  enable_advanced: bool = field(
127
  default=False,
128
+ metadata={
129
+ "label": "Enable Advanced Settings",
130
+ "help": "Check this box to reveal more experimental or fine-tuning options."
131
+ }
132
  )
133
  advanced_option: float = field(
134
  default=0.5,
 
139
  "maximum": 1.0,
140
  "step": 0.01,
141
  "interactive_if": {"field": "enable_advanced", "value": True},
142
+ "help": "An example of an advanced setting that is only visible when the corresponding checkbox is enabled."
143
  },
144
  )
145
  temperature: float = field(
 
149
  "component": "number_float",
150
  "minimum": 0.1,
151
  "maximum": 2.0,
152
+ "step": 0.1,
153
+ "help": "Controls the randomness of the sampling process. A value of 1.0 is standard. Higher values increase diversity at the risk of artifacts."
154
  }
155
  )
156
 
157
  @dataclass
158
  class RenderConfig:
159
+ api_settings: APISettings = field(
160
+ default_factory=APISettings,
161
+ metadata={"label": "API Settings"}
162
+ )
163
+ randomize_seed: bool = field(
164
+ default=True,
165
+ metadata={
166
+ "label": "Randomize Seed",
167
+ "help": "If checked, a new random seed will be used for each generation. Uncheck to use the specific seed value below."
168
+ }
169
+ )
170
  seed: int = field(
171
  default=-1,
172
+ metadata={
173
+ "component": "number_integer",
174
+ "label": "Seed",
175
+ "help": "The seed for the random number generator. A value of -1 means a random seed will be chosen. The same seed and settings will produce the same image."
176
+ }
177
+ )
178
+ model: ModelSettings = field(
179
+ default_factory=ModelSettings,
180
+ metadata={"label": "Model Settings"}
181
+ )
182
+ sampling: SamplingSettings = field(
183
+ default_factory=SamplingSettings,
184
+ metadata={"label": "Sampling Settings"}
185
+ )
186
+ quantization: QuantizationSettings = field(
187
+ default_factory=QuantizationSettings,
188
+ metadata={"label": "Quantization Settings"}
189
  )
 
 
190
 
191
  @dataclass
192
  class Lighting:
193
  sun_intensity: float = field(
194
  default=1.0,
195
+ metadata={
196
+ "component": "slider",
197
+ "label": "Sun Intensity",
198
+ "minimum": 0,
199
+ "maximum": 5,
200
+ "step": 0.1,
201
+ "help": "Controls the brightness of the main light source in the scene."
202
+ }
203
  )
204
  color: str = field(
205
+ default="#FFDDBB",
206
+ metadata={
207
+ "component": "colorpicker",
208
+ "label": "Sun Color",
209
+ "help": "Sets the color of the main light source."
210
+ }
211
  )
212
 
 
213
  @dataclass
214
  class EnvironmentConfig:
215
  background: Literal["Sky", "Color", "Image"] = field(
216
+ default="Sky",
217
+ metadata={
218
+ "component": "dropdown",
219
+ "label": "Background Type",
220
+ "help": "Choose the type of background for the environment."
221
+ }
222
+ )
223
+ lighting: Lighting = field(
224
+ default_factory=Lighting,
225
+ metadata={"label": "Lighting"}
226
  )
 
 
227
 
228
  @dataclass
229
  class EulerSettings:
230
  s_churn: float = field(
231
  default=0.0,
232
+ metadata={
233
+ "component": "slider",
234
+ "label": "S_Churn",
235
+ "minimum": 0.0,
236
+ "maximum": 1.0,
237
+ "step": 0.01,
238
+ "help": "Stochasticity churn factor for Euler samplers. Adds extra noise at each step, affecting diversity. 0.0 is deterministic."
239
+ }
240
  )
241
 
 
242
  @dataclass
243
  class DPM_Settings:
244
  karras_style: bool = field(
245
+ default=True,
246
+ metadata={
247
+ "label": "Use Karras Sigma Schedule",
248
+ "help": "If checked, uses the Karras noise schedule, which is often recommended for DPM++ samplers to improve image quality, especially in later steps."
249
+ }
250
  )
251
 
 
252
  # --- 2. Data Mappings and Initial Instances (unchanged) ---
253
  initial_render_config = RenderConfig()
254
  initial_env_config = EnvironmentConfig()
space.py CHANGED
@@ -49,41 +49,126 @@ from gradio_htmlinjector import HTMLInjector
49
 
50
  # --- 1. Dataclass Definitions (unchanged) ---
51
  @dataclass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  class ModelSettings:
53
  model_type: Literal["SD 1.5", "SDXL", "Pony", "Custom"] = field(
54
- default="SDXL", metadata={"component": "dropdown", "label": "Base Model"}
 
 
 
 
 
55
  )
56
  custom_model_path: str = field(
57
  default="/path/to/default.safetensors",
58
  metadata={
59
  "label": "Custom Model Path",
60
  "interactive_if": {"field": "model_type", "value": "Custom"},
 
61
  },
62
  )
63
- vae_path: str = field(default="", metadata={"label": "VAE Path (optional)"})
64
-
 
 
 
 
 
65
 
66
  @dataclass
67
  class SamplingSettings:
68
  scheduler: Literal["Karras", "Simple", "Exponential"] = field(
69
  default="Karras",
70
- metadata={"component": "radio", "label": "Scheduler"}
 
 
 
 
71
  )
72
  sampler_name: Literal["Euler", "Euler a", "DPM++ 2M Karras", "UniPC"] = field(
73
  default="DPM++ 2M Karras",
74
- metadata={"component": "dropdown", "label": "Sampler"},
 
 
 
 
75
  )
76
  steps: int = field(
77
  default=25,
78
- metadata={"component": "slider", "minimum": 1, "maximum": 150, "step": 1},
 
 
 
 
 
 
 
79
  )
80
  cfg_scale: float = field(
81
  default=7.0,
82
- metadata={"component": "slider", "minimum": 1.0, "maximum": 30.0, "step": 0.5},
 
 
 
 
 
 
 
83
  )
84
  enable_advanced: bool = field(
85
  default=False,
86
- metadata={"label": "Enable Advanced Settings"}
 
 
 
87
  )
88
  advanced_option: float = field(
89
  default=0.5,
@@ -94,6 +179,7 @@ class SamplingSettings:
94
  "maximum": 1.0,
95
  "step": 0.01,
96
  "interactive_if": {"field": "enable_advanced", "value": True},
 
97
  },
98
  )
99
  temperature: float = field(
@@ -103,54 +189,106 @@ class SamplingSettings:
103
  "component": "number_float",
104
  "minimum": 0.1,
105
  "maximum": 2.0,
106
- "step": 0.1
 
107
  }
108
  )
109
 
110
  @dataclass
111
  class RenderConfig:
112
- randomize_seed: bool = field(default=True, metadata={"label": "Randomize Seed"})
 
 
 
 
 
 
 
 
 
 
113
  seed: int = field(
114
  default=-1,
115
- metadata={"component": "number_integer", "label": "Seed (-1 for random)"},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  )
117
- model: ModelSettings = field(default_factory=ModelSettings, metadata={"label": "Model Settings"})
118
- sampling: SamplingSettings = field(default_factory=SamplingSettings)
119
 
120
  @dataclass
121
  class Lighting:
122
  sun_intensity: float = field(
123
  default=1.0,
124
- metadata={"component": "slider", "minimum": 0, "maximum": 5, "step": 0.1},
 
 
 
 
 
 
 
125
  )
126
  color: str = field(
127
- default="#FFDDBB", metadata={"component": "colorpicker", "label": "Sun Color"}
 
 
 
 
 
128
  )
129
 
130
-
131
  @dataclass
132
  class EnvironmentConfig:
133
  background: Literal["Sky", "Color", "Image"] = field(
134
- default="Sky", metadata={"component": "dropdown"}
 
 
 
 
 
 
 
 
 
135
  )
136
- lighting: Lighting = field(default_factory=Lighting)
137
-
138
 
139
  @dataclass
140
  class EulerSettings:
141
  s_churn: float = field(
142
  default=0.0,
143
- metadata={"component": "slider", "minimum": 0.0, "maximum": 1.0, "step": 0.01},
 
 
 
 
 
 
 
144
  )
145
 
146
-
147
  @dataclass
148
  class DPM_Settings:
149
  karras_style: bool = field(
150
- default=True, metadata={"label": "Use Karras Sigma Schedule"}
 
 
 
 
151
  )
152
 
153
-
154
  # --- 2. Data Mappings and Initial Instances (unchanged) ---
155
  initial_render_config = RenderConfig()
156
  initial_env_config = EnvironmentConfig()
 
49
 
50
  # --- 1. Dataclass Definitions (unchanged) ---
51
  @dataclass
52
+ class APISettings:
53
+ api_key: str = field(
54
+ default="ab123cd45ef67890ghij123klmno456p",
55
+ metadata={
56
+ "label": "API Key",
57
+ "component": "password",
58
+ "help": "Your secret API key. It will not be displayed."
59
+ }
60
+ )
61
+ endpoint_url: str = field(
62
+ default="https://api.example.com",
63
+ metadata={
64
+ "label": "API Endpoint",
65
+ "component": "string", # string normal
66
+ "help": "The URL of the API server."
67
+ }
68
+ )
69
+
70
+ @dataclass
71
+ class QuantizationSettings:
72
+ quantization_method: Literal["None", "Quanto Library", "Layerwise & Bnb"] = field(
73
+ default="Layerwise & Bnb",
74
+ metadata={
75
+ "component": "radio",
76
+ "label": "Quantization Method",
77
+ "help": "Quantization mechanism to save VRAM and increase speed."
78
+ }
79
+ )
80
+ # Option 1: Literal values
81
+ quantize_mode_list: Literal["FP8", "INT8", "IN4"] = field(
82
+ default="FP8",
83
+ metadata={
84
+ "interactive_if": {"field": "quantization_method", "value": ["Quanto Library", "Layerwise & Bnb"]},
85
+ "component": "radio",
86
+ "label": "Quantization Mode (List)",
87
+ "help": "This becomes interactive if Quantization Method is 'Quanto' OR 'Layerwise'."
88
+ }
89
+ )
90
+ # Option 2: neq operand
91
+ quantize_mode_neq: Literal["FP8", "INT8", "IN4"] = field(
92
+ default="FP8",
93
+ metadata={
94
+ "interactive_if": {"field": "quantization_method", "neq": "None"},
95
+ "component": "radio",
96
+ "label": "Quantization Mode (Not Equal)",
97
+ "help": "This becomes interactive if Quantization Method is NOT 'None'."
98
+ }
99
+ )
100
+ @dataclass
101
  class ModelSettings:
102
  model_type: Literal["SD 1.5", "SDXL", "Pony", "Custom"] = field(
103
+ default="SDXL",
104
+ metadata={
105
+ "component": "dropdown",
106
+ "label": "Base Model",
107
+ "help": "Select the base diffusion model."
108
+ }
109
  )
110
  custom_model_path: str = field(
111
  default="/path/to/default.safetensors",
112
  metadata={
113
  "label": "Custom Model Path",
114
  "interactive_if": {"field": "model_type", "value": "Custom"},
115
+ "help": "Provide the local file path to your custom .safetensors or .ckpt model file. This is only active when 'Base Model' is set to 'Custom'."
116
  },
117
  )
118
+ vae_path: str = field(
119
+ default="",
120
+ metadata={
121
+ "label": "VAE Path (optional)",
122
+ "help": "Optionally, provide a path to a separate VAE file to improve color and detail."
123
+ }
124
+ )
125
 
126
  @dataclass
127
  class SamplingSettings:
128
  scheduler: Literal["Karras", "Simple", "Exponential"] = field(
129
  default="Karras",
130
+ metadata={
131
+ "component": "radio",
132
+ "label": "Scheduler",
133
+ "help": "Determines how the noise schedule is interpreted during sampling. 'Karras' is often recommended for high-quality results."
134
+ }
135
  )
136
  sampler_name: Literal["Euler", "Euler a", "DPM++ 2M Karras", "UniPC"] = field(
137
  default="DPM++ 2M Karras",
138
+ metadata={
139
+ "component": "dropdown",
140
+ "label": "Sampler",
141
+ "help": "The algorithm used to denoise the image over multiple steps. Different samplers can produce stylistically different results."
142
+ }
143
  )
144
  steps: int = field(
145
  default=25,
146
+ metadata={
147
+ "component": "slider",
148
+ "label": "Sampling Steps",
149
+ "minimum": 1,
150
+ "maximum": 150,
151
+ "step": 1,
152
+ "help": "The number of denoising steps. More steps can increase detail but also take longer. Values between 20-40 are common."
153
+ }
154
  )
155
  cfg_scale: float = field(
156
  default=7.0,
157
+ metadata={
158
+ "component": "slider",
159
+ "label": "CFG Scale",
160
+ "minimum": 1.0,
161
+ "maximum": 30.0,
162
+ "step": 0.5,
163
+ "help": "Classifier-Free Guidance Scale. Higher values make the image adhere more strictly to the prompt, while lower values allow for more creativity."
164
+ }
165
  )
166
  enable_advanced: bool = field(
167
  default=False,
168
+ metadata={
169
+ "label": "Enable Advanced Settings",
170
+ "help": "Check this box to reveal more experimental or fine-tuning options."
171
+ }
172
  )
173
  advanced_option: float = field(
174
  default=0.5,
 
179
  "maximum": 1.0,
180
  "step": 0.01,
181
  "interactive_if": {"field": "enable_advanced", "value": True},
182
+ "help": "An example of an advanced setting that is only visible when the corresponding checkbox is enabled."
183
  },
184
  )
185
  temperature: float = field(
 
189
  "component": "number_float",
190
  "minimum": 0.1,
191
  "maximum": 2.0,
192
+ "step": 0.1,
193
+ "help": "Controls the randomness of the sampling process. A value of 1.0 is standard. Higher values increase diversity at the risk of artifacts."
194
  }
195
  )
196
 
197
  @dataclass
198
  class RenderConfig:
199
+ api_settings: APISettings = field(
200
+ default_factory=APISettings,
201
+ metadata={"label": "API Settings"}
202
+ )
203
+ randomize_seed: bool = field(
204
+ default=True,
205
+ metadata={
206
+ "label": "Randomize Seed",
207
+ "help": "If checked, a new random seed will be used for each generation. Uncheck to use the specific seed value below."
208
+ }
209
+ )
210
  seed: int = field(
211
  default=-1,
212
+ metadata={
213
+ "component": "number_integer",
214
+ "label": "Seed",
215
+ "help": "The seed for the random number generator. A value of -1 means a random seed will be chosen. The same seed and settings will produce the same image."
216
+ }
217
+ )
218
+ model: ModelSettings = field(
219
+ default_factory=ModelSettings,
220
+ metadata={"label": "Model Settings"}
221
+ )
222
+ sampling: SamplingSettings = field(
223
+ default_factory=SamplingSettings,
224
+ metadata={"label": "Sampling Settings"}
225
+ )
226
+ quantization: QuantizationSettings = field(
227
+ default_factory=QuantizationSettings,
228
+ metadata={"label": "Quantization Settings"}
229
  )
 
 
230
 
231
  @dataclass
232
  class Lighting:
233
  sun_intensity: float = field(
234
  default=1.0,
235
+ metadata={
236
+ "component": "slider",
237
+ "label": "Sun Intensity",
238
+ "minimum": 0,
239
+ "maximum": 5,
240
+ "step": 0.1,
241
+ "help": "Controls the brightness of the main light source in the scene."
242
+ }
243
  )
244
  color: str = field(
245
+ default="#FFDDBB",
246
+ metadata={
247
+ "component": "colorpicker",
248
+ "label": "Sun Color",
249
+ "help": "Sets the color of the main light source."
250
+ }
251
  )
252
 
 
253
  @dataclass
254
  class EnvironmentConfig:
255
  background: Literal["Sky", "Color", "Image"] = field(
256
+ default="Sky",
257
+ metadata={
258
+ "component": "dropdown",
259
+ "label": "Background Type",
260
+ "help": "Choose the type of background for the environment."
261
+ }
262
+ )
263
+ lighting: Lighting = field(
264
+ default_factory=Lighting,
265
+ metadata={"label": "Lighting"}
266
  )
 
 
267
 
268
  @dataclass
269
  class EulerSettings:
270
  s_churn: float = field(
271
  default=0.0,
272
+ metadata={
273
+ "component": "slider",
274
+ "label": "S_Churn",
275
+ "minimum": 0.0,
276
+ "maximum": 1.0,
277
+ "step": 0.01,
278
+ "help": "Stochasticity churn factor for Euler samplers. Adds extra noise at each step, affecting diversity. 0.0 is deterministic."
279
+ }
280
  )
281
 
 
282
  @dataclass
283
  class DPM_Settings:
284
  karras_style: bool = field(
285
+ default=True,
286
+ metadata={
287
+ "label": "Use Karras Sigma Schedule",
288
+ "help": "If checked, uses the Karras noise schedule, which is often recommended for DPM++ samplers to improve image quality, especially in later steps."
289
+ }
290
  )
291
 
 
292
  # --- 2. Data Mappings and Initial Instances (unchanged) ---
293
  initial_render_config = RenderConfig()
294
  initial_env_config = EnvironmentConfig()
src/README.md CHANGED
@@ -10,7 +10,7 @@ app_file: space.py
10
  ---
11
 
12
  # `gradio_propertysheet`
13
- <img alt="Static Badge" src="https://img.shields.io/badge/version%20-%200.0.12%20-%20blue"> <a href="https://huggingface.co/spaces/elismasilva/gradio_propertysheet"><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_propertysheet'>Component GitHub Code</a></span></p>
14
 
15
  The **PropertySheet** component for Gradio allows you to automatically generate a complete and interactive settings panel from a standard Python `dataclass`. It's designed to bring the power of IDE-like property editors directly into your Gradio applications.
16
 
@@ -57,41 +57,126 @@ from gradio_htmlinjector import HTMLInjector
57
 
58
  # --- 1. Dataclass Definitions (unchanged) ---
59
  @dataclass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  class ModelSettings:
61
  model_type: Literal["SD 1.5", "SDXL", "Pony", "Custom"] = field(
62
- default="SDXL", metadata={"component": "dropdown", "label": "Base Model"}
 
 
 
 
 
63
  )
64
  custom_model_path: str = field(
65
  default="/path/to/default.safetensors",
66
  metadata={
67
  "label": "Custom Model Path",
68
  "interactive_if": {"field": "model_type", "value": "Custom"},
 
69
  },
70
  )
71
- vae_path: str = field(default="", metadata={"label": "VAE Path (optional)"})
72
-
 
 
 
 
 
73
 
74
  @dataclass
75
  class SamplingSettings:
76
  scheduler: Literal["Karras", "Simple", "Exponential"] = field(
77
  default="Karras",
78
- metadata={"component": "radio", "label": "Scheduler"}
 
 
 
 
79
  )
80
  sampler_name: Literal["Euler", "Euler a", "DPM++ 2M Karras", "UniPC"] = field(
81
  default="DPM++ 2M Karras",
82
- metadata={"component": "dropdown", "label": "Sampler"},
 
 
 
 
83
  )
84
  steps: int = field(
85
  default=25,
86
- metadata={"component": "slider", "minimum": 1, "maximum": 150, "step": 1},
 
 
 
 
 
 
 
87
  )
88
  cfg_scale: float = field(
89
  default=7.0,
90
- metadata={"component": "slider", "minimum": 1.0, "maximum": 30.0, "step": 0.5},
 
 
 
 
 
 
 
91
  )
92
  enable_advanced: bool = field(
93
  default=False,
94
- metadata={"label": "Enable Advanced Settings"}
 
 
 
95
  )
96
  advanced_option: float = field(
97
  default=0.5,
@@ -102,6 +187,7 @@ class SamplingSettings:
102
  "maximum": 1.0,
103
  "step": 0.01,
104
  "interactive_if": {"field": "enable_advanced", "value": True},
 
105
  },
106
  )
107
  temperature: float = field(
@@ -111,54 +197,106 @@ class SamplingSettings:
111
  "component": "number_float",
112
  "minimum": 0.1,
113
  "maximum": 2.0,
114
- "step": 0.1
 
115
  }
116
  )
117
 
118
  @dataclass
119
  class RenderConfig:
120
- randomize_seed: bool = field(default=True, metadata={"label": "Randomize Seed"})
 
 
 
 
 
 
 
 
 
 
121
  seed: int = field(
122
  default=-1,
123
- metadata={"component": "number_integer", "label": "Seed (-1 for random)"},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  )
125
- model: ModelSettings = field(default_factory=ModelSettings, metadata={"label": "Model Settings"})
126
- sampling: SamplingSettings = field(default_factory=SamplingSettings)
127
 
128
  @dataclass
129
  class Lighting:
130
  sun_intensity: float = field(
131
  default=1.0,
132
- metadata={"component": "slider", "minimum": 0, "maximum": 5, "step": 0.1},
 
 
 
 
 
 
 
133
  )
134
  color: str = field(
135
- default="#FFDDBB", metadata={"component": "colorpicker", "label": "Sun Color"}
 
 
 
 
 
136
  )
137
 
138
-
139
  @dataclass
140
  class EnvironmentConfig:
141
  background: Literal["Sky", "Color", "Image"] = field(
142
- default="Sky", metadata={"component": "dropdown"}
 
 
 
 
 
 
 
 
 
143
  )
144
- lighting: Lighting = field(default_factory=Lighting)
145
-
146
 
147
  @dataclass
148
  class EulerSettings:
149
  s_churn: float = field(
150
  default=0.0,
151
- metadata={"component": "slider", "minimum": 0.0, "maximum": 1.0, "step": 0.01},
 
 
 
 
 
 
 
152
  )
153
 
154
-
155
  @dataclass
156
  class DPM_Settings:
157
  karras_style: bool = field(
158
- default=True, metadata={"label": "Use Karras Sigma Schedule"}
 
 
 
 
159
  )
160
 
161
-
162
  # --- 2. Data Mappings and Initial Instances (unchanged) ---
163
  initial_render_config = RenderConfig()
164
  initial_env_config = EnvironmentConfig()
 
10
  ---
11
 
12
  # `gradio_propertysheet`
13
+ <img alt="Static Badge" src="https://img.shields.io/badge/version%20-%200.0.13%20-%20blue"> <a href="https://huggingface.co/spaces/elismasilva/gradio_propertysheet"><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_propertysheet'>Component GitHub Code</a></span></p>
14
 
15
  The **PropertySheet** component for Gradio allows you to automatically generate a complete and interactive settings panel from a standard Python `dataclass`. It's designed to bring the power of IDE-like property editors directly into your Gradio applications.
16
 
 
57
 
58
  # --- 1. Dataclass Definitions (unchanged) ---
59
  @dataclass
60
+ class APISettings:
61
+ api_key: str = field(
62
+ default="ab123cd45ef67890ghij123klmno456p",
63
+ metadata={
64
+ "label": "API Key",
65
+ "component": "password",
66
+ "help": "Your secret API key. It will not be displayed."
67
+ }
68
+ )
69
+ endpoint_url: str = field(
70
+ default="https://api.example.com",
71
+ metadata={
72
+ "label": "API Endpoint",
73
+ "component": "string", # string normal
74
+ "help": "The URL of the API server."
75
+ }
76
+ )
77
+
78
+ @dataclass
79
+ class QuantizationSettings:
80
+ quantization_method: Literal["None", "Quanto Library", "Layerwise & Bnb"] = field(
81
+ default="Layerwise & Bnb",
82
+ metadata={
83
+ "component": "radio",
84
+ "label": "Quantization Method",
85
+ "help": "Quantization mechanism to save VRAM and increase speed."
86
+ }
87
+ )
88
+ # Option 1: Literal values
89
+ quantize_mode_list: Literal["FP8", "INT8", "IN4"] = field(
90
+ default="FP8",
91
+ metadata={
92
+ "interactive_if": {"field": "quantization_method", "value": ["Quanto Library", "Layerwise & Bnb"]},
93
+ "component": "radio",
94
+ "label": "Quantization Mode (List)",
95
+ "help": "This becomes interactive if Quantization Method is 'Quanto' OR 'Layerwise'."
96
+ }
97
+ )
98
+ # Option 2: neq operand
99
+ quantize_mode_neq: Literal["FP8", "INT8", "IN4"] = field(
100
+ default="FP8",
101
+ metadata={
102
+ "interactive_if": {"field": "quantization_method", "neq": "None"},
103
+ "component": "radio",
104
+ "label": "Quantization Mode (Not Equal)",
105
+ "help": "This becomes interactive if Quantization Method is NOT 'None'."
106
+ }
107
+ )
108
+ @dataclass
109
  class ModelSettings:
110
  model_type: Literal["SD 1.5", "SDXL", "Pony", "Custom"] = field(
111
+ default="SDXL",
112
+ metadata={
113
+ "component": "dropdown",
114
+ "label": "Base Model",
115
+ "help": "Select the base diffusion model."
116
+ }
117
  )
118
  custom_model_path: str = field(
119
  default="/path/to/default.safetensors",
120
  metadata={
121
  "label": "Custom Model Path",
122
  "interactive_if": {"field": "model_type", "value": "Custom"},
123
+ "help": "Provide the local file path to your custom .safetensors or .ckpt model file. This is only active when 'Base Model' is set to 'Custom'."
124
  },
125
  )
126
+ vae_path: str = field(
127
+ default="",
128
+ metadata={
129
+ "label": "VAE Path (optional)",
130
+ "help": "Optionally, provide a path to a separate VAE file to improve color and detail."
131
+ }
132
+ )
133
 
134
  @dataclass
135
  class SamplingSettings:
136
  scheduler: Literal["Karras", "Simple", "Exponential"] = field(
137
  default="Karras",
138
+ metadata={
139
+ "component": "radio",
140
+ "label": "Scheduler",
141
+ "help": "Determines how the noise schedule is interpreted during sampling. 'Karras' is often recommended for high-quality results."
142
+ }
143
  )
144
  sampler_name: Literal["Euler", "Euler a", "DPM++ 2M Karras", "UniPC"] = field(
145
  default="DPM++ 2M Karras",
146
+ metadata={
147
+ "component": "dropdown",
148
+ "label": "Sampler",
149
+ "help": "The algorithm used to denoise the image over multiple steps. Different samplers can produce stylistically different results."
150
+ }
151
  )
152
  steps: int = field(
153
  default=25,
154
+ metadata={
155
+ "component": "slider",
156
+ "label": "Sampling Steps",
157
+ "minimum": 1,
158
+ "maximum": 150,
159
+ "step": 1,
160
+ "help": "The number of denoising steps. More steps can increase detail but also take longer. Values between 20-40 are common."
161
+ }
162
  )
163
  cfg_scale: float = field(
164
  default=7.0,
165
+ metadata={
166
+ "component": "slider",
167
+ "label": "CFG Scale",
168
+ "minimum": 1.0,
169
+ "maximum": 30.0,
170
+ "step": 0.5,
171
+ "help": "Classifier-Free Guidance Scale. Higher values make the image adhere more strictly to the prompt, while lower values allow for more creativity."
172
+ }
173
  )
174
  enable_advanced: bool = field(
175
  default=False,
176
+ metadata={
177
+ "label": "Enable Advanced Settings",
178
+ "help": "Check this box to reveal more experimental or fine-tuning options."
179
+ }
180
  )
181
  advanced_option: float = field(
182
  default=0.5,
 
187
  "maximum": 1.0,
188
  "step": 0.01,
189
  "interactive_if": {"field": "enable_advanced", "value": True},
190
+ "help": "An example of an advanced setting that is only visible when the corresponding checkbox is enabled."
191
  },
192
  )
193
  temperature: float = field(
 
197
  "component": "number_float",
198
  "minimum": 0.1,
199
  "maximum": 2.0,
200
+ "step": 0.1,
201
+ "help": "Controls the randomness of the sampling process. A value of 1.0 is standard. Higher values increase diversity at the risk of artifacts."
202
  }
203
  )
204
 
205
  @dataclass
206
  class RenderConfig:
207
+ api_settings: APISettings = field(
208
+ default_factory=APISettings,
209
+ metadata={"label": "API Settings"}
210
+ )
211
+ randomize_seed: bool = field(
212
+ default=True,
213
+ metadata={
214
+ "label": "Randomize Seed",
215
+ "help": "If checked, a new random seed will be used for each generation. Uncheck to use the specific seed value below."
216
+ }
217
+ )
218
  seed: int = field(
219
  default=-1,
220
+ metadata={
221
+ "component": "number_integer",
222
+ "label": "Seed",
223
+ "help": "The seed for the random number generator. A value of -1 means a random seed will be chosen. The same seed and settings will produce the same image."
224
+ }
225
+ )
226
+ model: ModelSettings = field(
227
+ default_factory=ModelSettings,
228
+ metadata={"label": "Model Settings"}
229
+ )
230
+ sampling: SamplingSettings = field(
231
+ default_factory=SamplingSettings,
232
+ metadata={"label": "Sampling Settings"}
233
+ )
234
+ quantization: QuantizationSettings = field(
235
+ default_factory=QuantizationSettings,
236
+ metadata={"label": "Quantization Settings"}
237
  )
 
 
238
 
239
  @dataclass
240
  class Lighting:
241
  sun_intensity: float = field(
242
  default=1.0,
243
+ metadata={
244
+ "component": "slider",
245
+ "label": "Sun Intensity",
246
+ "minimum": 0,
247
+ "maximum": 5,
248
+ "step": 0.1,
249
+ "help": "Controls the brightness of the main light source in the scene."
250
+ }
251
  )
252
  color: str = field(
253
+ default="#FFDDBB",
254
+ metadata={
255
+ "component": "colorpicker",
256
+ "label": "Sun Color",
257
+ "help": "Sets the color of the main light source."
258
+ }
259
  )
260
 
 
261
  @dataclass
262
  class EnvironmentConfig:
263
  background: Literal["Sky", "Color", "Image"] = field(
264
+ default="Sky",
265
+ metadata={
266
+ "component": "dropdown",
267
+ "label": "Background Type",
268
+ "help": "Choose the type of background for the environment."
269
+ }
270
+ )
271
+ lighting: Lighting = field(
272
+ default_factory=Lighting,
273
+ metadata={"label": "Lighting"}
274
  )
 
 
275
 
276
  @dataclass
277
  class EulerSettings:
278
  s_churn: float = field(
279
  default=0.0,
280
+ metadata={
281
+ "component": "slider",
282
+ "label": "S_Churn",
283
+ "minimum": 0.0,
284
+ "maximum": 1.0,
285
+ "step": 0.01,
286
+ "help": "Stochasticity churn factor for Euler samplers. Adds extra noise at each step, affecting diversity. 0.0 is deterministic."
287
+ }
288
  )
289
 
 
290
  @dataclass
291
  class DPM_Settings:
292
  karras_style: bool = field(
293
+ default=True,
294
+ metadata={
295
+ "label": "Use Karras Sigma Schedule",
296
+ "help": "If checked, uses the Karras noise schedule, which is often recommended for DPM++ samplers to improve image quality, especially in later steps."
297
+ }
298
  )
299
 
 
300
  # --- 2. Data Mappings and Initial Instances (unchanged) ---
301
  initial_render_config = RenderConfig()
302
  initial_env_config = EnvironmentConfig()
src/backend/gradio_propertysheet/templates/component/index.js CHANGED
The diff for this file is too large to render. See raw diff
 
src/backend/gradio_propertysheet/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-109se4{display:flex;flex-direction:row;align-items:center;justify-content:center;z-index:var(--layer-3);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-109se4{border-top:none;border-right:none;border-radius:var(--block-label-right-radius)}.icon-button-wrapper.display-top-corner.svelte-109se4{border-radius:var(--radius-sm) 0 0 var(--radius-sm);top:var(--spacing-sm);right:-1px}.icon-button-wrapper.svelte-109se4:not(.top-panel){border:1px solid var(--border-color-primary);border-radius:var(--radius-sm)}.top-panel.svelte-109se4{position:absolute;top:var(--block-label-margin);right:var(--block-label-margin);margin:0}.icon-button-wrapper.svelte-109se4 button{margin:var(--spacing-xxs);border-radius:var(--radius-xs);position:relative}.icon-button-wrapper.svelte-109se4 a.download-link:not(:last-child),.icon-button-wrapper.svelte-109se4 button:not(:last-child){margin-right:var(--spacing-xxs)}.icon-button-wrapper.svelte-109se4 a.download-link:not(:last-child):not(.no-border *):after,.icon-button-wrapper.svelte-109se4 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-109se4>*{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-1pgj5gs{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-1pgj5gs{border:1px solid var(--color-red-700);background:var(--color-red-50)}.dark .toast-body.error.svelte-1pgj5gs{border:1px solid var(--color-red-500);background-color:var(--color-grey-950)}.toast-body.warning.svelte-1pgj5gs{border:1px solid var(--color-yellow-700);background:var(--color-yellow-50)}.dark .toast-body.warning.svelte-1pgj5gs{border:1px solid var(--color-yellow-500);background-color:var(--color-grey-950)}.toast-body.info.svelte-1pgj5gs{border:1px solid var(--color-grey-700);background:var (--color-grey-50)}.dark .toast-body.info.svelte-1pgj5gs{border:1px solid var(--color-grey-500);background-color:var(--color-grey-950)}.toast-body.success.svelte-1pgj5gs{border:1px solid var(--color-green-700);background:var(--color-green-50)}.dark .toast-body.success.svelte-1pgj5gs{border:1px solid var(--color-green-500);background-color:var(--color-grey-950)}.toast-title.svelte-1pgj5gs{display:flex;align-items:center;font-weight:var(--weight-bold);font-size:var(--text-lg);line-height:var(--line-sm)}.toast-title.error.svelte-1pgj5gs{color:var(--color-red-700)}.dark .toast-title.error.svelte-1pgj5gs{color:var(--color-red-50)}.toast-title.warning.svelte-1pgj5gs{color:var(--color-yellow-700)}.dark .toast-title.warning.svelte-1pgj5gs{color:var(--color-yellow-50)}.toast-title.info.svelte-1pgj5gs{color:var(--color-grey-700)}.dark .toast-title.info.svelte-1pgj5gs{color:var(--color-grey-50)}.toast-title.success.svelte-1pgj5gs{color:var(--color-green-700)}.dark .toast-title.success.svelte-1pgj5gs{color:var(--color-green-50)}.toast-close.svelte-1pgj5gs{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-1pgj5gs{color:var(--color-red-700)}.dark .toast-close.error.svelte-1pgj5gs{color:var(--color-red-500)}.toast-close.warning.svelte-1pgj5gs{color:var(--color-yellow-700)}.dark .toast-close.warning.svelte-1pgj5gs{color:var(--color-yellow-500)}.toast-close.info.svelte-1pgj5gs{color:var(--color-grey-700)}.dark .toast-close.info.svelte-1pgj5gs{color:var(--color-grey-500)}.toast-close.success.svelte-1pgj5gs{color:var(--color-green-700)}.dark .toast-close.success.svelte-1pgj5gs{color:var(--color-green-500)}.toast-text.svelte-1pgj5gs{font-size:var(--text-lg);word-wrap:break-word;overflow-wrap:break-word;word-break:break-word}.toast-text.error.svelte-1pgj5gs{color:var(--color-red-700)}.dark .toast-text.error.svelte-1pgj5gs{color:var(--color-red-50)}.toast-text.warning.svelte-1pgj5gs{color:var(--color-yellow-700)}.dark .toast-text.warning.svelte-1pgj5gs{color:var(--color-yellow-50)}.toast-text.info.svelte-1pgj5gs{color:var(--color-grey-700)}.dark .toast-text.info.svelte-1pgj5gs{color:var(--color-grey-50)}.toast-text.success.svelte-1pgj5gs{color:var(--color-green-700)}.dark .toast-text.success.svelte-1pgj5gs{color:var(--color-green-50)}.toast-details.svelte-1pgj5gs{margin:var(--size-3) var(--size-3) var(--size-3) 0;width:100%}.toast-icon.svelte-1pgj5gs{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-1pgj5gs{color:var(--color-red-700)}.dark .toast-icon.error.svelte-1pgj5gs{color:var(--color-red-500)}.toast-icon.warning.svelte-1pgj5gs{color:var(--color-yellow-700)}.dark .toast-icon.warning.svelte-1pgj5gs{color:var(--color-yellow-500)}.toast-icon.info.svelte-1pgj5gs{color:var(--color-grey-700)}.dark .toast-icon.info.svelte-1pgj5gs{color:var(--color-grey-500)}.toast-icon.success.svelte-1pgj5gs{color:var(--color-green-700)}.dark .toast-icon.success.svelte-1pgj5gs{color:var(--color-green-500)}@keyframes svelte-1pgj5gs-countdown{0%{transform:scaleX(1)}to{transform:scaleX(0)}}.timer.svelte-1pgj5gs{position:absolute;bottom:0;left:0;transform-origin:0 0;animation:svelte-1pgj5gs-countdown 10s linear forwards;width:100%;height:var(--size-1)}.timer.error.svelte-1pgj5gs{background:var(--color-red-700)}.dark .timer.error.svelte-1pgj5gs{background:var(--color-red-500)}.timer.warning.svelte-1pgj5gs{background:var(--color-yellow-700)}.dark .timer.warning.svelte-1pgj5gs{background:var(--color-yellow-500)}.timer.info.svelte-1pgj5gs{background:var(--color-grey-700)}.dark .timer.info.svelte-1pgj5gs{background:var(--color-grey-500)}.timer.success.svelte-1pgj5gs{background:var(--color-green-700)}.dark .timer.success.svelte-1pgj5gs{background:var(--color-green-500)}.hidden.svelte-1pgj5gs{display:none}.toast-text.svelte-1pgj5gs 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%)}}:host{display:flex;flex-direction:column;height:100%}.propertysheet-wrapper{overflow:hidden!important;display:flex;flex-direction:column;flex-grow:1;padding:var(--spacing-lg)!important}.accordion-header.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{display:flex;justify-content:space-between;align-items:center;width:100%;cursor:pointer;padding:var(--block-title-padding);background:var(--block-title-background-fill);color:var(--block-title-text-color);border-width:0;flex-shrink:0}.accordion-icon.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{margin-left:auto}.content-wrapper.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{flex-grow:1;min-height:0}.container.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{overflow-y:auto;height:auto;max-height:var(--sheet-max-height, 500px);border-radius:0!important;border:1px solid var(--border-color-primary);border-top:var(--show-group-name);border-bottom-left-radius:var(--radius-lg);border-bottom-right-radius:var(--radius-lg);background-color:var(--background-fill-secondary)}.closed.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{display:none}.group-header.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{display:flex;justify-content:space-between;align-items:center;width:100%;padding:var(--spacing-sm) var(--spacing-md);background-color:var(--input-background-fill);color:var(--body-text-color);text-align:left;cursor:pointer;font-size:var(--text-md);font-weight:var(--font-weight-bold);border:1px solid var(--border-color-primary)}.properties-grid.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{display:grid;grid-template-columns:1fr 2fr;gap:0;padding:0}.prop-label.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt,.prop-control.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{padding:var(--spacing-sm) var(--spacing-md);display:flex;align-items:center;border-bottom:1px solid var(--background-fill-secondary)}.prop-label.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{background-color:var(--background-fill-primary);color:var(--body-text-color);opacity:.7;font-weight:var(--font-weight-semibold);font-size:var(--text-xs);text-align:right;justify-content:flex-end;word-break:break-word}.prop-control.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{gap:var(--spacing-sm)}.properties-grid.svelte-31cuxt>.svelte-31cuxt.svelte-31cuxt:nth-last-child(-n+2){border-bottom:none}.prop-control.svelte-31cuxt input[type=text].svelte-31cuxt.svelte-31cuxt,.prop-control.svelte-31cuxt input[type=number].svelte-31cuxt.svelte-31cuxt{background-color:var(--input-background-fill);border:var(--input-border-width) solid var(--border-color-primary);box-shadow:var(--input-shadow);color:var(--input-text-color);font-size:var(--input-text-size);border-radius:0;width:100%;padding-top:var(--spacing-1);padding-bottom:var(--spacing-1);padding-left:var(--spacing-md);padding-right:var(--spacing-3)}.prop-control.svelte-31cuxt input[type=text].svelte-31cuxt.svelte-31cuxt:focus,.prop-control.svelte-31cuxt input[type=number].svelte-31cuxt.svelte-31cuxt:focus{box-shadow:var(--input-shadow-focus);border-color:var(--input-border-color-focus);background-color:var(--input-background-fill-focus);outline:none}.dropdown-wrapper.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{position:relative;width:100%}.dropdown-wrapper.svelte-31cuxt select.svelte-31cuxt.svelte-31cuxt{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--input-background-fill);border:var(--input-border-width) solid var(--border-color-primary);box-shadow:var(--input-shadow);color:var(--input-text-color);font-size:var(--input-text-size);width:100%;cursor:pointer;border-radius:0;padding-top:var(--spacing-1);padding-bottom:var(--spacing-1);padding-left:var(--spacing-md);padding-right:calc(var(--spacing-3) + 1.2em)}.dropdown-arrow-icon.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{position:absolute;top:50%;right:var(--spacing-3);transform:translateY(-50%);width:1em;height:1em;pointer-events:none;z-index:1;background-color:var(--body-text-color-subdued);-webkit-mask-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='currentColor' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M6 8l4 4 4-4'/%3e%3c/svg%3e");mask-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='currentColor' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M6 8l4 4 4-4'%3e%3c/svg%3e")}.dropdown-wrapper.svelte-31cuxt select.svelte-31cuxt.svelte-31cuxt:focus{box-shadow:var(--input-shadow-focus);border-color:var(--input-border-color-focus);background-color:var(--input-background-fill-focus);outline:none}.dropdown-wrapper.svelte-31cuxt select option.svelte-31cuxt.svelte-31cuxt{background:var(--input-background-fill);color:var(--body-text-color)}.prop-control.svelte-31cuxt input[type=checkbox].svelte-31cuxt.svelte-31cuxt{-webkit-appearance:none;-moz-appearance:none;appearance:none;position:relative;width:var(--size-4);height:var(--size-4);border-radius:5px!important;border:1px solid var(--checkbox-border-color);background-color:var(--checkbox-background-color);box-shadow:var(--checkbox-shadow);cursor:pointer;margin:0;transition:background-color .2s,border-color .2s}.prop-control.svelte-31cuxt input[type=checkbox].svelte-31cuxt.svelte-31cuxt:hover{border-color:var(--checkbox-border-color-hover);background-color:var(--checkbox-background-color-hover)}.prop-control.svelte-31cuxt input[type=checkbox].svelte-31cuxt.svelte-31cuxt:focus{border-color:var(--checkbox-border-color-focus);background-color:var(--checkbox-background-color-focus);outline:none}.prop-control.svelte-31cuxt input[type=checkbox].svelte-31cuxt.svelte-31cuxt:checked{background-color:var(--checkbox-background-color-selected);border-color:var(--checkbox-border-color-focus)}.prop-control.svelte-31cuxt input[type=checkbox].svelte-31cuxt.svelte-31cuxt:checked:after{content:"";position:absolute;display:block;top:50%;left:50%;width:4px;height:8px;border:solid var(--checkbox-label-text-color-selected);border-width:0 2px 2px 0;transform:translate(-50%,-60%) rotate(45deg)}.slider-container.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{display:flex;align-items:center;gap:var(--spacing-md);width:100%}.slider-container.svelte-31cuxt input[type=range].svelte-31cuxt.svelte-31cuxt{--slider-progress:0%;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;cursor:pointer;width:100%}.slider-container.svelte-31cuxt input[type=range].svelte-31cuxt.svelte-31cuxt::-webkit-slider-runnable-track{height:8px;border-radius:var(--radius-lg);background:linear-gradient(to right,var(--slider-color) var(--slider-progress),var(--input-background-fill) var(--slider-progress))}.slider-container.svelte-31cuxt input[type=range].svelte-31cuxt.svelte-31cuxt::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none;margin-top:-4px;background-color:#fff;border-radius:50%;height:16px;width:16px;border:1px solid var(--border-color-primary);box-shadow:var(--shadow-drop)}.slider-container.svelte-31cuxt input[type=range].svelte-31cuxt.svelte-31cuxt::-moz-range-track{height:8px;border-radius:var(--radius-lg);background:linear-gradient(to right,var(--slider-color) var(--slider-progress),var(--input-background-fill) var(--slider-progress))}.slider-container.svelte-31cuxt input[type=range].svelte-31cuxt.svelte-31cuxt::-moz-range-thumb{background-color:#fff;border-radius:50%;height:16px;width:16px;border:1px solid var(--border-color-primary);box-shadow:var(--shadow-drop)}.slider-value.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{min-width:40px;text-align:right;font-family:var(--font-mono);font-size:var(--text-xs)}.prop-label-wrapper.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{display:flex;justify-content:flex-end;align-items:center;gap:var(--spacing-sm);width:100%}.tooltip-container.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{position:relative;display:inline-flex;align-items:center;justify-content:center}.tooltip-icon.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{display:flex;align-items:center;justify-content:center;width:14px;height:14px;border-radius:50%;background-color:var(--body-text-color-subdued);color:var(--background-fill-primary);font-size:10px;font-weight:700;cursor:help;-webkit-user-select:none;user-select:none}.tooltip-text.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{visibility:hidden;width:200px;background-color:var(--body-text-color);color:var(--background-fill-primary);text-align:center;border-radius:var(--radius-md);padding:var(--spacing-md);position:absolute;z-index:10;bottom:125%;left:50%;transform:translate(-50%);opacity:0;transition:opacity .3s}.tooltip-container.svelte-31cuxt:hover .tooltip-text.svelte-31cuxt.svelte-31cuxt{visibility:visible;opacity:1}.color-picker-container.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{display:flex;align-items:center;gap:var(--spacing-md);width:100%}.color-picker-input.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{width:50px;height:28px;background-color:transparent;border:1px solid var(--border-color-primary);border-radius:var(--radius-sm);cursor:pointer;padding:0}.color-picker-input.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt::-webkit-color-swatch-wrapper{padding:2px}.color-picker-input.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt::-moz-padding{padding:2px}.color-picker-input.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt::-webkit-color-swatch{border:none;border-radius:var(--radius-sm)}.color-picker-input.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt::-moz-color-swatch{border:none;border-radius:var(--radius-sm)}.color-picker-value.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{font-family:var(--font-mono);font-size:var(--text-sm);color:var(--body-text-color-subdued)}.prop-control.svelte-31cuxt input.invalid.svelte-31cuxt.svelte-31cuxt{border-color:var(--error-border-color, red)!important;box-shadow:0 0 0 1px var(--error-border-color, red)!important}.reset-button-prop.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{display:flex;align-items:center;justify-content:center;background:none;border:none;border-left:1px solid var(--border-color-primary);cursor:pointer;color:var(--body-text-color-subdued);font-size:var(--text-lg);padding:0 var(--spacing-2);visibility:hidden;opacity:0;transition:opacity .15s ease-in-out,color .15s ease-in-out}.reset-button-prop.visible.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{visibility:visible;opacity:1}.reset-button-prop.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt:hover{color:var(--body-text-color);background-color:var(--background-fill-secondary-hover)}.reset-button-prop.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt:disabled{color:var(--body-text-color-subdued)!important;opacity:.5;cursor:not-allowed;background-color:transparent!important}.prop-control.svelte-31cuxt .disabled.svelte-31cuxt.svelte-31cuxt{opacity:.5;pointer-events:none;cursor:not-allowed}.prop-control.svelte-31cuxt .disabled input.svelte-31cuxt.svelte-31cuxt{cursor:not-allowed}.reset-button-prop.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt:disabled{opacity:.3;cursor:not-allowed;background-color:transparent!important}.radio-group.svelte-31cuxt.svelte-31cuxt.svelte-31cuxt{display:flex;flex-wrap:wrap;gap:var(--spacing-sm);width:100%}.radio-item.svelte-31cuxt input[type=radio].svelte-31cuxt.svelte-31cuxt{display:none}.radio-item.svelte-31cuxt label.svelte-31cuxt.svelte-31cuxt{display:inline-block;padding:var(--spacing-xs) var(--spacing-md);border:1px solid var(--border-color-primary);border-radius:5px!important;background-color:var(--input-background-fill);color:var(--body-text-color);font-size:var(--text-xs);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .2s,border-color .2s,color .2s}.radio-group.disabled.svelte-31cuxt .radio-item label.svelte-31cuxt.svelte-31cuxt{cursor:not-allowed}.radio-item.svelte-31cuxt input[type=radio].svelte-31cuxt:hover+label.svelte-31cuxt{border-color:var(--border-color-accent-subdued);background-color:var(--background-fill-secondary-hover)}.radio-item.svelte-31cuxt input[type=radio].svelte-31cuxt:checked+label.svelte-31cuxt{background-color:var(--primary-500);border-color:var(--primary-500);color:#fff;font-weight:var(--font-weight-bold)}.radio-group.disabled.svelte-31cuxt .radio-item input[type=radio].svelte-31cuxt:checked+label.svelte-31cuxt{background-color:var(--neutral-300);border-color:var(--neutral-300);color:var(--neutral-500)}
 
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-109se4{display:flex;flex-direction:row;align-items:center;justify-content:center;z-index:var(--layer-3);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-109se4{border-top:none;border-right:none;border-radius:var(--block-label-right-radius)}.icon-button-wrapper.display-top-corner.svelte-109se4{border-radius:var(--radius-sm) 0 0 var(--radius-sm);top:var(--spacing-sm);right:-1px}.icon-button-wrapper.svelte-109se4:not(.top-panel){border:1px solid var(--border-color-primary);border-radius:var(--radius-sm)}.top-panel.svelte-109se4{position:absolute;top:var(--block-label-margin);right:var(--block-label-margin);margin:0}.icon-button-wrapper.svelte-109se4 button{margin:var(--spacing-xxs);border-radius:var(--radius-xs);position:relative}.icon-button-wrapper.svelte-109se4 a.download-link:not(:last-child),.icon-button-wrapper.svelte-109se4 button:not(:last-child){margin-right:var(--spacing-xxs)}.icon-button-wrapper.svelte-109se4 a.download-link:not(:last-child):not(.no-border *):after,.icon-button-wrapper.svelte-109se4 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-109se4>*{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-1pgj5gs{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-1pgj5gs{border:1px solid var(--color-red-700);background:var(--color-red-50)}.dark .toast-body.error.svelte-1pgj5gs{border:1px solid var(--color-red-500);background-color:var(--color-grey-950)}.toast-body.warning.svelte-1pgj5gs{border:1px solid var(--color-yellow-700);background:var(--color-yellow-50)}.dark .toast-body.warning.svelte-1pgj5gs{border:1px solid var(--color-yellow-500);background-color:var(--color-grey-950)}.toast-body.info.svelte-1pgj5gs{border:1px solid var(--color-grey-700);background:var (--color-grey-50)}.dark .toast-body.info.svelte-1pgj5gs{border:1px solid var(--color-grey-500);background-color:var(--color-grey-950)}.toast-body.success.svelte-1pgj5gs{border:1px solid var(--color-green-700);background:var(--color-green-50)}.dark .toast-body.success.svelte-1pgj5gs{border:1px solid var(--color-green-500);background-color:var(--color-grey-950)}.toast-title.svelte-1pgj5gs{display:flex;align-items:center;font-weight:var(--weight-bold);font-size:var(--text-lg);line-height:var(--line-sm)}.toast-title.error.svelte-1pgj5gs{color:var(--color-red-700)}.dark .toast-title.error.svelte-1pgj5gs{color:var(--color-red-50)}.toast-title.warning.svelte-1pgj5gs{color:var(--color-yellow-700)}.dark .toast-title.warning.svelte-1pgj5gs{color:var(--color-yellow-50)}.toast-title.info.svelte-1pgj5gs{color:var(--color-grey-700)}.dark .toast-title.info.svelte-1pgj5gs{color:var(--color-grey-50)}.toast-title.success.svelte-1pgj5gs{color:var(--color-green-700)}.dark .toast-title.success.svelte-1pgj5gs{color:var(--color-green-50)}.toast-close.svelte-1pgj5gs{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-1pgj5gs{color:var(--color-red-700)}.dark .toast-close.error.svelte-1pgj5gs{color:var(--color-red-500)}.toast-close.warning.svelte-1pgj5gs{color:var(--color-yellow-700)}.dark .toast-close.warning.svelte-1pgj5gs{color:var(--color-yellow-500)}.toast-close.info.svelte-1pgj5gs{color:var(--color-grey-700)}.dark .toast-close.info.svelte-1pgj5gs{color:var(--color-grey-500)}.toast-close.success.svelte-1pgj5gs{color:var(--color-green-700)}.dark .toast-close.success.svelte-1pgj5gs{color:var(--color-green-500)}.toast-text.svelte-1pgj5gs{font-size:var(--text-lg);word-wrap:break-word;overflow-wrap:break-word;word-break:break-word}.toast-text.error.svelte-1pgj5gs{color:var(--color-red-700)}.dark .toast-text.error.svelte-1pgj5gs{color:var(--color-red-50)}.toast-text.warning.svelte-1pgj5gs{color:var(--color-yellow-700)}.dark .toast-text.warning.svelte-1pgj5gs{color:var(--color-yellow-50)}.toast-text.info.svelte-1pgj5gs{color:var(--color-grey-700)}.dark .toast-text.info.svelte-1pgj5gs{color:var(--color-grey-50)}.toast-text.success.svelte-1pgj5gs{color:var(--color-green-700)}.dark .toast-text.success.svelte-1pgj5gs{color:var(--color-green-50)}.toast-details.svelte-1pgj5gs{margin:var(--size-3) var(--size-3) var(--size-3) 0;width:100%}.toast-icon.svelte-1pgj5gs{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-1pgj5gs{color:var(--color-red-700)}.dark .toast-icon.error.svelte-1pgj5gs{color:var(--color-red-500)}.toast-icon.warning.svelte-1pgj5gs{color:var(--color-yellow-700)}.dark .toast-icon.warning.svelte-1pgj5gs{color:var(--color-yellow-500)}.toast-icon.info.svelte-1pgj5gs{color:var(--color-grey-700)}.dark .toast-icon.info.svelte-1pgj5gs{color:var(--color-grey-500)}.toast-icon.success.svelte-1pgj5gs{color:var(--color-green-700)}.dark .toast-icon.success.svelte-1pgj5gs{color:var(--color-green-500)}@keyframes svelte-1pgj5gs-countdown{0%{transform:scaleX(1)}to{transform:scaleX(0)}}.timer.svelte-1pgj5gs{position:absolute;bottom:0;left:0;transform-origin:0 0;animation:svelte-1pgj5gs-countdown 10s linear forwards;width:100%;height:var(--size-1)}.timer.error.svelte-1pgj5gs{background:var(--color-red-700)}.dark .timer.error.svelte-1pgj5gs{background:var(--color-red-500)}.timer.warning.svelte-1pgj5gs{background:var(--color-yellow-700)}.dark .timer.warning.svelte-1pgj5gs{background:var(--color-yellow-500)}.timer.info.svelte-1pgj5gs{background:var(--color-grey-700)}.dark .timer.info.svelte-1pgj5gs{background:var(--color-grey-500)}.timer.success.svelte-1pgj5gs{background:var(--color-green-700)}.dark .timer.success.svelte-1pgj5gs{background:var(--color-green-500)}.hidden.svelte-1pgj5gs{display:none}.toast-text.svelte-1pgj5gs 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%)}}:host{display:flex;flex-direction:column;height:100%}.propertysheet-wrapper{overflow:hidden!important;display:flex;flex-direction:column;flex-grow:1;padding:var(--spacing-lg)!important}.accordion-header.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{display:flex;justify-content:space-between;align-items:center;width:100%;cursor:pointer;padding:var(--block-title-padding);background:var(--block-title-background-fill);color:var(--block-title-text-color);border-width:0;flex-shrink:0}.accordion-icon.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{margin-left:auto}.content-wrapper.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{flex-grow:1;min-height:0}.container.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{overflow-y:auto;height:auto;max-height:var(--sheet-max-height, 500px);border-radius:0!important;border:1px solid var(--border-color-primary);border-top:var(--show-group-name);border-bottom-left-radius:var(--radius-lg);border-bottom-right-radius:var(--radius-lg);background-color:var(--background-fill-secondary)}.closed.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{display:none}.group-header.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{display:flex;justify-content:space-between;align-items:center;width:100%;padding:var(--spacing-sm) var(--spacing-md);background-color:var(--input-background-fill);color:var(--body-text-color);text-align:left;cursor:pointer;font-size:var(--text-md);font-weight:var(--font-weight-bold);border:1px solid var(--border-color-primary)}.properties-grid.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{display:grid;grid-template-columns:1fr 2fr;gap:0;padding:0}.prop-label.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn,.prop-control.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{padding:var(--spacing-sm) var(--spacing-md);display:flex;align-items:center;border-bottom:1px solid var(--background-fill-secondary)}.prop-label.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{background-color:var(--background-fill-primary);color:var(--body-text-color);opacity:3.7;font-weight:var(--font-weight-semibold);font-size:var(--text-xs);text-align:right;justify-content:flex-end;word-break:break-word}.prop-control.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{gap:var(--spacing-sm)}.properties-grid.svelte-1u03acn>.svelte-1u03acn.svelte-1u03acn:nth-last-child(-n+2){border-bottom:none}.prop-control.svelte-1u03acn input[type=text].svelte-1u03acn.svelte-1u03acn,.prop-control.svelte-1u03acn input[type=password].svelte-1u03acn.svelte-1u03acn,.prop-control.svelte-1u03acn input[type=number].svelte-1u03acn.svelte-1u03acn{background-color:var(--input-background-fill);border:var(--input-border-width) solid var(--border-color-primary);box-shadow:var(--input-shadow);color:var(--input-text-color);font-size:var(--input-text-size);border-radius:0;width:100%;padding-top:var(--spacing-1);padding-bottom:var(--spacing-1);padding-left:var(--spacing-md);padding-right:var(--spacing-3)}.prop-control.svelte-1u03acn input[type=text].svelte-1u03acn.svelte-1u03acn:focus,.prop-control.svelte-1u03acn input[type=number].svelte-1u03acn.svelte-1u03acn:focus{box-shadow:var(--input-shadow-focus);border-color:var(--input-border-color-focus);background-color:var(--input-background-fill-focus);outline:none}.dropdown-wrapper.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{position:relative;width:100%}.dropdown-wrapper.svelte-1u03acn select.svelte-1u03acn.svelte-1u03acn{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--input-background-fill);border:var(--input-border-width) solid var(--border-color-primary);box-shadow:var(--input-shadow);color:var(--input-text-color);font-size:var(--input-text-size);width:100%;cursor:pointer;border-radius:0;padding-top:var(--spacing-1);padding-bottom:var(--spacing-1);padding-left:var(--spacing-md);padding-right:calc(var(--spacing-3) + 1.2em)}.dropdown-arrow-icon.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{position:absolute;top:50%;right:var(--spacing-3);transform:translateY(-50%);width:1em;height:1em;pointer-events:none;z-index:1;background-color:var(--body-text-color-subdued);-webkit-mask-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='currentColor' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M6 8l4 4 4-4'/%3e%3c/svg%3e");mask-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='currentColor' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M6 8l4 4 4-4'%3e%3c/svg%3e")}.dropdown-wrapper.svelte-1u03acn select.svelte-1u03acn.svelte-1u03acn:focus{box-shadow:var(--input-shadow-focus);border-color:var(--input-border-color-focus);background-color:var(--input-background-fill-focus);outline:none}.dropdown-wrapper.svelte-1u03acn select option.svelte-1u03acn.svelte-1u03acn{background:var(--input-background-fill);color:var(--body-text-color)}.prop-control.svelte-1u03acn input[type=checkbox].svelte-1u03acn.svelte-1u03acn{-webkit-appearance:none;-moz-appearance:none;appearance:none;position:relative;width:var(--size-4);height:var(--size-4);border-radius:5px!important;border:1px solid var(--checkbox-border-color);background-color:var(--checkbox-background-color);box-shadow:var(--checkbox-shadow);cursor:pointer;margin:0;transition:background-color .2s,border-color .2s}.prop-control.svelte-1u03acn input[type=checkbox].svelte-1u03acn.svelte-1u03acn:hover{border-color:var(--checkbox-border-color-hover);background-color:var(--checkbox-background-color-hover)}.prop-control.svelte-1u03acn input[type=checkbox].svelte-1u03acn.svelte-1u03acn:focus{border-color:var(--checkbox-border-color-focus);background-color:var(--checkbox-background-color-focus);outline:none}.prop-control.svelte-1u03acn input[type=checkbox].svelte-1u03acn.svelte-1u03acn:checked{background-color:var(--checkbox-background-color-selected);border-color:var(--checkbox-border-color-focus)}.prop-control.svelte-1u03acn input[type=checkbox].svelte-1u03acn.svelte-1u03acn:checked:after{content:"";position:absolute;display:block;top:50%;left:50%;width:4px;height:8px;border:solid var(--checkbox-label-text-color-selected);border-width:0 2px 2px 0;transform:translate(-50%,-60%) rotate(45deg)}.slider-container.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{display:flex;align-items:center;gap:var(--spacing-md);width:100%}.slider-container.svelte-1u03acn input[type=range].svelte-1u03acn.svelte-1u03acn{--slider-progress:0%;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;cursor:pointer;width:100%}.slider-container.svelte-1u03acn input[type=range].svelte-1u03acn.svelte-1u03acn::-webkit-slider-runnable-track{height:8px;border-radius:var(--radius-lg);background:linear-gradient(to right,var(--slider-color) var(--slider-progress),var(--input-background-fill) var(--slider-progress))}.slider-container.svelte-1u03acn input[type=range].svelte-1u03acn.svelte-1u03acn::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none;margin-top:-4px;background-color:#fff;border-radius:50%;height:16px;width:16px;border:1px solid var(--border-color-primary);box-shadow:var(--shadow-drop)}.slider-container.svelte-1u03acn input[type=range].svelte-1u03acn.svelte-1u03acn::-moz-range-track{height:8px;border-radius:var(--radius-lg);background:linear-gradient(to right,var(--slider-color) var(--slider-progress),var(--input-background-fill) var(--slider-progress))}.slider-container.svelte-1u03acn input[type=range].svelte-1u03acn.svelte-1u03acn::-moz-range-thumb{background-color:#fff;border-radius:50%;height:16px;width:16px;border:1px solid var(--border-color-primary);box-shadow:var(--shadow-drop)}.slider-value.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{min-width:40px;text-align:right;font-family:var(--font-mono);font-size:var(--text-xs)}.prop-label-wrapper.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{display:flex;justify-content:flex-end;align-items:center;gap:var(--spacing-sm);width:100%}.tooltip-container.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{position:relative;display:inline-flex;align-items:center;justify-content:center}.tooltip-icon.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{display:flex;align-items:center;justify-content:center;width:14px;height:14px;border-radius:50%;background-color:var(--body-text-color-subdued);color:var(--background-fill-primary);font-size:10px;font-weight:700;cursor:help;-webkit-user-select:none;user-select:none}.tooltip-text.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{visibility:hidden;width:200px;background-color:var(--body-text-color);color:var(--background-fill-primary);text-align:center;border-radius:var(--radius-md);padding:var(--spacing-md);position:absolute;z-index:50;bottom:-50%;left:50%;transform:translate(-50%);opacity:0;transition:opacity .3s}.tooltip-container.svelte-1u03acn:hover .tooltip-text.svelte-1u03acn.svelte-1u03acn{visibility:visible;opacity:1}.color-picker-container.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{display:flex;align-items:center;gap:var(--spacing-md);width:100%}.color-picker-input.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{width:50px;height:28px;background-color:transparent;border:1px solid var(--border-color-primary);border-radius:var(--radius-sm);cursor:pointer;padding:0}.color-picker-input.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn::-webkit-color-swatch-wrapper{padding:2px}.color-picker-input.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn::-moz-padding{padding:2px}.color-picker-input.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn::-webkit-color-swatch{border:none;border-radius:var(--radius-sm)}.color-picker-input.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn::-moz-color-swatch{border:none;border-radius:var(--radius-sm)}.color-picker-value.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{font-family:var(--font-mono);font-size:var(--text-sm);color:var(--body-text-color-subdued)}.prop-control.svelte-1u03acn input.invalid.svelte-1u03acn.svelte-1u03acn{border-color:var(--error-border-color, red)!important;box-shadow:0 0 0 1px var(--error-border-color, red)!important}.reset-button-prop.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{display:flex;align-items:center;justify-content:center;background:none;border:none;border-left:1px solid var(--border-color-primary);cursor:pointer;color:var(--body-text-color-subdued);font-size:var(--text-lg);padding:0 var(--spacing-2);visibility:hidden;opacity:0;transition:opacity .15s ease-in-out,color .15s ease-in-out}.reset-button-prop.visible.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{visibility:visible;opacity:1}.reset-button-prop.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn:hover{color:var(--body-text-color);background-color:var(--background-fill-secondary-hover)}.reset-button-prop.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn:disabled{color:var(--body-text-color-subdued)!important;opacity:.5;cursor:not-allowed;background-color:transparent!important}.prop-control.svelte-1u03acn .disabled.svelte-1u03acn.svelte-1u03acn{opacity:.5;pointer-events:none;cursor:not-allowed}.prop-control.svelte-1u03acn .disabled input.svelte-1u03acn.svelte-1u03acn{cursor:not-allowed}.reset-button-prop.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn:disabled{opacity:.3;cursor:not-allowed;background-color:transparent!important}.radio-group.svelte-1u03acn.svelte-1u03acn.svelte-1u03acn{display:flex;flex-wrap:wrap;gap:var(--spacing-sm);width:100%}.radio-item.svelte-1u03acn input[type=radio].svelte-1u03acn.svelte-1u03acn{display:none}.radio-item.svelte-1u03acn label.svelte-1u03acn.svelte-1u03acn{display:inline-block;padding:var(--spacing-xs) var(--spacing-md);border:1px solid var(--border-color-primary);border-radius:5px!important;background-color:var(--input-background-fill);color:var(--body-text-color);font-size:var(--text-xs);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .2s,border-color .2s,color .2s}.radio-group.disabled.svelte-1u03acn .radio-item label.svelte-1u03acn.svelte-1u03acn{cursor:not-allowed}.radio-item.svelte-1u03acn input[type=radio].svelte-1u03acn:hover+label.svelte-1u03acn{border-color:var(--border-color-accent-subdued);background-color:var(--background-fill-secondary-hover)}.radio-item.svelte-1u03acn input[type=radio].svelte-1u03acn:checked+label.svelte-1u03acn{background-color:var(--primary-500);border-color:var(--primary-500);color:#fff;font-weight:var(--font-weight-bold)}.radio-group.disabled.svelte-1u03acn .radio-item input[type=radio].svelte-1u03acn:checked+label.svelte-1u03acn{background-color:var(--neutral-300);border-color:var(--neutral-300);color:var(--neutral-500)}
src/demo/app.py CHANGED
@@ -9,41 +9,126 @@ from gradio_htmlinjector import HTMLInjector
9
 
10
  # --- 1. Dataclass Definitions (unchanged) ---
11
  @dataclass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  class ModelSettings:
13
  model_type: Literal["SD 1.5", "SDXL", "Pony", "Custom"] = field(
14
- default="SDXL", metadata={"component": "dropdown", "label": "Base Model"}
 
 
 
 
 
15
  )
16
  custom_model_path: str = field(
17
  default="/path/to/default.safetensors",
18
  metadata={
19
  "label": "Custom Model Path",
20
  "interactive_if": {"field": "model_type", "value": "Custom"},
 
21
  },
22
  )
23
- vae_path: str = field(default="", metadata={"label": "VAE Path (optional)"})
24
-
 
 
 
 
 
25
 
26
  @dataclass
27
  class SamplingSettings:
28
  scheduler: Literal["Karras", "Simple", "Exponential"] = field(
29
  default="Karras",
30
- metadata={"component": "radio", "label": "Scheduler"}
 
 
 
 
31
  )
32
  sampler_name: Literal["Euler", "Euler a", "DPM++ 2M Karras", "UniPC"] = field(
33
  default="DPM++ 2M Karras",
34
- metadata={"component": "dropdown", "label": "Sampler"},
 
 
 
 
35
  )
36
  steps: int = field(
37
  default=25,
38
- metadata={"component": "slider", "minimum": 1, "maximum": 150, "step": 1},
 
 
 
 
 
 
 
39
  )
40
  cfg_scale: float = field(
41
  default=7.0,
42
- metadata={"component": "slider", "minimum": 1.0, "maximum": 30.0, "step": 0.5},
 
 
 
 
 
 
 
43
  )
44
  enable_advanced: bool = field(
45
  default=False,
46
- metadata={"label": "Enable Advanced Settings"}
 
 
 
47
  )
48
  advanced_option: float = field(
49
  default=0.5,
@@ -54,6 +139,7 @@ class SamplingSettings:
54
  "maximum": 1.0,
55
  "step": 0.01,
56
  "interactive_if": {"field": "enable_advanced", "value": True},
 
57
  },
58
  )
59
  temperature: float = field(
@@ -63,54 +149,106 @@ class SamplingSettings:
63
  "component": "number_float",
64
  "minimum": 0.1,
65
  "maximum": 2.0,
66
- "step": 0.1
 
67
  }
68
  )
69
 
70
  @dataclass
71
  class RenderConfig:
72
- randomize_seed: bool = field(default=True, metadata={"label": "Randomize Seed"})
 
 
 
 
 
 
 
 
 
 
73
  seed: int = field(
74
  default=-1,
75
- metadata={"component": "number_integer", "label": "Seed (-1 for random)"},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  )
77
- model: ModelSettings = field(default_factory=ModelSettings, metadata={"label": "Model Settings"})
78
- sampling: SamplingSettings = field(default_factory=SamplingSettings)
79
 
80
  @dataclass
81
  class Lighting:
82
  sun_intensity: float = field(
83
  default=1.0,
84
- metadata={"component": "slider", "minimum": 0, "maximum": 5, "step": 0.1},
 
 
 
 
 
 
 
85
  )
86
  color: str = field(
87
- default="#FFDDBB", metadata={"component": "colorpicker", "label": "Sun Color"}
 
 
 
 
 
88
  )
89
 
90
-
91
  @dataclass
92
  class EnvironmentConfig:
93
  background: Literal["Sky", "Color", "Image"] = field(
94
- default="Sky", metadata={"component": "dropdown"}
 
 
 
 
 
 
 
 
 
95
  )
96
- lighting: Lighting = field(default_factory=Lighting)
97
-
98
 
99
  @dataclass
100
  class EulerSettings:
101
  s_churn: float = field(
102
  default=0.0,
103
- metadata={"component": "slider", "minimum": 0.0, "maximum": 1.0, "step": 0.01},
 
 
 
 
 
 
 
104
  )
105
 
106
-
107
  @dataclass
108
  class DPM_Settings:
109
  karras_style: bool = field(
110
- default=True, metadata={"label": "Use Karras Sigma Schedule"}
 
 
 
 
111
  )
112
 
113
-
114
  # --- 2. Data Mappings and Initial Instances (unchanged) ---
115
  initial_render_config = RenderConfig()
116
  initial_env_config = EnvironmentConfig()
 
9
 
10
  # --- 1. Dataclass Definitions (unchanged) ---
11
  @dataclass
12
+ class APISettings:
13
+ api_key: str = field(
14
+ default="ab123cd45ef67890ghij123klmno456p",
15
+ metadata={
16
+ "label": "API Key",
17
+ "component": "password",
18
+ "help": "Your secret API key. It will not be displayed."
19
+ }
20
+ )
21
+ endpoint_url: str = field(
22
+ default="https://api.example.com",
23
+ metadata={
24
+ "label": "API Endpoint",
25
+ "component": "string", # string normal
26
+ "help": "The URL of the API server."
27
+ }
28
+ )
29
+
30
+ @dataclass
31
+ class QuantizationSettings:
32
+ quantization_method: Literal["None", "Quanto Library", "Layerwise & Bnb"] = field(
33
+ default="Layerwise & Bnb",
34
+ metadata={
35
+ "component": "radio",
36
+ "label": "Quantization Method",
37
+ "help": "Quantization mechanism to save VRAM and increase speed."
38
+ }
39
+ )
40
+ # Option 1: Literal values
41
+ quantize_mode_list: Literal["FP8", "INT8", "IN4"] = field(
42
+ default="FP8",
43
+ metadata={
44
+ "interactive_if": {"field": "quantization_method", "value": ["Quanto Library", "Layerwise & Bnb"]},
45
+ "component": "radio",
46
+ "label": "Quantization Mode (List)",
47
+ "help": "This becomes interactive if Quantization Method is 'Quanto' OR 'Layerwise'."
48
+ }
49
+ )
50
+ # Option 2: neq operand
51
+ quantize_mode_neq: Literal["FP8", "INT8", "IN4"] = field(
52
+ default="FP8",
53
+ metadata={
54
+ "interactive_if": {"field": "quantization_method", "neq": "None"},
55
+ "component": "radio",
56
+ "label": "Quantization Mode (Not Equal)",
57
+ "help": "This becomes interactive if Quantization Method is NOT 'None'."
58
+ }
59
+ )
60
+ @dataclass
61
  class ModelSettings:
62
  model_type: Literal["SD 1.5", "SDXL", "Pony", "Custom"] = field(
63
+ default="SDXL",
64
+ metadata={
65
+ "component": "dropdown",
66
+ "label": "Base Model",
67
+ "help": "Select the base diffusion model."
68
+ }
69
  )
70
  custom_model_path: str = field(
71
  default="/path/to/default.safetensors",
72
  metadata={
73
  "label": "Custom Model Path",
74
  "interactive_if": {"field": "model_type", "value": "Custom"},
75
+ "help": "Provide the local file path to your custom .safetensors or .ckpt model file. This is only active when 'Base Model' is set to 'Custom'."
76
  },
77
  )
78
+ vae_path: str = field(
79
+ default="",
80
+ metadata={
81
+ "label": "VAE Path (optional)",
82
+ "help": "Optionally, provide a path to a separate VAE file to improve color and detail."
83
+ }
84
+ )
85
 
86
  @dataclass
87
  class SamplingSettings:
88
  scheduler: Literal["Karras", "Simple", "Exponential"] = field(
89
  default="Karras",
90
+ metadata={
91
+ "component": "radio",
92
+ "label": "Scheduler",
93
+ "help": "Determines how the noise schedule is interpreted during sampling. 'Karras' is often recommended for high-quality results."
94
+ }
95
  )
96
  sampler_name: Literal["Euler", "Euler a", "DPM++ 2M Karras", "UniPC"] = field(
97
  default="DPM++ 2M Karras",
98
+ metadata={
99
+ "component": "dropdown",
100
+ "label": "Sampler",
101
+ "help": "The algorithm used to denoise the image over multiple steps. Different samplers can produce stylistically different results."
102
+ }
103
  )
104
  steps: int = field(
105
  default=25,
106
+ metadata={
107
+ "component": "slider",
108
+ "label": "Sampling Steps",
109
+ "minimum": 1,
110
+ "maximum": 150,
111
+ "step": 1,
112
+ "help": "The number of denoising steps. More steps can increase detail but also take longer. Values between 20-40 are common."
113
+ }
114
  )
115
  cfg_scale: float = field(
116
  default=7.0,
117
+ metadata={
118
+ "component": "slider",
119
+ "label": "CFG Scale",
120
+ "minimum": 1.0,
121
+ "maximum": 30.0,
122
+ "step": 0.5,
123
+ "help": "Classifier-Free Guidance Scale. Higher values make the image adhere more strictly to the prompt, while lower values allow for more creativity."
124
+ }
125
  )
126
  enable_advanced: bool = field(
127
  default=False,
128
+ metadata={
129
+ "label": "Enable Advanced Settings",
130
+ "help": "Check this box to reveal more experimental or fine-tuning options."
131
+ }
132
  )
133
  advanced_option: float = field(
134
  default=0.5,
 
139
  "maximum": 1.0,
140
  "step": 0.01,
141
  "interactive_if": {"field": "enable_advanced", "value": True},
142
+ "help": "An example of an advanced setting that is only visible when the corresponding checkbox is enabled."
143
  },
144
  )
145
  temperature: float = field(
 
149
  "component": "number_float",
150
  "minimum": 0.1,
151
  "maximum": 2.0,
152
+ "step": 0.1,
153
+ "help": "Controls the randomness of the sampling process. A value of 1.0 is standard. Higher values increase diversity at the risk of artifacts."
154
  }
155
  )
156
 
157
  @dataclass
158
  class RenderConfig:
159
+ api_settings: APISettings = field(
160
+ default_factory=APISettings,
161
+ metadata={"label": "API Settings"}
162
+ )
163
+ randomize_seed: bool = field(
164
+ default=True,
165
+ metadata={
166
+ "label": "Randomize Seed",
167
+ "help": "If checked, a new random seed will be used for each generation. Uncheck to use the specific seed value below."
168
+ }
169
+ )
170
  seed: int = field(
171
  default=-1,
172
+ metadata={
173
+ "component": "number_integer",
174
+ "label": "Seed",
175
+ "help": "The seed for the random number generator. A value of -1 means a random seed will be chosen. The same seed and settings will produce the same image."
176
+ }
177
+ )
178
+ model: ModelSettings = field(
179
+ default_factory=ModelSettings,
180
+ metadata={"label": "Model Settings"}
181
+ )
182
+ sampling: SamplingSettings = field(
183
+ default_factory=SamplingSettings,
184
+ metadata={"label": "Sampling Settings"}
185
+ )
186
+ quantization: QuantizationSettings = field(
187
+ default_factory=QuantizationSettings,
188
+ metadata={"label": "Quantization Settings"}
189
  )
 
 
190
 
191
  @dataclass
192
  class Lighting:
193
  sun_intensity: float = field(
194
  default=1.0,
195
+ metadata={
196
+ "component": "slider",
197
+ "label": "Sun Intensity",
198
+ "minimum": 0,
199
+ "maximum": 5,
200
+ "step": 0.1,
201
+ "help": "Controls the brightness of the main light source in the scene."
202
+ }
203
  )
204
  color: str = field(
205
+ default="#FFDDBB",
206
+ metadata={
207
+ "component": "colorpicker",
208
+ "label": "Sun Color",
209
+ "help": "Sets the color of the main light source."
210
+ }
211
  )
212
 
 
213
  @dataclass
214
  class EnvironmentConfig:
215
  background: Literal["Sky", "Color", "Image"] = field(
216
+ default="Sky",
217
+ metadata={
218
+ "component": "dropdown",
219
+ "label": "Background Type",
220
+ "help": "Choose the type of background for the environment."
221
+ }
222
+ )
223
+ lighting: Lighting = field(
224
+ default_factory=Lighting,
225
+ metadata={"label": "Lighting"}
226
  )
 
 
227
 
228
  @dataclass
229
  class EulerSettings:
230
  s_churn: float = field(
231
  default=0.0,
232
+ metadata={
233
+ "component": "slider",
234
+ "label": "S_Churn",
235
+ "minimum": 0.0,
236
+ "maximum": 1.0,
237
+ "step": 0.01,
238
+ "help": "Stochasticity churn factor for Euler samplers. Adds extra noise at each step, affecting diversity. 0.0 is deterministic."
239
+ }
240
  )
241
 
 
242
  @dataclass
243
  class DPM_Settings:
244
  karras_style: bool = field(
245
+ default=True,
246
+ metadata={
247
+ "label": "Use Karras Sigma Schedule",
248
+ "help": "If checked, uses the Karras noise schedule, which is often recommended for DPM++ samplers to improve image quality, especially in later steps."
249
+ }
250
  )
251
 
 
252
  # --- 2. Data Mappings and Initial Instances (unchanged) ---
253
  initial_render_config = RenderConfig()
254
  initial_env_config = EnvironmentConfig()
src/demo/space.py CHANGED
@@ -49,41 +49,126 @@ from gradio_htmlinjector import HTMLInjector
49
 
50
  # --- 1. Dataclass Definitions (unchanged) ---
51
  @dataclass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  class ModelSettings:
53
  model_type: Literal["SD 1.5", "SDXL", "Pony", "Custom"] = field(
54
- default="SDXL", metadata={"component": "dropdown", "label": "Base Model"}
 
 
 
 
 
55
  )
56
  custom_model_path: str = field(
57
  default="/path/to/default.safetensors",
58
  metadata={
59
  "label": "Custom Model Path",
60
  "interactive_if": {"field": "model_type", "value": "Custom"},
 
61
  },
62
  )
63
- vae_path: str = field(default="", metadata={"label": "VAE Path (optional)"})
64
-
 
 
 
 
 
65
 
66
  @dataclass
67
  class SamplingSettings:
68
  scheduler: Literal["Karras", "Simple", "Exponential"] = field(
69
  default="Karras",
70
- metadata={"component": "radio", "label": "Scheduler"}
 
 
 
 
71
  )
72
  sampler_name: Literal["Euler", "Euler a", "DPM++ 2M Karras", "UniPC"] = field(
73
  default="DPM++ 2M Karras",
74
- metadata={"component": "dropdown", "label": "Sampler"},
 
 
 
 
75
  )
76
  steps: int = field(
77
  default=25,
78
- metadata={"component": "slider", "minimum": 1, "maximum": 150, "step": 1},
 
 
 
 
 
 
 
79
  )
80
  cfg_scale: float = field(
81
  default=7.0,
82
- metadata={"component": "slider", "minimum": 1.0, "maximum": 30.0, "step": 0.5},
 
 
 
 
 
 
 
83
  )
84
  enable_advanced: bool = field(
85
  default=False,
86
- metadata={"label": "Enable Advanced Settings"}
 
 
 
87
  )
88
  advanced_option: float = field(
89
  default=0.5,
@@ -94,6 +179,7 @@ class SamplingSettings:
94
  "maximum": 1.0,
95
  "step": 0.01,
96
  "interactive_if": {"field": "enable_advanced", "value": True},
 
97
  },
98
  )
99
  temperature: float = field(
@@ -103,54 +189,106 @@ class SamplingSettings:
103
  "component": "number_float",
104
  "minimum": 0.1,
105
  "maximum": 2.0,
106
- "step": 0.1
 
107
  }
108
  )
109
 
110
  @dataclass
111
  class RenderConfig:
112
- randomize_seed: bool = field(default=True, metadata={"label": "Randomize Seed"})
 
 
 
 
 
 
 
 
 
 
113
  seed: int = field(
114
  default=-1,
115
- metadata={"component": "number_integer", "label": "Seed (-1 for random)"},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  )
117
- model: ModelSettings = field(default_factory=ModelSettings, metadata={"label": "Model Settings"})
118
- sampling: SamplingSettings = field(default_factory=SamplingSettings)
119
 
120
  @dataclass
121
  class Lighting:
122
  sun_intensity: float = field(
123
  default=1.0,
124
- metadata={"component": "slider", "minimum": 0, "maximum": 5, "step": 0.1},
 
 
 
 
 
 
 
125
  )
126
  color: str = field(
127
- default="#FFDDBB", metadata={"component": "colorpicker", "label": "Sun Color"}
 
 
 
 
 
128
  )
129
 
130
-
131
  @dataclass
132
  class EnvironmentConfig:
133
  background: Literal["Sky", "Color", "Image"] = field(
134
- default="Sky", metadata={"component": "dropdown"}
 
 
 
 
 
 
 
 
 
135
  )
136
- lighting: Lighting = field(default_factory=Lighting)
137
-
138
 
139
  @dataclass
140
  class EulerSettings:
141
  s_churn: float = field(
142
  default=0.0,
143
- metadata={"component": "slider", "minimum": 0.0, "maximum": 1.0, "step": 0.01},
 
 
 
 
 
 
 
144
  )
145
 
146
-
147
  @dataclass
148
  class DPM_Settings:
149
  karras_style: bool = field(
150
- default=True, metadata={"label": "Use Karras Sigma Schedule"}
 
 
 
 
151
  )
152
 
153
-
154
  # --- 2. Data Mappings and Initial Instances (unchanged) ---
155
  initial_render_config = RenderConfig()
156
  initial_env_config = EnvironmentConfig()
 
49
 
50
  # --- 1. Dataclass Definitions (unchanged) ---
51
  @dataclass
52
+ class APISettings:
53
+ api_key: str = field(
54
+ default="ab123cd45ef67890ghij123klmno456p",
55
+ metadata={
56
+ "label": "API Key",
57
+ "component": "password",
58
+ "help": "Your secret API key. It will not be displayed."
59
+ }
60
+ )
61
+ endpoint_url: str = field(
62
+ default="https://api.example.com",
63
+ metadata={
64
+ "label": "API Endpoint",
65
+ "component": "string", # string normal
66
+ "help": "The URL of the API server."
67
+ }
68
+ )
69
+
70
+ @dataclass
71
+ class QuantizationSettings:
72
+ quantization_method: Literal["None", "Quanto Library", "Layerwise & Bnb"] = field(
73
+ default="Layerwise & Bnb",
74
+ metadata={
75
+ "component": "radio",
76
+ "label": "Quantization Method",
77
+ "help": "Quantization mechanism to save VRAM and increase speed."
78
+ }
79
+ )
80
+ # Option 1: Literal values
81
+ quantize_mode_list: Literal["FP8", "INT8", "IN4"] = field(
82
+ default="FP8",
83
+ metadata={
84
+ "interactive_if": {"field": "quantization_method", "value": ["Quanto Library", "Layerwise & Bnb"]},
85
+ "component": "radio",
86
+ "label": "Quantization Mode (List)",
87
+ "help": "This becomes interactive if Quantization Method is 'Quanto' OR 'Layerwise'."
88
+ }
89
+ )
90
+ # Option 2: neq operand
91
+ quantize_mode_neq: Literal["FP8", "INT8", "IN4"] = field(
92
+ default="FP8",
93
+ metadata={
94
+ "interactive_if": {"field": "quantization_method", "neq": "None"},
95
+ "component": "radio",
96
+ "label": "Quantization Mode (Not Equal)",
97
+ "help": "This becomes interactive if Quantization Method is NOT 'None'."
98
+ }
99
+ )
100
+ @dataclass
101
  class ModelSettings:
102
  model_type: Literal["SD 1.5", "SDXL", "Pony", "Custom"] = field(
103
+ default="SDXL",
104
+ metadata={
105
+ "component": "dropdown",
106
+ "label": "Base Model",
107
+ "help": "Select the base diffusion model."
108
+ }
109
  )
110
  custom_model_path: str = field(
111
  default="/path/to/default.safetensors",
112
  metadata={
113
  "label": "Custom Model Path",
114
  "interactive_if": {"field": "model_type", "value": "Custom"},
115
+ "help": "Provide the local file path to your custom .safetensors or .ckpt model file. This is only active when 'Base Model' is set to 'Custom'."
116
  },
117
  )
118
+ vae_path: str = field(
119
+ default="",
120
+ metadata={
121
+ "label": "VAE Path (optional)",
122
+ "help": "Optionally, provide a path to a separate VAE file to improve color and detail."
123
+ }
124
+ )
125
 
126
  @dataclass
127
  class SamplingSettings:
128
  scheduler: Literal["Karras", "Simple", "Exponential"] = field(
129
  default="Karras",
130
+ metadata={
131
+ "component": "radio",
132
+ "label": "Scheduler",
133
+ "help": "Determines how the noise schedule is interpreted during sampling. 'Karras' is often recommended for high-quality results."
134
+ }
135
  )
136
  sampler_name: Literal["Euler", "Euler a", "DPM++ 2M Karras", "UniPC"] = field(
137
  default="DPM++ 2M Karras",
138
+ metadata={
139
+ "component": "dropdown",
140
+ "label": "Sampler",
141
+ "help": "The algorithm used to denoise the image over multiple steps. Different samplers can produce stylistically different results."
142
+ }
143
  )
144
  steps: int = field(
145
  default=25,
146
+ metadata={
147
+ "component": "slider",
148
+ "label": "Sampling Steps",
149
+ "minimum": 1,
150
+ "maximum": 150,
151
+ "step": 1,
152
+ "help": "The number of denoising steps. More steps can increase detail but also take longer. Values between 20-40 are common."
153
+ }
154
  )
155
  cfg_scale: float = field(
156
  default=7.0,
157
+ metadata={
158
+ "component": "slider",
159
+ "label": "CFG Scale",
160
+ "minimum": 1.0,
161
+ "maximum": 30.0,
162
+ "step": 0.5,
163
+ "help": "Classifier-Free Guidance Scale. Higher values make the image adhere more strictly to the prompt, while lower values allow for more creativity."
164
+ }
165
  )
166
  enable_advanced: bool = field(
167
  default=False,
168
+ metadata={
169
+ "label": "Enable Advanced Settings",
170
+ "help": "Check this box to reveal more experimental or fine-tuning options."
171
+ }
172
  )
173
  advanced_option: float = field(
174
  default=0.5,
 
179
  "maximum": 1.0,
180
  "step": 0.01,
181
  "interactive_if": {"field": "enable_advanced", "value": True},
182
+ "help": "An example of an advanced setting that is only visible when the corresponding checkbox is enabled."
183
  },
184
  )
185
  temperature: float = field(
 
189
  "component": "number_float",
190
  "minimum": 0.1,
191
  "maximum": 2.0,
192
+ "step": 0.1,
193
+ "help": "Controls the randomness of the sampling process. A value of 1.0 is standard. Higher values increase diversity at the risk of artifacts."
194
  }
195
  )
196
 
197
  @dataclass
198
  class RenderConfig:
199
+ api_settings: APISettings = field(
200
+ default_factory=APISettings,
201
+ metadata={"label": "API Settings"}
202
+ )
203
+ randomize_seed: bool = field(
204
+ default=True,
205
+ metadata={
206
+ "label": "Randomize Seed",
207
+ "help": "If checked, a new random seed will be used for each generation. Uncheck to use the specific seed value below."
208
+ }
209
+ )
210
  seed: int = field(
211
  default=-1,
212
+ metadata={
213
+ "component": "number_integer",
214
+ "label": "Seed",
215
+ "help": "The seed for the random number generator. A value of -1 means a random seed will be chosen. The same seed and settings will produce the same image."
216
+ }
217
+ )
218
+ model: ModelSettings = field(
219
+ default_factory=ModelSettings,
220
+ metadata={"label": "Model Settings"}
221
+ )
222
+ sampling: SamplingSettings = field(
223
+ default_factory=SamplingSettings,
224
+ metadata={"label": "Sampling Settings"}
225
+ )
226
+ quantization: QuantizationSettings = field(
227
+ default_factory=QuantizationSettings,
228
+ metadata={"label": "Quantization Settings"}
229
  )
 
 
230
 
231
  @dataclass
232
  class Lighting:
233
  sun_intensity: float = field(
234
  default=1.0,
235
+ metadata={
236
+ "component": "slider",
237
+ "label": "Sun Intensity",
238
+ "minimum": 0,
239
+ "maximum": 5,
240
+ "step": 0.1,
241
+ "help": "Controls the brightness of the main light source in the scene."
242
+ }
243
  )
244
  color: str = field(
245
+ default="#FFDDBB",
246
+ metadata={
247
+ "component": "colorpicker",
248
+ "label": "Sun Color",
249
+ "help": "Sets the color of the main light source."
250
+ }
251
  )
252
 
 
253
  @dataclass
254
  class EnvironmentConfig:
255
  background: Literal["Sky", "Color", "Image"] = field(
256
+ default="Sky",
257
+ metadata={
258
+ "component": "dropdown",
259
+ "label": "Background Type",
260
+ "help": "Choose the type of background for the environment."
261
+ }
262
+ )
263
+ lighting: Lighting = field(
264
+ default_factory=Lighting,
265
+ metadata={"label": "Lighting"}
266
  )
 
 
267
 
268
  @dataclass
269
  class EulerSettings:
270
  s_churn: float = field(
271
  default=0.0,
272
+ metadata={
273
+ "component": "slider",
274
+ "label": "S_Churn",
275
+ "minimum": 0.0,
276
+ "maximum": 1.0,
277
+ "step": 0.01,
278
+ "help": "Stochasticity churn factor for Euler samplers. Adds extra noise at each step, affecting diversity. 0.0 is deterministic."
279
+ }
280
  )
281
 
 
282
  @dataclass
283
  class DPM_Settings:
284
  karras_style: bool = field(
285
+ default=True,
286
+ metadata={
287
+ "label": "Use Karras Sigma Schedule",
288
+ "help": "If checked, uses the Karras noise schedule, which is often recommended for DPM++ samplers to improve image quality, especially in later steps."
289
+ }
290
  )
291
 
 
292
  # --- 2. Data Mappings and Initial Instances (unchanged) ---
293
  initial_render_config = RenderConfig()
294
  initial_env_config = EnvironmentConfig()
src/frontend/Index.svelte CHANGED
@@ -319,9 +319,28 @@
319
  {#if Array.isArray(group.properties)}
320
  {#each group.properties as prop (prop.name)}
321
  <!-- Conditional interactivity based on another property's value -->
322
- {@const is_interactive = interactive && (prop.interactive_if
323
- ? get_prop_value(prop.interactive_if.field) === prop.interactive_if.value
324
- : true)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
 
326
  <label class="prop-label" for={prop.name}>
327
  <div class="prop-label-wrapper">
@@ -346,6 +365,14 @@
346
  on:change={() => dispatch_update("change", prop)}
347
  on:input={() => dispatch_update("input", prop)}
348
  />
 
 
 
 
 
 
 
 
349
  {:else if prop.component === 'checkbox'}
350
  <input
351
  type="checkbox"
@@ -532,10 +559,11 @@
532
  align-items: center;
533
  border-bottom: 1px solid var(--background-fill-secondary);
534
  }
 
535
  .prop-label {
536
  background-color: var(--background-fill-primary);
537
  color: var(--body-text-color);
538
- opacity: 0.7;
539
  font-weight: var(--font-weight-semibold);
540
  font-size: var(--text-xs);
541
  text-align: right;
@@ -549,6 +577,7 @@
549
  border-bottom: none;
550
  }
551
  .prop-control input[type="text"],
 
552
  .prop-control input[type="number"] {
553
  background-color: var(--input-background-fill);
554
  border: var(--input-border-width) solid var(--border-color-primary);
@@ -737,16 +766,16 @@
737
  border-radius: var(--radius-md);
738
  padding: var(--spacing-md);
739
  position: absolute;
740
- z-index: 10;
741
- bottom: 125%;
742
- left: 50%;
743
  transform: translateX(-50%);
744
  opacity: 0;
745
  transition: opacity 0.3s;
746
  }
747
  .tooltip-container:hover .tooltip-text {
748
  visibility: visible;
749
- opacity: 1;
750
  }
751
  .color-picker-container {
752
  display: flex;
 
319
  {#if Array.isArray(group.properties)}
320
  {#each group.properties as prop (prop.name)}
321
  <!-- Conditional interactivity based on another property's value -->
322
+ {@const condition = prop.interactive_if}
323
+ {@const parent_value = condition ? get_prop_value(condition.field) : null}
324
+
325
+ {@const is_interactive = interactive && (
326
+ !condition ?
327
+ true // No condition, so it's interactive by default.
328
+ :
329
+ condition.value !== undefined ?
330
+ // Case 1: `value` key exists (equality check)
331
+ Array.isArray(condition.value) ?
332
+ // If `value` is an array, check if parent_value is IN the array.
333
+ condition.value.includes(parent_value)
334
+ :
335
+ // If `value` is a single item, do a strict equality check.
336
+ parent_value === condition.value
337
+ :
338
+ condition.neq !== undefined ?
339
+ // Case 2: `neq` key exists (inequality check)
340
+ parent_value !== condition.neq
341
+ :
342
+ true // Fallback if `interactive_if` is malformed.
343
+ )}
344
 
345
  <label class="prop-label" for={prop.name}>
346
  <div class="prop-label-wrapper">
 
365
  on:change={() => dispatch_update("change", prop)}
366
  on:input={() => dispatch_update("input", prop)}
367
  />
368
+ {:else if prop.component === 'password'}
369
+ <input
370
+ type="password"
371
+ bind:value={prop.value}
372
+ disabled={!is_interactive}
373
+ on:change={() => dispatch_update("change", prop)}
374
+ on:input={() => dispatch_update("input", prop)}
375
+ />
376
  {:else if prop.component === 'checkbox'}
377
  <input
378
  type="checkbox"
 
559
  align-items: center;
560
  border-bottom: 1px solid var(--background-fill-secondary);
561
  }
562
+
563
  .prop-label {
564
  background-color: var(--background-fill-primary);
565
  color: var(--body-text-color);
566
+ opacity: 3.7;
567
  font-weight: var(--font-weight-semibold);
568
  font-size: var(--text-xs);
569
  text-align: right;
 
577
  border-bottom: none;
578
  }
579
  .prop-control input[type="text"],
580
+ .prop-control input[type="password"],
581
  .prop-control input[type="number"] {
582
  background-color: var(--input-background-fill);
583
  border: var(--input-border-width) solid var(--border-color-primary);
 
766
  border-radius: var(--radius-md);
767
  padding: var(--spacing-md);
768
  position: absolute;
769
+ z-index: 50;
770
+ bottom: -50%;
771
+ left: 50%;
772
  transform: translateX(-50%);
773
  opacity: 0;
774
  transition: opacity 0.3s;
775
  }
776
  .tooltip-container:hover .tooltip-text {
777
  visibility: visible;
778
+ opacity: 1.0;
779
  }
780
  .color-picker-container {
781
  display: flex;
src/pyproject.toml CHANGED
@@ -8,7 +8,7 @@ build-backend = "hatchling.build"
8
 
9
  [project]
10
  name = "gradio_propertysheet"
11
- version = "0.0.12"
12
  description = "Property sheet"
13
  readme = "README.md"
14
  license = "apache-2.0"
 
8
 
9
  [project]
10
  name = "gradio_propertysheet"
11
+ version = "0.0.13"
12
  description = "Property sheet"
13
  readme = "README.md"
14
  license = "apache-2.0"