multimodalart HF staff commited on
Commit
89cc8a4
1 Parent(s): aff90d1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -218
app.py CHANGED
@@ -72,12 +72,16 @@ def update_selection(evt: gr.SelectData, selected_indices, width, height):
72
  selected_info_2 = ""
73
  lora_scale_1 = 0.95
74
  lora_scale_2 = 0.95
 
 
75
  if len(selected_indices) >= 1:
76
  lora1 = loras[selected_indices[0]]
77
  selected_info_1 = f"### LoRA 1 Selected: [{lora1['title']}](https://huggingface.co/{lora1['repo']}) ✨"
 
78
  if len(selected_indices) >= 2:
79
  lora2 = loras[selected_indices[1]]
80
  selected_info_2 = f"### LoRA 2 Selected: [{lora2['title']}](https://huggingface.co/{lora2['repo']}) ✨"
 
81
 
82
  # Update prompt placeholder based on last selected LoRA
83
  if selected_indices:
@@ -95,6 +99,8 @@ def update_selection(evt: gr.SelectData, selected_indices, width, height):
95
  lora_scale_2,
96
  width,
97
  height,
 
 
98
  )
99
 
100
  def remove_lora_1(selected_indices):
@@ -106,13 +112,17 @@ def remove_lora_1(selected_indices):
106
  selected_info_2 = ""
107
  lora_scale_1 = 0.95
108
  lora_scale_2 = 0.95
 
 
109
  if len(selected_indices) >= 1:
110
  lora1 = loras[selected_indices[0]]
111
  selected_info_1 = f"### LoRA 1 Selected: [{lora1['title']}](https://huggingface.co/{lora1['repo']}) ✨"
 
112
  if len(selected_indices) >= 2:
113
  lora2 = loras[selected_indices[1]]
114
  selected_info_2 = f"### LoRA 2 Selected: [{lora2['title']}](https://huggingface.co/{lora2['repo']}) ✨"
115
- return selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2
 
116
 
117
  def remove_lora_2(selected_indices):
118
  selected_indices = selected_indices or []
@@ -123,227 +133,35 @@ def remove_lora_2(selected_indices):
123
  selected_info_2 = ""
124
  lora_scale_1 = 0.95
125
  lora_scale_2 = 0.95
 
 
126
  if len(selected_indices) >= 1:
127
  lora1 = loras[selected_indices[0]]
128
  selected_info_1 = f"### LoRA 1 Selected: [{lora1['title']}](https://huggingface.co/{lora1['repo']}) ✨"
 
129
  if len(selected_indices) >= 2:
130
  lora2 = loras[selected_indices[1]]
131
  selected_info_2 = f"### LoRA 2 Selected: [{lora2['title']}](https://huggingface.co/{lora2['repo']}) ✨"
132
- return selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2
 
133
 
134
  def randomize_loras(selected_indices):
135
  if len(loras) < 2:
136
  raise gr.Error("Not enough LoRAs to randomize.")
137
  selected_indices = random.sample(range(len(loras)), 2)
138
- selected_info_1 = f"### LoRA 1 Selected: [{loras[selected_indices[0]]['title']}](https://huggingface.co/{loras[selected_indices[0]]['repo']}) ✨"
139
- selected_info_2 = f"### LoRA 2 Selected: [{loras[selected_indices[1]]['title']}](https://huggingface.co/{loras[selected_indices[1]]['repo']}) ✨"
 
 
140
  lora_scale_1 = 0.95
141
  lora_scale_2 = 0.95
142
- return selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2
 
 
143
 
