ivoryos 0.1.20__py3-none-any.whl → 0.1.22__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.

Potentially problematic release.


This version of ivoryos might be problematic. Click here for more details.

@@ -28,7 +28,7 @@
28
28
  <div class="accordion-body">
29
29
  {% if script['script'] or script['prep'] or script['cleanup'] %}
30
30
  <div class="row">
31
- <div class="col-lg-6 col-sm-12" id="run-panel">
31
+ <div class="col-lg-6 col-sm-12" id="run-panel" style="{{ 'display: none;' if pause_status else '' }}">
32
32
  <ul class="nav nav-tabs" id="myTabs" role="tablist">
33
33
  <li class="nav-item" role="presentation">
34
34
  <a class="nav-link {{ 'disabled' if config_list else '' }} {{ 'active' if not config_list else '' }}" id="tab1-tab" data-bs-toggle="tab" href="#tab1" role="tab" aria-controls="tab1" aria-selected="false">Repeat</a>
@@ -128,75 +128,132 @@
128
128
  {% endif %}
129
129
  </div>
130
130
 
131
- <div class="tab-pane fade " id="tab3" role="tabpanel" aria-labelledby="tab3-tab">
132
- <form role="form" method='POST' name="bo" action="{{ url_for('design.experiment_run')}}">
133
- <div class="form-group">
134
- <p><h5>Parameters:</h5><p>
135
- {% for config in config_list %}
136
- <div class="row g-3 align-items-center">
137
- <div class="col-lg-3 col-sm-6 ">
138
- {{config}}:
139
- </div>
131
+ {# <div class="tab-pane fade " id="tab3" role="tabpanel" aria-labelledby="tab3-tab">#}
132
+ {# <form role="form" method='POST' name="bo" action="{{ url_for('design.experiment_run')}}">#}
133
+ {# <div class="form-group">#}
134
+ {# <p><h5>Parameters:</h5><p>#}
135
+ {# {% for config in config_list %}#}
136
+ {# <div class="row g-3 align-items-center">#}
137
+ {# <div class="col-lg-3 col-sm-6 ">#}
138
+ {# {{config}}:#}
139
+ {# </div>#}
140
140
  {# <div class="col-auto">#}
141
141
  {# <label class="col-form-label" for="{{config}}_type">Type</label>#}
142
142
  {# </div>#}
143
- <div class="col-auto">
144
- <select class="form-select" id="{{config}}_type" name="{{config}}_type">
145
- <option selected value="range">range</option>
146
- <option value="choice">choice</option>
147
- <option value="fixed">fixed</option>
148
- </select>
149
- </div>
150
- <div class="col-auto">
151
- <label class="" for="{{config}}_value">Values</label>
152
- </div>
153
- <div class="col-auto">
154
- <input type="text" class="form-control" id="{{config}}_value" name="{{config}}_value" placeholder="1, 2, 3">
155
- </div>
143
+ {# <div class="col-auto">#}
144
+ {# <select class="form-select" id="{{config}}_type" name="{{config}}_type">#}
145
+ {# <option selected value="range">range</option>#}
146
+ {# <option value="choice">choice</option>#}
147
+ {# <option value="fixed">fixed</option>#}
148
+ {# </select>#}
149
+ {# </div>#}
150
+ {# <div class="col-auto">#}
151
+ {# <label class="" for="{{config}}_value">Values</label>#}
152
+ {# </div>#}
153
+ {# <div class="col-auto">#}
154
+ {# <input type="text" class="form-control" id="{{config}}_value" name="{{config}}_value" placeholder="1, 2, 3">#}
155
+ {# </div>#}
156
156
  {# <div class="col-auto">#}
157
157
  {# <input type="text" class="form-control" id="{{config}}_value_max" style="display: none;" placeholder="1, 2, 3">#}
158
158
  {# </div>#}
159
- </div>
160
- {% endfor %}
161
- <p><h5>Objective:</h5><p>
162
- {% for objective in return_list %}
163
- <div class="row gy-2 gx-3 align-items-center input-group">
164
- <div class="col-3">
165
- {{objective}}:
166
- </div>
159
+ {# </div>#}
160
+ {# {% endfor %}#}
161
+ {# <p><h5>Objective:</h5><p>#}
162
+ {# {% for objective in return_list %}#}
163
+ {# <div class="row gy-2 gx-3 align-items-center input-group">#}
164
+ {# <div class="col-3">#}
165
+ {# {{objective}}:#}
166
+ {# </div>#}
167
167
  {# <div class="col-auto">#}
168
168
  {# <label class="" for="{{objective}}_min">Minimize</label>#}
169
169
  {# </div>#}
170
- <div class="col-auto">
171
- <select class="form-select" id="{{objective}}_min" name="{{objective}}_min">
172
- <option selected>minimize</option>
173
- <option>maximize</option>
174
- <option>none</option>
175
- </select>
176
- </div>
170
+ {# <div class="col-auto">#}
171
+ {# <select class="form-select" id="{{objective}}_min" name="{{objective}}_min">#}
172
+ {# <option selected>minimize</option>#}
173
+ {# <option>maximize</option>#}
174
+ {# <option>none</option>#}
175
+ {# </select>#}
176
+ {# </div>#}
177
177
  {# <div class="col-auto">#}
178
178
  {# <label class="" for="{{objective}}_threshold">Threshold</label>#}
179
179
  {# </div>#}
180
180
  {# <div class="col-auto">#}
181
181
  {# <input type="text" class="form-control" id="{{objective}}_threshold" name="{{objective}}_threshold" placeholder="None">#}
182
182
  {# </div>#}
183
- </div>
184
- {% endfor %}
185
- <p><h5>Budget:</h5></p>
186
- <div class="input-group mb-3">
187
- <label class="input-group-text" for="repeat">Max iteration </label>
188
- <input class="form-control" type="number" id="repeat" name="repeat" min="1" max="1000" value="25">
189
- </div>
190
- {% if not no_deck_warning%}
191
- <div class="input-group mb-3">
192
- <button class="form-control" type="submit" name="bo">Run</button>
193
- </div>
194
- {% endif %}
195
- </div>
196
- </form>
197
- </div>
183
+ {# </div>#}
184
+ {# {% endfor %}#}
185
+ {# <p><h5>Budget:</h5></p>#}
186
+ {# <div class="input-group mb-3">#}
187
+ {# <label class="input-group-text" for="repeat">Max iteration </label>#}
188
+ {# <input class="form-control" type="number" id="repeat" name="repeat" min="1" max="1000" value="25">#}
189
+ {# </div>#}
190
+ {# {% if not no_deck_warning%}#}
191
+ {# <div class="input-group mb-3">#}
192
+ {# <button class="form-control" type="submit" name="bo">Run</button>#}
193
+ {# </div>#}
194
+ {# {% endif %}#}
195
+ {# </div>#}
196
+ {# </form>#}
197
+ {# </div>#}
198
+ <div class="tab-pane fade" id="tab3" role="tabpanel" aria-labelledby="tab3-tab">
199
+ <form method="POST" name="bo" action="{{ url_for('design.experiment_run') }}">
200
+ <div class="container py-2">
201
+
202
+ <!-- Parameters -->
203
+ <h6 class="fw-bold mt-2 mb-1">Parameters</h6>
204
+ {% for config in config_list %}
205
+ <div class="row align-items-center mb-2">
206
+ <div class="col-3 col-form-label-sm">
207
+ {{ config }}:
208
+ </div>
209
+ <div class="col-6">
210
+ <select class="form-select form-select-sm" id="{{config}}_type" name="{{config}}_type">
211
+ <option selected value="range">range</option>
212
+ <option value="choice">choice</option>
213
+ <option value="fixed">fixed</option>
214
+ </select>
215
+ </div>
216
+ <div class="col-3">
217
+ <input type="text" class="form-control form-control-sm" id="{{config}}_value" name="{{config}}_value" placeholder="1, 2, 3">
218
+ </div>
219
+ </div>
220
+ {% endfor %}
221
+
222
+ <!-- Objective -->
223
+ <h6 class="fw-bold mt-3 mb-1">Objectives</h6>
224
+ {% for objective in return_list %}
225
+ <div class="row align-items-center mb-2">
226
+ <div class="col-3 col-form-label-sm">
227
+ {{ objective }}:
228
+ </div>
229
+ <div class="col-6">
230
+ <select class="form-select form-select-sm" id="{{objective}}_min" name="{{objective}}_min">
231
+ <option selected>minimize</option>
232
+ <option>maximize</option>
233
+ <option>none</option>
234
+ </select>
235
+ </div>
236
+ </div>
237
+ {% endfor %}
238
+
239
+ <h6 class="fw-bold mt-3 mb-1">Budget</h6>
240
+
241
+ <div class="input-group mb-3">
242
+ <label class="input-group-text" for="repeat">Max iteration </label>
243
+ <input class="form-control" type="number" id="repeat" name="repeat" min="1" max="1000" value="25">
244
+ </div>
245
+ {% if not no_deck_warning%}
246
+ <div class="input-group mb-3">
247
+ <button class="form-control" type="submit" name="bo">Run</button>
248
+ </div>
249
+ {% endif %}
250
+ </div>
251
+ </form>
252
+ </div>
253
+
254
+
198
255
  <div class="tab-pane fade {{ 'show active' if config_list and config_list|count<=5 else '' }}" id="tab4" role="tabpanel" aria-labelledby="tab4-tab">
199
- <p><h5>Control panel:</h5></p>
256
+ {# <p><h5>Control panel:</h5></p>#}
200
257
  <div>
201
258
  <form method="POST" name="online-config" id="online-config" action="{{url_for('design.experiment_run')}}">
202
259
  <table id="dataInputTable" class="table table-striped">
@@ -210,21 +267,43 @@
210
267
  <tbody>
211
268
  </tbody>
212
269
  </table>
213
- <div class="btn btn-light" onclick="addRow()"><i class="bi bi-plus-circle" ></i></div>
214
- <button type="submit" name="online-config" class="btn btn-success">Run</button>
270
+ <div class="d-flex align-items-center gap-2">
271
+ <div class="btn btn-light" onclick="addRow()">
272
+ <i class="bi bi-plus-circle"></i>
273
+ </div>
274
+ <button type="submit" name="online-config" class="form-control">Run</button>
275
+ </div>
215
276
  </form>
216
277
  </div>
217
278
  </div>
218
279
  </div>
219
280
  </div>
220
- <div class="col-lg-6 col-sm-12" id="code-panel" style="display: none;">
281
+ <div class="col-lg-6 col-sm-12" id="code-panel" style="{{ '' if pause_status else 'display: none;'}}">
221
282
  <p>
222
283
  <h5>Progress:</h5>
223
- {% for stype, script in line_collection.items() %}
224
- {% for code in script %}
284
+ {% if "prep" in line_collection.keys() %} {% set stype = "cleanup" %}
285
+ {% set stype = "prep" %}
286
+
287
+ <h6>Preparation:</h6>
288
+ {% for code in line_collection["prep"] %}
289
+ <pre style="margin: 0; padding: 0; line-height: 1;"><code class="python" id="{{ stype }}-{{ loop.index0 }}" >{{code}}</code></pre>
290
+ {% endfor %}
291
+ {% endif %}
292
+ {% if "script" in line_collection.keys() %}
293
+ {% set stype = "script" %}
294
+
295
+ <h6>Experiment:</h6>
296
+ {% for code in line_collection["script"] %}
297
+ <pre style="margin: 0; padding: 0; line-height: 1;"><code class="python" id="{{ stype }}-{{ loop.index0 }}" >{{code}}</code></pre>
298
+ {% endfor %}
299
+ {% endif %}
300
+ {% if "cleanup" in line_collection.keys() %}
301
+ {% set stype = "cleanup" %}
302
+ <h6>Experiment:</h6>
303
+ {% for code in line_collection["cleanup"] %}
225
304
  <pre style="margin: 0; padding: 0; line-height: 1;"><code class="python" id="{{ stype }}-{{ loop.index0 }}" >{{code}}</code></pre>
226
305
  {% endfor %}
227
- {% endfor %}
306
+ {% endif %}
228
307
  </p>
229
308
  </div>
230
309
  <div class="col-lg-6 col-sm-12 logging-panel">
@@ -233,7 +312,11 @@
233
312
  <h5>Progress:</h5>
234
313
  <div class="d-flex gap-2 ms-auto">
235
314
  <button id="pause-resume" class="btn btn-info text-white" data-bs-toggle="tooltip" title="Pause execution">
236
- <i class="bi bi-pause-circle"></i> <!-- Icon for Pause -->
315
+ {% if pause_status %}
316
+ <i class="bi bi-play-circle"></i> <!-- Icon for Pause -->
317
+ {% else %}
318
+ <i class="bi bi-pause-circle"></i> <!
319
+ {% endif %}
237
320
  </button>
238
321
  <button id="abort-current" class="btn btn-danger text-white" data-bs-toggle="tooltip" title="Stop execution after current step">
239
322
  <i class="bi bi-stop-circle"></i> <!-- Icon for Stop After This Step -->
@@ -258,28 +341,28 @@
258
341
  </div>
259
342
  </div>
260
343
  </div>
261
- <div class="accordion-item design-control">
262
- <h2 class="accordion-header">
263
- <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#data" aria-expanded="false" aria-controls="script">
264
- Download experiment data csv
265
- </button>
266
- </h2>
267
- <div id="data" class="accordion-collapse collapse">
268
- <div class="accordion-body">
269
- {% if session["most_recent_result"] %}
270
- <p><a href="{{ url_for('design.download_results', filename=session["most_recent_result"]) }}">Download the latest data <i class="bi bi-download"></i></a></p>
271
- {% endif %}
272
- <p>
273
- <h5>All data files</h5>
274
- {% for datafile in data_list %}
275
- <div>
276
- {{ datafile }} <a href="{{ url_for('design.download_results', filename=datafile) }} "><i class="bi bi-download"></i></a>
277
- </div>
278
- {% endfor %}
279
- </p>
280
- </div>
281
- </div>
282
- </div>
344
+ {# <div class="accordion-item design-control">#}
345
+ {# <h2 class="accordion-header">#}
346
+ {# <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#data" aria-expanded="false" aria-controls="script">#}
347
+ {# Download experiment data csv#}
348
+ {# </button>#}
349
+ {# </h2>#}
350
+ {# <div id="data" class="accordion-collapse collapse">#}
351
+ {# <div class="accordion-body">#}
352
+ {# {% if session["most_recent_result"] %}#}
353
+ {# <p><a href="{{ url_for('design.download_results', filename=session["most_recent_result"]) }}">Download the latest data <i class="bi bi-download"></i></a></p>#}
354
+ {# {% endif %}#}
355
+ {# <p>#}
356
+ {# <h5>All data files</h5>#}
357
+ {# {% for datafile in data_list %}#}
358
+ {# <div>#}
359
+ {# {{ datafile }} <a href="{{ url_for('design.download_results', filename=datafile) }} "><i class="bi bi-download"></i></a>#}
360
+ {# </div>#}
361
+ {# {% endfor %}#}
362
+ {# </p>#}
363
+ {# </div>#}
364
+ {# </div>#}
365
+ {# </div>#}
283
366
  <div class="accordion-item design-control">
284
367
  <h2 class="accordion-header">
285
368
  <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#script" aria-expanded="false" aria-controls="script">
@@ -326,6 +409,28 @@
326
409
  </div>
327
410
  </div>
328
411
  </div>
412
+
413
+ <!-- Error Modal -->
414
+ <div class="modal fade" id="error-modal" tabindex="-1" aria-labelledby="errorModalLabel" aria-hidden="true">
415
+ <div class="modal-dialog">
416
+ <div class="modal-content">
417
+ <div class="modal-header">
418
+ <h5 class="modal-title" id="errorModalLabel">Error Detected</h5>
419
+ <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
420
+ </div>
421
+ <div class="modal-body">
422
+ <p id="error-message">An error has occurred.</p>
423
+ <p>Do you want to continue execution or stop?</p>
424
+ </div>
425
+ <div class="modal-footer">
426
+ <button type="button" class="btn btn-danger" id="stop-btn" data-bs-dismiss="modal">Stop Execution</button>
427
+ <button type="button" class="btn btn-success" id="continue-btn" data-bs-dismiss="modal">Continue</button>
428
+ </div>
429
+ </div>
430
+ </div>
431
+ </div>
432
+
433
+
329
434
  <script src="{{ url_for('static', filename='js/socket_handler.js') }}"></script>
330
435
  <script>
331
436
  var rowCount = 0; // Initialize row count
@@ -347,22 +452,4 @@
347
452
  }
348
453
  });
349
454
  </script>
350
-
351
- <script>
352
- var socket = io.connect(window.location.origin);
353
-
354
- socket.on('execution', function(data) {
355
- // Remove highlighting from all lines
356
- document.querySelectorAll('pre code').forEach(el => el.style.backgroundColor = '');
357
-
358
- // Get the currently executing line and highlight it
359
- let executingLine = document.getElementById(data.section);
360
- if (executingLine) {
361
- executingLine.style.backgroundColor = '#cce5ff'; // Highlight
362
- executingLine.style.transition = 'background-color 0.3s ease-in-out';
363
-
364
- }
365
- });
366
- </script>
367
-
368
455
  {% endblock %}
@@ -1,70 +1,103 @@
1
1
  {% extends 'base.html' %}
2
- {% block title %}IvoryOS | Welcome {% endblock %}
3
-
2
+ {% block title %}IvoryOS | Welcome{% endblock %}
4
3
 
5
4
  {% block body %}
6
- <div class="p-4" >
7
- <h1 style=" font-size: 3rem;font-weight: bold;color: #343a40;margin-bottom: 40px;">
5
+ <div class="p-4">
6
+ <h1 class="mb-4" style="font-size: 3rem; font-weight: bold; color: #343a40;">
8
7
  Welcome
9
8
  </h1>
10
- <p>Version: {{ version }}</p>
9
+ <p class="mb-5">Version: {{ version }}</p>
10
+
11
+ {% if enable_design %}
12
+ <!-- Workflow Design Section -->
13
+ <h4 class="mb-3">Workflow Design</h4>
11
14
  <div class="row">
12
- {% if enable_design %}
13
- <div class="col-lg-6 mb-4 d-flex align-items-stretch">
14
- <div class="card rounded shadow-sm flex-fill">
15
- <div class="card-body">
16
- <h5 class="card-title">Browse designs</h5>
17
- <p class="card-text">Browse all workflows saved in the database.</p>
18
- <a href="{{ url_for('database.load_from_database') }}" class="stretched-link"></a>
19
- </div>
15
+ <div class="col-lg-6 mb-3 d-flex align-items-stretch">
16
+ <div class="card rounded shadow-sm flex-fill">
17
+ <div class="card-body">
18
+ <h5 class="card-title">
19
+ <i class="bi bi-folder2-open me-2"></i>Browse designs
20
+ </h5>
21
+ <p class="card-text">View all saved workflows from the database.</p>
22
+ <a href="{{ url_for('database.load_from_database') }}" class="stretched-link"></a>
20
23
  </div>
21
24
  </div>
22
- <div class="col-lg-6 mb-4 d-flex align-items-stretch">
23
- <div class="card rounded shadow-sm flex-fill">
24
- <div class="card-body">
25
- <h5 class="card-title">Edit designs</h5>
26
- <p class="card-text">Build your workflow from current deck functions.</p>
27
- <a href="{{ url_for('design.experiment_builder') }}" class="stretched-link"></a>
28
- </div>
25
+ </div>
26
+ <div class="col-lg-6 mb-3 d-flex align-items-stretch">
27
+ <div class="card rounded shadow-sm flex-fill">
28
+ <div class="card-body">
29
+ <h5 class="card-title">
30
+ <i class="bi bi-pencil-square me-2"></i>Edit designs
31
+ </h5>
32
+ <p class="card-text">Create or modify workflows using available functions.</p>
33
+ <a href="{{ url_for('design.experiment_builder') }}" class="stretched-link"></a>
29
34
  </div>
30
35
  </div>
31
- {% endif %}
36
+ </div>
32
37
  </div>
38
+ {% endif %}
33
39
 
34
- <br><br><br>
35
- {% if not off_line %}
36
- <div class="row">
37
- {% if enable_design %}
38
- <div class="col-lg-6 mb-4 d-flex align-items-stretch">
39
- <div class="card rounded shadow-sm flex-fill">
40
- <div class="card-body">
41
- <h5 class="card-title">Run experiment</h5>
42
- <p class="card-text">Execute workflows with repeat times or variable configs. </p>
43
- <a href="{{ url_for('design.experiment_run') }}" class="stretched-link"></a>
44
- </div>
40
+ <!-- Workflow Control and Monitor Section -->
41
+ <h4 class="mt-5 mb-3">Workflow Control & Monitoring</h4>
42
+ <div class="row">
43
+ <!-- Always visible: Experiment data -->
44
+ <div class="col-lg-6 mb-3 d-flex align-items-stretch">
45
+ <div class="card rounded shadow-sm flex-fill">
46
+ <div class="card-body">
47
+ <h5 class="card-title">
48
+ <i class="bi bi-graph-up-arrow me-2"></i>Experiment data
49
+ </h5>
50
+ <p class="card-text">Browse workflow logs and output data.</p>
51
+ <a href="{{ url_for('database.list_workflows') }}" class="stretched-link"></a>
45
52
  </div>
46
53
  </div>
47
- {% endif %}
54
+ </div>
48
55
 
49
- <div class="col-lg-6 mb-4 d-flex align-items-stretch">
50
- <div class="card rounded shadow-sm flex-fill">
51
- <div class="card-body">
52
- <h5 class="card-title">Control device</h5>
53
- <p class="card-text">Browse and control instruments of current platform</p>
54
- <a href="{{ url_for('control.deck_controllers') }}" class="stretched-link"></a>
55
- </div>
56
+ <!-- Conditionally visible: Run current workflow -->
57
+ {% if not off_line %}
58
+ <div class="col-lg-6 mb-3 d-flex align-items-stretch">
59
+ <div class="card rounded shadow-sm flex-fill">
60
+ <div class="card-body">
61
+ <h5 class="card-title">
62
+ <i class="bi bi-play-circle me-2"></i>Run current workflow
63
+ </h5>
64
+ <p class="card-text">Execute workflows with configurable parameters.</p>
65
+ <a href="{{ url_for('design.experiment_run') }}" class="stretched-link"></a>
56
66
  </div>
57
67
  </div>
58
- <div class="col-lg-6 mb-4 d-flex align-items-stretch">
59
- <div class="card rounded shadow-sm flex-fill">
60
- <div class="card-body">
61
- <h5 class="card-title">Connect new device</h5>
62
- <p class="card-text">Connect new hardware: for simple/temporary configurations.</p>
63
- <a href="{{ url_for('control.controllers_home') }}" class="stretched-link"></a>
64
- </div>
68
+ </div>
69
+ {% endif %}
70
+ </div>
71
+
72
+
73
+
74
+ {% if not off_line %}
75
+ <!-- Direct Control Section -->
76
+ <h4 class="mt-5 mb-3">Direct Control</h4>
77
+ <div class="row">
78
+ <div class="col-lg-6 mb-3 d-flex align-items-stretch">
79
+ <div class="card rounded shadow-sm flex-fill">
80
+ <div class="card-body">
81
+ <h5 class="card-title">
82
+ <i class="bi bi-toggle-on me-2"></i>Direct control
83
+ </h5>
84
+ <p class="card-text">Manually control individual components.</p>
85
+ <a href="{{ url_for('control.deck_controllers') }}" class="stretched-link"></a>
65
86
  </div>
66
87
  </div>
67
88
  </div>
89
+ <div class="col-lg-6 mb-3 d-flex align-items-stretch">
90
+ <div class="card rounded shadow-sm flex-fill">
91
+ <div class="card-body">
92
+ <h5 class="card-title">
93
+ <i class="bi bi-usb-plug me-2"></i>Connect a new device
94
+ </h5>
95
+ <p class="card-text">Add new hardware temporarily or for testing purposes.</p>
96
+ <a href="{{ url_for('control.controllers_home') }}" class="stretched-link"></a>
97
+ </div>
98
+ </div>
99
+ </div>
100
+ </div>
68
101
  {% endif %}
69
102
  </div>
70
103
  {% endblock %}
@@ -27,6 +27,57 @@ document.addEventListener("DOMContentLoaded", function() {
27
27
  }, 1000); // Small delay to let users see the completion
28
28
  }
29
29
  });
30
+
31
+ socket.on('error', function(errorData) {
32
+ console.error("Error received:", errorData);
33
+ var progressBar = document.getElementById('progress-bar-inner');
34
+
35
+ progressBar.classList.remove('bg-success');
36
+ progressBar.classList.add('bg-danger'); // Red color for error
37
+ // Show error modal
38
+ var errorModal = new bootstrap.Modal(document.getElementById('error-modal'));
39
+ document.getElementById('error-message').innerText = "An error occurred: " + errorData.message;
40
+ errorModal.show();
41
+
42
+ });
43
+
44
+ // Handle Pause/Resume Button
45
+ document.getElementById('pause-resume').addEventListener('click', function() {
46
+ socket.emit('pause');
47
+ console.log('Pause/Resume is toggled.');
48
+ var button = this;
49
+ var icon = button.querySelector("i");
50
+
51
+ // Toggle Pause and Resume
52
+ if (icon.classList.contains("bi-pause-circle")) {
53
+ icon.classList.remove("bi-pause-circle");
54
+ icon.classList.add("bi-play-circle");
55
+ button.innerHTML = '<i class="bi bi-play-circle"></i>';
56
+ button.setAttribute("title", "Resume execution");
57
+ } else {
58
+ icon.classList.remove("bi-play-circle");
59
+ icon.classList.add("bi-pause-circle");
60
+ button.innerHTML = '<i class="bi bi-pause-circle"></i>';
61
+ button.setAttribute("title", "Pause execution");
62
+ }
63
+ });
64
+
65
+ // Handle Modal Buttons
66
+ document.getElementById('continue-btn').addEventListener('click', function() {
67
+ socket.emit('pause'); // Resume execution
68
+ console.log("Execution resumed.");
69
+ });
70
+
71
+ document.getElementById('stop-btn').addEventListener('click', function() {
72
+ socket.emit('pause'); // Resume execution
73
+ socket.emit('abort_current'); // Stop execution
74
+ console.log("Execution stopped.");
75
+
76
+ // Reset UI back to initial state
77
+ document.getElementById("code-panel").style.display = "none";
78
+ document.getElementById("run-panel").style.display = "block";
79
+ });
80
+
30
81
  socket.on('log', function(data) {
31
82
  var logMessage = data.message;
32
83
  console.log(logMessage);
@@ -49,24 +100,16 @@ document.addEventListener("DOMContentLoaded", function() {
49
100
  }
50
101
  });
51
102
 
52
- document.getElementById('pause-resume').addEventListener('click', function() {
103
+ socket.on('execution', function(data) {
104
+ // Remove highlighting from all lines
105
+ document.querySelectorAll('pre code').forEach(el => el.style.backgroundColor = '');
53
106
 
54
- socket.emit('pause');
55
- console.log('Pause/Resume is toggled.');
56
- var button = this;
57
- var icon = button.querySelector("i");
107
+ // Get the currently executing line and highlight it
108
+ let executingLine = document.getElementById(data.section);
109
+ if (executingLine) {
110
+ executingLine.style.backgroundColor = '#cce5ff'; // Highlight
111
+ executingLine.style.transition = 'background-color 0.3s ease-in-out';
58
112
 
59
- // Toggle between Pause and Resume
60
- if (icon.classList.contains("bi-pause-circle")) {
61
- icon.classList.remove("bi-pause-circle");
62
- icon.classList.add("bi-play-circle");
63
- button.innerHTML = '<i class="bi bi-play-circle"></i>';
64
- button.setAttribute("title", "Resume execution");
65
- } else {
66
- icon.classList.remove("bi-play-circle");
67
- icon.classList.add("bi-pause-circle");
68
- button.innerHTML = '<i class="bi bi-pause-circle"></i>';
69
- button.setAttribute("title", "Pause execution");
70
113
  }
71
114
  });
72
115
  });