gsarti commited on
Commit
a3fa4c8
1 Parent(s): 401e0c2

Update v 0.0.5

Browse files
README.md CHANGED
@@ -6,7 +6,7 @@ tags:
6
  - textbox
7
  - editing
8
  - color
9
- title: gradio_highlightedtextbox V0.0.4
10
  colorFrom: indigo
11
  colorTo: green
12
  sdk: docker
 
6
  - textbox
7
  - editing
8
  - color
9
+ title: gradio_highlightedtextbox v0.0.5
10
  colorFrom: indigo
11
  colorTo: green
12
  sdk: docker
src/README.md CHANGED
@@ -1,10 +1,455 @@
1
 
2
- # gradio_highlightedtextbox
3
- A Custom Gradio component.
4
 
5
- ## Example usage
 
 
 
 
 
 
 
 
6
 
7
  ```python
8
  import gradio as gr
9
  from gradio_highlightedtextbox import HighlightedTextbox
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
 
2
+ # `gradio_highlightedtextbox`
3
+ <a href="https://pypi.org/project/gradio_highlightedtextbox/" target="_blank"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/gradio_highlightedtextbox"></a> <a href="https://huggingface.co/spaces/gsarti/gradio_highlightedtextbox/discussions" target="_blank"><img alt="Static Badge" src="https://img.shields.io/badge/%F0%9F%A4%97%20Discuss-%23097EFF?style=flat&logoColor=black"></a>
4
 
5
+ Editable Gradio textarea supporting highlighting
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install gradio_highlightedtextbox
11
+ ```
12
+
13
+ ## Usage
14
 
15
  ```python
16
  import gradio as gr
17
  from gradio_highlightedtextbox import HighlightedTextbox
18
+
19
+
20
+ def convert_tagged_text_to_highlighted_text(
21
+ tagged_text: str, tag_id: str, tag_open: str, tag_close: str
22
+ ) -> list[tuple[str, str | None]]:
23
+ return HighlightedTextbox.tagged_text_to_tuples(
24
+ tagged_text, tag_id, tag_open, tag_close
25
+ )
26
+
27
+
28
+ def convert_highlighted_text_to_tagged_text(
29
+ highlighted_text: dict[str, str | list[tuple[str, str | None]]],
30
+ tag_id: str,
31
+ tag_open: str,
32
+ tag_close: str,
33
+ ) -> str:
34
+ return HighlightedTextbox.tuples_to_tagged_text(
35
+ highlighted_text["data"], tag_id, tag_open, tag_close
36
+ )
37
+
38
+
39
+ initial_text = "It is not something to be ashamed of: it is no different from the <h>personal fears</h> and <h>dislikes</h> of other things that <h>very many people</h> have."
40
+
41
+ with gr.Blocks() as demo:
42
+ tag_id = gr.Textbox(
43
+ "Potential issue",
44
+ label="Tag ID",
45
+ show_label=True,
46
+ info="Insert a tag ID to use in the highlighted textbox.",
47
+ )
48
+ tag_open = gr.Textbox(
49
+ "<h>",
50
+ label="Tag open",
51
+ show_label=True,
52
+ info="Insert a tag to mark the beginning of a highlighted section.",
53
+ )
54
+ tag_close = gr.Textbox(
55
+ "</h>",
56
+ label="Tag close",
57
+ show_label=True,
58
+ info="Insert a tag to mark the end of a highlighted section.",
59
+ )
60
+ with gr.Row():
61
+ tagged_t2h = gr.Textbox(
62
+ initial_text,
63
+ interactive=True,
64
+ label="Input",
65
+ show_label=True,
66
+ info="Insert a text with <h>...</h> tags to mark spans that will be highlighted.",
67
+ )
68
+ high_t2h = HighlightedTextbox(
69
+ convert_tagged_text_to_highlighted_text(
70
+ tagged_t2h.value, tag_id.value, tag_open.value, tag_close.value
71
+ ),
72
+ interactive=True,
73
+ label="Output",
74
+ info="Highlighted textbox.",
75
+ show_legend=True,
76
+ show_label=True,
77
+ legend_label="Legend:",
78
+ show_legend_label=True,
79
+ )
80
+ with gr.Row():
81
+ high_h2t = HighlightedTextbox(
82
+ convert_tagged_text_to_highlighted_text(
83
+ tagged_t2h.value, tag_id.value, tag_open.value, tag_close.value
84
+ ),
85
+ interactive=True,
86
+ label="Input",
87
+ info="The following text will be marked by spans according to its highlights.",
88
+ show_legend=True,
89
+ show_label=True,
90
+ legend_label="Legend:",
91
+ show_legend_label=True,
92
+ )
93
+ tagged_h2t = gr.Textbox(
94
+ initial_text,
95
+ interactive=True,
96
+ label="Output",
97
+ show_label=True,
98
+ )
99
+
100
+ # Functions
101
+
102
+ tagged_t2h.change(
103
+ fn=convert_tagged_text_to_highlighted_text,
104
+ inputs=[tagged_t2h, tag_id, tag_open, tag_close],
105
+ outputs=high_t2h,
106
+ )
107
+ high_t2h.change(
108
+ fn=lambda x: x["data"],
109
+ inputs=high_t2h,
110
+ outputs=high_h2t,
111
+ )
112
+ high_h2t.change(
113
+ fn=convert_highlighted_text_to_tagged_text,
114
+ inputs=[high_h2t, tag_id, tag_open, tag_close],
115
+ outputs=tagged_h2t,
116
+ )
117
+
118
+
119
+ demo.launch()
120
+
121
+ ```
122
+
123
+ ## `HighlightedTextbox`
124
+
125
+ ### Initialization
126
+
127
+ <table>
128
+ <thead>
129
+ <tr>
130
+ <th align="left">name</th>
131
+ <th align="left" style="width: 25%;">type</th>
132
+ <th align="left">default</th>
133
+ <th align="left">description</th>
134
+ </tr>
135
+ </thead>
136
+ <tbody>
137
+ <tr>
138
+ <td align="left"><code>value</code></td>
139
+ <td align="left" style="width: 25%;">
140
+
141
+ ```python
142
+ str | Callable | None
143
+ ```
144
+
145
+ </td>
146
+ <td align="left"><code>""</code></td>
147
+ <td align="left">default text to provide in textbox. If callable, the function will be called whenever the app loads to set the initial value of the component.</td>
148
+ </tr>
149
+
150
+ <tr>
151
+ <td align="left"><code>color_map</code></td>
152
+ <td align="left" style="width: 25%;">
153
+
154
+ ```python
155
+ dict[str, str] | None
156
+ ```
157
+
158
+ </td>
159
+ <td align="left"><code>None</code></td>
160
+ <td align="left">dictionary mapping labels to colors.</td>
161
+ </tr>
162
+
163
+ <tr>
164
+ <td align="left"><code>show_legend</code></td>
165
+ <td align="left" style="width: 25%;">
166
+
167
+ ```python
168
+ bool
169
+ ```
170
+
171
+ </td>
172
+ <td align="left"><code>False</code></td>
173
+ <td align="left">if True, will display legend.</td>
174
+ </tr>
175
+
176
+ <tr>
177
+ <td align="left"><code>show_legend_label</code></td>
178
+ <td align="left" style="width: 25%;">
179
+
180
+ ```python
181
+ bool
182
+ ```
183
+
184
+ </td>
185
+ <td align="left"><code>False</code></td>
186
+ <td align="left">if True, will display legend label.</td>
187
+ </tr>
188
+
189
+ <tr>
190
+ <td align="left"><code>legend_label</code></td>
191
+ <td align="left" style="width: 25%;">
192
+
193
+ ```python
194
+ str
195
+ ```
196
+
197
+ </td>
198
+ <td align="left"><code>""</code></td>
199
+ <td align="left">label to display above legend.</td>
200
+ </tr>
201
+
202
+ <tr>
203
+ <td align="left"><code>combine_adjacent</code></td>
204
+ <td align="left" style="width: 25%;">
205
+
206
+ ```python
207
+ bool
208
+ ```
209
+
210
+ </td>
211
+ <td align="left"><code>False</code></td>
212
+ <td align="left">if True, will combine adjacent spans with the same label.</td>
213
+ </tr>
214
+
215
+ <tr>
216
+ <td align="left"><code>adjacent_separator</code></td>
217
+ <td align="left" style="width: 25%;">
218
+
219
+ ```python
220
+ str
221
+ ```
222
+
223
+ </td>
224
+ <td align="left"><code>""</code></td>
225
+ <td align="left">separator to use when combining adjacent spans.</td>
226
+ </tr>
227
+
228
+ <tr>
229
+ <td align="left"><code>label</code></td>
230
+ <td align="left" style="width: 25%;">
231
+
232
+ ```python
233
+ str | None
234
+ ```
235
+
236
+ </td>
237
+ <td align="left"><code>None</code></td>
238
+ <td align="left">component name in interface.</td>
239
+ </tr>
240
+
241
+ <tr>
242
+ <td align="left"><code>info</code></td>
243
+ <td align="left" style="width: 25%;">
244
+
245
+ ```python
246
+ str | None
247
+ ```
248
+
249
+ </td>
250
+ <td align="left"><code>None</code></td>
251
+ <td align="left">None</td>
252
+ </tr>
253
+
254
+ <tr>
255
+ <td align="left"><code>every</code></td>
256
+ <td align="left" style="width: 25%;">
257
+
258
+ ```python
259
+ float | None
260
+ ```
261
+
262
+ </td>
263
+ <td align="left"><code>None</code></td>
264
+ <td align="left">If `value` is a callable, run the function 'every' number of seconds while the client connection is open. Has no effect otherwise. Queue must be enabled. The event can be accessed (e.g. to cancel it) via this component's .load_event attribute.</td>
265
+ </tr>
266
+
267
+ <tr>
268
+ <td align="left"><code>show_label</code></td>
269
+ <td align="left" style="width: 25%;">
270
+
271
+ ```python
272
+ bool | None
273
+ ```
274
+
275
+ </td>
276
+ <td align="left"><code>None</code></td>
277
+ <td align="left">if True, will display label.</td>
278
+ </tr>
279
+
280
+ <tr>
281
+ <td align="left"><code>container</code></td>
282
+ <td align="left" style="width: 25%;">
283
+
284
+ ```python
285
+ bool
286
+ ```
287
+
288
+ </td>
289
+ <td align="left"><code>True</code></td>
290
+ <td align="left">If True, will place the component in a container - providing some extra padding around the border.</td>
291
+ </tr>
292
+
293
+ <tr>
294
+ <td align="left"><code>scale</code></td>
295
+ <td align="left" style="width: 25%;">
296
+
297
+ ```python
298
+ int | None
299
  ```
