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,181 +1,172 @@
1
- <!DOCTYPE html>
1
+ <!doctype html>
2
2
  <html lang="en" data-theme="{{ theme }}">
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>{% block title %}{{ title }}{% endblock %}</title>
7
7
 
8
8
  <!-- Bootstrap CSS -->
9
- <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
9
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
10
10
 
11
11
  <!-- Bootstrap Icons -->
12
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css">
12
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css" />
13
13
 
14
14
  <!-- Plotly.js for waveform visualization -->
15
15
  <script src="https://cdn.plot.ly/plotly-2.26.0.min.js"></script>
16
16
 
17
17
  <style>
18
- :root[data-theme="dark"] {
19
- --bs-body-bg: #1a1a1a;
20
- --bs-body-color: #e0e0e0;
21
- --bs-border-color: #333;
22
- --bs-card-bg: #2a2a2a;
23
- --bs-primary: #00d9ff;
24
- --bs-secondary: #6c757d;
25
- --bs-success: #28a745;
26
- --bs-danger: #dc3545;
27
- }
28
-
29
- :root[data-theme="light"] {
30
- --bs-body-bg: #ffffff;
31
- --bs-body-color: #212529;
32
- --bs-border-color: #dee2e6;
33
- --bs-card-bg: #f8f9fa;
34
- --bs-primary: #0d6efd;
35
- --bs-secondary: #6c757d;
36
- --bs-success: #28a745;
37
- --bs-danger: #dc3545;
38
- }
39
-
40
- body {
41
- background-color: var(--bs-body-bg);
42
- color: var(--bs-body-color);
43
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
44
- }
45
-
46
- .navbar {
47
- background-color: var(--bs-card-bg);
48
- border-bottom: 1px solid var(--bs-border-color);
49
- }
50
-
51
- .card {
52
- background-color: var(--bs-card-bg);
53
- border: 1px solid var(--bs-border-color);
54
- }
55
-
56
- .btn-primary {
57
- background-color: var(--bs-primary);
58
- border-color: var(--bs-primary);
59
- }
60
-
61
- .dropzone {
62
- border: 2px dashed var(--bs-border-color);
63
- border-radius: 8px;
64
- padding: 40px;
65
- text-align: center;
66
- cursor: pointer;
67
- transition: all 0.3s ease;
68
- }
69
-
70
- .dropzone:hover, .dropzone.drag-over {
71
- border-color: var(--bs-primary);
72
- background-color: rgba(0, 217, 255, 0.1);
73
- }
74
-
75
- .progress-indicator {
76
- position: fixed;
77
- top: 50%;
78
- left: 50%;
79
- transform: translate(-50%, -50%);
80
- z-index: 9999;
81
- }
82
-
83
- .session-status {
84
- display: inline-block;
85
- padding: 4px 12px;
86
- border-radius: 4px;
87
- font-size: 0.85em;
88
- font-weight: 500;
89
- }
90
-
91
- .status-processing {
92
- background-color: rgba(255, 193, 7, 0.2);
93
- color: #ffc107;
94
- }
95
-
96
- .status-complete {
97
- background-color: rgba(40, 167, 69, 0.2);
98
- color: #28a745;
99
- }
100
-
101
- .status-error {
102
- background-color: rgba(220, 53, 69, 0.2);
103
- color: #dc3545;
104
- }
18
+ :root[data-theme='dark'] {
19
+ --bs-body-bg: #1a1a1a;
20
+ --bs-body-color: #e0e0e0;
21
+ --bs-border-color: #333;
22
+ --bs-card-bg: #2a2a2a;
23
+ --bs-primary: #00d9ff;
24
+ --bs-secondary: #6c757d;
25
+ --bs-success: #28a745;
26
+ --bs-danger: #dc3545;
27
+ }
28
+
29
+ :root[data-theme='light'] {
30
+ --bs-body-bg: #ffffff;
31
+ --bs-body-color: #212529;
32
+ --bs-border-color: #dee2e6;
33
+ --bs-card-bg: #f8f9fa;
34
+ --bs-primary: #0d6efd;
35
+ --bs-secondary: #6c757d;
36
+ --bs-success: #28a745;
37
+ --bs-danger: #dc3545;
38
+ }
39
+
40
+ body {
41
+ background-color: var(--bs-body-bg);
42
+ color: var(--bs-body-color);
43
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
44
+ }
45
+
46
+ .navbar {
47
+ background-color: var(--bs-card-bg);
48
+ border-bottom: 1px solid var(--bs-border-color);
49
+ }
50
+
51
+ .card {
52
+ background-color: var(--bs-card-bg);
53
+ border: 1px solid var(--bs-border-color);
54
+ }
55
+
56
+ .btn-primary {
57
+ background-color: var(--bs-primary);
58
+ border-color: var(--bs-primary);
59
+ }
60
+
61
+ .dropzone {
62
+ border: 2px dashed var(--bs-border-color);
63
+ border-radius: 8px;
64
+ padding: 40px;
65
+ text-align: center;
66
+ cursor: pointer;
67
+ transition: all 0.3s ease;
68
+ }
69
+
70
+ .dropzone:hover,
71
+ .dropzone.drag-over {
72
+ border-color: var(--bs-primary);
73
+ background-color: rgba(0, 217, 255, 0.1);
74
+ }
75
+
76
+ .progress-indicator {
77
+ position: fixed;
78
+ top: 50%;
79
+ left: 50%;
80
+ transform: translate(-50%, -50%);
81
+ z-index: 9999;
82
+ }
83
+
84
+ .session-status {
85
+ display: inline-block;
86
+ padding: 4px 12px;
87
+ border-radius: 4px;
88
+ font-size: 0.85em;
89
+ font-weight: 500;
90
+ }
91
+
92
+ .status-processing {
93
+ background-color: rgba(255, 193, 7, 0.2);
94
+ color: #ffc107;
95
+ }
96
+
97
+ .status-complete {
98
+ background-color: rgba(40, 167, 69, 0.2);
99
+ color: #28a745;
100
+ }
101
+
102
+ .status-error {
103
+ background-color: rgba(220, 53, 69, 0.2);
104
+ color: #dc3545;
105
+ }
105
106
  </style>
