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

Files changed (37) hide show
  1. ivoryos/__init__.py +118 -99
  2. ivoryos/config.py +47 -47
  3. ivoryos/routes/auth/auth.py +100 -65
  4. ivoryos/routes/auth/templates/auth/login.html +25 -25
  5. ivoryos/routes/auth/templates/auth/signup.html +32 -32
  6. ivoryos/routes/control/control.py +400 -272
  7. ivoryos/routes/control/templates/control/controllers.html +75 -75
  8. ivoryos/routes/control/templates/control/controllers_home.html +50 -50
  9. ivoryos/routes/control/templates/control/controllers_new.html +89 -89
  10. ivoryos/routes/database/database.py +188 -114
  11. ivoryos/routes/database/templates/database/experiment_database.html +72 -72
  12. ivoryos/routes/design/design.py +541 -416
  13. ivoryos/routes/design/templates/design/experiment_builder.html +415 -415
  14. ivoryos/routes/design/templates/design/experiment_run.html +325 -325
  15. ivoryos/routes/main/main.py +42 -25
  16. ivoryos/routes/main/templates/main/help.html +141 -141
  17. ivoryos/routes/main/templates/main/home.html +68 -68
  18. ivoryos/static/.DS_Store +0 -0
  19. ivoryos/static/js/overlay.js +12 -12
  20. ivoryos/static/js/socket_handler.js +34 -34
  21. ivoryos/static/js/sortable_card.js +24 -24
  22. ivoryos/static/js/sortable_design.js +36 -36
  23. ivoryos/static/style.css +201 -201
  24. ivoryos/templates/base.html +143 -143
  25. ivoryos/utils/db_models.py +518 -518
  26. ivoryos/utils/form.py +316 -316
  27. ivoryos/utils/global_config.py +67 -67
  28. ivoryos/utils/llm_agent.py +183 -183
  29. ivoryos/utils/script_runner.py +165 -164
  30. ivoryos/utils/utils.py +425 -422
  31. ivoryos/version.py +1 -0
  32. {ivoryos-0.1.9.dist-info → ivoryos-0.1.10.dist-info}/LICENSE +21 -21
  33. {ivoryos-0.1.9.dist-info → ivoryos-0.1.10.dist-info}/METADATA +170 -169
  34. ivoryos-0.1.10.dist-info/RECORD +47 -0
  35. {ivoryos-0.1.9.dist-info → ivoryos-0.1.10.dist-info}/WHEEL +1 -1
  36. ivoryos-0.1.9.dist-info/RECORD +0 -45
  37. {ivoryos-0.1.9.dist-info → ivoryos-0.1.10.dist-info}/top_level.txt +0 -0