144
- @spaces.GPU(duration=70)
145
- def generate_image(prompt_mash, steps, seed, cfg_scale, width, height, progress):
146
- pipe.to("cuda")
147
- generator = torch.Generator(device="cuda").manual_seed(seed)
148
- with calculateDuration("Generating image"):
149
- # Generate image
150
- for img in pipe.flux_pipe_call_that_returns_an_iterable_of_images(
151
- prompt=prompt_mash,
152
- num_inference_steps=steps,
153
- guidance_scale=cfg_scale,
154
- width=width,
155
- height=height,
156
- generator=generator,
157
- joint_attention_kwargs={"scale": 1.0},
158
- output_type="pil",
159
- good_vae=good_vae,
160
- ):
161
- yield img
162
-
163
- @spaces.GPU(duration=70)
164
- def generate_image_to_image(prompt_mash, image_input_path, image_strength, steps, cfg_scale, width, height, seed):
165
- generator = torch.Generator(device="cuda").manual_seed(seed)
166
- pipe_i2i.to("cuda")
167
- image_input = load_image(image_input_path)
168
- final_image = pipe_i2i(
169
- prompt=prompt_mash,
170
- image=image_input,
171
- strength=image_strength,
172
- num_inference_steps=steps,
173
- guidance_scale=cfg_scale,
174
- width=width,
175
- height=height,
176
- generator=generator,
177
- joint_attention_kwargs={"scale": 1.0},
178
- output_type="pil",
179
- ).images[0]
180
- return final_image
181
-
182
- def run_lora(prompt, image_input, image_strength, cfg_scale, steps, selected_indices, lora_scale_1, lora_scale_2, randomize_seed, seed, width, height, progress=gr.Progress(track_tqdm=True)):
183
- if not selected_indices:
184
- raise gr.Error("You must select at least one LoRA before proceeding.")
185
-
186
- selected_loras = [loras[idx] for idx in selected_indices]
187
-
188
- # Build the prompt with trigger words
189
- prompt_mash = prompt
190
- for lora in selected_loras:
191
- trigger_word = lora.get('trigger_word', '')
192
- if trigger_word:
193
- if lora.get("trigger_position") == "prepend":
194
- prompt_mash = f"{trigger_word} {prompt_mash}"
195
- else:
196
- prompt_mash = f"{prompt_mash} {trigger_word}"
197
-
198
- # Unload previous LoRA weights
199
- with calculateDuration("Unloading LoRA"):
200
- pipe.unload_lora_weights()
201
- pipe_i2i.unload_lora_weights()
202
-
203
- # Load LoRA weights with respective scales
204
- with calculateDuration("Loading LoRA weights"):
205
- for idx, lora in enumerate(selected_loras):
206
- lora_path = lora['repo']
207
- scale = lora_scale_1 if idx == 0 else lora_scale_2
208
- if image_input is not None:
209
- if "weights" in lora:
210
- pipe_i2i.load_lora_weights(lora_path, weight_name=lora["weights"], multiplier=scale)
211
- else:
212
- pipe_i2i.load_lora_weights(lora_path, multiplier=scale)
213
- else:
214
- if "weights" in lora:
215
- pipe.load_lora_weights(lora_path, weight_name=lora["weights"], multiplier=scale)
216
- else:
217
- pipe.load_lora_weights(lora_path, multiplier=scale)
218
-
219
- # Set random seed for reproducibility
220
- with calculateDuration("Randomizing seed"):
221
- if randomize_seed:
222
- seed = random.randint(0, MAX_SEED)
223
-
224
- # Generate image
225
- if image_input is not None:
226
- final_image = generate_image_to_image(prompt_mash, image_input, image_strength, steps, cfg_scale, width, height, seed)
227
- yield final_image, seed, gr.update(visible=False)
228
- else:
229
- image_generator = generate_image(prompt_mash, steps, seed, cfg_scale, width, height, progress)
230
- # Consume the generator to get the final image
231
- final_image = None
232
- step_counter = 0
233
- for image in image_generator:
234
- step_counter+=1
235
- final_image = image
236
- progress_bar = f'<div class="progress-container"><div class="progress-bar" style="--current: {step_counter}; --total: {steps};"></div></div>'
237
- yield image, seed, gr.update(value=progress_bar, visible=True)
238
- yield final_image, seed, gr.update(value=progress_bar, visible=False)
239
-
240
- def get_huggingface_safetensors(link):
241
- split_link = link.split("/")
242
- if len(split_link) == 2:
243
- model_card = ModelCard.load(link)
244
- base_model = model_card.data.get("base_model")
245
- print(base_model)
246
- if base_model not in ["black-forest-labs/FLUX.1-dev", "black-forest-labs/FLUX.1-schnell"]:
247
- raise Exception("Not a FLUX LoRA!")
248
- image_path = model_card.data.get("widget", [{}])[0].get("output", {}).get("url", None)
249
- trigger_word = model_card.data.get("instance_prompt", "")
250
- image_url = f"https://huggingface.co/{link}/resolve/main/{image_path}" if image_path else None
251
- fs = HfFileSystem()
252
- safetensors_name = None
253
- try:
254
- list_of_files = fs.ls(link, detail=False)
255
- for file in list_of_files:
256
- if file.endswith(".safetensors"):
257
- safetensors_name = file.split("/")[-1]
258
- if not image_url and file.lower().endswith((".jpg", ".jpeg", ".png", ".webp")):
259
- image_elements = file.split("/")
260
- image_url = f"https://huggingface.co/{link}/resolve/main/{image_elements[-1]}"
261
- except Exception as e:
262
- print(e)
263
- raise Exception("Invalid Hugging Face repository with a *.safetensors LoRA")
264
- if not safetensors_name:
265
- raise Exception("No *.safetensors file found in the repository")
266
- return split_link[1], link, safetensors_name, trigger_word, image_url
267
-
268
- def check_custom_model(link):
269
- if link.startswith("https://"):
270
- if link.startswith("https://huggingface.co") or link.startswith("https://www.huggingface.co"):
271
- link_split = link.split("huggingface.co/")
272
- return get_huggingface_safetensors(link_split[1])
273
- else:
274
- return get_huggingface_safetensors(link)
275
-
276
- def add_custom_lora(custom_lora, selected_indices):
277
- global loras
278
- if custom_lora:
279
- try:
280
- title, repo, path, trigger_word, image = check_custom_model(custom_lora)
281
- print(f"Loaded custom LoRA: {repo}")
282
- card = f'''
283
- <div class="custom_lora_card">
284
- <span>Loaded custom LoRA:</span>
285
- <div class="card_internal">
286
- <img src="{image}" />
287
- <div>
288
- <h3>{title}</h3>
289
- <small>{"Using: <code><b>"+trigger_word+"</code></b> as the trigger word" if trigger_word else "No trigger word found. If there's a trigger word, include it in your prompt"}<br></small>
290
- </div>
291
- </div>
292
- </div>
293
- '''
294
- existing_item_index = next((index for (index, item) in enumerate(loras) if item['repo'] == repo), None)
295
- if existing_item_index is None:
296
- new_item = {
297
- "image": image,
298
- "title": title,
299
- "repo": repo,
300
- "weights": path,
301
- "trigger_word": trigger_word
302
- }
303
- print(new_item)
304
- existing_item_index = len(loras)
305
- loras.append(new_item)
306
-
307
- # Update gallery
308
- gallery_items = [(item["image"], item["title"]) for item in loras]
309
- # Update selected_indices if there's room
310
- if len(selected_indices) < 2:
311
- selected_indices.append(existing_item_index)
312
- selected_info_1 = ""
313
- selected_info_2 = ""
314
- lora_scale_1 = 0.95
315
- lora_scale_2 = 0.95
316
- if len(selected_indices) >= 1:
317
- lora1 = loras[selected_indices[0]]
318
- selected_info_1 = f"### LoRA 1 Selected: [{lora1['title']}](https://huggingface.co/{lora1['repo']}) ✨"
319
- if len(selected_indices) >= 2:
320
- lora2 = loras[selected_indices[1]]
321
- selected_info_2 = f"### LoRA 2 Selected: [{lora2['title']}](https://huggingface.co/{lora2['repo']}) ✨"
322
- return (gr.update(visible=True, value=card), gr.update(visible=True), gr.update(value=gallery_items),
323
- selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2)
324
- else:
325
- return (gr.update(visible=True, value=card), gr.update(visible=True), gr.update(value=gallery_items),
326
- gr.NoChange(), gr.NoChange(), selected_indices, gr.NoChange(), gr.NoChange())
327
- except Exception as e:
328
- print(e)
329
- return gr.update(visible=True, value=str(e)), gr.update(visible=True), gr.NoChange(), gr.NoChange(), gr.NoChange(), selected_indices, gr.NoChange(), gr.NoChange()
330
- else:
331
- return gr.update(visible=False), gr.update(visible=False), gr.NoChange(), gr.NoChange(), gr.NoChange(), selected_indices, gr.NoChange(), gr.NoChange()
332
-
333
- def remove_custom_lora(custom_lora_info, custom_lora_button, selected_indices):
334
- global loras
335
- if loras:
336
- custom_lora_repo = loras[-1]['repo']
337
- # Remove from loras list
338
- loras = loras[:-1]
339
- # Remove from selected_indices if selected
340
- custom_lora_index = len(loras)
341
- if custom_lora_index in selected_indices:
342
- selected_indices.remove(custom_lora_index)
343
- # Update gallery
344
- gallery_items = [(item["image"], item["title"]) for item in loras]
345
- return gr.update(visible=False), gr.update(visible=False), gr.update(value=gallery_items), gr.NoChange(), gr.NoChange(), selected_indices, gr.NoChange(), gr.NoChange()
346
 
 
347
  run_lora.zerogpu = True