300
+
301
+ </td>
302
+ <td align="left"><code>None</code></td>
303
+ <td align="left">relative width compared to adjacent Components in a Row. For example, if Component A has scale=2, and Component B has scale=1, A will be twice as wide as B. Should be an integer.</td>
304
+ </tr>
305
+
306
+ <tr>
307
+ <td align="left"><code>min_width</code></td>
308
+ <td align="left" style="width: 25%;">
309
+
310
+ ```python
311
+ int
312
+ ```
313
+
314
+ </td>
315
+ <td align="left"><code>160</code></td>
316
+ <td align="left">minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first.</td>
317
+ </tr>
318
+
319
+ <tr>
320
+ <td align="left"><code>visible</code></td>
321
+ <td align="left" style="width: 25%;">
322
+
323
+ ```python
324
+ bool
325
+ ```
326
+
327
+ </td>
328
+ <td align="left"><code>True</code></td>
329
+ <td align="left">If False, component will be hidden.</td>
330
+ </tr>
331
+
332
+ <tr>
333
+ <td align="left"><code>elem_id</code></td>
334
+ <td align="left" style="width: 25%;">
335
+
336
+ ```python
337
+ str | None
338
+ ```
339
+
340
+ </td>
341
+ <td align="left"><code>None</code></td>
342
+ <td align="left">An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.</td>
343
+ </tr>
344
+
345
+ <tr>
346
+ <td align="left"><code>autofocus</code></td>
347
+ <td align="left" style="width: 25%;">
348
+
349
+ ```python
350
+ bool
351
+ ```
352
+
353
+ </td>
354
+ <td align="left"><code>False</code></td>
355
+ <td align="left">None</td>
356
+ </tr>
357
+
358
+ <tr>
359
+ <td align="left"><code>autoscroll</code></td>
360
+ <td align="left" style="width: 25%;">
361
+
362
+ ```python
363
+ bool
364
+ ```
365
+
366
+ </td>
367
+ <td align="left"><code>True</code></td>
368
+ <td align="left">If True, will automatically scroll to the bottom of the textbox when the value changes, unless the user scrolls up. If False, will not scroll to the bottom of the textbox when the value changes.</td>
369
+ </tr>
370
+
371
+ <tr>
372
+ <td align="left"><code>interactive</code></td>
373
+ <td align="left" style="width: 25%;">
374
+
375
+ ```python
376
+ bool
377
+ ```
378
+
379
+ </td>
380
+ <td align="left"><code>True</code></td>
381
+ <td align="left">if True, will be rendered as an editable textbox; if False, editing will be disabled. If not provided, this is inferred based on whether the component is used as an input or output.</td>
382
+ </tr>
383
+
384
+ <tr>
385
+ <td align="left"><code>elem_classes</code></td>
386
+ <td align="left" style="width: 25%;">
387
+
388
+ ```python
389
+ list[str] | str | None
390
+ ```
391
+
392
+ </td>
393
+ <td align="left"><code>None</code></td>
394
+ <td align="left">An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.</td>
395
+ </tr>
396
+
397
+ <tr>
398
+ <td align="left"><code>render</code></td>
399
+ <td align="left" style="width: 25%;">
400
+
401
+ ```python
402
+ bool
403
+ ```
404
+
405
+ </td>
406
+ <td align="left"><code>True</code></td>
407
+ <td align="left">If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.</td>
408
+ </tr>
409
+
410
+ <tr>
411
+ <td align="left"><code>show_copy_button</code></td>
412
+ <td align="left" style="width: 25%;">
413
+
414
+ ```python
415
+ bool
416
+ ```
417
+
418
+ </td>
419
+ <td align="left"><code>False</code></td>
420
+ <td align="left">If True, includes a copy button to copy the text in the textbox. Only applies if show_label is True.</td>
421
+ </tr>
422
+ </tbody></table>
423
+
424
+
425
+ ### Events
426
+
427
+ | name | description |
428
+ |:-----|:------------|
429
+ | `change` | Triggered when the value of the HighlightedTextbox changes either because of user input (e.g. a user types in a textbox) OR because of a function update (e.g. an image receives a value from the output of an event trigger). See `.input()` for a listener that is only triggered by user input. |
430
+ | `input` | This listener is triggered when the user changes the value of the HighlightedTextbox. |
431
+ | `select` | Event listener for when the user selects or deselects the HighlightedTextbox. Uses event data gradio.SelectData to carry `value` referring to the label of the HighlightedTextbox, and `selected` to refer to state of the HighlightedTextbox. See EventData documentation on how to use this event data |
432
+ | `submit` | This listener is triggered when the user presses the Enter key while the HighlightedTextbox is focused. |
433
+ | `focus` | This listener is triggered when the HighlightedTextbox is focused. |
434
+ | `blur` | This listener is triggered when the HighlightedTextbox is unfocused/blurred. |
435
+
436
+
437
+
438
+ ### User function
439
+
440
+ The impact on the users predict function varies depending on whether the component is used as an input or output for an event (or both).
441
+
442
+ - When used as an Input, the component only impacts the input signature of the user function.
443
+ - When used as an output, the component only impacts the return signature of the user function.
444
+
445
+ The code snippet below is accurate in cases where the component is used as both an input and an output.
446
+
447
+ - **As input:** Should return, list of (word, category) tuples, or a dictionary of two keys: "text", and "highlights", which itself is.
448
+
449
+ ```python
450
+ def predict(
451
+ value: dict
452
+ ) -> list[tuple[str, str | None]] | dict | None:
453
+ return value
454
+ ```
455
+
src/backend/gradio_highlightedtextbox/highlightedtextbox.py CHANGED
@@ -264,8 +264,13 @@ class HighlightedTextbox(FormComponent):
264
  tag_ids = [tag_ids]
