pygpt-net 2.4.36.post1__py3-none-any.whl → 2.4.38__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. CHANGELOG.md +14 -1
  2. README.md +54 -13
  3. pygpt_net/CHANGELOG.txt +14 -1
  4. pygpt_net/__init__.py +3 -3
  5. pygpt_net/controller/chat/attachment.py +7 -39
  6. pygpt_net/controller/config/placeholder.py +29 -0
  7. pygpt_net/controller/lang/mapping.py +2 -2
  8. pygpt_net/controller/settings/editor.py +6 -0
  9. pygpt_net/controller/theme/__init__.py +33 -8
  10. pygpt_net/controller/theme/common.py +22 -1
  11. pygpt_net/controller/theme/markdown.py +26 -14
  12. pygpt_net/controller/theme/menu.py +26 -5
  13. pygpt_net/core/attachments/context.py +145 -53
  14. pygpt_net/core/audio/__init__.py +59 -1
  15. pygpt_net/core/bridge/worker.py +16 -2
  16. pygpt_net/core/events/event.py +2 -1
  17. pygpt_net/core/filesystem/__init__.py +5 -19
  18. pygpt_net/core/idx/chat.py +22 -24
  19. pygpt_net/core/render/web/body.py +31 -15
  20. pygpt_net/data/config/config.json +11 -5
  21. pygpt_net/data/config/models.json +3 -3
  22. pygpt_net/data/config/modes.json +3 -3
  23. pygpt_net/data/config/settings.json +81 -10
  24. pygpt_net/data/config/settings_section.json +3 -0
  25. pygpt_net/data/css/style.light.css +1 -0
  26. pygpt_net/data/css/{web.css → web-blocks.css} +144 -133
  27. pygpt_net/data/css/web-chatgpt.css +342 -0
  28. pygpt_net/data/css/web-chatgpt.dark.css +64 -0
  29. pygpt_net/data/css/web-chatgpt.light.css +75 -0
  30. pygpt_net/data/css/web-chatgpt_wide.css +342 -0
  31. pygpt_net/data/css/web-chatgpt_wide.dark.css +64 -0
  32. pygpt_net/data/css/web-chatgpt_wide.light.css +75 -0
  33. pygpt_net/data/locale/locale.de.ini +16 -3
  34. pygpt_net/data/locale/locale.en.ini +24 -10
  35. pygpt_net/data/locale/locale.es.ini +16 -3
  36. pygpt_net/data/locale/locale.fr.ini +16 -3
  37. pygpt_net/data/locale/locale.it.ini +16 -3
  38. pygpt_net/data/locale/locale.pl.ini +17 -4
  39. pygpt_net/data/locale/locale.uk.ini +16 -3
  40. pygpt_net/data/locale/locale.zh.ini +17 -4
  41. pygpt_net/plugin/audio_input/simple.py +17 -3
  42. pygpt_net/plugin/idx_llama_index/__init__.py +2 -2
  43. pygpt_net/plugin/real_time/__init__.py +2 -2
  44. pygpt_net/provider/core/config/patch.py +26 -1
  45. pygpt_net/ui/menu/config.py +7 -11
  46. pygpt_net/ui/menu/theme.py +9 -2
  47. pygpt_net/ui/widget/lists/context.py +1 -0
  48. pygpt_net/ui/widget/textarea/search_input.py +4 -1
  49. {pygpt_net-2.4.36.post1.dist-info → pygpt_net-2.4.38.dist-info}/METADATA +55 -14
  50. {pygpt_net-2.4.36.post1.dist-info → pygpt_net-2.4.38.dist-info}/RECORD +55 -49
  51. /pygpt_net/data/css/{web.dark.css → web-blocks.dark.css} +0 -0
  52. /pygpt_net/data/css/{web.light.css → web-blocks.light.css} +0 -0
  53. {pygpt_net-2.4.36.post1.dist-info → pygpt_net-2.4.38.dist-info}/LICENSE +0 -0
  54. {pygpt_net-2.4.36.post1.dist-info → pygpt_net-2.4.38.dist-info}/WHEEL +0 -0
  55. {pygpt_net-2.4.36.post1.dist-info → pygpt_net-2.4.38.dist-info}/entry_points.txt +0 -0
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2024.11.26 04:00:00 #
9
+ # Updated Date: 2024.12.07 21:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os
@@ -46,21 +46,35 @@ class Body:
46
46
 