348
 
349
  css = '''
@@ -376,12 +194,14 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css, delete_cache=(60, 3600)) as app:
376
  generate_button = gr.Button("Generate", variant="primary")
377
  with gr.Row():
378
  with gr.Column(scale=1):
379
- randomize_button = gr.Button("🎲", variant="secondary", scale=1)
380
- with gr.Column(scale=3):
 
381
  selected_info_1 = gr.Markdown("Select a LoRA 1")
382
  lora_scale_1 = gr.Slider(label="LoRA 1 Scale", minimum=0, maximum=3, step=0.01, value=0.95)
383
  remove_button_1 = gr.Button("Remove LoRA 1")
384
- with gr.Column(scale=3):
 
385
  selected_info_2 = gr.Markdown("Select a LoRA 2")
386
  lora_scale_2 = gr.Slider(label="LoRA 2 Scale", minimum=0, maximum=3, step=0.01, value=0.95)
387
  remove_button_2 = gr.Button("Remove LoRA 2")
@@ -400,7 +220,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css, delete_cache=(60, 3600)) as app:
400
  custom_lora_info = gr.HTML(visible=False)
401
  custom_lora_button = gr.Button("Remove custom LoRA", visible=False)
402
  with gr.Column():
403
- progress_bar = gr.Markdown(elem_id="progress",visible=False)
404
  result = gr.Image(label="Generated Image")
405
  with gr.Row():
406
  with gr.Accordion("Advanced Settings", open=False):
@@ -423,33 +243,32 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css, delete_cache=(60, 3600)) as app:
423
  gallery.select(
424
  update_selection,
425
  inputs=[selected_indices, width, height],
426
- outputs=[prompt, selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2, width, height]
427
  )
428
  remove_button_1.click(
429
  remove_lora_1,
430
  inputs=[selected_indices],
431
- outputs=[selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2]
432
  )
433
  remove_button_2.click(
434
  remove_lora_2,
435
  inputs=[selected_indices],
436
- outputs=[selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2]
437
  )
438
  randomize_button.click(
439
  randomize_loras,
440
  inputs=[selected_indices],
441
- outputs=[selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2]
442
  )
443
- # Changed from submit to change to trigger on paste
444
  custom_lora.change(
445
  add_custom_lora,
446
  inputs=[custom_lora, selected_indices],
447
- outputs=[custom_lora_info, custom_lora_button, gallery, selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2]
448
  )
449
  custom_lora_button.click(
450
  remove_custom_lora,
451
  inputs=[custom_lora_info, custom_lora_button, selected_indices],
452
- outputs=[custom_lora_info, custom_lora_button, gallery, selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2]
453
  )
454
  gr.on(
455
  triggers=[generate_button.click, prompt.submit],
 
72
  selected_info_2 = ""
73
  lora_scale_1 = 0.95
74
  lora_scale_2 = 0.95
75
+ lora_image_1 = None
76
+ lora_image_2 = None
77
  if len(selected_indices) >= 1:
78
  lora1 = loras[selected_indices[0]]
79
  selected_info_1 = f"### LoRA 1 Selected: [{lora1['title']}](https://huggingface.co/{lora1['repo']}) ✨"
80
+ lora_image_1 = lora1['image']
81
  if len(selected_indices) >= 2:
82
  lora2 = loras[selected_indices[1]]
83
  selected_info_2 = f"### LoRA 2 Selected: [{lora2['title']}](https://huggingface.co/{lora2['repo']}) ✨"
84
+ lora_image_2 = lora2['image']
85
 
86
  # Update prompt placeholder based on last selected LoRA
87
  if selected_indices:
 
99
  lora_scale_2,
100
  width,
101
  height,
102
+ lora_image_1,
103
+ lora_image_2,
104
  )
105
 
106
  def remove_lora_1(selected_indices):
 
112
  selected_info_2 = ""
113
  lora_scale_1 = 0.95
114
  lora_scale_2 = 0.95
115
+ lora_image_1 = None
116
+ lora_image_2 = None
117
  if len(selected_indices) >= 1:
118
  lora1 = loras[selected_indices[0]]
119
  selected_info_1 = f"### LoRA 1 Selected: [{lora1['title']}](https://huggingface.co/{lora1['repo']}) ✨"
120
+ lora_image_1 = lora1['image']
121
  if len(selected_indices) >= 2:
122
  lora2 = loras[selected_indices[1]]
123
  selected_info_2 = f"### LoRA 2 Selected: [{lora2['title']}](https://huggingface.co/{lora2['repo']}) ✨"
124
+ lora_image_2 = lora2['image']
125
+ return selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2, lora_image_1, lora_image_2
126
 
127
  def remove_lora_2(selected_indices):
128
  selected_indices = selected_indices or []
 
133
  selected_info_2 = ""
134
  lora_scale_1 = 0.95
135
  lora_scale_2 = 0.95
136
+ lora_image_1 = None
137
+ lora_image_2 = None
138
  if len(selected_indices) >= 1:
139
  lora1 = loras[selected_indices[0]]
140
  selected_info_1 = f"### LoRA 1 Selected: [{lora1['title']}](https://huggingface.co/{lora1['repo']}) ✨"
141
+ lora_image_1 = lora1['image']
142
  if len(selected_indices) >= 2:
143
  lora2 = loras[selected_indices[1]]
144
  selected_info_2 = f"### LoRA 2 Selected: [{lora2['title']}](https://huggingface.co/{lora2['repo']}) ✨"
145
+ lora_image_2 = lora2['image']
146
+ return selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2, lora_image_1, lora_image_2
147
 
148
  def randomize_loras(selected_indices):
149
  if len(loras) < 2:
150
  raise gr.Error("Not enough LoRAs to randomize.")
151
  selected_indices = random.sample(range(len(loras)), 2)
152
+ lora1 = loras[selected_indices[0]]
153
+ lora2 = loras[selected_indices[1]]
154
+ selected_info_1 = f"### LoRA 1 Selected: [{lora1['title']}](https://huggingface.co/{lora1['repo']}) ✨"
155
+ selected_info_2 = f"### LoRA 2 Selected: [{lora2['title']}](https://huggingface.co/{lora2['repo']}) ✨"
156
  lora_scale_1 = 0.95
157
  lora_scale_2 = 0.95
158
+ lora_image_1 = lora1['image']
159
+ lora_image_2 = lora2['image']
160
+ return selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2, lora_image_1, lora_image_2
161
 
162
+ # ... (rest of your code remains unchanged)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
 
164
+ # Update your UI components to include image previews
165
  run_lora.zerogpu = True
166
 
167
  css = '''
 