265
  out = ""
266
  for text, tag_id in tuples:
 
 
 
 
 
267
  if tag_id in tag_ids:
268
- out += f" {tag_open}{text.strip()}{tag_close} "
269
  else:
270
- out += text.strip()
271
  return out.strip()
 
264
  tag_ids = [tag_ids]
265
  out = ""
266
  for text, tag_id in tuples:
267
+ space_or_not = (
268
+ " "
269
+ if text not in [".", "!", "?", ",", ":", ")", "]", ";", "}", """'"""]
270
+ else ""
271
+ )
272
  if tag_id in tag_ids:
273
+ out += f"{space_or_not}{tag_open}{text.strip()}{tag_close}"
274
  else:
275
+ out += f"{space_or_not}{text.strip()} "
276
  return out.strip()
src/backend/gradio_highlightedtextbox/highlightedtextbox.pyi CHANGED
@@ -260,10 +260,15 @@ class HighlightedTextbox(FormComponent):
260
  tag_ids = [tag_ids]
261
  out = ""
262
  for text, tag_id in tuples:
 
 
 
 
 
263
  if tag_id in tag_ids:
264
- out += f" {tag_open}{text.strip()}{tag_close} "
265
  else:
266
- out += text.strip()
267
  return out.strip()
268
 
269
 
 
260
  tag_ids = [tag_ids]
261
  out = ""
262
  for text, tag_id in tuples:
263
+ space_or_not = (
264
+ " "
265
+ if text not in [".", "!", "?", ",", ":", ")", "]", ";", "}", """'"""]
266
+ else ""
267
+ )
268
  if tag_id in tag_ids:
269
+ out += f"{space_or_not}{tag_open}{text.strip()}{tag_close}"
270
  else:
271
+ out += f"{space_or_not}{text.strip()} "
272
  return out.strip()
273
 
274
 
src/backend/gradio_highlightedtextbox/templates/component/index.js CHANGED
@@ -11,7 +11,7 @@ const {
11
  insert: ul,
12
  safe_not_equal: cl,
13
  set_dynamic_element_data: et,
14
- set_style: A,
15
  toggle_class: te,
16
  transition_in: Ot,
17
  transition_out: It,
@@ -70,7 +70,7 @@ function ml(n) {
70
  n[5] === "focus"
71
  ), te(e, "hide-container", !/*explicit_call*/
72
  n[8] && !/*container*/
73
- n[9]), A(
74
  e,
75
  "height",
76
  /*get_dimension*/
@@ -78,7 +78,7 @@ function ml(n) {
78
  /*height*/
79
  n[0]
80
  )
81
- ), A(e, "width", typeof /*width*/
82
  n[1] == "number" ? `calc(min(${/*width*/
83
  n[1]}px, 100%))` : (
84
  /*get_dimension*/
@@ -86,23 +86,23 @@ function ml(n) {
86
  /*width*/
87
  n[1]
88
  )
89
- )), A(
90
  e,
91
  "border-style",
92
  /*variant*/
93
  n[4]
94
- ), A(
95
  e,
96
  "overflow",
97
  /*allow_overflow*/
98
  n[11] ? "visible" : "hidden"
99
- ), A(
100
  e,
101
  "flex-grow",
102
  /*scale*/
103
  n[12]
104
- ), A(e, "min-width", `calc(min(${/*min_width*/
105
- n[13]}px, 100%))`), A(e, "border-width", "var(--block-border-width)");
106
  },
107
  m(f, a) {
108
  ul(f, e, a), o && o.m(e, null), l = !0;
@@ -161,7 +161,7 @@ function ml(n) {
161
  ), te(e, "hide-container", !/*explicit_call*/
162
  f[8] && !/*container*/
163
  f[9]), a & /*height*/
164
- 1 && A(
165
  e,
166
  "height",
167
  /*get_dimension*/
@@ -170,7 +170,7 @@ function ml(n) {
170
  f[0]
171
  )
172
  ), a & /*width*/
173
- 2 && A(e, "width", typeof /*width*/
174
  f[1] == "number" ? `calc(min(${/*width*/
175
  f[1]}px, 100%))` : (
176
  /*get_dimension*/
@@ -179,25 +179,25 @@ function ml(n) {
179
  f[1]
180
  )
181
  )), a & /*variant*/
182
- 16 && A(
183
  e,
184
  "border-style",
185
  /*variant*/
186
  f[4]
187
  ), a & /*allow_overflow*/
188
- 2048 && A(
189
  e,
190
  "overflow",
191
  /*allow_overflow*/
192
  f[11] ? "visible" : "hidden"
193
  ), a & /*scale*/
194
- 4096 && A(
195
  e,
196
  "flex-grow",
197
  /*scale*/
198
  f[12]
199
  ), a & /*min_width*/
200
- 8192 && A(e, "min-width", `calc(min(${/*min_width*/
201
  f[13]}px, 100%))`);
202
  },