@@ -1,325 +1,325 @@
1
- {% extends 'base.html' %}
2
- {% block title %}IvoryOS | Design execution{% endblock %}
3
-
4
- {% block body %}
5
- <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.1/socket.io.js"></script>
6
-
7
-
8
- {% if no_deck_warning and not dismiss %}
9
- {# auto pop import when there is no deck#}
10
- <script type="text/javascript">
11
- function OpenBootstrapPopup() {
12
- $("#importModal").modal('show');
13
- }
14
- window.onload = function () {
15
- OpenBootstrapPopup();
16
- };
17
- </script>
18
- {% endif %}
19
-
20
- <div class="accordion" id="accordionPanelsStayOpenExample">
21
- <div class="accordion-item design-control">
22
- <h2 class="accordion-header">
23
- <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#runpanel" aria-expanded="true" aria-controls="runpanel">
24
- Run Panel
25
- </button>
26
- </h2>
27
- <div id="runpanel" class="accordion-collapse collapse show">
28
- <div class="accordion-body">
29
- {% if script['script'] or script['prep'] or script['cleanup'] %}
30
- <div class="row">
31
- <div class="col-lg-6 col-sm-12">
32
- <ul class="nav nav-tabs" id="myTabs" role="tablist">
33
- <li class="nav-item" role="presentation">
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>
35
- </li>
36
- <li class="nav-item" role="presentation">
37
- <a class="nav-link {{ 'disabled' if (not config_list or config_list|count > 5) else '' }} {{ 'active' if config_list and config_list|count < 6 else '' }}" id="tab4-tab" data-bs-toggle="tab" href="#tab4" role="tab" aria-controls="tab4" aria-selected="false">Quick config</a>
38
- </li>
39
- <li class="nav-item" role="presentation">
40
- <a class="nav-link {{ 'disabled' if not config_list else '' }} {{ 'active' if config_list|count > 5 else '' }}" id="tab2-tab" data-bs-toggle="tab" href="#tab2" role="tab" aria-controls="tab2" aria-selected="false">Excel config</a>
41
- </li>
42
-
43
- <li class="nav-item" role="presentation">
44
- <a class="nav-link {{ 'disabled' if not config_list or not return_list else '' }}" id="tab3-tab" data-bs-toggle="tab" href="#tab3" role="tab" aria-controls="tab3" aria-selected="false">Bayesian Optimization</a>
45
- </li>
46
- </ul>
47
- <div class="tab-content" id="myTabsContent">
48
- <div class="tab-pane fade {{ 'show active' if not config_list else '' }}" id="tab1" role="tabpanel" aria-labelledby="tab1-tab">
49
- <p><h5>Control panel:</h5></p>
50
- <form role="form" method='POST' name="run" action="{{url_for('design.experiment_run')}}">
51
- <div class="input-group mb-3">
52
- <label class="input-group-text" for="repeat">Repeat for </label>
53
- <input class="form-control" type="number" id="repeat" name="repeat" min="1" max="100">
54
- <label class="input-group-text" for="repeat"> times</label>
55
- </div>
56
- {# {% if not no_deck_warning%}#}
57
- <div class="input-group mb-3">
58
- <button class="form-control" type="submit" class="btn btn-dark">Run</button>
59
- </div>
60
- {# {% endif %}#}
61
- </form>
62
- </div>
63
- <div class="tab-pane fade {{ 'show active' if config_list|count>5 else '' }}" id="tab2" role="tabpanel" aria-labelledby="tab2-tab">
64
- <div>
65
-
66
- </div>
67
- <p><h5>Control with csv config:</h5></p>
68
- <p>Current configure: {{ filename }}</p>
69
- <div>
70
-
71
- <form name="filenameForm" id="filenameForm" method="GET" action="{{ url_for('design.experiment_run') }}" enctype="multipart/form-data">
72
- <div class="input-group mb-3">
73
- <select class="form-select" name="filename" id="filenameSelect" required onchange="document.getElementById('filenameForm').submit();">
74
- <option selected disabled hidden style="overflow-wrap: break-word;" value=""> -- choose config file --</option>
75
- {% for config_file in config_file_list %}
76
- <option {{'selected' if filename == config_file else '' }} style="overflow-wrap: break-word;" value="{{config_file}}">{{config_file}}</option>
77
- {% endfor %}
78
- </select>
79
- </div>
80
- </form>
81
-
82
- {# <li><a class="dropdown-item" data-bs-toggle="collapse" href="#preview" role="button" aria-expanded="false">Preview config</a></li>#}
83
- <a class="btn btn-primary" href="{{ url_for('design.download', filetype='configure') }}" >empty config</a>
84
- <a class="btn btn-primary" data-bs-toggle="collapse" href="#loadfile" role="button" aria-expanded="false">Upload .csv</a>
85
-
86
-
87
- <div class="collapse" id="loadfile" name="loadfile">
88
- <form method="POST" id="loadFile" name="loadFile" action="{{ url_for('design.upload') }}" enctype="multipart/form-data">
89
- <div class="input-group">
90
- <input class="form-control" name="file" type="file" required="required" onchange="document.getElementById('loadFile').submit();">
91
- <input class="btn btn-secondary" type="submit" value="Upload .csv">
92
- </div>
93
- </form>
94
- </div>
95
- </div>
96
-
97
- {#Preview config file#}
98
- <div id="preview">
99
- {% if config_preview %}
100
- <table class="table table-hover">
101
- <thead>
102
- <tr>
103
- {% for line in config_preview[0].keys() %}
104
- <th scope="col">{{ line }}</th>
105
- {% endfor %}
106
- </tr>
107
- </thead>
108
- <tbody>
109
- {% for line in config_preview %}
110
- <tr>
111
- {% for i in line.values() %}
112
- <td>{{ i }}</td>
113
- {% endfor %}
114
- </tr>
115
- {% endfor %}
116
- </tbody>
117
- </table>
118
- {% else %}
119
- Empty config file
120
- {% endif %}
121
- </div>
122
- {% if filename and not no_deck_warning %}
123
- <form role="form" method='POST' name="run" action="{{ url_for('design.experiment_run')}}">
124
- <div class="form-group">
125
- <button type="submit" class="btn btn-success">Run</button>
126
- </div>
127
- </form>
128
- {% endif %}
129
- </div>
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>
140
- {# <div class="col-auto">#}
141
- {# <label class="col-form-label" for="{{config}}_type">Type</label>#}
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>
156
- {# <div class="col-auto">#}
157
- {# <input type="text" class="form-control" id="{{config}}_value_max" style="display: none;" placeholder="1, 2, 3">#}
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>
167
- {# <div class="col-auto">#}
168
- {# <label class="" for="{{objective}}_min">Minimize</label>#}
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>
177
- {# <div class="col-auto">#}
178
- {# <label class="" for="{{objective}}_threshold">Threshold</label>#}
179
- {# </div>#}
180
- {# <div class="col-auto">#}
181
- {# <input type="text" class="form-control" id="{{objective}}_threshold" name="{{objective}}_threshold" placeholder="None">#}
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="100">
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 {{ '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>
200
- <div>
201
- <form method="POST" name="online-config" id="online-config" action="{{url_for('design.experiment_run')}}">
202
- <table id="dataInputTable" class="table table-striped">
203
- <thead class="thead-dark">
204
- <tr>
205
- {% for column in config_list %}
206
- <th>{{ column }}</th>
207
- {% endfor %}
208
- </tr>
209
- </thead>
210
- <tbody>
211
- </tbody>
212
- </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>
215
- </form>
216
- </div>
217
- </div>
218
- </div>
219
- </div>
220
- <div class="col-lg-6 col-sm-12 logging-panel">
221
- <p>
222
- <div class="p d-flex justify-content-between align-items-center">
223
- <h5>Progress:</h5>
224
- <button id="abort" class="btn btn-danger ">Abort Pending Actions</button>
225
- </div>
226
- </p>
227
- <div class="progress" role="progressbar" aria-label="Animated striped example" aria-valuenow="10" aria-valuemin="0" aria-valuemax="100">
228
- <div id="progress-bar-inner" class="progress-bar progress-bar-striped progress-bar-animated"></div>
229
- </div>
230
- <p><h5>Log:</h5></p>
231
- <div id="logging-panel"></div>
232
- </div>
233
- </div>
234
- {% endif %}
235
- </div>
236
- </div>
237
- </div>
238
- <div class="accordion-item design-control">
239
- <h2 class="accordion-header">
240
- <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#data" aria-expanded="false" aria-controls="script">
241
- Download experiment data csv
242
- </button>
243
- </h2>
244
- <div id="data" class="accordion-collapse collapse">
245
- <div class="accordion-body">
246
- {% if session["most_recent_result"] %}
247
- <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>
248
- {% endif %}
249
- <p>
250
- <h5>All data files</h5>
251
- {% for datafile in data_list %}
252
- <div>
253
- {{ datafile }} <a href="{{ url_for('design.download_results', filename=datafile) }} "><i class="bi bi-download"></i></a>
254
- </div>
255
- {% endfor %}
256
- </p>
257
- </div>
258
- </div>
259
- </div>
260
- <div class="accordion-item design-control">
261
- <h2 class="accordion-header">
262
- <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#script" aria-expanded="false" aria-controls="script">
263
- Script
264
- </button>
265
- </h2>
266
- <div id="script" class="accordion-collapse collapse">
267
- <div class="accordion-body">
268
- {% set labels = {
269
- 'prep': 'Preparation:',
270
- 'script': 'Experiment:',
271
- 'cleanup': 'Clean up:'
272
- } %}
273
- {% for key, buttons in design_buttons.items() %}
274
- {% if buttons %}
275
- <h6>
276
- {{labels[key]}}
277
- </h6>
278
- <ul>
279
- {% for button in buttons %}
280
- <li id="{{ button['id'] }}" style="list-style-type: none;">
281
- <button type="button" class="btn btn-light" style="{{ button['style'] }}">{{ button['label'] }}</button>
282
- </li>
283
- {% endfor %}
284
- </ul>
285
- {% endif %}
286
- {% endfor %}
287
- </div>
288
- </div>
289
- </div>
290
- <div class="accordion-item design-control">
291
- <h2 class="accordion-header">
292
- <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#python" aria-expanded="false" aria-controls="python">
293
- Python Script
294
- </button>
295
- </h2>
296
- <div id="python" class="accordion-collapse collapse">
297
- <div class="accordion-body">
298
- <pre><code class="python" >{{dot_py}}</code></pre>
299
- <a href="{{ url_for('design.download', filetype='python') }}">Download <i class="bi bi-download"></i></a>
300
- </div>
301
- </div>
302
- </div>
303
- </div>
304
- <script src="{{ url_for('static', filename='js/socket_handler.js') }}"></script>
305
- <script>
306
- var rowCount = 0; // Initialize row count
307
- function addRow() {
308
- rowCount++; // Increment row count each time a row is added
309
- var table = document.getElementById("dataInputTable");
310
- var newRow = table.insertRow(-1); // Adds a row at the end of the table
311
- {% for column, type in config_type_list.items() %}
312
- var cell = newRow.insertCell(-1);
313
- cell.innerHTML = '<input type="text" class="form-control" name="{{ column }}[' + rowCount + ']" placeholder={{ type }}>';
314
- {% endfor %}
315
- }
316
- </script>
317
- <script>
318
- // Initially add 5 rows when the page loads
319
- document.addEventListener("DOMContentLoaded", function() {
320
- for (let i = 0; i < 5; i++) {
321
- addRow();
322
- }
323
- });
324
- </script>
325
- {% endblock %}
1
+ {% extends 'base.html' %}
2
+ {% block title %}IvoryOS | Design execution{% endblock %}
3
+
4
+ {% block body %}
5
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.1/socket.io.js"></script>
6
+
7
+
8
+ {% if no_deck_warning and not dismiss %}
9
+ {# auto pop import when there is no deck#}
10
+ <script type="text/javascript">
11
+ function OpenBootstrapPopup() {
12
+ $("#importModal").modal('show');
13
+ }
14
+ window.onload = function () {
15
+ OpenBootstrapPopup();
16
+ };
17
+ </script>
18
+ {% endif %}
19
+
20
+ <div class="accordion" id="accordionPanelsStayOpenExample">
21
+ <div class="accordion-item design-control">
22
+ <h2 class="accordion-header">
23
+ <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#runpanel" aria-expanded="true" aria-controls="runpanel">
24
+ Run Panel
25
+ </button>
26
+ </h2>
27
+ <div id="runpanel" class="accordion-collapse collapse show">
28
+ <div class="accordion-body">
29
+ {% if script['script'] or script['prep'] or script['cleanup'] %}
30
+ <div class="row">
31
+ <div class="col-lg-6 col-sm-12">
32
+ <ul class="nav nav-tabs" id="myTabs" role="tablist">
33
+ <li class="nav-item" role="presentation">
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>
35
+ </li>
36
+ <li class="nav-item" role="presentation">
37
+ <a class="nav-link {{ 'disabled' if (not config_list or config_list|count > 5) else '' }} {{ 'active' if config_list and config_list|count < 6 else '' }}" id="tab4-tab" data-bs-toggle="tab" href="#tab4" role="tab" aria-controls="tab4" aria-selected="false">Quick config</a>
38
+ </li>
39
+ <li class="nav-item" role="presentation">
40
+ <a class="nav-link {{ 'disabled' if not config_list else '' }} {{ 'active' if config_list|count > 5 else '' }}" id="tab2-tab" data-bs-toggle="tab" href="#tab2" role="tab" aria-controls="tab2" aria-selected="false">Excel config</a>
41
+ </li>
42
+
43
+ <li class="nav-item" role="presentation">
44
+ <a class="nav-link {{ 'disabled' if not config_list or not return_list else '' }}" id="tab3-tab" data-bs-toggle="tab" href="#tab3" role="tab" aria-controls="tab3" aria-selected="false">Bayesian Optimization</a>
45
+ </li>
46
+ </ul>
47
+ <div class="tab-content" id="myTabsContent">
48
+ <div class="tab-pane fade {{ 'show active' if not config_list else '' }}" id="tab1" role="tabpanel" aria-labelledby="tab1-tab">
49
+ <p><h5>Control panel:</h5></p>
50
+ <form role="form" method='POST' name="run" action="{{url_for('design.experiment_run')}}">
51
+ <div class="input-group mb-3">
52
+ <label class="input-group-text" for="repeat">Repeat for </label>
53
+ <input class="form-control" type="number" id="repeat" name="repeat" min="1" max="100">
54
+ <label class="input-group-text" for="repeat"> times</label>
55
+ </div>
56
+ {# {% if not no_deck_warning%}#}
57
+ <div class="input-group mb-3">
58
+ <button class="form-control" type="submit" class="btn btn-dark">Run</button>
59
+ </div>
60
+ {# {% endif %}#}
61
+ </form>
62
+ </div>
63
+ <div class="tab-pane fade {{ 'show active' if config_list|count>5 else '' }}" id="tab2" role="tabpanel" aria-labelledby="tab2-tab">
64
+ <div>
65
+
66
+ </div>
67
+ <p><h5>Control with csv config:</h5></p>
68
+ <p>Current configure: {{ filename }}</p>
69
+ <div>
70
+
71
+ <form name="filenameForm" id="filenameForm" method="GET" action="{{ url_for('design.experiment_run') }}" enctype="multipart/form-data">
72
+ <div class="input-group mb-3">
73
+ <select class="form-select" name="filename" id="filenameSelect" required onchange="document.getElementById('filenameForm').submit();">
74
+ <option selected disabled hidden style="overflow-wrap: break-word;" value=""> -- choose config file --</option>
75
+ {% for config_file in config_file_list %}
76
+ <option {{'selected' if filename == config_file else '' }} style="overflow-wrap: break-word;" value="{{config_file}}">{{config_file}}</option>
77
+ {% endfor %}
78
+ </select>
79
+ </div>
80
+ </form>
81
+
82
+ {# <li><a class="dropdown-item" data-bs-toggle="collapse" href="#preview" role="button" aria-expanded="false">Preview config</a></li>#}
83
+ <a class="btn btn-primary" href="{{ url_for('design.download', filetype='configure') }}" >empty config</a>
84
+ <a class="btn btn-primary" data-bs-toggle="collapse" href="#loadfile" role="button" aria-expanded="false">Upload .csv</a>
85
+
86
+
87
+ <div class="collapse" id="loadfile" name="loadfile">
88
+ <form method="POST" id="loadFile" name="loadFile" action="{{ url_for('design.upload') }}" enctype="multipart/form-data">
89
+ <div class="input-group">
90
+ <input class="form-control" name="file" type="file" required="required" onchange="document.getElementById('loadFile').submit();">
91
+ <input class="btn btn-secondary" type="submit" value="Upload .csv">
92
+ </div>
93
+ </form>
94
+ </div>
95
+ </div>
96
+
97
+ {#Preview config file#}
98
+ <div id="preview">
99
+ {% if config_preview %}
100
+ <table class="table table-hover">
101
+ <thead>
102
+ <tr>
103
+ {% for line in config_preview[0].keys() %}
104
+ <th scope="col">{{ line }}</th>
105
+ {% endfor %}
106
+ </tr>
107
+ </thead>
108
+ <tbody>
109
+ {% for line in config_preview %}
110
+ <tr>
111
+ {% for i in line.values() %}
112
+ <td>{{ i }}</td>
113
+ {% endfor %}
114
+ </tr>
115
+ {% endfor %}
116
+ </tbody>
117
+ </table>
118
+ {% else %}
119
+ Empty config file
120
+ {% endif %}
121
+ </div>
122
+ {% if filename and not no_deck_warning %}
123
+ <form role="form" method='POST' name="run" action="{{ url_for('design.experiment_run')}}">
124
+ <div class="form-group">
125
+ <button type="submit" class="btn btn-success">Run</button>
126
+ </div>
127
+ </form>
128
+ {% endif %}
129
+ </div>
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>
140
+ {# <div class="col-auto">#}
141
+ {# <label class="col-form-label" for="{{config}}_type">Type</label>#}
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>
156
+ {# <div class="col-auto">#}
157
+ {# <input type="text" class="form-control" id="{{config}}_value_max" style="display: none;" placeholder="1, 2, 3">#}
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>
167
+ {# <div class="col-auto">#}
168
+ {# <label class="" for="{{objective}}_min">Minimize</label>#}
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>
177
+ {# <div class="col-auto">#}
178
+ {# <label class="" for="{{objective}}_threshold">Threshold</label>#}
179
+ {# </div>#}
180
+ {# <div class="col-auto">#}
181
+ {# <input type="text" class="form-control" id="{{objective}}_threshold" name="{{objective}}_threshold" placeholder="None">#}
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="100">
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 {{ '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>
200
+ <div>
201
+ <form method="POST" name="online-config" id="online-config" action="{{url_for('design.experiment_run')}}">
202
+ <table id="dataInputTable" class="table table-striped">
203
+ <thead class="thead-dark">
204
+ <tr>
205
+ {% for column in config_list %}
206
+ <th>{{ column }}</th>
207
+ {% endfor %}
208
+ </tr>
209
+ </thead>
210
+ <tbody>
211
+ </tbody>
212
+ </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>
215
+ </form>
216
+ </div>
217
+ </div>
218
+ </div>
219
+ </div>
220
+ <div class="col-lg-6 col-sm-12 logging-panel">
221
+ <p>
222
+ <div class="p d-flex justify-content-between align-items-center">
223
+ <h5>Progress:</h5>
224
+ <button id="abort" class="btn btn-danger ">Abort Pending Actions</button>
225
+ </div>
226
+ </p>
227
+ <div class="progress" role="progressbar" aria-label="Animated striped example" aria-valuenow="10" aria-valuemin="0" aria-valuemax="100">
228
+ <div id="progress-bar-inner" class="progress-bar progress-bar-striped progress-bar-animated"></div>
229
+ </div>
230
+ <p><h5>Log:</h5></p>
231
+ <div id="logging-panel"></div>
232
+ </div>
233
+ </div>
234
+ {% endif %}
235
+ </div>
236
+ </div>
237
+ </div>
238
+ <div class="accordion-item design-control">
239
+ <h2 class="accordion-header">
240
+ <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#data" aria-expanded="false" aria-controls="script">
241
+ Download experiment data csv
242
+ </button>
243
+ </h2>
244
+ <div id="data" class="accordion-collapse collapse">
245
+ <div class="accordion-body">
246
+ {% if session["most_recent_result"] %}
247
+ <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>
248
+ {% endif %}
249
+ <p>
250
+ <h5>All data files</h5>
251
+ {% for datafile in data_list %}
252
+ <div>
253
+ {{ datafile }} <a href="{{ url_for('design.download_results', filename=datafile) }} "><i class="bi bi-download"></i></a>
254
+ </div>
255
+ {% endfor %}
256
+ </p>
257
+ </div>
258
+ </div>
259
+ </div>
260
+ <div class="accordion-item design-control">
261
+ <h2 class="accordion-header">
262
+ <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#script" aria-expanded="false" aria-controls="script">
263
+ Script
264
+ </button>
265
+ </h2>
266
+ <div id="script" class="accordion-collapse collapse">
267
+ <div class="accordion-body">
268
+ {% set labels = {
269
+ 'prep': 'Preparation:',
270
+ 'script': 'Experiment:',
271
+ 'cleanup': 'Clean up:'
272
+ } %}
273
+ {% for key, buttons in design_buttons.items() %}
274
+ {% if buttons %}
275
+ <h6>
276
+ {{labels[key]}}
277
+ </h6>
278
+ <ul>
279
+ {% for button in buttons %}
280
+ <li id="{{ button['id'] }}" style="list-style-type: none;">
281
+ <button type="button" class="btn btn-light" style="{{ button['style'] }}">{{ button['label'] }}</button>
282
+ </li>
283
+ {% endfor %}
284
+ </ul>
285
+ {% endif %}
286
+ {% endfor %}
287
+ </div>
288
+ </div>
289
+ </div>
290
+ <div class="accordion-item design-control">
291
+ <h2 class="accordion-header">
292
+ <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#python" aria-expanded="false" aria-controls="python">
293
+ Python Script
294
+ </button>
295
+ </h2>
296
+ <div id="python" class="accordion-collapse collapse">
297
+ <div class="accordion-body">
298
+ <pre><code class="python" >{{dot_py}}</code></pre>
299
+ <a href="{{ url_for('design.download', filetype='python') }}">Download <i class="bi bi-download"></i></a>
300
+ </div>
301
+ </div>
302
+ </div>
303
+ </div>
304
+ <script src="{{ url_for('static', filename='js/socket_handler.js') }}"></script>
305
+ <script>
306
+ var rowCount = 0; // Initialize row count
307
+ function addRow() {
308
+ rowCount++; // Increment row count each time a row is added
309
+ var table = document.getElementById("dataInputTable");
310
+ var newRow = table.insertRow(-1); // Adds a row at the end of the table
311
+ {% for column, type in config_type_list.items() %}
312
+ var cell = newRow.insertCell(-1);
313
+ cell.innerHTML = '<input type="text" class="form-control" name="{{ column }}[' + rowCount + ']" placeholder={{ type }}>';
314
+ {% endfor %}
315
+ }
316
+ </script>
317
+ <script>
318
+ // Initially add 5 rows when the page loads
319
+ document.addEventListener("DOMContentLoaded", function() {
320
+ for (let i = 0; i < 5; i++) {
321
+ addRow();
322
+ }
323
+ });
324
+ </script>
325
+ {% endblock %}