106
107
 
107
108
  {% block extra_head %}{% endblock %}
108
- </head>
109
- <body>
109
+ </head>
110
+ <body>
110
111
  <!-- Navigation -->
111
112
  <nav class="navbar navbar-expand-lg sticky-top">
112
- <div class="container-fluid">
113
- <a class="navbar-brand" href="/">
114
- <i class="bi bi-cpu"></i> Oscura Dashboard
115
- </a>
116
- <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
117
- <span class="navbar-toggler-icon"></span>
113
+ <div class="container-fluid">
114
+ <a class="navbar-brand" href="/"> <i class="bi bi-cpu"></i> Oscura Dashboard </a>
115
+ <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
116
+ <span class="navbar-toggler-icon"></span>
117
+ </button>
118
+ <div class="collapse navbar-collapse" id="navbarNav">
119
+ <ul class="navbar-nav me-auto">
120
+ <li class="nav-item">
121
+ <a class="nav-link" href="/"> <i class="bi bi-house"></i> Home </a>
122
+ </li>
123
+ <li class="nav-item">
124
+ <a class="nav-link" href="/sessions"> <i class="bi bi-list-task"></i> Sessions </a>
125
+ </li>
126
+ <li class="nav-item">
127
+ <a class="nav-link" href="/protocols"> <i class="bi bi-diagram-3"></i> Protocols </a>
128
+ </li>
129
+ </ul>
130
+ <div class="d-flex">
131
+ <button class="btn btn-outline-secondary btn-sm" onclick="toggleTheme()">
132
+ <i class="bi bi-moon-stars" id="theme-icon"></i>
118
133
  </button>