194
  generate_button = gr.Button("Generate", variant="primary")
195
  with gr.Row():
196
  with gr.Column(scale=1):
197
+ randomize_button = gr.Button("🎲", variant="secondary", scale=1, min_width=50)
198
+ with gr.Column(scale=4):
199
+ lora_image_1 = gr.Image(label="LoRA 1 Image", interactive=False)
200
  selected_info_1 = gr.Markdown("Select a LoRA 1")
201
  lora_scale_1 = gr.Slider(label="LoRA 1 Scale", minimum=0, maximum=3, step=0.01, value=0.95)
202
  remove_button_1 = gr.Button("Remove LoRA 1")
203
+ with gr.Column(scale=4):
204
+ lora_image_2 = gr.Image(label="LoRA 2 Image", interactive=False)
205
  selected_info_2 = gr.Markdown("Select a LoRA 2")
206
  lora_scale_2 = gr.Slider(label="LoRA 2 Scale", minimum=0, maximum=3, step=0.01, value=0.95)
207
  remove_button_2 = gr.Button("Remove LoRA 2")
 
220
  custom_lora_info = gr.HTML(visible=False)
221
  custom_lora_button = gr.Button("Remove custom LoRA", visible=False)
222
  with gr.Column():
223
+ progress_bar = gr.Markdown(elem_id="progress", visible=False)
224
  result = gr.Image(label="Generated Image")