47
47
  :return: CSS styles
48
48
  """
49
- dark_styles = ["dracula", "fruity", "github-dark", "gruvbox-dark", "inkpot", "material", "monokai",
50
- "native", "nord", "nord-darker", "one-dark", "paraiso-dark", "rrt", "solarized-dark",
51
- "stata-dark", "vim", "zenburn"]
52
- style = self.window.core.config.get("render.code_syntax")
53
- if style is None or style == "":
54
- style = "default"
49
+ syntax_dark = [
50
+ "dracula",
51
+ "fruity",
52
+ "github-dark",
53
+ "gruvbox-dark",
54
+ "inkpot",
55
+ "material",
56
+ "monokai",
57
+ "native",
58
+ "nord",
59
+ "nord-darker",
60
+ "one-dark",
61
+ "paraiso-dark",
62
+ "rrt",
63
+ "solarized-dark",
64
+ "stata-dark",
65
+ "vim",
66
+ "zenburn",
67
+ ]
68
+ syntax_style = self.window.core.config.get("render.code_syntax")
69
+ if syntax_style is None or syntax_style == "":
70
+ syntax_style = "default"
55
71
  fonts_path = os.path.join(self.window.core.config.get_app_path(), "data", "fonts").replace("\\", "/")
56
72
  stylesheet = self.window.controller.theme.markdown.get_web_css().replace('%fonts%', fonts_path)
57
- if style in dark_styles:
73
+ if syntax_style in syntax_dark:
58
74
  stylesheet += "pre { color: #fff; }"
59
75
  else:
60
76
  stylesheet += "pre { color: #000; }"
61
- content = stylesheet + """
62
- """ + self.highlight.get_style_defs()
63
- return content
77
+ return stylesheet + " " + self.highlight.get_style_defs()
64
78
 
65
79
  def prepare_action_icons(self, ctx: CtxItem) -> str:
66
80
  """
@@ -187,9 +201,9 @@ class Body:
187
201
  """
188
202
  icon_path = os.path.join(
189
203
  self.window.core.config.get_app_path(),
190
- "data", "icons", "public_filled.svg"
204
+ "data", "icons", "language.svg"
191
205
  )
192
- icon = '<img src="file://{}" width="25" height="25" valign="middle" class="extra-src-icon">'.format(icon_path)
206
+ icon = '<img src="file://{}" class="extra-src-icon">'.format(icon_path)
193
207
  num_str = ""
194
208
  if num is not None and num_all is not None and num_all > 1:
195
209
  num_str = " [{}]".format(num)
@@ -235,7 +249,7 @@ class Body:
235
249
  self.window.core.config.get_app_path(),
236
250
  "data", "icons", "db.svg"
237
251
  )
238
- icon = '<img src="file://{}" width="25" height="25" valign="middle" class="extra-src-icon">'.format(icon_path)
252
+ icon = '<img src="file://{}" class="extra-src-icon">'.format(icon_path)
239
253
  if html_sources != "":
240
254
  html += "<p>{icon}<small><b>{prefix}:</b></small></p>".format(
241
255
  prefix=trans('chat.prefix.doc'),
@@ -259,7 +273,7 @@ class Body:
259
273
  self.window.core.config.get_app_path(),
260
274
  "data", "icons", "attachments.svg"
261
275
  )
262
- icon = '<img src="file://{}" width="25" height="25" valign="middle" class="extra-src-icon">'.format(icon_path)
276
+ icon = '<img src="file://{}" class="extra-src-icon">'.format(icon_path)
263
277
  num_str = ""
264
278
  if num is not None and num_all is not None and num_all > 1:
265
279
  num_str = " [{}]".format(num)
@@ -319,12 +333,14 @@ class Body:
319
333
  """
