scilens 0.1.0__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 (95) hide show
  1. scilens/LICENSE +37 -0
  2. scilens/__init__.py +1 -0
  3. scilens/app.py +9 -0
  4. scilens/cli/__init__.py +0 -0
  5. scilens/cli/cglb.py +10 -0
  6. scilens/cli/config.py +15 -0
  7. scilens/cli/info.py +12 -0
  8. scilens/cli/main.py +74 -0
  9. scilens/components/analyse_folder.py +4 -0
  10. scilens/components/compare_2_files.py +22 -0
  11. scilens/components/compare_errors.py +22 -0
  12. scilens/components/compare_floats.py +39 -0
  13. scilens/components/compare_folders.py +39 -0
  14. scilens/components/executor.py +58 -0
  15. scilens/components/file_reader.py +29 -0
  16. scilens/config/__init__.py +0 -0
  17. scilens/config/cli_run_options.py +8 -0
  18. scilens/config/env_var.py +3 -0
  19. scilens/config/load.py +40 -0
  20. scilens/config/models/__init__.py +12 -0
  21. scilens/config/models/app.py +9 -0
  22. scilens/config/models/compare.py +5 -0
  23. scilens/config/models/compare_float_thresholds.py +4 -0
  24. scilens/config/models/execute.py +4 -0
  25. scilens/config/models/execute_and_compare.py +4 -0
  26. scilens/config/models/file_reader.py +3 -0
  27. scilens/config/models/reader_format_csv.py +18 -0
  28. scilens/config/models/reader_format_txt.py +5 -0
  29. scilens/config/models/readers.py +4 -0
  30. scilens/config/models/report.py +6 -0
  31. scilens/config/models/report_html.py +6 -0
  32. scilens/config/models/report_output.py +4 -0
  33. scilens/helpers/assets.py +27 -0
  34. scilens/helpers/search_and_index.py +26 -0
  35. scilens/helpers/templates/index.html +20 -0
  36. scilens/helpers/templates/style.css +124 -0
  37. scilens/processors/__init__.py +3 -0
  38. scilens/processors/analyse.py +14 -0
  39. scilens/processors/compare.py +7 -0
  40. scilens/processors/execute_and_compare.py +17 -0
  41. scilens/processors/models/__init__.py +0 -0
  42. scilens/processors/models/results.py +2 -0
  43. scilens/processors/processor_interface.py +9 -0
  44. scilens/readers/__init__.py +0 -0
  45. scilens/readers/exceptions.py +1 -0
  46. scilens/readers/reader_com_txt_lines.py +2 -0
  47. scilens/readers/reader_csv.py +73 -0
  48. scilens/readers/reader_interface.py +15 -0
  49. scilens/readers/reader_manager.py +30 -0
  50. scilens/readers/reader_txt.py +82 -0
  51. scilens/readers/transform.py +8 -0
  52. scilens/report/__init__.py +0 -0
  53. scilens/report/assets/logo.svg +9 -0
  54. scilens/report/assets/logo_cglb.svg +1 -0
  55. scilens/report/assets.py +11 -0
  56. scilens/report/html_report.py +26 -0
  57. scilens/report/report.py +30 -0
  58. scilens/report/template.py +8 -0
  59. scilens/report/templates/body_01_title.html +61 -0
  60. scilens/report/templates/body_99_footer.html +11 -0
  61. scilens/report/templates/compare_11_summary.html +75 -0
  62. scilens/report/templates/compare_12_sections.html +150 -0
  63. scilens/report/templates/compare_13_section_numbers copy.html +48 -0
  64. scilens/report/templates/compare_13_section_numbers.html +91 -0
  65. scilens/report/templates/index.html +92 -0
  66. scilens/report/templates/js_chartlibs_echarts.js +34 -0
  67. scilens/report/templates/js_chartlibs_plotly.js +55 -0
  68. scilens/report/templates/js_com_dom.js +21 -0
  69. scilens/report/templates/js_com_page.js +199 -0
  70. scilens/report/templates/js_com_palette.js +7 -0
  71. scilens/report/templates/js_curvemgr.js +319 -0
  72. scilens/report/templates/style.css +144 -0
  73. scilens/report/templates/utils_compare_report_anim.js +73 -0
  74. scilens/report/templates/utils_compare_report_framesseries.js +143 -0
  75. scilens/report/vendors/tailwindcss_3_4_15.js +83 -0
  76. scilens/report/vendors/tailwindcss_min_4.0.0-beta.4.js +26 -0
  77. scilens/run/__init__.py +0 -0
  78. scilens/run/models/task_results.py +5 -0
  79. scilens/run/models/task_runtime.py +2 -0
  80. scilens/run/run_task.py +41 -0
  81. scilens/run/standalone_task_runner.py +9 -0
  82. scilens/run/task_context.py +12 -0
  83. scilens/run/tasks_collector.py +52 -0
  84. scilens/utils/dict.py +6 -0
  85. scilens/utils/file.py +43 -0
  86. scilens/utils/php.py +15 -0
  87. scilens/utils/system.py +2 -0
  88. scilens/utils/template.py +5 -0
  89. scilens/utils/time_tracker.py +6 -0
  90. scilens/utils/vectors.py +4 -0
  91. scilens/utils/web.py +20 -0
  92. scilens-0.1.0.dist-info/METADATA +44 -0
  93. scilens-0.1.0.dist-info/RECORD +95 -0
  94. scilens-0.1.0.dist-info/WHEEL +4 -0
  95. scilens-0.1.0.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,199 @@