119
- <div class="collapse navbar-collapse" id="navbarNav">
120
- <ul class="navbar-nav me-auto">
121
- <li class="nav-item">
122
- <a class="nav-link" href="/">
123
- <i class="bi bi-house"></i> Home
124
- </a>
125
- </li>
126
- <li class="nav-item">
127
- <a class="nav-link" href="/sessions">
128
- <i class="bi bi-list-task"></i> Sessions
129
- </a>
130
- </li>
131
- <li class="nav-item">
132
- <a class="nav-link" href="/protocols">
133
- <i class="bi bi-diagram-3"></i> Protocols
134
- </a>
135
- </li>
136
- </ul>
137
- <div class="d-flex">
138
- <button class="btn btn-outline-secondary btn-sm" onclick="toggleTheme()">
139
- <i class="bi bi-moon-stars" id="theme-icon"></i>
140
- </button>
141
- </div>
142
- </div>
134
+ </div>
143
135
  </div>
136
+ </div>
144
137
  </nav>
145
138
 
146
139
  <!-- Main Content -->
147
- <main class="container-fluid py-4">
148
- {% block content %}{% endblock %}
149
- </main>
140
+ <main class="container-fluid py-4">{% block content %}{% endblock %}</main>
150
141
 
151
142
  <!-- Bootstrap JS -->
152
143
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
153
144
 
154
145
  <!-- Theme Toggle -->
155
146
  <script>
156
- function toggleTheme() {
157
- const html = document.documentElement;
158
- const currentTheme = html.getAttribute('data-theme');
159
- const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
160
- html.setAttribute('data-theme', newTheme);
147
+ function toggleTheme() {
148
+ const html = document.documentElement;
149
+ const currentTheme = html.getAttribute('data-theme');
150
+ const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
151
+ html.setAttribute('data-theme', newTheme);
161
152
 
162
- // Update icon
163
- const icon = document.getElementById('theme-icon');
164
- icon.className = newTheme === 'dark' ? 'bi bi-moon-stars' : 'bi bi-sun';
153
+ // Update icon
154
+ const icon = document.getElementById('theme-icon');
155
+ icon.className = newTheme === 'dark' ? 'bi bi-moon-stars' : 'bi bi-sun';
165
156
 
166
- // Save preference
167
- localStorage.setItem('theme', newTheme);
168
- }
157
+ // Save preference
158
+ localStorage.setItem('theme', newTheme);
159
+ }
169
160
 
170
- // Load saved theme preference
171
- const savedTheme = localStorage.getItem('theme') || '{{ theme }}';
172
- document.documentElement.setAttribute('data-theme', savedTheme);
161
+ // Load saved theme preference
162
+ const savedTheme = localStorage.getItem('theme') || '{{ theme }}';
163
+ document.documentElement.setAttribute('data-theme', savedTheme);
173
164
 
174
- // Update icon
175
- const icon = document.getElementById('theme-icon');
176
- icon.className = savedTheme === 'dark' ? 'bi bi-moon-stars' : 'bi bi-sun';
165
+ // Update icon
166
+ const icon = document.getElementById('theme-icon');
167
+ icon.className = savedTheme === 'dark' ? 'bi bi-moon-stars' : 'bi bi-sun';
177
168
  </script>
178
169
 
179
170
  {% block extra_scripts %}{% endblock %}
180
- </body>
171
+ </body>
181
172
  </html>
@@ -1,120 +1,94 @@
1
- {% extends "base.html" %}
2
-
3
- {% block title %}Export - {{ title }}{% endblock %}
4
-
5
- {% block content %}
1
+ {% extends "base.html" %} {% block title %}Export - {{ title }}{% endblock %} {% block content %}
6
2
  <div class="row">