225
  with gr.Row():
226
  with gr.Accordion("Advanced Settings", open=False):
 
243
  gallery.select(
244
  update_selection,
245
  inputs=[selected_indices, width, height],
246
+ outputs=[prompt, selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2, width, height, lora_image_1, lora_image_2]
247
  )
248
  remove_button_1.click(
249
  remove_lora_1,
250
  inputs=[selected_indices],
251
+ outputs=[selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2, lora_image_1, lora_image_2]
252
  )
253
  remove_button_2.click(
254
  remove_lora_2,
255
  inputs=[selected_indices],
256
+ outputs=[selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2, lora_image_1, lora_image_2]
257
  )
258
  randomize_button.click(
259
  randomize_loras,
260
  inputs=[selected_indices],
261
+ outputs=[selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2, lora_image_1, lora_image_2]
262
  )
 
263
  custom_lora.change(
264
  add_custom_lora,
265
  inputs=[custom_lora, selected_indices],
266
+ outputs=[custom_lora_info, custom_lora_button, gallery, selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2, lora_image_1, lora_image_2]
267
  )
268
  custom_lora_button.click(
269
  remove_custom_lora,
270
  inputs=[custom_lora_info, custom_lora_button, selected_indices],
271
+ outputs=[custom_lora_info, custom_lora_button, gallery, selected_info_1, selected_info_2, selected_indices, lora_scale_1, lora_scale_2, lora_image_1, lora_image_2]
272
  )
273
  gr.on(
274
  triggers=[generate_button.click, prompt.submit],