1
+ ((w_1, undef) => {
2
+
3
+ // ***************************************************************************
4
+ // ***************************************************************************
5
+ // parameters
6
+ // ***************************************************************************
7
+ // ***************************************************************************
8
+
9
+ const parameters=[
10
+ {
11
+ id: 'page_mode',
12
+ label: 'Display Mode',
13
+ is_user: {{ 'true' if meta.config.parameter_page_mode.is_user_preference else 'false' }},
14
+ values: ['onepage', 'tabs'],
15
+ action: "actions.render_page()",
16
+ default: '{{ meta.config.parameter_page_mode.default_value}}',
17
+ },{
18
+ id: 'open_file_in',
19
+ label: 'Open File in',
20
+ is_user: {{ 'true' if meta.config.parameter_open_file_in.is_user_preference else 'false' }},
21
+ values: ['browser', 'vscode'],
22
+ default: '{{ meta.config.parameter_open_file_in.default_value}}',
23
+ },{
24
+ id: 'js_lib',
25
+ label: 'Chart Lib',
26
+ is_user: false,
27
+ values: ['plotly', 'echarts'],
28
+ default: 'plotly',
29
+ // action: load_curves(),
30
+ },
31
+ ];
32
+
33
+ function build_parameters() {
34
+ const div = dom.get("parameters");
35
+
36
+ const out = dom.tree_o(
37
+ null,
38
+ {out:"root", tag:"form", attrs: {name:"parameters"}, children: parameters.map((p) => {
39
+ return (p.is_user) ? {tag:"fieldset", style:"display: inline-block;", children: [
40
+ {tag:"legend", html: p.label},
41
+ {tag:"div", children: p.values.map((value) => {
42
+ return {tag:"div", children: [
43
+ {tag:"input", attrs: {type:"radio", name: p.id, id: p.id+"_"+value, value: value, onclick: p.action}},
44
+ {tag:"label", attrs: {for: p.id+"_"+value}, html:value},
45
+ ]}
46
+ })}
47
+ ]} : null
48
+ })}
49
+ );
50
+
51
+ dom.get("section_parameters_form").appendChild(out.root);
52
+ // default values
53
+ parameters.forEach((p) => { if (p.is_user) { dom.get(p.id+"_"+p.default).checked=true; }});
54
+ };
55
+
56
+ function get_parameter(id) {
57
+ for (const p of parameters) {
58
+ if (p.id == id) { return (p.is_user) ? dom.getRadio("parameters", id) : p.default; }
59
+ }
60
+ };
61
+
62
+ // ***************************************************************************
63
+ // ***************************************************************************
64
+ // action
65
+ // ***************************************************************************
66
+ // ***************************************************************************
67
+ function openNewTab(text) {
68
+ const blob = new Blob([text], {type: 'text/plain'});
69
+ const url = URL.createObjectURL(blob);
70
+ window.open(url, '_blank');
71
+ }
72
+ function open_file(route) {
73
+ const arr = window.location.pathname.split('/');
74
+ arr.pop();
75
+ const root = arr.join('/');
76
+ const url = root + '/' + route;
77
+ const open_file_in = get_parameter("open_file_in");
78
+ switch (open_file_in) {
79
+ case "browser": window.open(url, '_blank'); break;
80
+ case "vscode": window.open('vscode://file' + url, '_blank'); break;
81
+ }
82
+ };
83
+
84
+ // const BUTTON_CLASSES = "bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded";
85
+ const BUTTON_CLASSES = "text-xs rounded-lg";
86
+
87
+ const action = {
88
+ init: function() {
89
+ const elts = document.body.getElementsByTagName("action");
90
+ for (const eAction of elts) {
91
+ dom.tree(
92
+ eAction,
93
+ {
94
+ out:"child",
95
+ tag:"button",
96
+ attrs: {type:"button", class:BUTTON_CLASSES},
97
+ html: eAction.dataset.label,
98
+ click: function() { action.action(eAction); },
99
+ },
100
+ eAction
101
+ );
102
+ if (eAction.dataset.command=="toogle") this.toogleUpdate(eAction);
103
+ }
104
+ },
105
+ action: function(eAction) {
106
+ const command = eAction.dataset.command;
107
+ const args = eAction.dataset.args;
108
+ if (command === "toogle") {
109
+ const inf = this.toogleGetInfo(eAction);
110
+ dom.toogle(inf.eTarget);
111
+ this.toogleUpdate(eAction);
112
+ } else if (command === "open_file") {
113
+ open_file(args);
114
+ }
115
+ },
116
+ toogleGetInfo: function(eAction) {
117
+ const x = dom.get(eAction.dataset.args);
118
+ return { eTarget: x, isHidden: (x.style.display === "none")};
119
+ },
120
+ toogleUpdate: function(eAction) {
121
+ const inf = this.toogleGetInfo(eAction);
122
+ eAction.child.innerHTML = inf.isHidden ? "Show" : "Hide";
123
+ },
124
+ };
125
+ // ***************************************************************************
126
+
127
+ const NB_FILES = {{ data.files|length }};
128
+ const NB_SECTIONS = NB_FILES+1;
129
+
130
+ w_1.actions = {
131
+ toogle: function(id) {
132
+ const x = dom.get(id);
133
+ x.style.display = (x.style.display === "none") ? "" : "none";
134
+ },
135
+ open_file: function(route) {
136
+ const arr = window.location.pathname.split('/');
137
+ arr.pop();arr.pop();
138
+ const root = arr.join('/');
139
+ const url = root + '/' + route;
140
+ const open_file_in = get_parameter("open_file_in");
141
+ switch (open_file_in) {
142
+ case "browser": window.open(url, '_blank'); break;
143
+ case "vscode": window.open('vscode://file' + url, '_blank'); break;
144
+ }
145
+ },
146
+ see_details: function(index) {
147
+ const page_mode = get_parameter("page_mode");
148
+ switch (page_mode) {
149
+ case "onepage":
150
+ location.hash = "#section_" + index;
151
+ break;
152
+ case "tabs":
153
+ // tabs active
154
+ var children = dom.get("tabs").children;
155
+ for (i = 0; i < children.length; i++) { children[i].className = children[i].className.replace(" active", "") }
156
+ children[parseInt(index)].className += " active";
157
+ // display section
158
+ for (i = 0; i < NB_SECTIONS; i++) {
159
+ const section = dom.get("section_"+i);
160
+ if (section) section.style.display = "none";
161
+ }
162
+ dom.get("section_"+index).style.display = "";
163
+ break;
164
+ }
165
+ },
166
+ click_tab: function(event, index) {
167
+ this.see_details(index)
168
+ },
169
+ get_parameter: function(id) {
170
+ return get_parameter(id);
171
+ },
172
+ render_page: function() {
173
+ // by default all sections are hidden
174
+ const page_mode = get_parameter("page_mode");
175
+ // tabs
176
+ dom.get("tabs").style.display = page_mode == "tabs" ? "" : "none";
177
+ // sections
178
+ switch (page_mode) {
179
+ case "onepage":
180
+ for (i = 0; i < NB_SECTIONS; i++) {
181
+ const sec = dom.get("section_"+i);
182
+ if (sec) sec.style.display = "";
183
+ }
184
+ window.scrollTo(0,0);
185
+ break;
186
+ case "tabs":
187
+ this.see_details(0);
188
+ window.scrollTo(0,0);
189
+ break;
190
+ }
191
+ },
192
+ init_page: function() {
193
+ console.log(parameters)
194
+ build_parameters();
195
+ action.init();
196
+ this.render_page();
197
+ },
198
+ }
199
+ })(window);
@@ -0,0 +1,7 @@
1
+ ((w_1, undef) => {
2
+ const a = ['#845ec2','#d65db1','#ff6f91','#ff9671','#ffc75f','#f9f871'];
3
+ w_1.palette = {
4
+ get: function(n) { return a[n % a.length]; },
5
+ get1: function(n) { return this.get(n-1); },
6
+ };
7
+ })(window);
@@ -0,0 +1,319 @@
1
+ // dependances: utils_dom.js, chartlibs.js
2
+ //
3
+ // global_curves = {
4
+ // test: [
5
+ // {
6
+ // curves: [
7
+ // {
8
+ // title: "Curve 1",
9
+ // short_title: "C1",
10
+ // series: [[1,2],[2,3],[3,4],[4,5],[5,6]],
11
+ // },
12
+ // {
13
+ // title: "Curve 2",
14
+ // short_title: "C2",
15
+ // series: [[1,3],[2,4],[3,5],[4,6],[5,7]],
16
+ // },
17
+ // ],
18
+ // charts: [
19
+ // {
20
+ // title: "Chart 1",
21
+ // xaxis: "X",
22
+ // yaxis: "Y",
23
+ // curves: [0,1],
24
+ // },
25
+ // {
26
+ // title: "Chart 2",
27
+ // xaxis: "X",
28
+ // yaxis: "Y",
29
+ // curves: [0],
30
+ // },
31
+ // ],
32
+ // },
33
+ // ],
34
+ // reference: [
35
+ // {
36
+ // curves: [
37
+ // ...
38
+ //
39
+ //
40
+
41
+ ((w_1, undef) => {
42
+
43
+ //
44
+ const ERROR_LABEL = "*"
45
+ // button gen
46
+
47
+ const BUTTON_CLASSES = "text-xs rounded-lg mx-1 my-1";
48
+ const BUTTON_CLASSES_ACTIVE = "text-xs rounded-lg mx-1 my-1 bg-slate-500 text-white";
49
+
50
+ const BUTTON_CLASSES_ERR = "text-xs rounded-lg mx-1 my-1 bg-red-400";
51
+ const BUTTON_CLASSES_ERR_ACTIVE = "text-xs rounded-lg mx-1 my-1 bg-red-600 text-white";
52
+
53
+ // button selcect
54
+
55
+ const SEL_BUTTON_CLASSES = "text-xs rounded-lg mx-1 my-1";
56
+ const SEL_BUTTON_CLASSES_ACTIVE = "text-xs rounded-lg mx-1 my-1 bg-slate-500 text-white";
57
+
58
+
59
+ const CONFIG = {
60
+ display_on_load: false,
61
+ init_width: 600,
62
+ init_height: 400,
63
+ }
64
+
65
+
66
+ const curve_add_chart = function(element_parent, data, zoom) {
67
+ zoom = zoom || 1;
68
+ //
69
+ const width = CONFIG.init_width * zoom;
70
+ const height = CONFIG.init_height * zoom;
71
+ //
72
+ // create div
73
+ const div = document.createElement('div');
74
+ div.style.cssText = "width: "+width+"; height: "+height+"px;";
75
+ div.className = "m-1 shadow-lg";
76
+ element_parent.appendChild(div);
77
+ // chart
78
+ chartlibs.plotly.add(
79
+ div,
80
+ { title: data.title, xaxis: data.xaxis , yaxis: data.yaxis },
81
+ data.series.map((item) => {return {
82
+ name: item.name,
83
+ color: item.color,
84
+ x_data: item.data.map((e) => e[0]),
85
+ y_data: item.data.map((e) => e[1]),
86
+ }}),
87
+ )
88
+ };
89
+
90
+
91
+ const standalone = function() {
92
+ const curve = global_curves.test[0].curves[0];
93
+ curve_add_chart(document.body, {
94
+ title: "title",
95
+ xaxis: "xaxis",
96
+ yaxis: "yaxis",
97
+ series : [
98
+ {
99
+ name: curve.short_title,
100
+ data: curve.series,
101
+ color: null,
102
+ },
103
+ ]
104
+ });
105
+ };
106
+
107
+ const INIT_DISPLAY = false ;
108
+
109
+
110
+ const CurvesChart = function(blockIndex, chartIndex) {
111
+ this.curve_block = new CurvesBlock(blockIndex);
112
+ this.blockIndex = blockIndex;
113
+ this.chartIndex = chartIndex;
114
+ this.chart = global_curves.test[blockIndex].charts[chartIndex];
115
+ this.curves = {
116
+ test: global_curves.test[blockIndex],
117
+ reference: global_curves.reference[blockIndex],
118
+ }
119
+ }
120
+ CurvesChart.prototype = {
121
+ getDomToogleInit: function() {
122
+ const blockIndex = this.blockIndex;
123
+ const chartIndex = this.chartIndex;
124
+ const has_error = this.chart.comparison && this.chart.comparison.curves_nb_with_error;
125
+ const children = [{
126
+ tag:"button",
127
+ attrs: {id: `chart_toogle_${blockIndex}_${chartIndex}`, type:"button", class: BUTTON_CLASSES },
128
+ html: this.chart.title + (has_error ? " " + ERROR_LABEL : ""),
129
+ click: function() { CurvesChart.toogle(blockIndex,chartIndex); },
130
+ }];
131
+ // if (this.chart.comparison) {
132
+ // if (this.chart.comparison.curves_nb_with_error) {
133
+ // // children.push({tag:"span", attrs: { class:"text-xs ERROR"}, html: `${this.chart.comparison.curves_nb_with_error} curves with errors`});
134
+ // // children.push({tag:"span", attrs: { class:"text-xs ERROR"}, html: "*errors"});
135
+ // }
136
+ // }
137
+ return {tag:"span", attrs:{class: has_error ? "error_container" : "" }, children: children};
138
+ },
139
+ // state : true = visible, false = hidden
140
+ toogle: function(force_state) {
141
+ const blockIndex = this.blockIndex;
142
+ const chartIndex = this.chartIndex;
143
+ const b = dom.get(`chart_toogle_${blockIndex}_${chartIndex}`);
144
+ const current_isHidden = (b.className == BUTTON_CLASSES);
145
+ const target_state = (force_state != undef) ? force_state : current_isHidden;
146
+ // update button
147
+ b.className = (target_state)?BUTTON_CLASSES_ACTIVE:BUTTON_CLASSES;
148
+ // update curves
149
+ const id = `chart_container_${blockIndex}_${chartIndex}`;
150
+ // remove if hidden
151
+ if (!target_state && !current_isHidden) { dom.get(id).remove(); }
152
+ if (target_state && current_isHidden) {
153
+ const chart = this.chart;
154
+ const eContainer = dom.get(`curves_${parseInt(blockIndex)}`);
155
+ let comparison = ""
156
+ if (this.chart.comparison && this.chart.comparison.curves_nb_with_error) {
157
+ comparison = `${this.chart.comparison.curves_nb_with_error} curve(s) with errors`;
158
+ for (let i = 0; i < this.chart.curves.length; i++) {
159
+ const curve = this.curves["test"].curves[this.chart.curves[i]]
160
+ comparison += ` - ${curve.title}: ${curve.comparison_error}`
161
+ }
162
+ }
163
+ const out = dom.tree_o(
164
+ eContainer,
165
+ {tag:"div", attrs: {id:id}, children: [
166
+ {tag:"div", style:"margin:10px 0px;", children: [
167
+ {tag:"strong", html: chart.title},
168
+ {tag:"button", attrs: { type:"button", class:BUTTON_CLASSES}, html: "Remove",
169
+ click: function() { CurvesChart.toogle(blockIndex,chartIndex); },
170
+ },
171
+ {tag:"span", attrs: {class:"ERROR"}, html: comparison},
172
+ ]},
173
+ {out:"row_1", tag:"div", style:"display: flex;flex-wrap: wrap;"},
174
+ {out:"row_2", tag:"div", style:"display: flex;flex-wrap: wrap;"},
175
+ ]},
176
+ );
177
+ // display test and reference
178
+ const labels = { test: "Test", reference: "Reference" }
179
+ for (type in labels) {
180
+
181
+ const series = []
182
+
183
+ chart.curves.forEach(curve_index => {
184
+ const curve = this.curves[type].curves[curve_index]
185
+ series.push({
186
+ name: curve.short_title,
187
+ data: curve.series,
188
+ color: null,
189
+ })
190
+ });
191
+ const data = {
192
+ title: chart.title + " [" + labels[type] + "]",
193
+ xaxis: chart.xaxis,
194
+ yaxis: chart.yaxis,
195
+ series : series,
196
+ }
197
+ curve_add_chart(out.row_1, data, this.curve_block.zoom);
198
+
199
+ }
200
+ // display each curve test vs reference
201
+ for (index_curve in chart.curves) {
202
+ real_index = chart.curves[index_curve]
203
+
204
+ const series = [
205
+ {
206
+ name: "Test",
207
+ data: this.curves["test"].curves[real_index].series,
208
+ color: '#1982c4',
209
+ },
210
+ {
211
+ name: "Reference",
212
+ data: this.curves["reference"].curves[real_index].series,
213
+ color: '#6a4c93',
214
+ },
215
+ ]
216
+ const data = {
217
+ title: this.curves["test"].curves[real_index].title + " [Test vs Reference]",
218
+ xaxis: chart.xaxis,
219
+ yaxis: chart.yaxis,
220
+ series : series,
221
+ }
222
+ curve_add_chart((chart.curves.length > 1) ? out.row_2 : out.row_1, data, this.curve_block.zoom);
223
+ }
224
+ }
225
+ },
226
+ }
227
+ CurvesChart.toogle = function(blockIndex, chartIndex, force_state) {
228
+ (new CurvesChart(blockIndex, chartIndex)).toogle(force_state);
229
+ };
230
+
231
+
232
+ const CurvesBlock = function(blockIndex) {
233
+ this.blockIndex = blockIndex;
234
+ this.charts = global_curves.test[blockIndex].charts; // ASSUMPTION test and reference have same charts
235
+ this.eContainer = dom.get(`curves_${parseInt(blockIndex)}`); // ASSUMPTION always exists
236
+ this.zoom = this.eContainer.dataset.zoom || 1;
237
+ }
238
+ CurvesBlock.prototype = {
239
+ toogleCharts: function(force_state) {
240
+ const blockIndex = this.blockIndex
241
+ this.charts.forEach((chart, chartIndex) => {
242
+ CurvesChart.toogle(blockIndex, chartIndex, force_state);
243
+ });
244
+ },
245
+ resize: function(direction) {
246
+ const mult = (1 + direction * 0.1);
247
+ this.eContainer.dataset.zoom = this.zoom * mult;
248
+ const curves = dom.qc(this.eContainer, ".js-plotly-plot");
249
+ curves.forEach((e) => {
250
+ const w = parseFloat(e.style.width) * mult;
251
+ const h = parseFloat(e.style.height) * mult;
252
+ e.style.width = w + "px";
253
+ e.style.height = h + "px";
254
+ Plotly.relayout(e, { width: w, height: h } );
255
+ });
256
+ },
257
+ init: function() {
258
+ const blockIndex = this.blockIndex
259
+ const charts = this.charts;
260
+ // buttons (global and per chart)
261
+ dom.tree(
262
+ this.eContainer,
263
+ {tag:"div", attrs: {id: `curvemgr_block_${blockIndex}`} , children:[
264
+ {tag:"div", children: [
265
+ {tag:"strong", html: "All"},
266
+ {tag:"button", attrs: { type:"button", class:BUTTON_CLASSES}, html: "Show", click: function() { CurvesBlock.toogle(blockIndex, true); }},
267
+ {tag:"button", attrs: { type:"button", class:BUTTON_CLASSES}, html: "Remove", click: function() { CurvesBlock.toogle(blockIndex, false); }},
268
+ {tag:"strong", html: "Size"},
269
+ {tag:"button", attrs: { type:"button", class:BUTTON_CLASSES}, html: "Increase", click: function() { CurvesBlock.resize(blockIndex, 1); }},
270
+ {tag:"button", attrs: { type:"button", class:BUTTON_CLASSES}, html: "Decrease", click: function() { CurvesBlock.resize(blockIndex, -1); }},
271
+ ]},
272
+ {tag:"div", children: charts.map((chart, chartIndex) => {
273
+ const cc = new CurvesChart(blockIndex, chartIndex);
274
+ return cc.getDomToogleInit();
275
+ })}
276
+ ]}
277
+ );
278
+ // load
279
+ if (CONFIG.display_on_load) {
280
+ charts.forEach((chart, chartIndex) => {
281
+ CurvesChart.toogle(blockIndex, chartIndex);
282
+ });
283
+ }
284
+ },
285
+ };
286
+ //
287
+ // Static Methods
288
+ CurvesBlock.toogle = function(blockIndex, force_state) {
289
+ (new CurvesBlock(blockIndex)).toogleCharts(force_state);
290
+ };
291
+ CurvesBlock.resize = function(blockIndex, direction) {
292
+ (new CurvesBlock(blockIndex)).resize(direction);
293
+ };
294
+
295
+
296
+ // ***************************************************************************
297
+ // ***************************************************************************
298
+ // CURVE MANAGER
299
+ // ***************************************************************************
300
+ // ***************************************************************************
301
+
302
+ w_1.curvemgr = {
303
+ init_group_curves: function() {
304
+ for (const i in global_curves.test) {
305
+ if (global_curves.test[i]) {
306
+ const cb = new CurvesBlock(i);
307
+ cb.init();
308
+ }
309
+ }
310
+ },
311
+ init(config) {
312
+ for (const k in CONFIG) {
313
+ if (config[k] != undef) {CONFIG[k] = config[k];}
314
+ }
315
+ this.init_group_curves();
316
+ }
317
+ };
318
+
319
+ })(window);
@@ -0,0 +1,144 @@
1
+ *:not(code):not(pre):not(td):not(th) {
2
+ font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;
3
+ font-family-monospace: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;
4
+ }
5
+ h1, h2, h3 {
6
+ border-bottom: 1px solid #eee;
7
+ padding-bottom: 10px;
8
+ }
9
+ form { margin:0; padding:0;}
10
+ h4 {
11
+ margin-bottom: 0px;
12
+ }
13
+ table {
14
+ border-collapse: collapse;
15
+ }
16
+ table, th, td {
17
+ border: 1px solid #aaa;
18
+ font-size:0.8rem;
19
+ padding:1px 4px;
20
+ font-family: monospace;
21
+ white-space: nowrap;
22
+ }
23
+
24
+ fieldset {
25
+ border-radius: 5px;
26
+ color:#999999;
27
+ font-size:0.9rem;
28
+ border: 1px #999999 solid;
29
+ }
30
+
31
+ .inset {
32
+ border-style: inset;
33
+
34
+ border-width: 1px;
35
+ padding:15px;
36
+
37
+ background-color: #fafafa;
38
+ }
39
+
40
+
41
+ .ERROR { background-color:#c52a0f20;color:#c52a0f; }
42
+ .WARNING { background-color:#bcbc0620;color:#bcbc06; }
43
+ .SUCCESS { background-color:#16840020;color:#168400; }
44
+ .test-bg-80 { background-color:#{{ meta.config.compare_color_test }}80; }
45
+ .test-bg-50 { background-color:#{{ meta.config.compare_color_test }}50; }
46
+ .test-bg-20 { background-color:#{{ meta.config.compare_color_test }}20; }
47
+ .refe-bg-80 { background-color:#{{ meta.config.compare_color_reference }}80; }
48
+ .refe-bg-50 { background-color:#{{ meta.config.compare_color_reference }}50; }
49
+ .refe-bg-20 { background-color:#{{ meta.config.compare_color_reference }}20; }
50
+ th {
51
+ background-color:#eee;color:#333;
52
+ }
53
+ .number {
54
+ text-align: right;
55
+ }
56
+ .center {
57
+ text-align: center;
58
+ }
59
+ a, a:link, a:visited, a:hover, a:active { color: #666; }
60
+ .muted { font-size: 0.9rem; color:#999; }
61
+ .footer {text-align: center; padding:40px;}
62
+
63
+ .img_reader {
64
+ max-width: 600px;
65
+ max-height: 400px;
66
+ }
67
+
68
+ .tabs {
69
+ display: table;
70
+ width: 100%;
71
+ }
72
+ .tabs .tab, .tabs .tabend {
73
+ display: table-cell;
74
+ border: 1px solid transparent;
75
+ border-bottom: 1px solid #ccc;
76
+ }
77
+ .tabs .tab {
78
+ width: 1px;
79
+ padding:10px 15px;
80
+ border-radius: 8px 8px 0 0;
81
+ margin-left: 10px;
82
+ color: #777;
83
+ }
84
+ .tabs .tab:hover {
85
+ background-color: #eee;
86
+ cursor: pointer;
87
+ }
88
+ .tabs .tab.active {
89
+ border: 1px solid #ccc;
90
+ border-bottom: 1px solid transparent;
91
+ color: inherit;
92
+ }
93
+ /* tailwind like */
94
+ button {border: 0;user-select: none; /* Standard syntax */ cursor: pointer;}
95
+
96
+ .text-white { color: rgb(255 255 255); }
97
+
98
+ .text-xs { font-size: .75rem; line-height: 1rem; }
99
+
100
+ .p-1 { padding: .25rem; }
101
+ .p-2 { padding: .5rem; }
102
+ .p-3 { padding: .75rem; }
103
+
104
+ .py-1 { padding-bottom: .25rem; padding-top: .25rem; }
105
+ .py-2 { padding-bottom: .5rem; padding-top: .5rem; }
106
+ .py-3 { padding-bottom: .75rem; padding-top: .75rem; }
107
+
108
+ .px-1 { padding-left: .25rem; padding-right: .25rem; }
109
+ .px-2 { padding-left: .5rem; padding-right: .5rem; }
110
+ .px-3 { padding-left: .75rem; padding-right: .75rem; }
111
+
112
+ .mx-1 { margin-left: 0.25rem; margin-right: 0.25rem; }
113
+ .my-1 { margin-top: 0.25rem; margin-bottom: 0.25rem; }
114
+
115
+ .m-1 { margin: .25rem; }
116
+ .m-2 { margin: .5rem; }
117
+ .m-3 { margin: .5rem; }
118
+ .m-4 { margin: 1rem; }
119
+
120
+ .rounded-lg { border-radius: .5rem; }
121
+
122
+ .bg-blue-700 { background-color: rgb(26 86 219); }
123
+ .bg-slate-400 { background-color: rgb(148 163 184); }
124
+ .bg-slate-500 { background-color: rgb(100 116 139); }
125
+ .bg-slate-600 { background-color: rgb(71 85 105); }
126
+ .bg-red-400 { background-color: #fca5a5; }
127
+ .bg-red-500 { background-color: #ef4444; }
128
+ .bg-red-600 { background-color: #dc2626; }
129
+
130
+ .error_container button { background-color: #ef4444; }
131
+
132
+
133
+ .hover\:bg-blue-800:hover { background-color: rgb(30 66 159); }
134
+
135
+
136
+ .shadow-sm { box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); }
137
+ .shadow { box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); }
138
+ .shadow-md { box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); }
139
+ .shadow-lg { box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); }
140
+ .shadow-xl { box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); }
141
+ .shadow-2xl { box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25); }
142
+ .shadow-inner { box-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05); }
143
+ .shadow-none { box-shadow: 0 0 #0000; }
144
+