320
334
  classes = []
321
335
  classes_str = ""
336
+ style = self.window.core.config.get("theme.style", "blocks")
322
337
  if self.window.core.config.get('render.blocks'):
323
338
  classes.append("display-blocks")
324
339
  if self.window.core.config.get('ctx.edit_icons'):
325
340
  classes.append("display-edit-icons")
326
341
  if self.is_timestamp_enabled():
327
342
  classes.append("display-timestamp")
343
+ classes.append("theme-" + style)
328
344
  if classes:
329
345
  classes_str = ' class="' + " ".join(classes) + '"'
330
346
 
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.4.36",
4
- "app.version": "2.4.36",
5
- "updated_at": "2024-11-28T00:00:00"
3
+ "version": "2.4.38",
4
+ "app.version": "2.4.38",
5
+ "updated_at": "2024-12-08T00:00:00"
6
6
  },
7
7
  "access.audio.event.speech": false,
8
8
  "access.audio.event.speech.disabled": [],
@@ -65,15 +65,20 @@
65
65
  "assistant": "",
66
66
  "assistant_thread": "",
67
67
  "assistant.store.hide_threads": true,
68
- "attachments_auto_index": false,
68
+ "attachments_auto_index": true,
69
69
  "attachments_send_clear": true,
70
70
  "attachments_capture_clear": true,
71
+ "audio.input.channels": 1,
72
+ "audio.input.device": "0",
73
+ "audio.input.rate": 44100,
71
74
  "audio.transcribe.convert_video": true,
72
75
  "context_threshold": 200,
73
76
  "cmd": false,
74
77
  "ctx": "",
75
78
  "ctx.attachment.img": false,
76
- "ctx.attachment.mode": "full",
79
+ "ctx.attachment.mode": "query",
80
+ "ctx.attachment.rag.history": true,
81
+ "ctx.attachment.rag.history.max_items": 3,
77
82
  "ctx.attachment.summary.model": "gpt-4o-mini",
78
83
  "ctx.attachment.query.model": "gpt-4o-mini",
79
84
  "ctx.attachment.verbose": false,
@@ -333,6 +338,7 @@
333
338
  "temperature": 1.0,
334
339
  "theme": "dark_cyan",
335
340
  "theme.markdown": true,
341
+ "theme.style": "chatgpt",
336
342
  "top_p": 1.0,
337
343
  "upload.store": true,
338
344
  "upload.data_dir": false,
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.4.36",
4
- "app.version": "2.4.36",
5
- "updated_at": "2024-11-28T00:00:00"
3
+ "version": "2.4.38",
4
+ "app.version": "2.4.38",
5
+ "updated_at": "2024-12-08T00:00:00"
6
6
  },
7
7
  "items": {
8
8
  "claude-3-5-sonnet-20240620": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.4.36",
4
- "app.version": "2.4.36",
5
- "updated_at": "2024-11-28T00:00:00"
3
+ "version": "2.4.38",
4
+ "app.version": "2.4.38",
5
+ "updated_at": "2024-12-08T00:00:00"
6
6
  },