7
- <div class="col-lg-8 offset-lg-2">
8
- <div class="card">
9
- <div class="card-body">
10
- <h2 class="card-title mb-4">
11
- <i class="bi bi-download"></i> Export & Download
12
- </h2>
13
-
14
- <p class="lead">Download generated artifacts for protocol analysis tools.</p>
15
-
16
- <hr>
3
+ <div class="col-lg-8 offset-lg-2">
4
+ <div class="card">
5
+ <div class="card-body">
6
+ <h2 class="card-title mb-4"><i class="bi bi-download"></i> Export & Download</h2>
17
7
 
18
- <div class="row g-3">
19
- {% if artifacts.dissector_path %}
20
- <div class="col-md-6">
21
- <div class="card h-100">
22
- <div class="card-body">
23
- <h5 class="card-title">
24
- <i class="bi bi-puzzle"></i> Wireshark Dissector
25
- </h5>
26
- <p class="card-text">Lua dissector for Wireshark protocol analysis</p>
27
- <a href="/api/download/{{ session_id }}/dissector" class="btn btn-primary">
28
- <i class="bi bi-download"></i> Download
29
- </a>
30
- </div>
31
- </div>
32
- </div>
33
- {% endif %}
8
+ <p class="lead">Download generated artifacts for protocol analysis tools.</p>
34
9
 
35
- {% if artifacts.scapy_layer_path %}
36
- <div class="col-md-6">
37
- <div class="card h-100">
38
- <div class="card-body">
39
- <h5 class="card-title">
40
- <i class="bi bi-code-slash"></i> Scapy Layer
41
- </h5>
42
- <p class="card-text">Python Scapy layer for packet manipulation</p>
43
- <a href="/api/download/{{ session_id }}/scapy" class="btn btn-primary">
44
- <i class="bi bi-download"></i> Download
45
- </a>
46
- </div>
47
- </div>
48
- </div>
49
- {% endif %}
10
+ <hr />
50
11
 
