oscura 0.8.0__py3-none-any.whl → 0.10.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 (151) hide show
  1. oscura/__init__.py +19 -19
  2. oscura/analyzers/__init__.py +2 -0
  3. oscura/analyzers/digital/extraction.py +2 -3
  4. oscura/analyzers/digital/quality.py +1 -1
  5. oscura/analyzers/digital/timing.py +1 -1
  6. oscura/analyzers/patterns/__init__.py +66 -0
  7. oscura/analyzers/power/basic.py +3 -3
  8. oscura/analyzers/power/soa.py +1 -1
  9. oscura/analyzers/power/switching.py +3 -3
  10. oscura/analyzers/signal_classification.py +529 -0
  11. oscura/analyzers/signal_integrity/sparams.py +3 -3
  12. oscura/analyzers/statistics/basic.py +10 -7
  13. oscura/analyzers/validation.py +1 -1
  14. oscura/analyzers/waveform/measurements.py +200 -156
  15. oscura/analyzers/waveform/measurements_with_uncertainty.py +91 -35
  16. oscura/analyzers/waveform/spectral.py +164 -73
  17. oscura/api/dsl/commands.py +15 -6
  18. oscura/api/server/templates/base.html +137 -146
  19. oscura/api/server/templates/export.html +84 -110
  20. oscura/api/server/templates/home.html +248 -267
  21. oscura/api/server/templates/protocols.html +44 -48
  22. oscura/api/server/templates/reports.html +27 -35
  23. oscura/api/server/templates/session_detail.html +68 -78
  24. oscura/api/server/templates/sessions.html +62 -72
  25. oscura/api/server/templates/waveforms.html +54 -64
  26. oscura/automotive/__init__.py +1 -1
  27. oscura/automotive/can/session.py +1 -1
  28. oscura/automotive/dbc/generator.py +638 -23
  29. oscura/automotive/uds/decoder.py +99 -6
  30. oscura/cli/analyze.py +8 -2
  31. oscura/cli/batch.py +36 -5
  32. oscura/cli/characterize.py +18 -4
  33. oscura/cli/export.py +47 -5
  34. oscura/cli/main.py +2 -0
  35. oscura/cli/onboarding/wizard.py +10 -6
  36. oscura/cli/pipeline.py +585 -0
  37. oscura/cli/visualize.py +6 -4
  38. oscura/convenience.py +400 -32
  39. oscura/core/measurement_result.py +286 -0
  40. oscura/core/progress.py +1 -1
  41. oscura/core/types.py +232 -239
  42. oscura/correlation/multi_protocol.py +1 -1
  43. oscura/export/legacy/__init__.py +11 -0
  44. oscura/export/legacy/wav.py +75 -0
  45. oscura/exporters/__init__.py +19 -0
  46. oscura/exporters/wireshark.py +809 -0
  47. oscura/hardware/acquisition/file.py +5 -19
  48. oscura/hardware/acquisition/saleae.py +10 -10
  49. oscura/hardware/acquisition/socketcan.py +4 -6
  50. oscura/hardware/acquisition/synthetic.py +1 -5
  51. oscura/hardware/acquisition/visa.py +6 -6
  52. oscura/hardware/security/side_channel_detector.py +5 -508
  53. oscura/inference/message_format.py +686 -1
  54. oscura/jupyter/display.py +2 -2
  55. oscura/jupyter/magic.py +3 -3
  56. oscura/loaders/__init__.py +17 -12
  57. oscura/loaders/binary.py +1 -1
  58. oscura/loaders/chipwhisperer.py +1 -2
  59. oscura/loaders/configurable.py +1 -1
  60. oscura/loaders/csv_loader.py +2 -2
  61. oscura/loaders/hdf5_loader.py +1 -1
  62. oscura/loaders/lazy.py +6 -1
  63. oscura/loaders/mmap_loader.py +0 -1
  64. oscura/loaders/numpy_loader.py +8 -7
  65. oscura/loaders/preprocessing.py +3 -5
  66. oscura/loaders/rigol.py +21 -7
  67. oscura/loaders/sigrok.py +2 -5
  68. oscura/loaders/tdms.py +3 -2
  69. oscura/loaders/tektronix.py +38 -32
  70. oscura/loaders/tss.py +20 -27
  71. oscura/loaders/vcd.py +13 -8
  72. oscura/loaders/wav.py +1 -6
  73. oscura/pipeline/__init__.py +76 -0
  74. oscura/pipeline/handlers/__init__.py +165 -0
  75. oscura/pipeline/handlers/analyzers.py +1045 -0
  76. oscura/pipeline/handlers/decoders.py +899 -0
  77. oscura/pipeline/handlers/exporters.py +1103 -0
  78. oscura/pipeline/handlers/filters.py +891 -0
  79. oscura/pipeline/handlers/loaders.py +640 -0
  80. oscura/pipeline/handlers/transforms.py +768 -0
  81. oscura/reporting/formatting/measurements.py +55 -14
  82. oscura/reporting/templates/enhanced/protocol_re.html +504 -503
  83. oscura/side_channel/__init__.py +38 -57
  84. oscura/utils/builders/signal_builder.py +5 -5
  85. oscura/utils/comparison/compare.py +7 -9
  86. oscura/utils/comparison/golden.py +1 -1
  87. oscura/utils/filtering/convenience.py +2 -2
  88. oscura/utils/math/arithmetic.py +38 -62
  89. oscura/utils/math/interpolation.py +20 -20
  90. oscura/utils/pipeline/__init__.py +4 -17
  91. oscura/utils/progressive.py +1 -4
  92. oscura/utils/triggering/edge.py +1 -1
  93. oscura/utils/triggering/pattern.py +2 -2
  94. oscura/utils/triggering/pulse.py +2 -2
  95. oscura/utils/triggering/window.py +3 -3
  96. oscura/validation/hil_testing.py +11 -11
  97. oscura/visualization/__init__.py +46 -284
  98. oscura/visualization/batch.py +72 -433
  99. oscura/visualization/plot.py +542 -53
  100. oscura/visualization/styles.py +184 -318
  101. oscura/workflows/batch/advanced.py +1 -1
  102. oscura/workflows/batch/aggregate.py +7 -8
  103. oscura/workflows/complete_re.py +251 -23
  104. oscura/workflows/digital.py +27 -4
  105. oscura/workflows/multi_trace.py +136 -17
  106. oscura/workflows/waveform.py +11 -6
  107. {oscura-0.8.0.dist-info → oscura-0.10.0.dist-info}/METADATA +59 -79
  108. {oscura-0.8.0.dist-info → oscura-0.10.0.dist-info}/RECORD +111 -136
  109. oscura/side_channel/dpa.py +0 -1025
  110. oscura/utils/optimization/__init__.py +0 -19
  111. oscura/utils/optimization/parallel.py +0 -443
  112. oscura/utils/optimization/search.py +0 -532
  113. oscura/utils/pipeline/base.py +0 -338
  114. oscura/utils/pipeline/composition.py +0 -248
  115. oscura/utils/pipeline/parallel.py +0 -449
  116. oscura/utils/pipeline/pipeline.py +0 -375
  117. oscura/utils/search/__init__.py +0 -16
  118. oscura/utils/search/anomaly.py +0 -424
  119. oscura/utils/search/context.py +0 -294
  120. oscura/utils/search/pattern.py +0 -288
  121. oscura/utils/storage/__init__.py +0 -61
  122. oscura/utils/storage/database.py +0 -1166
  123. oscura/visualization/accessibility.py +0 -526
  124. oscura/visualization/annotations.py +0 -371
  125. oscura/visualization/axis_scaling.py +0 -305
  126. oscura/visualization/colors.py +0 -451
  127. oscura/visualization/digital.py +0 -436
  128. oscura/visualization/eye.py +0 -571
  129. oscura/visualization/histogram.py +0 -281
  130. oscura/visualization/interactive.py +0 -1035
  131. oscura/visualization/jitter.py +0 -1042
  132. oscura/visualization/keyboard.py +0 -394
  133. oscura/visualization/layout.py +0 -400
  134. oscura/visualization/optimization.py +0 -1079
  135. oscura/visualization/palettes.py +0 -446
  136. oscura/visualization/power.py +0 -508
  137. oscura/visualization/power_extended.py +0 -955
  138. oscura/visualization/presets.py +0 -469
  139. oscura/visualization/protocols.py +0 -1246
  140. oscura/visualization/render.py +0 -223
  141. oscura/visualization/rendering.py +0 -444
  142. oscura/visualization/reverse_engineering.py +0 -838
  143. oscura/visualization/signal_integrity.py +0 -989
  144. oscura/visualization/specialized.py +0 -643
  145. oscura/visualization/spectral.py +0 -1226
  146. oscura/visualization/thumbnails.py +0 -340
  147. oscura/visualization/time_axis.py +0 -351
  148. oscura/visualization/waveform.py +0 -454
  149. {oscura-0.8.0.dist-info → oscura-0.10.0.dist-info}/WHEEL +0 -0
  150. {oscura-0.8.0.dist-info → oscura-0.10.0.dist-info}/entry_points.txt +0 -0
  151. {oscura-0.8.0.dist-info → oscura-0.10.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,525 +1,526 @@
1
- <!DOCTYPE html>
1
+ <!doctype html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>{{ title }}</title>
7
7
  <script src="https://cdn.plot.ly/plotly-2.27.0.min.js"></script>
8
8
  <style>
9
- :root {
10
- --bg-color: {{ theme.background_color }};
11
- --text-color: {{ theme.text_color }};
12
- --primary-color: {{ theme.primary_color }};
13
- --secondary-color: {{ theme.secondary_color }};
14
- --border-color: {{ theme.border_color }};
15
- --code-bg: {{ theme.code_background }};
16
- }
17
-
18
- * {
19
- box-sizing: border-box;
20
- margin: 0;
21
- padding: 0;
22
- }
23
-
24
- body {
25
- font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
26
- line-height: 1.6;
27
- background-color: var(--bg-color);
28
- color: var(--text-color);
29
- padding: 0;
30
- }
31
-
32
- .container {
33
- max-width: 1400px;
34
- margin: 0 auto;
35
- padding: 40px 20px;
36
- }
37
-
38
- /* Header */
39
- .header {
40
- background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
41
- color: white;
42
- padding: 60px 40px;
43
- margin: -40px -20px 40px -20px;
44
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
45
- }
46
-
47
- .header h1 {
48
- font-size: 2.5rem;
49
- margin-bottom: 10px;
50
- font-weight: 600;
51
- }
52
-
53
- .header .meta {
54
- opacity: 0.9;
55
- font-size: 0.95rem;
56
- }
57
-
58
- /* Table of Contents */
59
- .toc {
60
- background: var(--code-bg);
61
- border-left: 4px solid var(--primary-color);
62
- padding: 20px;
63
- margin: 30px 0;
64
- border-radius: 4px;
65
- }
66
-
67
- .toc h2 {
68
- margin-bottom: 15px;
69
- font-size: 1.3rem;
70
- }
71
-
72
- .toc ul {
73
- list-style: none;
74
- }
75
-
76
- .toc li {
77
- margin: 8px 0;
78
- }
79
-
80
- .toc a {
81
- color: var(--secondary-color);
82
- text-decoration: none;
83
- transition: color 0.2s;
84
- }
85
-
86
- .toc a:hover {
87
- color: var(--primary-color);
88
- text-decoration: underline;
89
- }
90
-
91
- /* Sections */
92
- .section {
93
- margin: 50px 0;
94
- scroll-margin-top: 20px;
95
- }
96
-
97
- .section h2 {
98
- color: var(--primary-color);
99
- border-bottom: 3px solid var(--primary-color);
100
- padding-bottom: 12px;
101
- margin-bottom: 25px;
102
- font-size: 1.8rem;
103
- }
104
-
105
- .section h3 {
106
- color: var(--secondary-color);
107
- margin-top: 30px;
108
- margin-bottom: 15px;
109
- font-size: 1.4rem;
110
- }
111
-
112
- /* Cards */
113
- .card {
114
- background: var(--code-bg);
115
- border: 1px solid var(--border-color);
116
- border-radius: 8px;
117
- padding: 25px;
118
- margin: 20px 0;
119
- box-shadow: 0 2px 4px rgba(0,0,0,0.05);
120
- }
121
-
122
- .card-header {
123
- font-weight: 600;
124
- color: var(--primary-color);
125
- margin-bottom: 15px;
126
- font-size: 1.1rem;
127
- }
128
-
129
- /* Tables */
130
- table {
131
- width: 100%;
132
- border-collapse: collapse;
133
- margin: 20px 0;
134
- background: white;
135
- box-shadow: 0 2px 4px rgba(0,0,0,0.05);
136
- }
137
-
138
- th {
139
- background: var(--primary-color);
140
- color: white;
141
- padding: 15px;
142
- text-align: left;
143
- font-weight: 600;
144
- }
145
-
146
- td {
147
- padding: 12px 15px;
148
- border-bottom: 1px solid var(--border-color);
149
- }
150
-
151
- tr:nth-child(even) {
152
- background-color: rgba(0,0,0,0.02);
153
- }
154
-
155
- tr:hover {
156
- background-color: rgba(0,0,0,0.05);
157
- }
158
-
159
- /* Badges */
160
- .badge {
161
- display: inline-block;
162
- padding: 4px 12px;
163
- border-radius: 12px;
164
- font-size: 0.85rem;
165
- font-weight: 600;
166
- }
167
-
168
- .badge-success {
169
- background: #d4edda;
170
- color: #155724;
171
- }
172
-
173
- .badge-warning {
174
- background: #fff3cd;
175
- color: #856404;
176
- }
177
-
178
- .badge-danger {
179
- background: #f8d7da;
180
- color: #721c24;
181
- }
182
-
183
- /* Warnings */
184
- .warning {
185
- background: #fff3cd;
186
- border-left: 4px solid #ffc107;
187
- padding: 15px;
188
- margin: 15px 0;
189
- border-radius: 4px;
190
- }
191
-
192
- .warning::before {
193
- content: "⚠ ";
194
- font-weight: bold;
195
- }
196
-
197
- /* Plots */
198
- .plot-container {
199
- margin: 30px 0;
200
- padding: 20px;
201
- background: white;
202
- border-radius: 8px;
203
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
204
- }
205
-
206
- .plot-title {
207
- font-size: 1.2rem;
208
- font-weight: 600;
209
- margin-bottom: 15px;
210
- color: var(--primary-color);
211
- }
212
-
213
- .plot-container img {
214
- max-width: 100%;
215
- height: auto;
216
- display: block;
217
- margin: 0 auto;
218
- }
219
-
220
- /* Artifacts List */
221
- .artifacts-list {
222
- list-style: none;
223
- padding: 0;
224
- }
225
-
226
- .artifacts-list li {
227
- background: var(--code-bg);
228
- padding: 15px;
229
- margin: 10px 0;
230
- border-left: 4px solid var(--secondary-color);
231
- border-radius: 4px;
232
- }
233
-
234
- .artifacts-list strong {
235
- color: var(--primary-color);
236
- }
237
-
238
- /* Metrics Grid */
239
- .metrics-grid {
240
- display: grid;
241
- grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
242
- gap: 20px;
243
- margin: 20px 0;
244
- }
245
-
246
- .metric-card {
247
- background: var(--code-bg);
248
- padding: 20px;
249
- border-radius: 8px;
250
- text-align: center;
251
- border: 1px solid var(--border-color);
252
- }
253
-
254
- .metric-value {
255
- font-size: 2rem;
256
- font-weight: 700;
257
- color: var(--primary-color);
258
- margin: 10px 0;
259
- }
260
-
261
- .metric-label {
262
- font-size: 0.9rem;
263
- color: var(--text-color);
264
- opacity: 0.8;
265
- }
266
-
267
- /* Code blocks */
268
- code {
269
- background: var(--code-bg);
270
- padding: 2px 6px;
271
- border-radius: 3px;
272
- font-family: 'Consolas', 'Monaco', monospace;
273
- font-size: 0.9em;
274
- }
275
-
276
- /* Responsive */
277
- @media (max-width: 768px) {
278
- .header {
279
- padding: 40px 20px;
280
- }
281
-
282
- .header h1 {
283
- font-size: 2rem;
284
- }
285
-
286
- .section h2 {
287
- font-size: 1.5rem;
288
- }
289
-
290
- .metrics-grid {
291
- grid-template-columns: 1fr;
292
- }
293
- }
294
-
295
- /* Print styles */
296
- @media print {
297
- .header {
298
- background: white !important;
299
- color: black !important;
300
- box-shadow: none !important;
301
- }
302
-
303
- .toc {
304
- display: none;
305
- }
306
-
307
- .section {
308
- page-break-inside: avoid;
309
- }
310
- }
9
+ :root {
10
+ --bg-color: {{ theme.background_color }};
11
+ --text-color: {{ theme.text_color }};
12
+ --primary-color: {{ theme.primary_color }};
13
+ --secondary-color: {{ theme.secondary_color }};
14
+ --border-color: {{ theme.border_color }};
15
+ --code-bg: {{ theme.code_background }};
16
+ }
17
+
18
+ * {
19
+ box-sizing: border-box;
20
+ margin: 0;
21
+ padding: 0;
22
+ }
23
+
24
+ body {
25
+ font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
26
+ line-height: 1.6;
27
+ background-color: var(--bg-color);
28
+ color: var(--text-color);
29
+ padding: 0;
30
+ }
31
+
32
+ .container {
33
+ max-width: 1400px;
34
+ margin: 0 auto;
35
+ padding: 40px 20px;
36
+ }
37
+
38
+ /* Header */
39
+ .header {
40
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
41
+ color: white;
42
+ padding: 60px 40px;
43
+ margin: -40px -20px 40px -20px;
44
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
45
+ }
46
+
47
+ .header h1 {
48
+ font-size: 2.5rem;
49
+ margin-bottom: 10px;
50
+ font-weight: 600;
51
+ }
52
+
53
+ .header .meta {
54
+ opacity: 0.9;
55
+ font-size: 0.95rem;
56
+ }
57
+
58
+ /* Table of Contents */
59
+ .toc {
60
+ background: var(--code-bg);
61
+ border-left: 4px solid var(--primary-color);
62
+ padding: 20px;
63
+ margin: 30px 0;
64
+ border-radius: 4px;
65
+ }
66
+
67
+ .toc h2 {
68
+ margin-bottom: 15px;
69
+ font-size: 1.3rem;
70
+ }
71
+
72
+ .toc ul {
73
+ list-style: none;
74
+ }
75
+
76
+ .toc li {
77
+ margin: 8px 0;
78
+ }
79
+
80
+ .toc a {
81
+ color: var(--secondary-color);
82
+ text-decoration: none;
83
+ transition: color 0.2s;
84
+ }
85
+
86
+ .toc a:hover {
87
+ color: var(--primary-color);
88
+ text-decoration: underline;
89
+ }
90
+
91
+ /* Sections */
92
+ .section {
93
+ margin: 50px 0;
94
+ scroll-margin-top: 20px;
95
+ }
96
+
97
+ .section h2 {
98
+ color: var(--primary-color);
99
+ border-bottom: 3px solid var(--primary-color);
100
+ padding-bottom: 12px;
101
+ margin-bottom: 25px;
102
+ font-size: 1.8rem;
103
+ }
104
+
105
+ .section h3 {
106
+ color: var(--secondary-color);
107
+ margin-top: 30px;
108
+ margin-bottom: 15px;
109
+ font-size: 1.4rem;
110
+ }
111
+
112
+ /* Cards */
113
+ .card {
114
+ background: var(--code-bg);
115
+ border: 1px solid var(--border-color);
116
+ border-radius: 8px;
117
+ padding: 25px;
118
+ margin: 20px 0;
119
+ box-shadow: 0 2px 4px rgba(0,0,0,0.05);
120
+ }
121
+
122
+ .card-header {
123
+ font-weight: 600;
124
+ color: var(--primary-color);
125
+ margin-bottom: 15px;
126
+ font-size: 1.1rem;
127
+ }
128
+
129
+ /* Tables */
130
+ table {
131
+ width: 100%;
132
+ border-collapse: collapse;
133
+ margin: 20px 0;
134
+ background: white;
135
+ box-shadow: 0 2px 4px rgba(0,0,0,0.05);
136
+ }
137
+
138
+ th {
139
+ background: var(--primary-color);
140
+ color: white;
141
+ padding: 15px;
142
+ text-align: left;
143
+ font-weight: 600;
144
+ }
145
+
146
+ td {
147
+ padding: 12px 15px;
148
+ border-bottom: 1px solid var(--border-color);
149
+ }
150
+
151
+ tr:nth-child(even) {
152
+ background-color: rgba(0,0,0,0.02);
153
+ }
154
+
155
+ tr:hover {
156
+ background-color: rgba(0,0,0,0.05);
157
+ }
158
+
159
+ /* Badges */
160
+ .badge {
161
+ display: inline-block;
162
+ padding: 4px 12px;
163
+ border-radius: 12px;
164
+ font-size: 0.85rem;
165
+ font-weight: 600;
166
+ }
167
+
168
+ .badge-success {
169
+ background: #d4edda;
170
+ color: #155724;
171
+ }
172
+
173
+ .badge-warning {
174
+ background: #fff3cd;
175
+ color: #856404;
176
+ }
177
+
178
+ .badge-danger {
179
+ background: #f8d7da;
180
+ color: #721c24;
181
+ }
182
+
183
+ /* Warnings */
184
+ .warning {
185
+ background: #fff3cd;
186
+ border-left: 4px solid #ffc107;
187
+ padding: 15px;
188
+ margin: 15px 0;
189
+ border-radius: 4px;
190
+ }
191
+
192
+ .warning::before {
193
+ content: "⚠ ";
194
+ font-weight: bold;
195
+ }
196
+
197
+ /* Plots */
198
+ .plot-container {
199
+ margin: 30px 0;
200
+ padding: 20px;
201
+ background: white;
202
+ border-radius: 8px;
203
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
204
+ }
205
+
206
+ .plot-title {
207
+ font-size: 1.2rem;
208
+ font-weight: 600;
209
+ margin-bottom: 15px;
210
+ color: var(--primary-color);
211
+ }
212
+
213
+ .plot-container img {
214
+ max-width: 100%;
215
+ height: auto;
216
+ display: block;
217
+ margin: 0 auto;
218
+ }
219
+
220
+ /* Artifacts List */
221
+ .artifacts-list {
222
+ list-style: none;
223
+ padding: 0;
224
+ }
225
+
226
+ .artifacts-list li {
227
+ background: var(--code-bg);
228
+ padding: 15px;
229
+ margin: 10px 0;
230
+ border-left: 4px solid var(--secondary-color);
231
+ border-radius: 4px;
232
+ }
233
+
234
+ .artifacts-list strong {
235
+ color: var(--primary-color);
236
+ }
237
+
238
+ /* Metrics Grid */
239
+ .metrics-grid {
240
+ display: grid;
241
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
242
+ gap: 20px;
243
+ margin: 20px 0;
244
+ }
245
+
246
+ .metric-card {
247
+ background: var(--code-bg);
248
+ padding: 20px;
249
+ border-radius: 8px;
250
+ text-align: center;
251
+ border: 1px solid var(--border-color);
252
+ }
253
+
254
+ .metric-value {
255
+ font-size: 2rem;
256
+ font-weight: 700;
257
+ color: var(--primary-color);
258
+ margin: 10px 0;
259
+ }
260
+
261
+ .metric-label {
262
+ font-size: 0.9rem;
263
+ color: var(--text-color);
264
+ opacity: 0.8;
265
+ }
266
+
267
+ /* Code blocks */
268
+ code {
269
+ background: var(--code-bg);
270
+ padding: 2px 6px;
271
+ border-radius: 3px;
272
+ font-family: 'Consolas', 'Monaco', monospace;
273
+ font-size: 0.9em;
274
+ }
275
+
276
+ /* Responsive */
277
+ @media (max-width: 768px) {
278
+ .header {
279
+ padding: 40px 20px;
280
+ }
281
+
282
+ .header h1 {
283
+ font-size: 2rem;
284
+ }
285
+
286
+ .section h2 {
287
+ font-size: 1.5rem;
288
+ }
289
+
290
+ .metrics-grid {
291
+ grid-template-columns: 1fr;
292
+ }
293
+ }
294
+
295
+ /* Print styles */
296
+ @media print {
297
+ .header {
298
+ background: white !important;
299
+ color: black !important;
300
+ box-shadow: none !important;
301
+ }
302
+
303
+ .toc {
304
+ display: none;
305
+ }
306
+
307
+ .section {
308
+ page-break-inside: avoid;
309
+ }
310
+ }
311
311
  </style>
312
- </head>
313
- <body>
312
+ </head>
313
+ <body>
314
314
  <div class="container">
315
- <div class="header">
316
- <h1>{{ title }}</h1>
317
- <div class="meta">
318
- {% if config.show_timestamps %}
319
- <p>Generated: {{ generated_at|format_timestamp }}</p>
320
- {% endif %}
321
- <p>Author: {{ author }}</p>
322
- <p>Report Type: Protocol Reverse Engineering</p>
323
- </div>
315
+ <div class="header">
316
+ <h1>{{ title }}</h1>
317
+ <div class="meta">
318
+ {% if config.show_timestamps %}
319
+ <p>Generated: {{ generated_at|format_timestamp }}</p>
320
+ {% endif %}
321
+ <p>Author: {{ author }}</p>
322
+ <p>Report Type: Protocol Reverse Engineering</p>
324
323
  </div>
325
-
326
- {% if config.show_toc %}
327
- <div class="toc">
328
- <h2>Table of Contents</h2>
329
- <ul>
330
- <li><a href="#executive-summary">Executive Summary</a></li>
331
- <li><a href="#protocol-spec">Protocol Specification</a></li>
332
- {% if plots %}<li><a href="#visualizations">Visualizations</a></li>{% endif %}
333
- {% if artifacts %}<li><a href="#artifacts">Generated Artifacts</a></li>{% endif %}
334
- {% if partial_results %}<li><a href="#analysis">Detailed Analysis</a></li>{% endif %}
335
- {% if warnings %}<li><a href="#warnings">Warnings</a></li>{% endif %}
336
- </ul>
324
+ </div>
325
+
326
+ {% if config.show_toc %}
327
+ <div class="toc">
328
+ <h2>Table of Contents</h2>
329
+ <ul>
330
+ <li><a href="#executive-summary">Executive Summary</a></li>
331
+ <li><a href="#protocol-spec">Protocol Specification</a></li>
332
+ {% if plots %}
333
+ <li><a href="#visualizations">Visualizations</a></li>
334
+ {% endif %} {% if artifacts %}
335
+ <li><a href="#artifacts">Generated Artifacts</a></li>
336
+ {% endif %} {% if partial_results %}
337
+ <li><a href="#analysis">Detailed Analysis</a></li>
338
+ {% endif %} {% if warnings %}
339
+ <li><a href="#warnings">Warnings</a></li>
340
+ {% endif %}
341
+ </ul>
342
+ </div>
343
+ {% endif %}
344
+
345
+ <!-- Executive Summary -->
346
+ <div class="section" id="executive-summary">
347
+ <h2>Executive Summary</h2>
348
+ <div class="card">
349
+ <p>
350
+ This report presents the results of automated protocol reverse engineering performed by the Oscura
351
+ framework. The analysis identified protocol characteristics, decoded message structures, and generated
352
+ working dissectors for further analysis.
353
+ </p>
337
354
  </div>
338
- {% endif %}
339
355
 
340
- <!-- Executive Summary -->
341
- <div class="section" id="executive-summary">
342
- <h2>Executive Summary</h2>
343
- <div class="card">
344
- <p>This report presents the results of automated protocol reverse engineering
345
- performed by the Oscura framework. The analysis identified protocol characteristics,
346
- decoded message structures, and generated working dissectors for further analysis.</p>
347
- </div>
348
-
349
- {% if confidence_score %}
350
- <div class="metrics-grid">
351
- <div class="metric-card">
352
- <div class="metric-label">Overall Confidence</div>
353
- <div class="metric-value">{{ (confidence_score * 100)|round(1) }}%</div>
354
- {% if confidence_score >= 0.8 %}
355
- <span class="badge badge-success">High</span>
356
- {% elif confidence_score >= 0.6 %}
357
- <span class="badge badge-warning">Medium</span>
358
- {% else %}
359
- <span class="badge badge-danger">Low</span>
360
- {% endif %}
361
- </div>
362
-
363
- {% if execution_time %}
364
- <div class="metric-card">
365
- <div class="metric-label">Execution Time</div>
366
- <div class="metric-value">{{ execution_time|round(1) }}s</div>
367
- </div>
368
- {% endif %}
369
-
370
- {% if protocol_spec %}
371
- <div class="metric-card">
372
- <div class="metric-label">Fields Detected</div>
373
- <div class="metric-value">{{ protocol_spec.fields|length }}</div>
374
- </div>
375
- {% endif %}
376
-
377
- {% if artifacts %}
378
- <div class="metric-card">
379
- <div class="metric-label">Artifacts Generated</div>
380
- <div class="metric-value">{{ artifacts|length }}</div>
381
- </div>
382
- {% endif %}
383
- </div>
356
+ {% if confidence_score %}
357
+ <div class="metrics-grid">
358
+ <div class="metric-card">
359
+ <div class="metric-label">Overall Confidence</div>
360
+ <div class="metric-value">{{ (confidence_score * 100)|round(1) }}%</div>
361
+ {% if confidence_score >= 0.8 %}
362
+ <span class="badge badge-success">High</span>
363
+ {% elif confidence_score >= 0.6 %}
364
+ <span class="badge badge-warning">Medium</span>
365
+ {% else %}
366
+ <span class="badge badge-danger">Low</span>
384
367
  {% endif %}
368
+ </div>
369
+
370
+ {% if execution_time %}
371
+ <div class="metric-card">
372
+ <div class="metric-label">Execution Time</div>
373
+ <div class="metric-value">{{ execution_time|round(1) }}s</div>
374
+ </div>
375
+ {% endif %} {% if protocol_spec %}
376
+ <div class="metric-card">
377
+ <div class="metric-label">Fields Detected</div>
378
+ <div class="metric-value">{{ protocol_spec.fields|length }}</div>
379
+ </div>
380
+ {% endif %} {% if artifacts %}
381
+ <div class="metric-card">
382
+ <div class="metric-label">Artifacts Generated</div>
383
+ <div class="metric-value">{{ artifacts|length }}</div>
384
+ </div>
385
+ {% endif %}
385
386
  </div>
386
-
387
- <!-- Protocol Specification -->
388
- {% if protocol_spec %}
389
- <div class="section" id="protocol-spec">
390
- <h2>Protocol Specification</h2>
391
-
392
- <div class="card">
393
- <div class="card-header">Overview</div>
394
- <table>
395
- <tr>
396
- <th>Property</th>
397
- <th>Value</th>
398
- </tr>
399
- <tr>
400
- <td><strong>Protocol Name</strong></td>
401
- <td>{{ protocol_spec.name }}</td>
402
- </tr>
403
- <tr>
404
- <td><strong>Baud Rate</strong></td>
405
- <td>{{ protocol_spec.baud_rate|format_number }} bps</td>
406
- </tr>
407
- <tr>
408
- <td><strong>Frame Format</strong></td>
409
- <td><code>{{ protocol_spec.frame_format }}</code></td>
410
- </tr>
411
- <tr>
412
- <td><strong>Sync Pattern</strong></td>
413
- <td><code>{{ protocol_spec.sync_pattern }}</code></td>
414
- </tr>
415
- <tr>
416
- <td><strong>Frame Length</strong></td>
417
- <td>{{ protocol_spec.frame_length or "Variable" }} bytes</td>
418
- </tr>
419
- <tr>
420
- <td><strong>Checksum Type</strong></td>
421
- <td>{{ protocol_spec.checksum_type or "None detected" }}</td>
422
- </tr>
423
- {% if protocol_spec.checksum_position %}
424
- <tr>
425
- <td><strong>Checksum Position</strong></td>
426
- <td>Byte {{ protocol_spec.checksum_position }}</td>
427
- </tr>
428
- {% endif %}
429
- <tr>
430
- <td><strong>Detection Confidence</strong></td>
431
- <td>{{ (protocol_spec.confidence * 100)|round(1) }}%</td>
432
- </tr>
433
- </table>
434
- </div>
435
-
436
- {% if protocol_spec.fields %}
437
- <h3>Field Structure</h3>
438
- <div class="card">
439
- <table>
440
- <thead>
441
- <tr>
442
- <th>Field Name</th>
443
- <th>Offset (bytes)</th>
444
- <th>Size (bytes)</th>
445
- <th>Type</th>
446
- </tr>
447
- </thead>
448
- <tbody>
449
- {% for field in protocol_spec.fields %}
450
- <tr>
451
- <td><code>{{ field.name }}</code></td>
452
- <td>{{ field.offset }}</td>
453
- <td>{{ field.size }}</td>
454
- <td>{{ field.type }}</td>
455
- </tr>
456
- {% endfor %}
457
- </tbody>
458
- </table>
459
- </div>
387
+ {% endif %}
388
+ </div>
389
+
390
+ <!-- Protocol Specification -->
391
+ {% if protocol_spec %}
392
+ <div class="section" id="protocol-spec">
393
+ <h2>Protocol Specification</h2>
394
+
395
+ <div class="card">
396
+ <div class="card-header">Overview</div>
397
+ <table>
398
+ <tr>
399
+ <th>Property</th>
400
+ <th>Value</th>
401
+ </tr>
402
+ <tr>
403
+ <td><strong>Protocol Name</strong></td>
404
+ <td>{{ protocol_spec.name }}</td>
405
+ </tr>
406
+ <tr>
407
+ <td><strong>Baud Rate</strong></td>
408
+ <td>{{ protocol_spec.baud_rate|format_number }} bps</td>
409
+ </tr>
410
+ <tr>
411
+ <td><strong>Frame Format</strong></td>
412
+ <td><code>{{ protocol_spec.frame_format }}</code></td>
413
+ </tr>
414
+ <tr>
415
+ <td><strong>Sync Pattern</strong></td>
416
+ <td><code>{{ protocol_spec.sync_pattern }}</code></td>
417
+ </tr>
418
+ <tr>
419
+ <td><strong>Frame Length</strong></td>
420
+ <td>{{ protocol_spec.frame_length or "Variable" }} bytes</td>
421
+ </tr>
422
+ <tr>
423
+ <td><strong>Checksum Type</strong></td>
424
+ <td>{{ protocol_spec.checksum_type or "None detected" }}</td>
425
+ </tr>
426
+ {% if protocol_spec.checksum_position %}
427
+ <tr>
428
+ <td><strong>Checksum Position</strong></td>
429
+ <td>Byte {{ protocol_spec.checksum_position }}</td>
430
+ </tr>
460
431
  {% endif %}
432
+ <tr>
433
+ <td><strong>Detection Confidence</strong></td>
434
+ <td>{{ (protocol_spec.confidence * 100)|round(1) }}%</td>
435
+ </tr>
436
+ </table>
461
437
  </div>
462
- {% endif %}
463
438
 
464
- <!-- Visualizations -->
465
- {% if plots %}
466
- <div class="section" id="visualizations">
467
- <h2>Visualizations</h2>
468
- {% for plot in plots %}
469
- <div class="plot-container">
470
- <div class="plot-title">{{ plot.title }}</div>
471
- {% if plot.type == "embedded" %}
472
- <img src="{{ plot.data }}" alt="{{ plot.title }}">
473
- {% else %}
474
- <img src="{{ plot.path }}" alt="{{ plot.title }}">
475
- {% endif %}
476
- </div>
477
- {% endfor %}
439
+ {% if protocol_spec.fields %}
440
+ <h3>Field Structure</h3>
441
+ <div class="card">
442
+ <table>
443
+ <thead>
444
+ <tr>
445
+ <th>Field Name</th>
446
+ <th>Offset (bytes)</th>
447
+ <th>Size (bytes)</th>
448
+ <th>Type</th>
449
+ </tr>
450
+ </thead>
451
+ <tbody>
452
+ {% for field in protocol_spec.fields %}
453
+ <tr>
454
+ <td><code>{{ field.name }}</code></td>
455
+ <td>{{ field.offset }}</td>
456
+ <td>{{ field.size }}</td>
457
+ <td>{{ field.type }}</td>
458
+ </tr>
459
+ {% endfor %}
460
+ </tbody>
461
+ </table>
478
462
  </div>
479
463
  {% endif %}
480
-
481
- <!-- Generated Artifacts -->
482
- {% if artifacts %}
483
- <div class="section" id="artifacts">
484
- <h2>Generated Artifacts</h2>
485
- <div class="card">
486
- <p>The following artifacts were generated and can be used for further analysis:</p>
487
- <ul class="artifacts-list">
488
- {% for artifact in artifacts %}
489
- <li>
490
- <strong>{{ artifact.name }}</strong><br>
491
- <code>{{ artifact.path }}</code>
492
- </li>
493
- {% endfor %}
494
- </ul>
495
- </div>
464
+ </div>
465
+ {% endif %}
466
+
467
+ <!-- Visualizations -->
468
+ {% if plots %}
469
+ <div class="section" id="visualizations">
470
+ <h2>Visualizations</h2>
471
+ {% for plot in plots %}
472
+ <div class="plot-container">
473
+ <div class="plot-title">{{ plot.title }}</div>
474
+ {% if plot.type == "embedded" %}
475
+ <img src="{{ plot.data }}" alt="{{ plot.title }}" />
476
+ {% else %}
477
+ <img src="{{ plot.path }}" alt="{{ plot.title }}" />
478
+ {% endif %}
496
479
  </div>
497
- {% endif %}
498
-
499
- <!-- Detailed Analysis -->
500
- {% if partial_results %}
501
- <div class="section" id="analysis">
502
- <h2>Detailed Analysis Results</h2>
503
- {% for key, value in partial_results.items() %}
504
- {% if key not in ['traces'] %}
505
- <div class="card">
506
- <div class="card-header">{{ key|replace('_', ' ')|title }}</div>
507
- <p>{{ value }}</p>
508
- </div>
509
- {% endif %}
480
+ {% endfor %}
481
+ </div>
482
+ {% endif %}
483
+
484
+ <!-- Generated Artifacts -->
485
+ {% if artifacts %}
486
+ <div class="section" id="artifacts">
487
+ <h2>Generated Artifacts</h2>
488
+ <div class="card">
489
+ <p>The following artifacts were generated and can be used for further analysis:</p>
490
+ <ul class="artifacts-list">
491
+ {% for artifact in artifacts %}
492
+ <li>
493
+ <strong>{{ artifact.name }}</strong><br />
494
+ <code>{{ artifact.path }}</code>
495
+ </li>
510
496
  {% endfor %}
497
+ </ul>
511
498
  </div>
512
- {% endif %}
513
-
514
- <!-- Warnings -->
515
- {% if warnings %}
516
- <div class="section" id="warnings">
517
- <h2>Warnings and Notes</h2>
518
- {% for warning in warnings %}
519
- <div class="warning">{{ warning }}</div>
520
- {% endfor %}
499
+ </div>
500
+ {% endif %}
501
+
502
+ <!-- Detailed Analysis -->
503
+ {% if partial_results %}
504
+ <div class="section" id="analysis">
505
+ <h2>Detailed Analysis Results</h2>
506
+ {% for key, value in partial_results.items() %} {% if key not in ['traces'] %}
507
+ <div class="card">
508
+ <div class="card-header">{{ key|replace('_', ' ')|title }}</div>
509
+ <p>{{ value }}</p>
521
510
  </div>
522
- {% endif %}
511
+ {% endif %} {% endfor %}
512
+ </div>
513
+ {% endif %}
514
+
515
+ <!-- Warnings -->
516
+ {% if warnings %}
517
+ <div class="section" id="warnings">
518
+ <h2>Warnings and Notes</h2>
519
+ {% for warning in warnings %}
520
+ <div class="warning">{{ warning }}</div>
521
+ {% endfor %}
522
+ </div>
523
+ {% endif %}
523
524
  </div>
524
- </body>
525
+ </body>
525
526
  </html>