7
7
  "items": {
8
8
  "chat": {
@@ -146,6 +146,15 @@
146
146
  "step": 1,
147
147
  "advanced": false
148
148
  },
149
+ "theme.style": {
150
+ "section": "layout",
151
+ "type": "combo",
152
+ "use": "styles",
153
+ "label": "settings.theme.style",
154
+ "description": "settings.render.web.only.desc",
155
+ "value": "chatgpt",
156
+ "advanced": false
157
+ },
149
158
  "render.code_syntax": {
150
159
  "section": "layout",
151
160
  "type": "combo",
@@ -372,6 +381,32 @@
372
381
  "step": null,
373
382
  "advanced": false
374
383
  },
384
+ "ctx.attachment.rag.history": {
385
+ "section": "files",
386
+ "type": "bool",
387
+ "slider": false,
388
+ "label": "settings.ctx.attachment.rag.history",
389
+ "description": "settings.ctx.attachment.rag.history.desc",
390
+ "value": true,
391
+ "min": null,
392
+ "max": null,
393
+ "multiplier": null,
394
+ "step": null,
395
+ "advanced": false
396
+ },
397
+ "ctx.attachment.rag.history.max_items": {
398
+ "section": "files",
399
+ "type": "int",
400
+ "slider": true,
401
+ "label": "settings.ctx.attachment.rag.history.max_items",
402
+ "description": "settings.ctx.attachment.rag.history.max_items.desc",
403
+ "value": 5,
404
+ "min": 0,
405
+ "max": 100,
406
+ "multiplier": 1,
407
+ "step": 1,
408
+ "advanced": false
409
+ },
375
410
  "download.dir": {
376
411
  "section": "files",
377
412
  "type": "text",
@@ -911,6 +946,19 @@
911
946
  "step": null,
912
947
  "advanced": true
913
948
  },
949
+ "vision.capture.idx": {
950
+ "section": "vision",
951
+ "type": "int",
952
+ "slider": true,
953
+ "label": "settings.vision.capture.idx",
954
+ "description": "settings.vision.capture.idx.desc",
955
+ "value": 0,
956
+ "min": 0,
957
+ "max": 3,
958
+ "multiplier": 1,
959
+ "step": 1,
960
+ "advanced": false
961
+ },
914
962
  "vision.capture.width": {
915
963
  "section": "vision",
916
964
  "type": "int",
@@ -935,26 +983,49 @@
935
983
  "step": 1,
936
984
  "advanced": false
937
985
  },
938
- "vision.capture.idx": {
986
+ "vision.capture.quality": {
939
987
  "section": "vision",
940
988
  "type": "int",
941
989
  "slider": true,
942
- "label": "settings.vision.capture.idx",
943
- "value": 0,
944
- "min": 0,
945
- "max": 3,
990
+ "label": "settings.vision.capture.quality",
991
+ "value": 85,
992
+ "min": 1,
993
+ "max": 100,
946
994
  "multiplier": 1,
947
995
  "step": 1,
948
996
  "advanced": false
949
997
  },
950
- "vision.capture.quality": {
951
- "section": "vision",
998
+ "audio.input.device": {
999
+ "section": "audio",
1000
+ "type": "combo",
1001
+ "use": "audio_input_devices",
1002
+ "label": "settings.audio.input.device",
1003
+ "description": "settings.audio.input.device.desc",
1004
+ "value": 0,
1005
+ "advanced": false
1006
+ },
1007
+ "audio.input.channels": {
1008
+ "section": "audio",
952
1009
  "type": "int",
953
1010
  "slider": true,
954
- "label": "settings.vision.capture.quality",
955
- "value": 85,
1011
+ "label": "settings.audio.input.channels",
1012
+ "description": "settings.audio.input.channels.desc",
1013
+ "value": 1,
956
1014
  "min": 1,
957
- "max": 100,
1015
+ "max": 4,
1016
+ "multiplier": 1,
1017
+ "step": 1,
1018
+ "advanced": false
1019
+ },
1020
+ "audio.input.rate": {
1021
+ "section": "audio",
1022
+ "type": "int",
1023
+ "slider": true,
1024
+ "label": "settings.audio.input.rate",
1025
+ "description": "settings.audio.input.rate.desc",
1026
+ "value": 44100,
1027
+ "min": 8,
1028
+ "max": 256000,
958
1029
  "multiplier": 1,
959
1030
  "step": 1,
960
1031
  "advanced": false
@@ -23,6 +23,9 @@
23
23
  "vision": {
24
24
  "label": "settings.section.vision"
25
25
  },
26
+ "audio": {
27
+ "label": "settings.section.audio"
28
+ },
26
29
  "llama-index": {
27
30
  "label": "settings.section.llama_index"
28
31
  },
@@ -4,6 +4,7 @@
4
4
  QWidget {{
5
5
  background-color: #e7e7e7;
6
6
  color: #000;
7
+ margin: 1px;
7
8
  }}
8
9
 
9
10
  QListView,
@@ -26,6 +26,11 @@ body {{
26
26
  -webkit-border-radius: 1ex;
27
27
  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.75);
28
28
  }}
29
+ .ts {{
30
+ display: none;
31
+ }}
32
+
33
+ /* base */
29
34
  a {{
30
35
  text-decoration: none;
31
36
  color: #a1b5c4 !important;
@@ -38,129 +43,20 @@ p {{
38
43
  margin-top: 5px;
39
44
  margin-bottom: 5px;
40
45
  }}
41
- .extra-src-icon {{
42
- padding-right: 2px;
43
- }}
44
- .extra-src-img-box {{
45
- display: inline-block;
46
- text-align: center;
47
- padding: 5px;
48
- margin: 5px;
49
- max-width: 400px;
50
- height: auto;
51
- white-space: pre-wrap;
52
- word-break: break-all !important;
53
- }}
54
- .extra-src-img-box:hover {{
55
- cursor: pointer;
56
- }}
57
- .extra-src-img-box .title {{
58
- width: 400px;
59
- overflow: hidden;
60
- white-space: nowrap;
61
- text-overflow: ellipsis;
62
- display: block;
63
- text-align: center;
64
- padding: 0;
65
- margin: 0;
66
- padding-top: 10px;
67
- display: block;
68
- font-size: 0.95rem;
69
- }}
70
- .extra-src-img-box .img-outer {{
71
- display: flex;
72
- flex-direction: column;
73
- }}
74
- .extra-src-img-box .img-wrapper {{
75
- position: relative;
76
- overflow: hidden;
77
- border: 1px solid #000;
78
- background: #000;
79
- width: 400px;
80
- height: 280px;
81
- margin: 0;
82
- margin-bottom: 0px !important;
83
- border-radius: 5px;
84
- -webkit-box-shadow: 8px 8px 22px -16px rgba(0, 0, 0, 1);
85
- -moz-box-shadow: 8px 8px 22px -16px rgba(0, 0, 0, 1);
86
- box-shadow: 8px 8px 22px -16px rgba(0, 0, 0, 1);
87
- }}
88
- .extra-src-img-box .img-wrapper:hover {{
89
- border: 1px solid gray;
90
- }}
91
- .extra-src-img-box img {{
92
- margin-bottom: 2px;
93
- padding-bottom: 0px;
94
- display: block;
95
- width: 100%;
96
- height: 100%;
97
- object-fit: cover;
98
- }}
99
- .msg-user {{
100
- white-space: pre-wrap;
101
- width: auto;
102
- max-width: 100%;
103
- padding-top: 5px;
104
- padding-bottom: 5px;
105
- padding-left: 10px;
106
- margin-top: 10px;
107
- margin-left: 0px;
108
- margin-bottom: 5px;
109
- }}
110
- .msg-bot {{
111
- white-space: pre-wrap;
112
- width: auto;
113
- max-width: 100%;
114
- margin-top: 10px;
115
- margin-bottom: 0px;
116
- padding-bottom: 0px;
117
- }}
118
- .msg-extra {{
119
- margin-top: 10px;
120
- margin-bottom: 0px;
121
- color: gray;
122
- }}
123
- .msg-extra a {{
124
- color: gray;
125
- }}
126
- .msg-user .msg-extra {{
127
- font-weight: bold;
128
- padding-top: 5px;
129
- }}
130
- .msg-box {{
131
- padding: 5px;
132
- max-width: 100%;
133
- }}
134
- .msg-box .msg {{
135
- margin: 0;
136
- padding: 15px;
137
- }}
138
- .msg-box:first-child {{
139
- margin-top: 0px;
140
- }}
141
- .msg-box:last-child {{
142
- border-bottom: none;
143
- }}
144
- .msg-box .name-header {{
145
- display: none;
146
- }}
46
+
47
+ /* images */
147
48
  .image {{
148
49
  max-width: 400px;
149
50
  }}
51
+
52
+ /* cmd */
150
53
  .cmd {{
151
54
  font-family: 'Lato';
152
55
  text-decoration: none;
153
56
  padding-bottom: 0px;
154
57
  }}
155
- .ts {{
156
- display: none;
157
- }}
158
- .tool-output-header {{
159
- margin-top: 15px;
160
- margin-bottom: 10px;
161
- font-weight: bold;
162
- color: gray;
163
- }}
58
+
59
+ /* lists, code */
164
60
  ul, ol, .list {{
165
61
  margin-top: 0px;
166
62
  margin-bottom: 0px;
@@ -192,6 +88,7 @@ code {{
192
88
  }}
193
89
  .code-header-lang {{
194
90
  float: left;
91
+ padding-left: .25rem;
195
92
  }}
196
93
  .code-header-copy {{
197
94
  text-align: right;
@@ -199,6 +96,7 @@ code {{
199
96
  font-weight: bold;
200
97
  display: inline-block;
201
98
  color: #6e6e6e;
99
+ padding-right: .25rem;
202
100
  }}
203
101
  .code-header-copy img {{
204
102
  vertical-align: middle;
@@ -217,43 +115,65 @@ code {{
217
115
  .highlight span {{
218
116
  font-family: 'Monaspace Neon';
219
117
  }}
118
+
119
+ /* action icons */
220
120
  .action-icons {{
221
- margin-top: 10px;
121
+ margin-top: 20px;
222
122
  }}
223
123
  .action-icons a {{
224
124
  text-decoration: none;
225
125
  }}
226
126
  .action-icons a:hover {{
227
- filter: brightness(60%);
127
+ filter: brightness(120%);
228
128
  }}
229
129
  .action-img {{
230
130
  width: 20px;
231
131
  height: 20px;
232
132
  }}
233
133
  .edit-icon {{
234
- display: none;
235
- }}
236
- .display-edit-icons .edit-icon {{
237
134
  display: inline;
238
135
  }}
239
- .display-timestamp .ts {{
136
+ .theme-blocks.display-timestamp .ts {{
240
137
  display: inline;
241
138
  }}
242
- .display-blocks {{
243
- }}
244
- .display-blocks .msg-box {{
139
+
140
+ /* message box */
141
+ .msg-box {{
142
+ max-width: 100%;
245
143
  border-radius: 10px;
246
144
  padding: 10px;
247
145
  margin-right: 10px;
248
146
  }}
249
- .display-blocks .msg-box:not(first-child) {{
147
+ .msg-user {{
148
+ white-space: pre-wrap;
149
+ width: auto;
150
+ max-width: 100%;
151
+ padding-top: 10px;
152
+ padding-bottom: 5px;
153
+ padding-left: 10px;
154
+ margin-top: 10px;
155
+ margin-left: 0px;
156
+ margin-bottom: 5px;
157
+ }}
158
+ .msg-bot {{
159
+ white-space: pre-wrap;
160
+ width: auto;
161
+ max-width: 100%;
162
+ margin-top: 10px;
163
+ margin-bottom: 0px;
164
+ padding-bottom: 0px;
165
+ }}
166
+ .msg-box:not(first-child) {{
250
167
  margin-top: 20px !important;
251
168
  }}
252
- .display-blocks .name-header {{
169
+ .msg-box:first-child {{
170
+ margin-top: 0px;
171
+ }}
172
+ .msg-box .name-header {{
253
173
  display: block;
254
174
  font-size: 0.8rem;
255
175
  }}
256
- .display-blocks .name-header::before {{
176
+ .msg-box .name-header::before {{
257
177
  content: '';
258
178
  display: inline-block;
259
179
  width: 10px;
@@ -262,15 +182,29 @@ code {{
262
182
  margin-right: 8px;
263
183
  vertical-align: middle;
264
184
  }}
265
- .append_input {{
266
- margin: 0;
267
- padding: 0;
185
+ .msg-extra {{
186
+ margin-top: 10px;
187
+ margin-bottom: 0px;
188
+ color: gray;
268
189
  }}
269
- .append_output {{
190
+ .msg-extra a {{
191
+ color: gray;
192
+ }}
193
+ .msg-user .msg-extra {{
194
+ font-weight: bold;
195
+ padding-top: 5px;
196
+ }}
197
+ .msg-box .msg {{
270
198
  margin: 0;
271
- padding: 0;
199
+ padding: 15px;
272
200
  }}
273
- .empty_list {{
201
+
202
+ /* tool output */
203
+ .tool-output-header {{
204
+ margin-top: 15px;
205
+ margin-bottom: 10px;
206
+ font-weight: bold;
207
+ color: gray;
274
208
  }}
275
209
  .tool-output .content {{
276
210
  padding: 10px;
@@ -282,9 +216,84 @@ code {{
282
216
  display: block;
283
217
  color: gray;
284
218
  }}
219
+
220
+ /* extra source */
221
+ .extra-src-icon {{
222
+ padding-right: 2px;
223
+ width: 25px;
224
+ height: 25px;
225
+ vertical-align: middle;
226
+ }}
227
+ .extra-src-img-box {{
228
+ display: inline-block;
229
+ text-align: center;
230
+ padding: 5px;
231
+ margin: 5px;
232
+ max-width: 400px;
233
+ height: auto;
234
+ white-space: pre-wrap;
235
+ word-break: break-all !important;
236
+ }}
237
+ .extra-src-img-box:hover {{
238
+ cursor: pointer;
239
+ }}
240
+ .extra-src-img-box .title {{
241
+ width: 400px;
242
+ overflow: hidden;
243
+ white-space: nowrap;
244
+ text-overflow: ellipsis;
245
+ display: block;
246
+ text-align: center;
247
+ padding: 0;
248
+ margin: 0;
249
+ padding-top: 10px;
250
+ display: block;
251
+ font-size: 0.95rem;
252
+ }}
253
+ .extra-src-img-box .img-outer {{
254
+ display: flex;
255
+ flex-direction: column;
256
+ }}
257
+ .extra-src-img-box .img-wrapper {{
258
+ position: relative;
259
+ overflow: hidden;
260
+ border: 1px solid #000;
261
+ background: #000;
262
+ width: 400px;
263
+ height: 280px;
264
+ margin: 0;
265
+ margin-bottom: 0px !important;
266
+ border-radius: 5px;
267
+ -webkit-box-shadow: 8px 8px 22px -16px rgba(0, 0, 0, 1);
268
+ -moz-box-shadow: 8px 8px 22px -16px rgba(0, 0, 0, 1);
269
+ box-shadow: 8px 8px 22px -16px rgba(0, 0, 0, 1);
270
+ }}
271
+ .extra-src-img-box .img-wrapper:hover {{
272
+ border: 1px solid gray;
273
+ }}
274
+ .extra-src-img-box img {{
275
+ margin-bottom: 2px;
276
+ padding-bottom: 0px;
277
+ display: block;
278
+ width: 100%;
279
+ height: 100%;
280
+ object-fit: cover;
281
+ }}
282
+
283
+ /* common */
285
284
  .toggle-expanded {{
286
285
  transform: rotateX(180deg);
287
286
  }}
287
+ .append_input {{
288
+ margin: 0;
289
+ padding: 0;
290
+ }}
291
+ .append_output {{
292
+ margin: 0;
293
+ padding: 0;
294
+ }}
295
+ .empty_list {{
296
+ }}
288
297
  .spinner {{
289
298
  display: inline-block;
290
299
  animation: spin 2s linear infinite;
@@ -300,6 +309,8 @@ code {{
300
309
  width: 100% !important;
301
310
  height: 100% !important;
302
311
  }}
312
+
313
+ /* anims */
303
314
  @keyframes spin {{
304
315
  from {{
305
316
  transform: rotate(0deg);