203
  i(f) {
@@ -240,16 +240,16 @@ function bl(n) {
240
  }
241
  function gl(n, e, t) {
242
  let { $$slots: l = {}, $$scope: i } = e, { height: o = void 0 } = e, { width: s = void 0 } = e, { elem_id: r = "" } = e, { elem_classes: f = [] } = e, { variant: a = "solid" } = e, { border_mode: _ = "base" } = e, { padding: u = !0 } = e, { type: c = "normal" } = e, { test_id: m = void 0 } = e, { explicit_call: p = !1 } = e, { container: T = !0 } = e, { visible: S = !0 } = e, { allow_overflow: L = !0 } = e, { scale: C = null } = e, { min_width: d = 0 } = e, y = c === "fieldset" ? "fieldset" : "div";
243
- const M = (g) => {
244
- if (g !== void 0) {
245
- if (typeof g == "number")
246
- return g + "px";
247
- if (typeof g == "string")
248
- return g;
249
  }
250
  };
251
- return n.$$set = (g) => {
252
- "height" in g && t(0, o = g.height), "width" in g && t(1, s = g.width), "elem_id" in g && t(2, r = g.elem_id), "elem_classes" in g && t(3, f = g.elem_classes), "variant" in g && t(4, a = g.variant), "border_mode" in g && t(5, _ = g.border_mode), "padding" in g && t(6, u = g.padding), "type" in g && t(16, c = g.type), "test_id" in g && t(7, m = g.test_id), "explicit_call" in g && t(8, p = g.explicit_call), "container" in g && t(9, T = g.container), "visible" in g && t(10, S = g.visible), "allow_overflow" in g && t(11, L = g.allow_overflow), "scale" in g && t(12, C = g.scale), "min_width" in g && t(13, d = g.min_width), "$$scope" in g && t(17, i = g.$$scope);
253
  }, [
254
  o,
255
  s,
@@ -1118,7 +1118,7 @@ const {
1118
  toggle_class: mt,
1119
  transition_in: ne,
1120
  transition_out: ce
1121
- } = window.__gradio__svelte__internal, { beforeUpdate: zn, afterUpdate: En, createEventDispatcher: Pn, tick: Ui } = window.__gradio__svelte__internal;
1122
  function bt(n, e, t) {
1123
  const l = n.slice();
1124
  return l[39] = e[t][0], l[40] = e[t][1], l[42] = t, l;
@@ -1530,35 +1530,35 @@ function Un(n) {
1530
  }
1531
  function Wn(n, e, t) {
1532
  const l = typeof document < "u";
1533
- let { value: i = [] } = e, { value_is_output: o = !1 } = e, { label: s } = e, { legend_label: r } = e, { info: f = void 0 } = e, { show_label: a = !0 } = e, { show_legend: _ = !1 } = e, { show_legend_label: u = !1 } = e, { container: c = !0 } = e, { color_map: m = {} } = e, { show_copy_button: p = !1 } = e, { disabled: T } = e, S, L = "", C = "", d, y = {}, M = {}, g = !1, B;
1534
  function Q() {
1535
  if (!m || Object.keys(m).length === 0 ? y = {} : y = m, i.length > 0) {
1536
- for (let [b, j] of i)
1537
  if (j !== null && !(j in y)) {
1538
- let E = wn(Object.keys(y).length);
1539
- y[j] = E;
1540
  }
1541
  }
1542
  t(12, M = qn(y, l, d));
1543
  }
1544
- function z() {
1545
- i.length > 0 && o && (t(11, L = i.map(([b, j]) => b).join(" ")), t(9, C = i.map(([b, j]) => j !== null ? `<mark class="hl ${j}" style="background-color:${M[j].secondary}">${b}</mark>` : b).join(" ") + " "));
1546
  }
1547
  const R = Pn();
1548
  zn(() => {
1549
  S && S.offsetHeight + S.scrollTop > S.scrollHeight - 100;
1550
  });
1551
  function U() {
1552
- R("change", C), o || R("input"), V();
1553
  }
1554
  En(() => {
1555
- Q(), z(), t(18, o = !1);
1556
  });
1557
  function se() {
1558
- let b = [], j = "", E = null, ee = !1, be = "";
1559
  for (let fe = 0; fe < C.length; fe++) {
1560
  let re = C[fe];
1561
- re === "<" ? (ee = !0, j && b.push([j, E]), j = "", E = null) : re === ">" ? (ee = !1, be.startsWith("mark") && (E = Un([
1562
  be,
1563
  "access",
1564
  (W) => W.match,
@@ -1568,27 +1568,27 @@ function Wn(n, e, t) {
1568
  (W) => W[1]
1569
  ]) || null), be = "") : ee ? be += re : j += re;
1570
  }
1571
- j && b.push([j, E]), t(17, i = b);
1572
  }
1573
  async function D() {
1574
  "clipboard" in navigator && (await navigator.clipboard.writeText(L), x());
1575
  }
1576
  function x() {
1577
- t(13, g = !0), B && clearTimeout(B), B = setTimeout(
1578
  () => {
1579
- t(13, g = !1);
1580
  },
1581
  1e3
1582
  );
1583
  }
1584
- function V() {
1585
- const b = window.getSelection(), j = b.anchorOffset;
1586
- if (b.rangeCount > 0) {
1587
- var E = b.getRangeAt(0).commonAncestorContainer.parentElement;
1588
- if (E && E.tagName.toLowerCase() === "mark") {
1589
- const el = E.textContent;
1590
- var ee = E.parentElement, be = document.createTextNode(el);
1591
- ee.replaceChild(be, E), t(9, C = ee.innerHTML);
1592
  var fe = document.createRange(), re = window.getSelection();
1593
  const tl = j + Ln(ee);
1594
  var W = Tn(ee, tl);
@@ -1596,43 +1596,43 @@ function Wn(n, e, t) {
1596
  }
1597
  }
1598
  }
1599
- function de(b) {
1600
- qe.call(this, n, b);
1601
  }
1602
- function h(b) {
1603
- qe.call(this, n, b);
1604
  }
1605
- function Fe(b) {
1606
- qe.call(this, n, b);
1607
  }
1608
- function Me(b) {
1609
- qe.call(this, n, b);
1610
  }
1611
- function me(b) {
1612
- qe.call(this, n, b);
1613
  }
1614
- function Pe(b) {
1615
- ct[b ? "unshift" : "push"](() => {
1616
- S = b, t(10, S);
1617
  });
1618
  }
1619
  function Ze() {
1620
  L = this.textContent, C = this.innerHTML, t(11, L), t(9, C);
1621
  }
1622
- function w(b) {
1623
- ct[b ? "unshift" : "push"](() => {
1624
- S = b, t(10, S);
1625
  });
1626
  }
1627
  function $t() {
1628
  L = this.textContent, C = this.innerHTML, t(11, L), t(9, C);
1629
  }
1630
- return n.$$set = (b) => {
1631
- "value" in b && t(17, i = b.value), "value_is_output" in b && t(18, o = b.value_is_output), "label" in b && t(0, s = b.label), "legend_label" in b && t(1, r = b.legend_label), "info" in b && t(2, f = b.info), "show_label" in b && t(3, a = b.show_label), "show_legend" in b && t(4, _ = b.show_legend), "show_legend_label" in b && t(5, u = b.show_legend_label), "container" in b && t(6, c = b.container), "color_map" in b && t(19, m = b.color_map), "show_copy_button" in b && t(7, p = b.show_copy_button), "disabled" in b && t(8, T = b.disabled);
1632
  }, n.$$.update = () => {
1633
  n.$$.dirty[0] & /*marked_el_text*/
1634
  512 && U();
1635
- }, z(), Q(), [
1636
  s,
1637
  r,
1638
  f,
@@ -1646,10 +1646,10 @@ function Wn(n, e, t) {
1646
  S,
1647
  L,
1648
  M,
1649
- g,
1650
  se,
1651
  D,
1652
- V,
1653
  i,
1654
  o,
1655
  m,
@@ -2610,17 +2610,17 @@ async function Ti(n, e = !0) {
2610
  }
2611
  }
2612
  function Fi(n, e, t) {
2613
- let l, { $$slots: i = {}, $$scope: o } = e, { i18n: s } = e, { eta: r = null } = e, { queue_position: f } = e, { queue_size: a } = e, { status: _ } = e, { scroll_to_output: u = !1 } = e, { timer: c = !0 } = e, { show_progress: m = "full" } = e, { message: p = null } = e, { progress: T = null } = e, { variant: S = "default" } = e, { loading_text: L = "Loading..." } = e, { absolute: C = !0 } = e, { translucent: d = !1 } = e, { border: y = !1 } = e, { autoscroll: M } = e, g, B = !1, Q = 0, z = 0, R = null, U = null, se = 0, D = null, x, V = null, de = !0;
2614
  const h = () => {
2615
- t(0, r = t(26, R = t(19, me = null))), t(24, Q = performance.now()), t(25, z = 0), B = !0, Fe();
2616
  };
2617
  function Fe() {
2618
  requestAnimationFrame(() => {
2619
- t(25, z = (performance.now() - Q) / 1e3), B && Fe();
2620
  });
2621
  }
2622
  function Me() {
2623
- t(25, z = 0), t(0, r = t(26, R = t(19, me = null))), B && (B = !1);
2624
  }
2625
  mi(() => {
2626
  B && Me();
@@ -2628,12 +2628,12 @@ function Fi(n, e, t) {
2628
  let me = null;
2629
  function Pe(w) {
2630
  Ct[w ? "unshift" : "push"](() => {
2631
- V = w, t(16, V), t(7, T), t(14, D), t(15, x);
2632
  });
2633
  }
2634
  function Ze(w) {
2635
  Ct[w ? "unshift" : "push"](() => {
2636
- g = w, t(13, g);
2637
  });
2638
  }
2639
  return n.$$set = (w) => {
@@ -2641,18 +2641,18 @@ function Fi(n, e, t) {
2641
  }, n.$$.update = () => {
2642
  n.$$.dirty[0] & /*eta, old_eta, timer_start, eta_from_start*/
2643
  218103809 && (r === null && t(0, r = R), r != null && R !== r && (t(27, U = (performance.now() - Q) / 1e3 + r), t(19, me = U.toFixed(1)), t(26, R = r))), n.$$.dirty[0] & /*eta_from_start, timer_diff*/
2644
- 167772160 && t(17, se = U === null || U <= 0 || !z ? null : Math.min(z / U, 1)), n.$$.dirty[0] & /*progress*/
2645
  128 && T != null && t(18, de = !1), n.$$.dirty[0] & /*progress, progress_level, progress_bar, last_progress_level*/
2646
  114816 && (T != null ? t(14, D = T.map((w) => {
2647
  if (w.index != null && w.length != null)
2648
  return w.index / w.length;
2649
  if (w.progress != null)
2650
  return w.progress;
2651
- })) : t(14, D = null), D ? (t(15, x = D[D.length - 1]), V && (x === 0 ? t(16, V.style.transition = "0", V) : t(16, V.style.transition = "150ms", V))) : t(15, x = void 0)), n.$$.dirty[0] & /*status*/
2652
  16 && (_ === "pending" ? h() : Me()), n.$$.dirty[0] & /*el, scroll_to_output, status, autoscroll*/
2653
- 10493968 && g && u && (_ === "pending" || _ === "complete") && Ti(g, M), n.$$.dirty[0] & /*status, message*/
2654
  4194320, n.$$.dirty[0] & /*timer_diff*/
2655
- 33554432 && t(20, l = z.toFixed(1));
2656
  }, [
2657
  r,
2658
  s,
@@ -2667,10 +2667,10 @@ function Fi(n, e, t) {
2667
  C,
2668
  d,
2669
  y,
2670
- g,
2671
  D,
2672
  x,
2673
- V,
2674
  se,
2675
  de,
2676
  me,
@@ -2679,7 +2679,7 @@ function Fi(n, e, t) {
2679
  p,
2680
  M,
2681
  Q,
2682
- z,
2683
  R,
2684
  U,
2685
  o,
@@ -2997,17 +2997,17 @@ function Oi(n) {
2997
  };
2998
  }
2999
  function Ii(n, e, t) {
3000
- let { gradio: l } = e, { label: i = "Highlighted Textbox" } = e, { legend_label: o = "Highlights:" } = e, { info: s = void 0 } = e, { elem_id: r = "" } = e, { elem_classes: f = [] } = e, { visible: a = !0 } = e, { value: _ } = e, { show_label: u } = e, { show_legend: c } = e, { show_legend_label: m } = e, { color_map: p = {} } = e, { container: T = !0 } = e, { scale: S = null } = e, { min_width: L = void 0 } = e, { show_copy_button: C = !1 } = e, { loading_status: d = void 0 } = e, { value_is_output: y = !1 } = e, { combine_adjacent: M = !1 } = e, { interactive: g = !0 } = e;
3001
  const B = !1, Q = !0;
3002
- function z(h) {
3003
  _ = h, t(0, _), t(19, M);
3004
  }
3005
  function R(h) {
3006
  y = h, t(2, y);
3007
  }
3008
- const U = () => l.dispatch("change"), se = () => l.dispatch("input"), D = () => l.dispatch("submit"), x = () => l.dispatch("blur"), V = (h) => l.dispatch("select", h.detail), de = () => l.dispatch("focus");
3009
  return n.$$set = (h) => {
3010
- "gradio" in h && t(3, l = h.gradio), "label" in h && t(4, i = h.label), "legend_label" in h && t(5, o = h.legend_label), "info" in h && t(6, s = h.info), "elem_id" in h && t(7, r = h.elem_id), "elem_classes" in h && t(8, f = h.elem_classes), "visible" in h && t(9, a = h.visible), "value" in h && t(0, _ = h.value), "show_label" in h && t(10, u = h.show_label), "show_legend" in h && t(11, c = h.show_legend), "show_legend_label" in h && t(12, m = h.show_legend_label), "color_map" in h && t(1, p = h.color_map), "container" in h && t(13, T = h.container), "scale" in h && t(14, S = h.scale), "min_width" in h && t(15, L = h.min_width), "show_copy_button" in h && t(16, C = h.show_copy_button), "loading_status" in h && t(17, d = h.loading_status), "value_is_output" in h && t(2, y = h.value_is_output), "combine_adjacent" in h && t(19, M = h.combine_adjacent), "interactive" in h && t(18, g = h.interactive);
3011
  }, n.$$.update = () => {
3012
  n.$$.dirty & /*color_map*/
3013
  2 && !p && Object.keys(p).length && t(1, p), n.$$.dirty & /*value, combine_adjacent*/
@@ -3031,21 +3031,21 @@ function Ii(n, e, t) {
3031
  L,
3032
  C,
3033
  d,
3034
- g,
3035
  M,
3036
  B,
3037
  Q,
3038
- z,
3039
  R,
3040
  U,
3041
  se,
3042
  D,
3043
  x,
3044
- V,
3045
  de
3046
  ];
3047
  }
3048
- class Wi extends Ni {
3049
  constructor(e) {
3050
  super(), Pi(this, e, Ii, Oi, Bi, {
3051
  gradio: 3,
@@ -3200,5 +3200,5 @@ class Wi extends Ni {
3200
  }
3201
  }
3202
  export {
3203
- Wi as default
3204
  };
 
11
  insert: ul,
12
  safe_not_equal: cl,
13
  set_dynamic_element_data: et,
14
+ set_style: z,
15
  toggle_class: te,
16
  transition_in: Ot,
17
  transition_out: It,
 
70
  n[5] === "focus"
71
  ), te(e, "hide-container", !/*explicit_call*/
72
  n[8] && !/*container*/
73
+ n[9]), z(
74
  e,
75
  "height",
76
  /*get_dimension*/
 
78
  /*height*/
79
  n[0]
80
  )
81
+ ), z(e, "width", typeof /*width*/
82
  n[1] == "number" ? `calc(min(${/*width*/
83
  n[1]}px, 100%))` : (
84
  /*get_dimension*/
 
86
  /*width*/
87
  n[1]
88
  )
89
+ )), z(
90
  e,
91
  "border-style",
92
  /*variant*/
93
  n[4]
94
+ ), z(
95
  e,
96
  "overflow",
97
  /*allow_overflow*/
98
  n[11] ? "visible" : "hidden"
99
+ ), z(
100
  e,
101
  "flex-grow",
102
  /*scale*/
103
  n[12]
104
+ ), z(e, "min-width", `calc(min(${/*min_width*/
105
+ n[13]}px, 100%))`), z(e, "border-width", "var(--block-border-width)");
106
  },
107
  m(f, a) {
108
  ul(f, e, a), o && o.m(e, null), l = !0;
 
161
  ), te(e, "hide-container", !/*explicit_call*/
162
  f[8] && !/*container*/
163
  f[9]), a & /*height*/
164
+ 1 && z(
165
  e,
166
  "height",
167
  /*get_dimension*/
 
170
  f[0]
171
  )
172
  ), a & /*width*/
173
+ 2 && z(e, "width", typeof /*width*/
174
  f[1] == "number" ? `calc(min(${/*width*/
175
  f[1]}px, 100%))` : (
176
  /*get_dimension*/
 
179
  f[1]
180
  )
181
  )), a & /*variant*/
182
+ 16 && z(
183
  e,
184
  "border-style",
185
  /*variant*/
186
  f[4]
187
  ), a & /*allow_overflow*/
188
+ 2048 && z(
189
  e,
190
  "overflow",
191
  /*allow_overflow*/
192
  f[11] ? "visible" : "hidden"
193
  ), a & /*scale*/
194
+ 4096 && z(
195
  e,
196
  "flex-grow",
197
  /*scale*/
198
  f[12]
199
  ), a & /*min_width*/
200
+ 8192 && z(e, "min-width", `calc(min(${/*min_width*/
201
  f[13]}px, 100%))`);
202
  },
203
  i(f) {
 
240
  }
241
  function gl(n, e, t) {
242
  let { $$slots: l = {}, $$scope: i } = e, { height: o = void 0 } = e, { width: s = void 0 } = e, { elem_id: r = "" } = e, { elem_classes: f = [] } = e, { variant: a = "solid" } = e, { border_mode: _ = "base" } = e, { padding: u = !0 } = e, { type: c = "normal" } = e, { test_id: m = void 0 } = e, { explicit_call: p = !1 } = e, { container: T = !0 } = e, { visible: S = !0 } = e, { allow_overflow: L = !0 } = e, { scale: C = null } = e, { min_width: d = 0 } = e, y = c === "fieldset" ? "fieldset" : "div";
243
+ const M = (b) => {
244
+ if (b !== void 0) {
245
+ if (typeof b == "number")
246
+ return b + "px";
247
+ if (typeof b == "string")
248
+ return b;
249
  }
250
  };
251
+ return n.$$set = (b) => {
252
+ "height" in b && t(0, o = b.height), "width" in b && t(1, s = b.width), "elem_id" in b && t(2, r = b.elem_id), "elem_classes" in b && t(3, f = b.elem_classes), "variant" in b && t(4, a = b.variant), "border_mode" in b && t(5, _ = b.border_mode), "padding" in b && t(6, u = b.padding), "type" in b && t(16, c = b.type), "test_id" in b && t(7, m = b.test_id), "explicit_call" in b && t(8, p = b.explicit_call), "container" in b && t(9, T = b.container), "visible" in b && t(10, S = b.visible), "allow_overflow" in b && t(11, L = b.allow_overflow), "scale" in b && t(12, C = b.scale), "min_width" in b && t(13, d = b.min_width), "$$scope" in b && t(17, i = b.$$scope);
253
  }, [
254
  o,
255
  s,
 
1118
  toggle_class: mt,
1119
  transition_in: ne,
1120
  transition_out: ce
1121
+ } = window.__gradio__svelte__internal, { beforeUpdate: zn, afterUpdate: En, createEventDispatcher: Pn } = window.__gradio__svelte__internal;
1122
  function bt(n, e, t) {
1123
  const l = n.slice();
1124
  return l[39] = e[t][0], l[40] = e[t][1], l[42] = t, l;
 
1530
  }
1531
  function Wn(n, e, t) {
1532
  const l = typeof document < "u";
1533
+ let { value: i = [] } = e, { value_is_output: o = !1 } = e, { label: s } = e, { legend_label: r } = e, { info: f = void 0 } = e, { show_label: a = !0 } = e, { show_legend: _ = !1 } = e, { show_legend_label: u = !1 } = e, { container: c = !0 } = e, { color_map: m = {} } = e, { show_copy_button: p = !1 } = e, { disabled: T } = e, S, L = "", C = "", d, y = {}, M = {}, b = !1, B;
1534
  function Q() {
1535
  if (!m || Object.keys(m).length === 0 ? y = {} : y = m, i.length > 0) {
1536
+ for (let [g, j] of i)
1537
  if (j !== null && !(j in y)) {
1538
+ let V = wn(Object.keys(y).length);
1539
+ y[j] = V;
1540
  }
1541
  }
1542
  t(12, M = qn(y, l, d));
1543
  }
1544
+ function E(g) {
1545
+ i.length > 0 && g && (t(11, L = i.map(([j, V]) => j).join(" ")), t(9, C = i.map(([j, V]) => V !== null ? `<mark class="hl ${V}" style="background-color:${M[V].secondary}">${j}</mark>` : j).join(" ") + " "));
1546
  }
1547
  const R = Pn();
1548
  zn(() => {
1549
  S && S.offsetHeight + S.scrollTop > S.scrollHeight - 100;
1550
  });
1551
  function U() {
1552
+ R("change", C), o || R("input"), A();
1553
  }
1554
  En(() => {
1555
+ Q(), E(o), t(18, o = !1);
1556
  });
1557
  function se() {
1558
+ let g = [], j = "", V = null, ee = !1, be = "";
1559
  for (let fe = 0; fe < C.length; fe++) {
1560
  let re = C[fe];
1561
+ re === "<" ? (ee = !0, j && g.push([j, V]), j = "", V = null) : re === ">" ? (ee = !1, be.startsWith("mark") && (V = Un([
1562
  be,
1563
  "access",
1564
  (W) => W.match,
 
1568
  (W) => W[1]
1569
  ]) || null), be = "") : ee ? be += re : j += re;
1570
  }
1571
+ j && g.push([j, V]), t(17, i = g);
1572
  }
1573
  async function D() {
1574
  "clipboard" in navigator && (await navigator.clipboard.writeText(L), x());
1575
  }
1576
  function x() {
1577
+ t(13, b = !0), B && clearTimeout(B), B = setTimeout(
1578
  () => {
1579
+ t(13, b = !1);
1580
  },
1581
  1e3
1582
  );
1583
  }
1584
+ function A() {
1585
+ const g = window.getSelection(), j = g.anchorOffset;
1586
+ if (g.rangeCount > 0) {
1587
+ var V = g.getRangeAt(0).commonAncestorContainer.parentElement;
1588
+ if (V && V.tagName.toLowerCase() === "mark") {
1589
+ const el = V.textContent;
1590
+ var ee = V.parentElement, be = document.createTextNode(el);
1591
+ ee.replaceChild(be, V), t(9, C = ee.innerHTML);
1592
  var fe = document.createRange(), re = window.getSelection();
1593
  const tl = j + Ln(ee);
1594
  var W = Tn(ee, tl);
 
1596
  }
1597
  }
1598
  }
1599
+ function de(g) {
1600
+ qe.call(this, n, g);
1601
  }
1602
+ function h(g) {
1603
+ qe.call(this, n, g);
1604
  }
1605
+ function Fe(g) {
1606
+ qe.call(this, n, g);
1607
  }
1608
+ function Me(g) {
1609
+ qe.call(this, n, g);
1610
  }
1611
+ function me(g) {
1612
+ qe.call(this, n, g);
1613
  }
1614
+ function Pe(g) {
1615
+ ct[g ? "unshift" : "push"](() => {
1616
+ S = g, t(10, S);
1617
  });
1618
  }
1619
  function Ze() {
1620
  L = this.textContent, C = this.innerHTML, t(11, L), t(9, C);
1621
  }
1622
+ function w(g) {
1623
+ ct[g ? "unshift" : "push"](() => {
1624
+ S = g, t(10, S);
1625
  });
1626
  }
1627
  function $t() {
1628
  L = this.textContent, C = this.innerHTML, t(11, L), t(9, C);
1629
  }
1630
+ return n.$$set = (g) => {
1631
+ "value" in g && t(17, i = g.value), "value_is_output" in g && t(18, o = g.value_is_output), "label" in g && t(0, s = g.label), "legend_label" in g && t(1, r = g.legend_label), "info" in g && t(2, f = g.info), "show_label" in g && t(3, a = g.show_label), "show_legend" in g && t(4, _ = g.show_legend), "show_legend_label" in g && t(5, u = g.show_legend_label), "container" in g && t(6, c = g.container), "color_map" in g && t(19, m = g.color_map), "show_copy_button" in g && t(7, p = g.show_copy_button), "disabled" in g && t(8, T = g.disabled);
1632
  }, n.$$.update = () => {
1633
  n.$$.dirty[0] & /*marked_el_text*/
1634
  512 && U();
1635
+ }, Q(), E(!0), [
1636
  s,
1637
  r,
1638
  f,
 
1646
  S,
1647
  L,
1648
  M,
1649
+ b,
1650
  se,
1651
  D,
1652
+ A,
1653
  i,
1654
  o,
1655
  m,
 
2610
  }
2611
  }
2612
  function Fi(n, e, t) {
2613
+ let l, { $$slots: i = {}, $$scope: o } = e, { i18n: s } = e, { eta: r = null } = e, { queue_position: f } = e, { queue_size: a } = e, { status: _ } = e, { scroll_to_output: u = !1 } = e, { timer: c = !0 } = e, { show_progress: m = "full" } = e, { message: p = null } = e, { progress: T = null } = e, { variant: S = "default" } = e, { loading_text: L = "Loading..." } = e, { absolute: C = !0 } = e, { translucent: d = !1 } = e, { border: y = !1 } = e, { autoscroll: M } = e, b, B = !1, Q = 0, E = 0, R = null, U = null, se = 0, D = null, x, A = null, de = !0;
2614
  const h = () => {
2615
+ t(0, r = t(26, R = t(19, me = null))), t(24, Q = performance.now()), t(25, E = 0), B = !0, Fe();
2616
  };
2617
  function Fe() {
2618
  requestAnimationFrame(() => {
2619
+ t(25, E = (performance.now() - Q) / 1e3), B && Fe();
2620
  });
2621
  }
2622
  function Me() {
2623
+ t(25, E = 0), t(0, r = t(26, R = t(19, me = null))), B && (B = !1);
2624
  }
2625
  mi(() => {
2626
  B && Me();
 
2628
  let me = null;
2629
  function Pe(w) {
2630
  Ct[w ? "unshift" : "push"](() => {
2631
+ A = w, t(16, A), t(7, T), t(14, D), t(15, x);
2632
  });
2633
  }
2634
  function Ze(w) {
2635
  Ct[w ? "unshift" : "push"](() => {
2636
+ b = w, t(13, b);
2637
  });
2638
  }
2639
  return n.$$set = (w) => {
 
2641
  }, n.$$.update = () => {
2642
  n.$$.dirty[0] & /*eta, old_eta, timer_start, eta_from_start*/
2643
  218103809 && (r === null && t(0, r = R), r != null && R !== r && (t(27, U = (performance.now() - Q) / 1e3 + r), t(19, me = U.toFixed(1)), t(26, R = r))), n.$$.dirty[0] & /*eta_from_start, timer_diff*/
2644
+ 167772160 && t(17, se = U === null || U <= 0 || !E ? null : Math.min(E / U, 1)), n.$$.dirty[0] & /*progress*/
2645
  128 && T != null && t(18, de = !1), n.$$.dirty[0] & /*progress, progress_level, progress_bar, last_progress_level*/
2646
  114816 && (T != null ? t(14, D = T.map((w) => {
2647
  if (w.index != null && w.length != null)
2648
  return w.index / w.length;
2649
  if (w.progress != null)
2650
  return w.progress;
2651
+ })) : t(14, D = null), D ? (t(15, x = D[D.length - 1]), A && (x === 0 ? t(16, A.style.transition = "0", A) : t(16, A.style.transition = "150ms", A))) : t(15, x = void 0)), n.$$.dirty[0] & /*status*/
2652
  16 && (_ === "pending" ? h() : Me()), n.$$.dirty[0] & /*el, scroll_to_output, status, autoscroll*/
2653
+ 10493968 && b && u && (_ === "pending" || _ === "complete") && Ti(b, M), n.$$.dirty[0] & /*status, message*/
2654
  4194320, n.$$.dirty[0] & /*timer_diff*/
2655
+ 33554432 && t(20, l = E.toFixed(1));
2656
  }, [
2657
  r,
2658
  s,
 
2667
  C,
2668
  d,
2669
  y,
2670
+ b,
2671
  D,
2672
  x,
2673
+ A,
2674
  se,
2675
  de,
2676
  me,
 
2679
  p,
2680
  M,
2681
  Q,
2682
+ E,
2683
  R,
2684
  U,
2685
  o,
 
2997
  };
2998
  }
2999
  function Ii(n, e, t) {
3000
+ let { gradio: l } = e, { label: i = "Highlighted Textbox" } = e, { legend_label: o = "Highlights:" } = e, { info: s = void 0 } = e, { elem_id: r = "" } = e, { elem_classes: f = [] } = e, { visible: a = !0 } = e, { value: _ } = e, { show_label: u } = e, { show_legend: c } = e, { show_legend_label: m } = e, { color_map: p = {} } = e, { container: T = !0 } = e, { scale: S = null } = e, { min_width: L = void 0 } = e, { show_copy_button: C = !1 } = e, { loading_status: d = void 0 } = e, { value_is_output: y = !1 } = e, { combine_adjacent: M = !1 } = e, { interactive: b = !0 } = e;
3001
  const B = !1, Q = !0;
3002
+ function E(h) {
3003
  _ = h, t(0, _), t(19, M);
3004
  }
3005
  function R(h) {
3006
  y = h, t(2, y);
3007
  }
3008
+ const U = () => l.dispatch("change"), se = () => l.dispatch("input"), D = () => l.dispatch("submit"), x = () => l.dispatch("blur"), A = (h) => l.dispatch("select", h.detail), de = () => l.dispatch("focus");
3009
  return n.$$set = (h) => {
3010
+ "gradio" in h && t(3, l = h.gradio), "label" in h && t(4, i = h.label), "legend_label" in h && t(5, o = h.legend_label), "info" in h && t(6, s = h.info), "elem_id" in h && t(7, r = h.elem_id), "elem_classes" in h && t(8, f = h.elem_classes), "visible" in h && t(9, a = h.visible), "value" in h && t(0, _ = h.value), "show_label" in h && t(10, u = h.show_label), "show_legend" in h && t(11, c = h.show_legend), "show_legend_label" in h && t(12, m = h.show_legend_label), "color_map" in h && t(1, p = h.color_map), "container" in h && t(13, T = h.container), "scale" in h && t(14, S = h.scale), "min_width" in h && t(15, L = h.min_width), "show_copy_button" in h && t(16, C = h.show_copy_button), "loading_status" in h && t(17, d = h.loading_status), "value_is_output" in h && t(2, y = h.value_is_output), "combine_adjacent" in h && t(19, M = h.combine_adjacent), "interactive" in h && t(18, b = h.interactive);
3011
  }, n.$$.update = () => {
3012
  n.$$.dirty & /*color_map*/
3013
  2 && !p && Object.keys(p).length && t(1, p), n.$$.dirty & /*value, combine_adjacent*/
 
3031
  L,
3032
  C,
3033
  d,
3034
+ b,
3035
  M,
3036
  B,
3037
  Q,
3038
+ E,
3039
  R,
3040
  U,
3041
  se,
3042
  D,
3043
  x,
3044
+ A,
3045
  de
3046
  ];
3047
  }
3048
+ class Ui extends Ni {
3049
  constructor(e) {
3050
  super(), Pi(this, e, Ii, Oi, Bi, {
3051
  gradio: 3,
 
3200
  }
3201
  }
3202
  export {
3203
+ Ui as default
3204
  };
src/demo/app.py CHANGED
@@ -10,6 +10,19 @@ def convert_tagged_text_to_highlighted_text(
10
  )
11
 
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  with gr.Blocks() as demo:
14
  tag_id = gr.Textbox(
15
  "Potential issue",
@@ -30,14 +43,17 @@ with gr.Blocks() as demo:
30
  info="Insert a tag to mark the end of a highlighted section.",
31
  )
32
  with gr.Row():
33
- tagged = gr.Textbox(
34
- "It is not something to be ashamed of: it is no different from the <h>personal fears</h> and <h>dislikes</h> of other things that <h>very many people</h> have.",
35
  interactive=True,
36
  label="Input",
37
  show_label=True,
38
  info="Insert a text with <h>...</h> tags to mark spans that will be highlighted.",
39
  )
40
- high = HighlightedTextbox(
 
 
 
41
  interactive=True,
42
  label="Output",
43
  info="Highlighted textbox.",
@@ -46,20 +62,42 @@ with gr.Blocks() as demo:
46
  legend_label="Legend:",
47
  show_legend_label=True,
48
  )
49
- button = gr.Button("Submit")
50
- button.click(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  fn=convert_tagged_text_to_highlighted_text,
52
- inputs=[tagged, tag_id, tag_open, tag_close],
53
- outputs=high,
54
  )
55
- # Initialization does not work
56
- high = HighlightedTextbox(
57
- convert_tagged_text_to_highlighted_text(
58
- tagged.value, tag_id.value, tag_open.value, tag_close.value
59
- ),
60
- interactive=True,
61
- label="Does not work",
62
- show_label=True,
 
63
  )
64
 
65
 
 
10
  )
11
 
12
 
13
+ def convert_highlighted_text_to_tagged_text(
14
+ highlighted_text: dict[str, str | list[tuple[str, str | None]]],
15
+ tag_id: str,
16
+ tag_open: str,
17
+ tag_close: str,
18
+ ) -> str:
19
+ return HighlightedTextbox.tuples_to_tagged_text(
20
+ highlighted_text["data"], tag_id, tag_open, tag_close
21
+ )
22
+
23
+
24
+ initial_text = "It is not something to be ashamed of: it is no different from the <h>personal fears</h> and <h>dislikes</h> of other things that <h>very many people</h> have."
25
+
26
  with gr.Blocks() as demo:
27
  tag_id = gr.Textbox(
28
  "Potential issue",
 
43
  info="Insert a tag to mark the end of a highlighted section.",
44
  )
45
  with gr.Row():
46
+ tagged_t2h = gr.Textbox(
47
+ initial_text,
48
  interactive=True,
49
  label="Input",
50
  show_label=True,
51
  info="Insert a text with <h>...</h> tags to mark spans that will be highlighted.",
52
  )
53
+ high_t2h = HighlightedTextbox(
54
+ convert_tagged_text_to_highlighted_text(
55
+ tagged_t2h.value, tag_id.value, tag_open.value, tag_close.value
56
+ ),
57
  interactive=True,
58
  label="Output",
59
  info="Highlighted textbox.",
 
62
  legend_label="Legend:",
63
  show_legend_label=True,
64
  )
65
+ with gr.Row():
66
+ high_h2t = HighlightedTextbox(
67
+ convert_tagged_text_to_highlighted_text(
68
+ tagged_t2h.value, tag_id.value, tag_open.value, tag_close.value
69
+ ),
70
+ interactive=True,
71
+ label="Input",
72
+ info="The following text will be marked by spans according to its highlights.",
73
+ show_legend=True,
74
+ show_label=True,
75
+ legend_label="Legend:",
76
+ show_legend_label=True,
77
+ )
78
+ tagged_h2t = gr.Textbox(
79
+ initial_text,
80
+ interactive=True,
81
+ label="Output",
82
+ show_label=True,
83
+ )
84
+
85
+ # Functions
86
+
87
+ tagged_t2h.change(
88
  fn=convert_tagged_text_to_highlighted_text,
89
+ inputs=[tagged_t2h, tag_id, tag_open, tag_close],
90
+ outputs=high_t2h,
91
  )
92
+ high_t2h.change(
93
+ fn=lambda x: x["data"],
94
+ inputs=high_t2h,
95
+ outputs=high_h2t,
96
+ )
97
+ high_h2t.change(
98
+ fn=convert_highlighted_text_to_tagged_text,
99
+ inputs=[high_h2t, tag_id, tag_open, tag_close],
100
+ outputs=tagged_h2t,
101
  )
102
 
103
 
src/frontend/HighlightedTextbox.svelte CHANGED
@@ -3,7 +3,6 @@
3
  beforeUpdate,
4
  afterUpdate,
5
  createEventDispatcher,
6
- tick,
7
  } from "svelte";
8
  import { BlockTitle } from "@gradio/atoms";
9
  import { Copy, Check } from "@gradio/icons";
@@ -54,8 +53,8 @@
54
  _color_map = correct_color_map(current_color_map, browser, ctx);
55
  }
56
 
57
- function set_text_from_value(): void {
58
- if (value.length > 0 && value_is_output) {
59
  el_text = value.map(([text, _]) => text).join(" ");
60
  marked_el_text = value.map(([text, category]) => {
61
  if (category !== null) {
@@ -67,15 +66,15 @@
67
  }
68
  }
69
 
70
- $: set_text_from_value();
71
  $: set_color_map();
 
72
 
73
  const dispatch = createEventDispatcher<{
74
  change: string;
75
  submit: undefined;
76
  blur: undefined;
77
  select: SelectData;
78
- input: undefined;
79
  focus: undefined;
80
  }>();
81
 
@@ -92,7 +91,7 @@
92
  }
93
  afterUpdate(() => {
94
  set_color_map();
95
- set_text_from_value();
96
  value_is_output = false;
97
  });
98
  $: marked_el_text, handle_change();
 
3
  beforeUpdate,
4
  afterUpdate,
5
  createEventDispatcher,
 
6
  } from "svelte";
7
  import { BlockTitle } from "@gradio/atoms";
8
  import { Copy, Check } from "@gradio/icons";
 
53
  _color_map = correct_color_map(current_color_map, browser, ctx);
54
  }
55
 
56
+ function set_text_from_value(as_output: boolean): void {
57
+ if (value.length > 0 && as_output) {
58
  el_text = value.map(([text, _]) => text).join(" ");
59
  marked_el_text = value.map(([text, category]) => {
60
  if (category !== null) {
 
66
  }
67
  }
68
 
 
69
  $: set_color_map();
70
+ $: set_text_from_value(true);
71
 
72
  const dispatch = createEventDispatcher<{
73
  change: string;
74
  submit: undefined;
75
  blur: undefined;
76
  select: SelectData;
77
+ input: string;
78
  focus: undefined;
79
  }>();
80
 
 
91
  }
92
  afterUpdate(() => {
93
  set_color_map();
94
+ set_text_from_value(value_is_output);
95
  value_is_output = false;
96
  });
97
  $: marked_el_text, handle_change();
src/pyproject.toml CHANGED
@@ -8,7 +8,7 @@ build-backend = "hatchling.build"
8
 
9
  [project]
10
  name = "gradio_highlightedtextbox"
11
- version = "0.0.4"
12
  description = "Editable Gradio textarea supporting highlighting"
13
  readme = "README.md"
14
  license = "mit"
@@ -35,8 +35,11 @@ classifiers = [
35
  [project.optional-dependencies]
36
  dev = ["build", "twine"]
37
 
 
 
 
38
  [tool.hatch.build]
39
- artifacts = ["/backend/gradio_highlightedtextbox/templates", "*.pyi", "backend/gradio_highlightedtextbox/templates", "backend/gradio_highlightedtextbox/templates", "Users/gsarti/Documents/projects/highlightedtextbox/backend/gradio_highlightedtextbox/templates", "Users/gsarti/Documents/projects/highlightedtextbox/backend/gradio_highlightedtextbox/templates", "backend/gradio_highlightedtextbox/templates", "backend/gradio_highlightedtextbox/templates", "backend/gradio_highlightedtextbox/templates", "backend/gradio_highlightedtextbox/templates", "backend/gradio_highlightedtextbox/templates"]
40
 
41
  [tool.hatch.build.targets.wheel]
42
  packages = ["/backend/gradio_highlightedtextbox"]
 
8
 
9
  [project]
10
  name = "gradio_highlightedtextbox"
11
+ version = "0.0.5"
12
  description = "Editable Gradio textarea supporting highlighting"
13
  readme = "README.md"
14
  license = "mit"
 
35
  [project.optional-dependencies]
36
  dev = ["build", "twine"]
37
 
38
+ [project.urls]
39
+ space = "https://huggingface.co/spaces/gsarti/gradio_highlightedtextbox"
40
+
41
  [tool.hatch.build]
42
+ artifacts = ["/backend/gradio_highlightedtextbox/templates", "*.pyi", "backend/gradio_highlightedtextbox/templates", "backend/gradio_highlightedtextbox/templates", "Users/gsarti/Documents/projects/highlightedtextbox/backend/gradio_highlightedtextbox/templates", "Users/gsarti/Documents/projects/highlightedtextbox/backend/gradio_highlightedtextbox/templates", "backend/gradio_highlightedtextbox/templates", "backend/gradio_highlightedtextbox/templates", "backend/gradio_highlightedtextbox/templates", "backend/gradio_highlightedtextbox/templates", "backend/gradio_highlightedtextbox/templates", "backend/gradio_highlightedtextbox/templates", "backend/gradio_highlightedtextbox/templates"]
43
 
44
  [tool.hatch.build.targets.wheel]
45
  packages = ["/backend/gradio_highlightedtextbox"]