51
- {% if artifacts.kaitai_path %}
52
- <div class="col-md-6">
53
- <div class="card h-100">
54
- <div class="card-body">
55
- <h5 class="card-title">
56
- <i class="bi bi-file-binary"></i> Kaitai Struct
57
- </h5>
58
- <p class="card-text">Binary parser definition for multiple languages</p>
59
- <a href="/api/download/{{ session_id }}/kaitai" class="btn btn-primary">
60
- <i class="bi bi-download"></i> Download
61
- </a>
62
- </div>
63
- </div>
64
- </div>
65
- {% endif %}
66
-
67
- {% if artifacts.test_vectors_path %}
68
- <div class="col-md-6">
69
- <div class="card h-100">
70
- <div class="card-body">
71
- <h5 class="card-title">
72
- <i class="bi bi-check2-square"></i> Test Vectors
73
- </h5>
74
- <p class="card-text">Generated test cases for protocol validation</p>
75
- <a href="/api/download/{{ session_id }}/tests" class="btn btn-primary">
76
- <i class="bi bi-download"></i> Download
77
- </a>
78
- </div>
79
- </div>
80
- </div>
81
- {% endif %}
82
-
83
- {% if artifacts.report_path %}
84
- <div class="col-md-6">
85
- <div class="card h-100">
86
- <div class="card-body">
87
- <h5 class="card-title">
88
- <i class="bi bi-file-text"></i> Analysis Report
89
- </h5>
90
- <p class="card-text">Comprehensive analysis report (HTML/PDF)</p>
91
- <a href="/api/download/{{ session_id }}/report" class="btn btn-primary">
92
- <i class="bi bi-download"></i> Download
93
- </a>
94
- </div>
95
- </div>
96
- </div>
97
- {% endif %}
98
-
99
- {% if not artifacts %}
100
- <div class="col-12">
101
- <div class="alert alert-warning">
102
- <i class="bi bi-exclamation-triangle"></i>
103
- No artifacts available yet. Analysis may still be in progress or incomplete.
104
- </div>
105
- </div>
106
- {% endif %}
107
- </div>
12
+ <div class="row g-3">
13
+ {% if artifacts.dissector_path %}
14
+ <div class="col-md-6">
15
+ <div class="card h-100">
16
+ <div class="card-body">
17
+ <h5 class="card-title"><i class="bi bi-puzzle"></i> Wireshark Dissector</h5>
18
+ <p class="card-text">Lua dissector for Wireshark protocol analysis</p>
19
+ <a href="/api/download/{{ session_id }}/dissector" class="btn btn-primary">
20
+ <i class="bi bi-download"></i> Download
21
+ </a>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ {% endif %} {% if artifacts.scapy_layer_path %}
26
+ <div class="col-md-6">
27
+ <div class="card h-100">
28
+ <div class="card-body">
29
+ <h5 class="card-title"><i class="bi bi-code-slash"></i> Scapy Layer</h5>
30
+ <p class="card-text">Python Scapy layer for packet manipulation</p>
31
+ <a href="/api/download/{{ session_id }}/scapy" class="btn btn-primary">
32
+ <i class="bi bi-download"></i> Download
33
+ </a>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ {% endif %} {% if artifacts.kaitai_path %}
38
+ <div class="col-md-6">
39
+ <div class="card h-100">
40
+ <div class="card-body">
41
+ <h5 class="card-title"><i class="bi bi-file-binary"></i> Kaitai Struct</h5>
42
+ <p class="card-text">Binary parser definition for multiple languages</p>
43
+ <a href="/api/download/{{ session_id }}/kaitai" class="btn btn-primary">
44
+ <i class="bi bi-download"></i> Download
45
+ </a>
46
+ </div>
47
+ </div>
48
+ </div>
49
+ {% endif %} {% if artifacts.test_vectors_path %}
50
+ <div class="col-md-6">
51
+ <div class="card h-100">
52
+ <div class="card-body">
53
+ <h5 class="card-title"><i class="bi bi-check2-square"></i> Test Vectors</h5>
54
+ <p class="card-text">Generated test cases for protocol validation</p>
55
+ <a href="/api/download/{{ session_id }}/tests" class="btn btn-primary">
56
+ <i class="bi bi-download"></i> Download
57
+ </a>
58
+ </div>
59
+ </div>
60
+ </div>
61
+ {% endif %} {% if artifacts.report_path %}
62
+ <div class="col-md-6">
63
+ <div class="card h-100">
64
+ <div class="card-body">
65
+ <h5 class="card-title"><i class="bi bi-file-text"></i> Analysis Report</h5>
66
+ <p class="card-text">Comprehensive analysis report (HTML/PDF)</p>
67
+ <a href="/api/download/{{ session_id }}/report" class="btn btn-primary">
68
+ <i class="bi bi-download"></i> Download
69
+ </a>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ {% endif %} {% if not artifacts %}
74
+ <div class="col-12">
75
+ <div class="alert alert-warning">
76
+ <i class="bi bi-exclamation-triangle"></i>
77
+ No artifacts available yet. Analysis may still be in progress or incomplete.
78
+ </div>
79
+ </div>
80
+ {% endif %}
81
+ </div>
108
82
 
109
- <hr class="mt-4">
83
+ <hr class="mt-4" />
110
84
 
111
- <div class="d-grid gap-2">
112
- <a href="/session/{{ session_id }}" class="btn btn-outline-secondary">
113
- <i class="bi bi-arrow-left"></i> Back to Session
114
- </a>
115
- </div>
116
- </div>
85
+ <div class="d-grid gap-2">
86
+ <a href="/session/{{ session_id }}" class="btn btn-outline-secondary">
87
+ <i class="bi bi-arrow-left"></i> Back to Session
88
+ </a>
117
89
  </div>
90
+ </div>
118
91
  </div>
92
+ </div>
119
93
  </div>
120
94
  {% endblock %}