Skylorjustine commited on
Commit
3e5f0a6
·
verified ·
1 Parent(s): 0a7a837

Upload 5 files

Browse files
Files changed (5) hide show
  1. README_DOCUVERSE.md +84 -0
  2. app.py +1519 -0
  3. requirements.txt +17 -0
  4. run.bat +58 -0
  5. run.sh +101 -0
README_DOCUVERSE.md ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # DocuVerse AI Guide
2
+
3
+ A modern PDF/text analysis and summarization app built with Streamlit.
4
+
5
+ ## What’s inside
6
+ - Document upload and text input (5000-word limit for input text)
7
+ - Analysis: word/sentence counts, complexity index, reading-time estimate, and key phrases
8
+ - Summarization: styles (Executive, Academic, Bullet/Key Points, Narrative, Technical) and approaches (Extractive, Abstractive, Hybrid)
9
+ - Q&A: document-grounded answers only
10
+ - Download summaries as TXT or PDF-mime
11
+
12
+ ## How summarization works (in code)
13
+ The summarization logic is in `app.py` under the class `QuantumSummarizer`.
14
+
15
+ - Entry point: `quantum_summarize(text, style, sentences, summary_type)`
16
+ - Chooses a path based on `summary_type`: `extractive`, `abstractive`, or `hybrid`.
17
+
18
+ - Extractive (`_extractive_summary`):
19
+ 1. Split text into sentences and compute a score per sentence via `_quantum_score`.
20
+ 2. `_quantum_score` blends:
21
+ - length_score: prefers informative lengths
22
+ - pos_score: favors early sentences (lead-bias for overviews)
23
+ - freq_score: term-frequency emphasis using `_quantum_frequency_analysis` over the whole doc
24
+ 3. Style-specific weighting via `_apply_quantum_weights` (e.g., executive favors early content, bullet favors shorter, punchy lines).
25
+ 4. Pick top-N scored sentences, restore original order, and join them.
26
+
27
+ - Abstractive (`_abstractive_summary`):
28
+ 1. Extract key concepts with `_extract_key_concepts` (term frequency without common stop words).
29
+ 2. Rank sentences by concept density with `_concept_score`.
30
+ 3. Create a compressed/abstracted version of the best sentences via `_abstract_sentence` by simplifying structure while preserving key terms.
31
+
32
+ - Hybrid (`_hybrid_summary`):
33
+ 1. Generate an extractive summary (signal preservation).
34
+ 2. Generate an abstractive summary (compression and smoothing).
35
+ 3. Merge and deduplicate with `_optimize_hybrid_summary` to remove redundancy and cap length.
36
+
37
+ All paths return a dictionary like:
38
+ ```
39
+ {"summary": str, "confidence": float, "method": str, "type": str}
40
+ ```
41
+
42
+ ## How Q&A is retrieved
43
+ Q&A lives in `NeuroQA` (also in `app.py`). It is strictly document-grounded.
44
+
45
+ - Input: `question` + `document` (the extracted or pasted text)
46
+ - Context retrieval (`_discover_neural_contexts`):
47
+ 1. Split the document into sentences and build sliding windows (3-sentence chunks).
48
+ 2. Compute lexical overlap between question terms and each chunk.
49
+ 3. Keep the highest-overlap chunks sorted by score (top 3).
50
+ - Answer synthesis (`neural_answer`):
51
+ 1. Take the best chunk and split into sentences.
52
+ 2. Select the sentence with the largest word-overlap with the question as the answer (fallbacks to first sentence if needed).
53
+ 3. Report a confidence derived from the retrieval score.
54
+
55
+ This approach ensures answers are drawn only from the provided document text. If no overlap is found, the system responds accordingly.
56
+
57
+ ## Running the app
58
+ ```bash
59
+ pip install -r requirements.txt
60
+ streamlit run app.py
61
+ ```
62
+
63
+ ## Usage flow
64
+ 1. Document Upload or Text Input
65
+ 2. Analysis → review stats and key phrases
66
+ 3. Summary → choose Style + Approach, set Length → Generate Summary → Download
67
+ 4. Q&A → ask a question → get a grounded answer
68
+
69
+ ## Notes
70
+ - The “Engine” UI for external models is disabled by default to maximize portability. The built-in summarizer is fast and offline.
71
+ - PDF downloads are provided with text MIME for portability. Use a PDF generator (e.g., ReportLab) if you need fully formatted PDFs.
72
+
73
+ ## File layout
74
+ ```
75
+ DOCUVERSE AI/
76
+ ├── app.py
77
+ ├── requirements.txt
78
+ ├── run.sh / run.bat
79
+ └── README.md (this guide)
80
+ ```
81
+
82
+ ## License
83
+ © 2025 Justine & Krishna. All Rights Reserved.
84
+ DocuVerse AI – Revolutionary PDF Intelligence Platform
app.py ADDED
@@ -0,0 +1,1519 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ 🌟 DOCUVERSE AI 🌟
4
+ Revolutionary PDF Assistant with stunning design and proper footer
5
+ Copyright © 2025 Justine & Krishna. All Rights Reserved.
6
+ """
7
+
8
+ import streamlit as st
9
+ import PyPDF2
10
+ import re
11
+ import time
12
+ import hashlib
13
+ from datetime import datetime
14
+ from typing import Dict, List, Tuple
15
+ import io
16
+ import base64
17
+
18
+ # Page Configuration
19
+ st.set_page_config(
20
+ page_title="DocuVerse AI - Revolutionary PDF Assistant",
21
+ page_icon="",
22
+ layout="wide"
23
+ )
24
+
25
+ def load_revolutionary_css():
26
+ """Load the most stunning CSS ever created"""
27
+ st.markdown("""
28
+ <style>
29
+ @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@300;400;700;900&family=Rajdhani:wght@300;400;600;700&family=Space+Mono:wght@400;700&display=swap');
30
+
31
+ /* Global Styles */
32
+ .stApp {
33
+ background: linear-gradient(135deg, #0F0C29 0%, #24243e 30%, #302B63 70%, #0F0C29 100%);
34
+ background-attachment: fixed;
35
+ color: #E2E8F0;
36
+ font-family: 'Rajdhani', sans-serif;
37
+ }
38
+
39
+ /* Hide Streamlit Elements */
40
+ #MainMenu {visibility: hidden;}
41
+ footer {visibility: hidden;}
42
+ .stDeployButton {display: none;}
43
+
44
+ /* Main Title */
45
+ .main-title {
46
+ font-family: 'Orbitron', monospace;
47
+ font-size: 4.5rem;
48
+ font-weight: 900;
49
+ background: linear-gradient(45deg, #FF6B6B, #4ECDC4, #45B7D1, #96CEB4, #FFEAA7, #FF6B6B);
50
+ background-size: 400% 400%;
51
+ -webkit-background-clip: text;
52
+ -webkit-text-fill-color: transparent;
53
+ background-clip: text;
54
+ animation: gradientFlow 4s ease-in-out infinite;
55
+ text-align: center;
56
+ margin: 2rem 0;
57
+ letter-spacing: 4px;
58
+ text-shadow: 0 0 50px rgba(255, 107, 107, 0.3);
59
+ position: relative;
60
+ }
61
+
62
+ .main-title::after {
63
+ content: '';
64
+ position: absolute;
65
+ bottom: -10px;
66
+ left: 50%;
67
+ transform: translateX(-50%);
68
+ width: 200px;
69
+ height: 3px;
70
+ background: linear-gradient(90deg, transparent, #4ECDC4, transparent);
71
+ animation: lineGlow 2s ease-in-out infinite;
72
+ }
73
+
74
+ @keyframes gradientFlow {
75
+ 0% { background-position: 0% 50%; }
76
+ 50% { background-position: 100% 50%; }
77
+ 100% { background-position: 0% 50%; }
78
+ }
79
+
80
+ @keyframes lineGlow {
81
+ 0%, 100% { opacity: 0.3; width: 100px; }
82
+ 50% { opacity: 1; width: 300px; }
83
+ }
84
+
85
+ .subtitle {
86
+ font-family: 'Rajdhani', sans-serif;
87
+ font-size: 1.6rem;
88
+ font-weight: 300;
89
+ color: #A8A8B3;
90
+ text-align: center;
91
+ margin-bottom: 3rem;
92
+ text-transform: uppercase;
93
+ letter-spacing: 3px;
94
+ }
95
+
96
+ /* Navigation Bar */
97
+ .nav-container {
98
+ display: flex;
99
+ justify-content: center;
100
+ margin: 3rem 0;
101
+ padding: 0 2rem;
102
+ }
103
+
104
+ .nav-bar {
105
+ display: flex;
106
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.02) 100%);
107
+ backdrop-filter: blur(20px);
108
+ border-radius: 25px;
109
+ border: 1px solid rgba(255, 255, 255, 0.1);
110
+ padding: 8px;
111
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.1);
112
+ position: relative;
113
+ overflow: hidden;
114
+ }
115
+
116
+ .nav-bar::before {
117
+ content: '';
118
+ position: absolute;
119
+ top: 0;
120
+ left: -100%;
121
+ width: 100%;
122
+ height: 100%;
123
+ background: linear-gradient(90deg, transparent, rgba(78, 205, 196, 0.2), transparent);
124
+ animation: navScan 3s linear infinite;
125
+ }
126
+
127
+ @keyframes navScan {
128
+ 0% { left: -100%; }
129
+ 100% { left: 100%; }
130
+ }
131
+
132
+ .nav-item {
133
+ position: relative;
134
+ margin: 0 4px;
135
+ border-radius: 20px;
136
+ overflow: hidden;
137
+ transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
138
+ }
139
+
140
+ .nav-button {
141
+ display: flex;
142
+ align-items: center;
143
+ justify-content: center;
144
+ padding: 18px 32px;
145
+ background: transparent;
146
+ border: none;
147
+ color: #A8A8B3;
148
+ font-family: 'Rajdhani', sans-serif;
149
+ font-size: 1.1rem;
150
+ font-weight: 600;
151
+ text-transform: uppercase;
152
+ letter-spacing: 1.5px;
153
+ cursor: pointer;
154
+ transition: all 0.4s ease;
155
+ position: relative;
156
+ min-width: 180px;
157
+ border-radius: 20px;
158
+ }
159
+
160
+ .nav-button::before {
161
+ content: '';
162
+ position: absolute;
163
+ top: 0;
164
+ left: 0;
165
+ width: 100%;
166
+ height: 100%;
167
+ background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.05) 50%, transparent 70%);
168
+ transform: translateX(-100%) skew(-10deg);
169
+ transition: transform 0.6s;
170
+ }
171
+
172
+ .nav-button:hover::before {
173
+ transform: translateX(100%) skew(-10deg);
174
+ }
175
+
176
+ .nav-button .icon {
177
+ font-size: 1.4rem;
178
+ margin-right: 12px;
179
+ transition: all 0.3s ease;
180
+ }
181
+
182
+ .nav-button:hover {
183
+ transform: translateY(-3px);
184
+ color: white;
185
+ }
186
+
187
+ .nav-button:hover .icon {
188
+ transform: scale(1.2) rotateZ(5deg);
189
+ }
190
+
191
+ /* Tab Active States */
192
+ .upload-active .nav-button {
193
+ background: linear-gradient(135deg, #FF6B6B 0%, #FF8E8E 100%);
194
+ color: white;
195
+ box-shadow: 0 15px 35px rgba(255, 107, 107, 0.4);
196
+ }
197
+
198
+ .analysis-active .nav-button {
199
+ background: linear-gradient(135deg, #4ECDC4 0%, #44A08D 100%);
200
+ color: white;
201
+ box-shadow: 0 15px 35px rgba(78, 205, 196, 0.4);
202
+ }
203
+
204
+ .summary-active .nav-button {
205
+ background: linear-gradient(135deg, #FFEAA7 0%, #FFD93D 100%);
206
+ color: #2D3748;
207
+ box-shadow: 0 15px 35px rgba(255, 234, 167, 0.4);
208
+ }
209
+
210
+ .qa-active .nav-button {
211
+ background: linear-gradient(135deg, #96CEB4 0%, #ABEBC6 100%);
212
+ color: #2D3748;
213
+ box-shadow: 0 15px 35px rgba(150, 206, 180, 0.4);
214
+ }
215
+
216
+ /* Content Sections */
217
+ .content-section {
218
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.01) 100%);
219
+ backdrop-filter: blur(15px);
220
+ border-radius: 25px;
221
+ border: 1px solid rgba(255, 255, 255, 0.1);
222
+ padding: 3rem;
223
+ margin: 2rem 0;
224
+ box-shadow: 0 25px 50px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.1);
225
+ position: relative;
226
+ overflow: hidden;
227
+ }
228
+
229
+ .content-section::before {
230
+ content: '';
231
+ position: absolute;
232
+ top: 0;
233
+ left: 0;
234
+ right: 0;
235
+ height: 2px;
236
+ background: linear-gradient(90deg, transparent, #4ECDC4, transparent);
237
+ animation: topGlow 2s ease-in-out infinite;
238
+ }
239
+
240
+ @keyframes topGlow {
241
+ 0%, 100% { opacity: 0.3; }
242
+ 50% { opacity: 1; }
243
+ }
244
+
245
+ .section-title {
246
+ font-family: 'Orbitron', monospace;
247
+ font-size: 2.5rem;
248
+ font-weight: 700;
249
+ background: linear-gradient(135deg, #4ECDC4, #45B7D1);
250
+ -webkit-background-clip: text;
251
+ -webkit-text-fill-color: transparent;
252
+ background-clip: text;
253
+ margin-bottom: 2rem;
254
+ text-align: center;
255
+ letter-spacing: 2px;
256
+ }
257
+
258
+ /* Cyber Cards */
259
+ .cyber-card {
260
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.02) 100%);
261
+ backdrop-filter: blur(12px);
262
+ border-radius: 20px;
263
+ border: 1px solid rgba(255, 255, 255, 0.15);
264
+ padding: 2rem;
265
+ margin: 1.5rem 0;
266
+ box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.1);
267
+ transition: all 0.4s ease;
268
+ position: relative;
269
+ overflow: hidden;
270
+ }
271
+
272
+ .cyber-card::after {
273
+ content: '';
274
+ position: absolute;
275
+ top: 0;
276
+ left: -100%;
277
+ width: 100%;
278
+ height: 100%;
279
+ background: linear-gradient(90deg, transparent, rgba(78, 205, 196, 0.1), transparent);
280
+ transition: left 0.8s ease;
281
+ }
282
+
283
+ .cyber-card:hover::after {
284
+ left: 100%;
285
+ }
286
+
287
+ .cyber-card:hover {
288
+ transform: translateY(-8px) scale(1.02);
289
+ box-shadow: 0 25px 60px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(78, 205, 196, 0.2);
290
+ }
291
+
292
+ /* Metrics */
293
+ .metrics-grid {
294
+ display: grid;
295
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
296
+ gap: 1.5rem;
297
+ margin: 2rem 0;
298
+ }
299
+
300
+ .metric-card {
301
+ background: linear-gradient(135deg, rgba(0, 255, 127, 0.08), rgba(0, 191, 255, 0.08));
302
+ border: 1px solid rgba(0, 255, 127, 0.2);
303
+ border-radius: 20px;
304
+ padding: 2rem;
305
+ text-align: center;
306
+ backdrop-filter: blur(10px);
307
+ transition: all 0.3s ease;
308
+ position: relative;
309
+ overflow: hidden;
310
+ }
311
+
312
+ .metric-card::before {
313
+ content: '';
314
+ position: absolute;
315
+ top: -50%;
316
+ left: -50%;
317
+ width: 200%;
318
+ height: 200%;
319
+ background: repeating-linear-gradient(
320
+ 0deg,
321
+ transparent,
322
+ transparent 2px,
323
+ rgba(0, 255, 127, 0.03) 2px,
324
+ rgba(0, 255, 127, 0.03) 4px
325
+ );
326
+ animation: scan 3s linear infinite;
327
+ }
328
+
329
+ @keyframes scan {
330
+ 0% { transform: translateY(0); }
331
+ 100% { transform: translateY(20px); }
332
+ }
333
+
334
+ .metric-card:hover {
335
+ transform: scale(1.05);
336
+ border-color: rgba(0, 255, 127, 0.4);
337
+ box-shadow: 0 20px 40px rgba(0, 255, 127, 0.2);
338
+ }
339
+
340
+ .metric-value {
341
+ font-family: 'Orbitron', monospace;
342
+ font-size: 2.5rem;
343
+ font-weight: 700;
344
+ color: #00FF7F;
345
+ text-shadow: 0 0 20px rgba(0, 255, 127, 0.5);
346
+ margin-bottom: 0.5rem;
347
+ position: relative;
348
+ z-index: 1;
349
+ }
350
+
351
+ .metric-label {
352
+ color: #A8A8B3;
353
+ text-transform: uppercase;
354
+ font-size: 0.9rem;
355
+ font-weight: 600;
356
+ letter-spacing: 1px;
357
+ position: relative;
358
+ z-index: 1;
359
+ }
360
+
361
+ /* Buttons */
362
+ .cyber-button {
363
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
364
+ border: none;
365
+ border-radius: 15px;
366
+ padding: 1rem 2.5rem;
367
+ color: white;
368
+ font-family: 'Rajdhani', sans-serif;
369
+ font-size: 1.1rem;
370
+ font-weight: 600;
371
+ text-transform: uppercase;
372
+ letter-spacing: 1px;
373
+ cursor: pointer;
374
+ transition: all 0.3s ease;
375
+ position: relative;
376
+ overflow: hidden;
377
+ box-shadow: 0 15px 35px rgba(102, 126, 234, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2);
378
+ }
379
+
380
+ .cyber-button::before {
381
+ content: '';
382
+ position: absolute;
383
+ top: 0;
384
+ left: -100%;
385
+ width: 100%;
386
+ height: 100%;
387
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
388
+ transition: left 0.5s;
389
+ }
390
+
391
+ .cyber-button:hover::before {
392
+ left: 100%;
393
+ }
394
+
395
+ .cyber-button:hover {
396
+ transform: translateY(-3px) scale(1.05);
397
+ box-shadow: 0 20px 45px rgba(102, 126, 234, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.3);
398
+ }
399
+
400
+ /* Keyword tags */
401
+ .keyword-tag {
402
+ background: linear-gradient(135deg, #667eea, #764ba2);
403
+ color: white;
404
+ padding: 0.4rem 1rem;
405
+ margin: 0.3rem;
406
+ border-radius: 20px;
407
+ display: inline-block;
408
+ font-size: 0.9rem;
409
+ font-weight: 500;
410
+ transition: all 0.3s ease;
411
+ box-shadow: 0 5px 15px rgba(102, 126, 234, 0.3);
412
+ }
413
+
414
+ .keyword-tag:hover {
415
+ transform: translateY(-2px) scale(1.1);
416
+ box-shadow: 0 10px 25px rgba(102, 126, 234, 0.5);
417
+ }
418
+
419
+ @keyframes pulse {
420
+ 0%, 100% { opacity: 0.8; transform: scale(1); }
421
+ 50% { opacity: 1; transform: scale(1.05); }
422
+ }
423
+
424
+ /* Footer Styles */
425
+ .footer-container {
426
+ text-align: center;
427
+ padding: 4rem 2rem;
428
+ background: linear-gradient(135deg, rgba(15, 12, 41, 0.9), rgba(48, 43, 99, 0.9));
429
+ border-radius: 30px;
430
+ margin: 3rem 0;
431
+ position: relative;
432
+ overflow: hidden;
433
+ border: 1px solid rgba(255, 255, 255, 0.1);
434
+ }
435
+
436
+ .footer-container::before {
437
+ content: '';
438
+ position: absolute;
439
+ top: 0;
440
+ left: 0;
441
+ right: 0;
442
+ height: 3px;
443
+ background: linear-gradient(90deg, #FF6B6B, #4ECDC4, #45B7D1, #96CEB4, #FFEAA7);
444
+ animation: gradientFlow 4s ease-in-out infinite;
445
+ }
446
+
447
+ .footer-title {
448
+ font-family: 'Orbitron', monospace;
449
+ color: #00FF7F;
450
+ margin-bottom: 1.5rem;
451
+ text-shadow: 0 0 20px rgba(0, 255, 127, 0.5);
452
+ font-size: 2.5rem;
453
+ font-weight: 700;
454
+ }
455
+
456
+ .footer-subtitle {
457
+ color: #A8A8B3;
458
+ font-family: 'Rajdhani', sans-serif;
459
+ font-size: 1.3rem;
460
+ margin-bottom: 2rem;
461
+ font-weight: 300;
462
+ }
463
+
464
+ .footer-tags {
465
+ display: flex;
466
+ justify-content: center;
467
+ gap: 2rem;
468
+ flex-wrap: wrap;
469
+ margin: 2rem 0;
470
+ }
471
+
472
+ .footer-tag {
473
+ padding: 1rem 2rem;
474
+ border-radius: 25px;
475
+ font-weight: 600;
476
+ font-size: 1rem;
477
+ transition: all 0.3s ease;
478
+ cursor: pointer;
479
+ }
480
+
481
+ .footer-tag:hover {
482
+ transform: translateY(-5px) scale(1.1);
483
+ }
484
+
485
+ .footer-tag-1 {
486
+ background: linear-gradient(135deg, #FF6B6B, #FF8E8E);
487
+ animation: pulse 2s infinite;
488
+ }
489
+
490
+ .footer-tag-2 {
491
+ background: linear-gradient(135deg, #4ECDC4, #44A08D);
492
+ animation: pulse 2s infinite 0.5s;
493
+ }
494
+
495
+ .footer-tag-3 {
496
+ background: linear-gradient(135deg, #667eea, #764ba2);
497
+ animation: pulse 2s infinite 1s;
498
+ }
499
+
500
+ .footer-tag-4 {
501
+ background: linear-gradient(135deg, #96CEB4, #ABEBC6);
502
+ animation: pulse 2s infinite 1.5s;
503
+ }
504
+
505
+ .footer-copyright {
506
+ color: #6B7280;
507
+ margin-top: 2rem;
508
+ font-size: 0.9rem;
509
+ line-height: 1.6;
510
+ }
511
+
512
+ /* Text and Typography */
513
+ h1, h2, h3, h4 {
514
+ color: #4ECDC4;
515
+ font-family: 'Orbitron', monospace;
516
+ }
517
+
518
+ .cyber-text {
519
+ color: #00FF7F;
520
+ text-shadow: 0 0 10px rgba(0, 255, 127, 0.3);
521
+ font-family: 'Space Mono', monospace;
522
+ }
523
+
524
+ /* Enhanced Sidebar Styles */
525
+ .css-1d391kg {
526
+ background: linear-gradient(135deg, rgba(15, 12, 41, 0.95), rgba(48, 43, 99, 0.95));
527
+ backdrop-filter: blur(20px);
528
+ border-right: 1px solid rgba(78, 205, 196, 0.2);
529
+ }
530
+
531
+ /* Enhanced Text Area */
532
+ .stTextArea > div > div > textarea {
533
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.01));
534
+ border: 2px solid rgba(78, 205, 196, 0.3);
535
+ border-radius: 15px;
536
+ color: #E2E8F0;
537
+ font-family: 'Rajdhani', sans-serif;
538
+ font-size: 1.1rem;
539
+ padding: 1rem;
540
+ transition: all 0.3s ease;
541
+ }
542
+
543
+ .stTextArea > div > div > textarea:focus {
544
+ border-color: #4ECDC4;
545
+ box-shadow: 0 0 20px rgba(78, 205, 196, 0.3);
546
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.02));
547
+ }
548
+
549
+ /* Enhanced Radio Buttons */
550
+ .stRadio > div {
551
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.01));
552
+ border-radius: 15px;
553
+ padding: 1rem;
554
+ border: 1px solid rgba(78, 205, 196, 0.2);
555
+ }
556
+
557
+ /* Enhanced Download Buttons */
558
+ .stDownloadButton > button {
559
+ background: linear-gradient(135deg, #4ECDC4 0%, #44A08D 100%) !important;
560
+ border: none !important;
561
+ border-radius: 15px !important;
562
+ color: white !important;
563
+ font-weight: 600 !important;
564
+ transition: all 0.3s ease !important;
565
+ box-shadow: 0 10px 25px rgba(78, 205, 196, 0.3) !important;
566
+ }
567
+
568
+ .stDownloadButton > button:hover {
569
+ transform: translateY(-2px) scale(1.05) !important;
570
+ box-shadow: 0 15px 35px rgba(78, 205, 196, 0.5) !important;
571
+ }
572
+
573
+ /* Enhanced Code Blocks */
574
+ .stCode {
575
+ background: linear-gradient(135deg, rgba(0, 255, 127, 0.05), rgba(78, 205, 196, 0.05));
576
+ border: 1px solid rgba(0, 255, 127, 0.2);
577
+ border-radius: 10px;
578
+ padding: 1rem;
579
+ }
580
+
581
+ /* Responsive Design */
582
+ @media (max-width: 768px) {
583
+ .main-title {
584
+ font-size: 3rem;
585
+ }
586
+
587
+ .nav-bar {
588
+ flex-direction: column;
589
+ gap: 8px;
590
+ }
591
+
592
+ .nav-button {
593
+ min-width: auto;
594
+ width: 100%;
595
+ }
596
+
597
+ .content-section {
598
+ padding: 2rem 1rem;
599
+ }
600
+
601
+ .metrics-grid {
602
+ grid-template-columns: repeat(2, 1fr);
603
+ }
604
+
605
+ .footer-tags {
606
+ flex-direction: column;
607
+ gap: 1rem;
608
+ }
609
+ }
610
+
611
+ @media (max-width: 480px) {
612
+ .metrics-grid {
613
+ grid-template-columns: 1fr;
614
+ }
615
+ }
616
+
617
+ /* Progress bars and spinners */
618
+ .stProgress > div > div {
619
+ background: linear-gradient(90deg, #667eea, #764ba2);
620
+ border-radius: 10px;
621
+ }
622
+
623
+ /* File uploader styling */
624
+ .uploadedFile {
625
+ background: linear-gradient(135deg, rgba(255, 107, 107, 0.1), rgba(78, 205, 196, 0.1));
626
+ border: 2px dashed rgba(255, 107, 107, 0.3);
627
+ border-radius: 20px;
628
+ padding: 2rem;
629
+ }
630
+
631
+ /* Streamlit button override */
632
+ .stButton > button {
633
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
634
+ border: none !important;
635
+ border-radius: 15px !important;
636
+ padding: 1rem 2.5rem !important;
637
+ color: white !important;
638
+ font-family: 'Rajdhani', sans-serif !important;
639
+ font-size: 1.1rem !important;
640
+ font-weight: 600 !important;
641
+ text-transform: uppercase !important;
642
+ letter-spacing: 1px !important;
643
+ cursor: pointer !important;
644
+ transition: all 0.3s ease !important;
645
+ box-shadow: 0 15px 35px rgba(102, 126, 234, 0.4) !important;
646
+ }
647
+
648
+ .stButton > button:hover {
649
+ transform: translateY(-3px) scale(1.05) !important;
650
+ box-shadow: 0 20px 45px rgba(102, 126, 234, 0.6) !important;
651
+ }
652
+ </style>
653
+ """, unsafe_allow_html=True)
654
+
655
+ class PDFProcessor:
656
+ """Advanced PDF processing with quantum algorithms"""
657
+
658
+ def extract_text(self, pdf_file):
659
+ try:
660
+ pdf_reader = PyPDF2.PdfReader(pdf_file)
661
+ text = ""
662
+
663
+ for page_num, page in enumerate(pdf_reader.pages[:15]):
664
+ page_text = page.extract_text()
665
+ if page_text:
666
+ text += page_text + "\n"
667
+
668
+ # Quantum text cleaning
669
+ text = re.sub(r'\s+', ' ', text)
670
+ text = text.strip()
671
+
672
+ return text
673
+ except Exception as e:
674
+ return f"Quantum extraction error: {str(e)}"
675
+
676
+ def get_advanced_stats(self, text):
677
+ words = text.split()
678
+ sentences = [s.strip() for s in text.split('.') if s.strip()]
679
+ paragraphs = [p.strip() for p in text.split('\n\n') if p.strip()]
680
+
681
+ # Advanced metrics
682
+ long_words = [w for w in words if len(w) > 6]
683
+ complexity = len(long_words) / max(len(words), 1) * 100
684
+
685
+ return {
686
+ 'words': len(words),
687
+ 'sentences': len(sentences),
688
+ 'paragraphs': len(paragraphs),
689
+ 'characters': len(text),
690
+ 'complexity': round(complexity, 1),
691
+ 'unique_words': len(set(word.lower() for word in words)),
692
+ 'reading_time': max(1, len(words) // 200)
693
+ }
694
+
695
+ class QuantumSummarizer:
696
+ """Revolutionary quantum-inspired summarization"""
697
+
698
+ def __init__(self):
699
+ self.styles = {
700
+ 'executive': 'Executive Summary',
701
+ 'academic': 'Academic Abstract',
702
+ 'bullet': 'Key Points',
703
+ 'narrative': 'Story Format',
704
+ 'technical': 'Technical Brief'
705
+ }
706
+
707
+ # Three types of summarization
708
+ self.summary_types = {
709
+ 'extractive': 'Extractive Summary',
710
+ 'abstractive': 'Abstractive Summary',
711
+ 'hybrid': 'Hybrid Summary'
712
+ }
713
+
714
+ def quantum_summarize(self, text, style='executive', sentences=3, summary_type='extractive'):
715
+ if not text:
716
+ return {'summary': 'No quantum data to process', 'confidence': 0}
717
+
718
+ # Quantum sentence extraction
719
+ raw_sentences = [s.strip() for s in text.split('.') if len(s.strip()) > 15]
720
+
721
+ if len(raw_sentences) <= sentences:
722
+ return {
723
+ 'summary': text,
724
+ 'confidence': 100,
725
+ 'method': 'quantum_full',
726
+ 'style': self.styles.get(style),
727
+ 'type': summary_type
728
+ }
729
+
730
+ if summary_type == 'extractive':
731
+ return self._extractive_summary(text, raw_sentences, sentences, style)
732
+ elif summary_type == 'abstractive':
733
+ return self._abstractive_summary(text, raw_sentences, sentences, style)
734
+ elif summary_type == 'hybrid':
735
+ return self._hybrid_summary(text, raw_sentences, sentences, style)
736
+ else:
737
+ return self._extractive_summary(text, raw_sentences, sentences, style)
738
+
739
+ def _extractive_summary(self, text, raw_sentences, sentences, style):
740
+ """Extractive summarization - selects most important sentences"""
741
+ # Quantum scoring algorithm
742
+ scored = []
743
+ for i, sentence in enumerate(raw_sentences):
744
+ score = self._quantum_score(sentence, i, len(raw_sentences), text)
745
+ scored.append((score, sentence, i))
746
+
747
+ # Apply quantum style weights
748
+ styled = self._apply_quantum_weights(scored, style)
749
+
750
+ # Quantum selection
751
+ top = sorted(styled, reverse=True)[:sentences]
752
+ top.sort(key=lambda x: x[2]) # Restore quantum order
753
+
754
+ summary = '. '.join([s[1] for s in top]) + '.'
755
+ confidence = min(100, sum(s[0] for s in top) / len(top) * 100)
756
+
757
+ return {
758
+ 'summary': summary,
759
+ 'confidence': round(confidence, 1),
760
+ 'method': f'extractive_{style}',
761
+ 'style': self.styles.get(style, style),
762
+ 'type': 'extractive'
763
+ }
764
+
765
+ def _abstractive_summary(self, text, raw_sentences, sentences, style):
766
+ """Abstractive summarization - generates new content based on key concepts"""
767
+ # Extract key concepts and phrases
768
+ keywords = self._extract_key_concepts(text)
769
+
770
+ # Find sentences with highest keyword density
771
+ concept_sentences = []
772
+ for sentence in raw_sentences:
773
+ score = self._concept_score(sentence, keywords)
774
+ concept_sentences.append((score, sentence))
775
+
776
+ # Select top sentences and create abstractive summary
777
+ top_sentences = sorted(concept_sentences, reverse=True)[:max(2, sentences//2)]
778
+
779
+ # Generate abstractive content
780
+ summary_parts = []
781
+ for score, sentence in top_sentences:
782
+ # Simplify and abstract the sentence
783
+ abstracted = self._abstract_sentence(sentence, keywords)
784
+ summary_parts.append(abstracted)
785
+
786
+ summary = '. '.join(summary_parts) + '.'
787
+ confidence = min(95, sum(score for score, _ in top_sentences) / len(top_sentences) * 100)
788
+
789
+ return {
790
+ 'summary': summary,
791
+ 'confidence': round(confidence, 1),
792
+ 'method': f'abstractive_{style}',
793
+ 'style': self.styles.get(style, style),
794
+ 'type': 'abstractive'
795
+ }
796
+
797
+ def _hybrid_summary(self, text, raw_sentences, sentences, style):
798
+ """Hybrid summarization - combines extractive and abstractive methods"""
799
+ # Get extractive summary
800
+ extractive_result = self._extractive_summary(text, raw_sentences, sentences//2 + 1, style)
801
+
802
+ # Get abstractive summary
803
+ abstractive_result = self._abstractive_summary(text, raw_sentences, sentences//2 + 1, style)
804
+
805
+ # Combine both approaches
806
+ combined_summary = f"{extractive_result['summary']} {abstractive_result['summary']}"
807
+
808
+ # Clean up and optimize
809
+ combined_summary = self._optimize_hybrid_summary(combined_summary)
810
+
811
+ confidence = (extractive_result['confidence'] + abstractive_result['confidence']) / 2
812
+
813
+ return {
814
+ 'summary': combined_summary,
815
+ 'confidence': round(confidence, 1),
816
+ 'method': f'hybrid_{style}',
817
+ 'style': self.styles.get(style, style),
818
+ 'type': 'hybrid'
819
+ }
820
+
821
+ def _extract_key_concepts(self, text):
822
+ """Extract key concepts from text"""
823
+ words = re.findall(r'\b[a-zA-Z]{4,}\b', text.lower())
824
+ word_freq = {}
825
+ for word in words:
826
+ if word not in {'this', 'that', 'with', 'have', 'will', 'from', 'they', 'been', 'were', 'said'}:
827
+ word_freq[word] = word_freq.get(word, 0) + 1
828
+
829
+ # Return top concepts
830
+ return sorted(word_freq.items(), key=lambda x: x[1], reverse=True)[:10]
831
+
832
+ def _concept_score(self, sentence, keywords):
833
+ """Score sentence based on concept density"""
834
+ sentence_words = set(re.findall(r'\b[a-zA-Z]{4,}\b', sentence.lower()))
835
+ keyword_words = set([word for word, freq in keywords])
836
+
837
+ overlap = len(sentence_words.intersection(keyword_words))
838
+ return overlap / max(len(sentence_words), 1)
839
+
840
+ def _abstract_sentence(self, sentence, keywords):
841
+ """Create abstract version of sentence"""
842
+ # Simple abstraction - keep key concepts, simplify structure
843
+ words = sentence.split()
844
+ key_concepts = [word for word, freq in keywords[:5]]
845
+
846
+ # Keep sentences that contain key concepts
847
+ if any(concept in sentence.lower() for concept in key_concepts):
848
+ # Simplify the sentence
849
+ simplified = ' '.join(words[:min(15, len(words))])
850
+ return simplified
851
+ return sentence
852
+
853
+ def _optimize_hybrid_summary(self, summary):
854
+ """Optimize hybrid summary by removing redundancy"""
855
+ sentences = [s.strip() for s in summary.split('.') if s.strip()]
856
+ unique_sentences = []
857
+
858
+ for sentence in sentences:
859
+ if not any(sentence.lower() in existing.lower() or existing.lower() in sentence.lower()
860
+ for existing in unique_sentences):
861
+ unique_sentences.append(sentence)
862
+
863
+ return '. '.join(unique_sentences[:5]) + '.'
864
+
865
+ def _quantum_score(self, sentence, pos, total, full_text):
866
+ words = sentence.split()
867
+
868
+ # Quantum length optimization
869
+ length_score = min(1.0, len(words) / 20)
870
+
871
+ # Quantum position matrix
872
+ pos_ratio = pos / max(total - 1, 1)
873
+ pos_score = 1.0 - abs(pos_ratio - 0.25) # Quantum preference for early content
874
+
875
+ # Quantum frequency analysis
876
+ freq_score = self._quantum_frequency_analysis(sentence, full_text)
877
+
878
+ # Quantum interference pattern
879
+ return length_score * 0.3 + pos_score * 0.4 + freq_score * 0.3
880
+
881
+ def _quantum_frequency_analysis(self, sentence, full_text):
882
+ sentence_words = set(re.findall(r'\b[a-zA-Z]{4,}\b', sentence.lower()))
883
+ all_words = re.findall(r'\b[a-zA-Z]{4,}\b', full_text.lower())
884
+
885
+ word_freq = {}
886
+ for word in all_words:
887
+ word_freq[word] = word_freq.get(word, 0) + 1
888
+
889
+ quantum_score = 0
890
+ for word in sentence_words:
891
+ if word in word_freq and word_freq[word] > 1:
892
+ quantum_score += min(word_freq[word] / len(all_words) * 100, 1.0)
893
+
894
+ return min(quantum_score / max(len(sentence_words), 1), 1.0)
895
+
896
+ def _apply_quantum_weights(self, scored, style):
897
+ if style == 'bullet':
898
+ return [(s * 1.5 if len(sent.split()) < 15 else s * 0.8, sent, pos)
899
+ for s, sent, pos in scored]
900
+ elif style == 'executive':
901
+ return [(s * 1.4 if pos < len(scored) * 0.3 else s, sent, pos)
902
+ for s, sent, pos in scored]
903
+ elif style == 'academic':
904
+ research_terms = ['study', 'research', 'analysis', 'results', 'findings']
905
+ return [(s * 1.3 if any(term in sent.lower() for term in research_terms) else s, sent, pos)
906
+ for s, sent, pos in scored]
907
+ return scored
908
+
909
+ class NeuroQA:
910
+ """Neural-inspired question answering system"""
911
+
912
+ def neural_answer(self, question, document):
913
+ if not question or not document:
914
+ return {
915
+ 'answer': 'Neural pathways require both question and document data.',
916
+ 'confidence': 0,
917
+ 'method': 'neural_error'
918
+ }
919
+
920
+ # Neural context discovery
921
+ contexts = self._discover_neural_contexts(question, document)
922
+
923
+ if not contexts:
924
+ return {
925
+ 'answer': 'Neural networks found no relevant quantum patterns. Try rephrasing your query.',
926
+ 'confidence': 0,
927
+ 'method': 'neural_no_match'
928
+ }
929
+
930
+ # Neural answer synthesis
931
+ best_context = contexts[0]
932
+ sentences = [s.strip() for s in best_context['text'].split('.') if s.strip()]
933
+
934
+ if not sentences:
935
+ return {'answer': 'Neural processing incomplete.', 'confidence': 0}
936
+
937
+ # Neural sentence matching
938
+ question_words = set(re.findall(r'\b[a-zA-Z]{3,}\b', question.lower()))
939
+ best_sentence = ""
940
+ max_neural_score = 0
941
+
942
+ for sentence in sentences:
943
+ sentence_words = set(re.findall(r'\b[a-zA-Z]{3,}\b', sentence.lower()))
944
+ neural_score = len(question_words.intersection(sentence_words))
945
+
946
+ if neural_score > max_neural_score:
947
+ max_neural_score = neural_score
948
+ best_sentence = sentence
949
+
950
+ if not best_sentence:
951
+ best_sentence = sentences[0]
952
+
953
+ confidence = min(95, best_context['score'] * 100)
954
+
955
+ return {
956
+ 'answer': best_sentence + '.',
957
+ 'confidence': round(confidence, 1),
958
+ 'method': 'neural_synthesis',
959
+ 'neural_pathways': len(contexts)
960
+ }
961
+
962
+ def _discover_neural_contexts(self, question, document):
963
+ sentences = [s.strip() for s in document.split('.') if len(s.strip()) > 10]
964
+ question_words = set(re.findall(r'\b[a-zA-Z]{3,}\b', question.lower()))
965
+
966
+ neural_contexts = []
967
+ window_size = 3
968
+
969
+ for i in range(len(sentences) - window_size + 1):
970
+ context = '. '.join(sentences[i:i + window_size])
971
+ context_words = set(re.findall(r'\b[a-zA-Z]{3,}\b', context.lower()))
972
+
973
+ neural_overlap = len(question_words.intersection(context_words))
974
+ if neural_overlap > 0:
975
+ neural_score = neural_overlap / max(len(question_words), 1)
976
+ if neural_score > 0.2:
977
+ neural_contexts.append({
978
+ 'text': context,
979
+ 'score': neural_score,
980
+ 'overlap': neural_overlap
981
+ })
982
+
983
+ return sorted(neural_contexts, key=lambda x: x['score'], reverse=True)[:3]
984
+
985
+ def extract_quantum_keywords(text, top_k=10):
986
+ """Extract quantum-enhanced keywords"""
987
+ words = re.findall(r'\b[a-zA-Z]{4,}\b', text.lower())
988
+
989
+ quantum_stop_words = {
990
+ 'this', 'that', 'with', 'have', 'will', 'from', 'they', 'been',
991
+ 'were', 'said', 'each', 'which', 'their', 'time', 'about',
992
+ 'would', 'there', 'could', 'other', 'after', 'first', 'well',
993
+ 'also', 'make', 'here', 'where', 'much', 'take','were', 'said',
994
+ 'each', 'which', 'their', 'time', 'about','also', 'make', 'here',
995
+ 'where', 'much', 'take', 'than', 'only'
996
+ }
997
+
998
+ quantum_filtered = [w for w in words if w not in quantum_stop_words and len(w) > 3]
999
+
1000
+ quantum_freq = {}
1001
+ for word in quantum_filtered:
1002
+ quantum_freq[word] = quantum_freq.get(word, 0) + 1
1003
+
1004
+ return sorted(quantum_freq.items(), key=lambda x: x[1], reverse=True)[:top_k]
1005
+
1006
+ def create_download_file(content, filename, file_type="txt"):
1007
+ """Create downloadable file content"""
1008
+ if file_type == "txt":
1009
+ return content.encode('utf-8')
1010
+ elif file_type == "pdf":
1011
+ # For PDF, we'll create a simple text-based PDF
1012
+ # This is a simplified version - in production, use reportlab or similar
1013
+ return content.encode('utf-8')
1014
+ return content.encode('utf-8')
1015
+
1016
+ def main():
1017
+ """Revolutionary main application with enhanced navigation and proper footer"""
1018
+
1019
+ # Initialize quantum components
1020
+ if 'pdf_processor' not in st.session_state:
1021
+ st.session_state.pdf_processor = PDFProcessor()
1022
+ if 'quantum_summarizer' not in st.session_state:
1023
+ st.session_state.quantum_summarizer = QuantumSummarizer()
1024
+ if 'neuro_qa' not in st.session_state:
1025
+ st.session_state.neuro_qa = NeuroQA()
1026
+ if 'active_page' not in st.session_state:
1027
+ st.session_state.active_page = 'upload'
1028
+ # Lazy HF objects referenced only if transformers is available
1029
+ if 'hf_summarizer' not in st.session_state:
1030
+ st.session_state.hf_summarizer = None
1031
+ if 'hf_summarizer_name' not in st.session_state:
1032
+ st.session_state.hf_summarizer_name = 'facebook/bart-large-cnn'
1033
+ if 'hf_qa' not in st.session_state:
1034
+ st.session_state.hf_qa = None
1035
+ if 'hf_qa_name' not in st.session_state:
1036
+ st.session_state.hf_qa_name = 'deepset/roberta-base-squad2'
1037
+
1038
+ # Initialize quantum data
1039
+ if 'document_text' not in st.session_state:
1040
+ st.session_state.document_text = ""
1041
+ if 'neural_history' not in st.session_state:
1042
+ st.session_state.neural_history = []
1043
+
1044
+ # Load revolutionary CSS
1045
+ load_revolutionary_css()
1046
+
1047
+ # Sidebar removed as requested
1048
+
1049
+ # Revolutionary Header
1050
+ st.markdown('<h1 class="main-title">DOCUVERSE AI</h1>', unsafe_allow_html=True)
1051
+ st.markdown('<p class="subtitle">Revolutionary PDF Intelligence Platform</p>', unsafe_allow_html=True)
1052
+
1053
+ # Functional top bar (buttons)
1054
+ top_cols = st.columns(5)
1055
+ with top_cols[0]:
1056
+ if st.button("Document Upload", key="top_upload"):
1057
+ st.session_state.active_page = 'upload'
1058
+ with top_cols[1]:
1059
+ if st.button("Text Input", key="top_text"):
1060
+ st.session_state.active_page = 'text'
1061
+ with top_cols[2]:
1062
+ if st.button("Analysis", key="top_analysis"):
1063
+ st.session_state.active_page = 'analysis'
1064
+ with top_cols[3]:
1065
+ if st.button("Summary", key="top_summary"):
1066
+ st.session_state.active_page = 'summary'
1067
+ with top_cols[4]:
1068
+ if st.button("Q&A", key="top_qa"):
1069
+ st.session_state.active_page = 'qa'
1070
+
1071
+ # No secondary navigator (removed per request)
1072
+
1073
+ if st.session_state.active_page == 'upload':
1074
+ st.markdown('<div class="content-section">', unsafe_allow_html=True)
1075
+ st.markdown('<h2 class="section-title">Document Upload</h2>', unsafe_allow_html=True)
1076
+
1077
+ uploaded_file = st.file_uploader(
1078
+ "DRAG YOUR PDF INTO THE FIELD",
1079
+ type="pdf",
1080
+ key="quantum_uploader",
1081
+ help="Upload PDF documents for processing"
1082
+ )
1083
+
1084
+ if uploaded_file:
1085
+ file_size = len(uploaded_file.getvalue()) / 1024 / 1024
1086
+
1087
+ st.markdown(f"""
1088
+ <div class="cyber-card">
1089
+ <h4 class="cyber-text">File Detected</h4>
1090
+ <p><strong>Filename:</strong> {uploaded_file.name}</p>
1091
+ <p><strong>Size:</strong> {file_size:.1f} MB</p>
1092
+ <p><strong>Type:</strong> {uploaded_file.type}</p>
1093
+ <p><strong>Status:</strong> <span class="cyber-text">Ready for processing</span></p>
1094
+ </div>
1095
+ """, unsafe_allow_html=True)
1096
+
1097
+ col1, col2, col3 = st.columns([1, 2, 1])
1098
+ with col2:
1099
+ if st.button("Initiate Extraction", key="quantum_extract"):
1100
+ with st.spinner("Processing..."):
1101
+ progress_bar = st.progress(0)
1102
+ status_text = st.empty()
1103
+
1104
+ # Quantum extraction sequence
1105
+ status_text.text("Analyzing document structure...")
1106
+ progress_bar.progress(25)
1107
+ time.sleep(0.8)
1108
+
1109
+ status_text.text("Extracting text patterns...")
1110
+ progress_bar.progress(50)
1111
+ time.sleep(0.8)
1112
+
1113
+ status_text.text("Processing neural pathways...")
1114
+ progress_bar.progress(75)
1115
+ time.sleep(0.8)
1116
+
1117
+ # Actual processing
1118
+ text = st.session_state.pdf_processor.extract_text(uploaded_file)
1119
+ progress_bar.progress(100)
1120
+ status_text.text("Extraction complete!")
1121
+
1122
+ if text and not text.startswith("Quantum extraction error"):
1123
+ st.session_state.document_text = text
1124
+ time.sleep(1)
1125
+ progress_bar.empty()
1126
+ status_text.empty()
1127
+
1128
+ st.success("Document extraction successful.")
1129
+
1130
+ # Show quantum preview
1131
+ with st.expander("Text Preview", expanded=True):
1132
+ preview = text[:1500] + "..." if len(text) > 1500 else text
1133
+ st.markdown(f"""
1134
+ <div class="cyber-card">
1135
+ <div class="cyber-text">{preview}</div>
1136
+ </div>
1137
+ """, unsafe_allow_html=True)
1138
+ else:
1139
+ st.error("Extraction failed. Please try another document.")
1140
+ progress_bar.empty()
1141
+ status_text.empty()
1142
+
1143
+ # Reset button for this page
1144
+ st.markdown("---")
1145
+ if st.button("Reset", key="reset_upload"):
1146
+ st.session_state.document_text = ""
1147
+ st.rerun()
1148
+ st.markdown('</div>', unsafe_allow_html=True)
1149
+
1150
+ if st.session_state.active_page == 'text':
1151
+ st.markdown('<div class="content-section">', unsafe_allow_html=True)
1152
+ st.markdown('<h2 class="section-title">Text Input</h2>', unsafe_allow_html=True)
1153
+
1154
+ st.markdown("""
1155
+ <div class="cyber-card">
1156
+ <h4 class="cyber-text">Direct Text Input</h4>
1157
+ <p>Paste your text directly here for immediate processing and summarization.</p>
1158
+ </div>
1159
+ """, unsafe_allow_html=True)
1160
+
1161
+ # Text input area (limit to 5000 words)
1162
+ input_text = st.text_area(
1163
+ "Enter your text here:",
1164
+ height=300,
1165
+ placeholder="Paste your document text here for analysis and summarization...",
1166
+ key="text_input_area"
1167
+ )
1168
+
1169
+ if input_text:
1170
+ words_count = len(input_text.split())
1171
+ st.caption(f"Word count: {words_count}/5000")
1172
+ if words_count > 5000:
1173
+ st.error("Input exceeds 5000-word limit. Please shorten your text.")
1174
+ else:
1175
+ col1, col2, col3 = st.columns([1, 2, 1])
1176
+ with col2:
1177
+ if st.button("Process Text", key="process_text_btn"):
1178
+ with st.spinner("Processing text..."):
1179
+ st.session_state.document_text = input_text
1180
+ st.success("✅ Text processed successfully!")
1181
+ # Show preview
1182
+ with st.expander("Text Preview", expanded=True):
1183
+ preview = input_text[:1500] + "..." if len(input_text) > 1500 else input_text
1184
+ st.markdown(f"""
1185
+ <div class="cyber-card">
1186
+ <div class="cyber-text">{preview}</div>
1187
+ </div>
1188
+ """, unsafe_allow_html=True)
1189
+
1190
+ st.markdown("---")
1191
+ if st.button("Reset", key="reset_text"):
1192
+ st.session_state.document_text = ""
1193
+ st.rerun()
1194
+ st.markdown('</div>', unsafe_allow_html=True)
1195
+
1196
+ if st.session_state.active_page == 'analysis':
1197
+ if st.session_state.document_text:
1198
+ st.markdown('<div class="content-section">', unsafe_allow_html=True)
1199
+ st.markdown('<h2 class="section-title">Neural Document Analysis</h2>', unsafe_allow_html=True)
1200
+
1201
+ # Quantum metrics
1202
+ stats = st.session_state.pdf_processor.get_advanced_stats(st.session_state.document_text)
1203
+
1204
+ st.markdown('<div class="metrics-grid">', unsafe_allow_html=True)
1205
+
1206
+ col1, col2, col3, col4 = st.columns(4)
1207
+
1208
+ with col1:
1209
+ st.markdown(f"""
1210
+ <div class="metric-card">
1211
+ <div class="metric-value">{stats['words']:,}</div>
1212
+ <div class="metric-label">Quantum Words</div>
1213
+ </div>
1214
+ """, unsafe_allow_html=True)
1215
+
1216
+ with col2:
1217
+ st.markdown(f"""
1218
+ <div class="metric-card">
1219
+ <div class="metric-value">{stats['sentences']:,}</div>
1220
+ <div class="metric-label">Neural Sentences</div>
1221
+ </div>
1222
+ """, unsafe_allow_html=True)
1223
+
1224
+ with col3:
1225
+ st.markdown(f"""
1226
+ <div class="metric-card">
1227
+ <div class="metric-value">{stats['complexity']:.1f}%</div>
1228
+ <div class="metric-label">Complexity Index</div>
1229
+ </div>
1230
+ """, unsafe_allow_html=True)
1231
+
1232
+ with col4:
1233
+ st.markdown(f"""
1234
+ <div class="metric-card">
1235
+ <div class="metric-value">{stats['reading_time']}</div>
1236
+ <div class="metric-label">Neural Minutes</div>
1237
+ </div>
1238
+ """, unsafe_allow_html=True)
1239
+
1240
+ st.markdown('</div>', unsafe_allow_html=True)
1241
+
1242
+ # Quantum keywords
1243
+ st.markdown("### Key Phrases")
1244
+ keywords = extract_quantum_keywords(st.session_state.document_text)
1245
+
1246
+ keyword_html = ""
1247
+ for word, freq in keywords:
1248
+ keyword_html += f'<span class="keyword-tag">{word} ({freq})</span>'
1249
+
1250
+ st.markdown(f'<div style="text-align: center; margin: 2rem 0;">{keyword_html}</div>',
1251
+ unsafe_allow_html=True)
1252
+
1253
+ st.markdown("---")
1254
+ if st.button("Reset", key="reset_analysis"):
1255
+ st.session_state.document_text = ""
1256
+ st.rerun()
1257
+ st.markdown('</div>', unsafe_allow_html=True)
1258
+ else:
1259
+ st.info("🌌 Please upload and extract a document first")
1260
+
1261
+ if st.session_state.active_page == 'summary':
1262
+ if st.session_state.document_text:
1263
+ st.markdown('<div class="content-section">', unsafe_allow_html=True)
1264
+ st.markdown('<h2 class="section-title">Advanced Summarization Engine</h2>', unsafe_allow_html=True)
1265
+
1266
+ # Layout: content left, parameters right
1267
+ col1, col2 = st.columns([2, 1])
1268
+
1269
+ with col2:
1270
+ st.markdown("""
1271
+ <div class="cyber-card">
1272
+ <h4 class="cyber-text">Parameters</h4>
1273
+ </div>
1274
+ """, unsafe_allow_html=True)
1275
+
1276
+ # Place Style and Approach side-by-side
1277
+ p1, p2 = st.columns(2)
1278
+ with p1:
1279
+ style = st.selectbox(
1280
+ "Style:",
1281
+ options=list(st.session_state.quantum_summarizer.styles.keys()),
1282
+ format_func=lambda x: st.session_state.quantum_summarizer.styles[x],
1283
+ key="quantum_style"
1284
+ )
1285
+ with p2:
1286
+ summary_type = st.selectbox(
1287
+ "Summarization Approach:",
1288
+ options=list(st.session_state.quantum_summarizer.summary_types.keys()),
1289
+ format_func=lambda x: st.session_state.quantum_summarizer.summary_types[x],
1290
+ key="summary_type_select"
1291
+ )
1292
+
1293
+ length = st.slider("Length:", 2, 15, 8, key="quantum_length")
1294
+
1295
+ with col1:
1296
+ if st.button("Generate Summary", key="quantum_summary_btn"):
1297
+ with st.spinner("Generating summary..."):
1298
+ result = st.session_state.quantum_summarizer.quantum_summarize(
1299
+ st.session_state.document_text,
1300
+ style=style,
1301
+ sentences=length,
1302
+ summary_type=summary_type
1303
+ )
1304
+
1305
+ # Store result in session state for download
1306
+ st.session_state.last_summary = result
1307
+
1308
+ st.markdown(f"""
1309
+ <div class="cyber-card">
1310
+ <h4 class="cyber-text">{st.session_state.quantum_summarizer.summary_types[summary_type]}</h4>
1311
+ <div style="background: rgba(0, 255, 127, 0.05); padding: 2rem; border-radius: 15px; margin: 1rem 0; border-left: 4px solid #00FF7F;">
1312
+ <p style="font-size: 1.2rem; line-height: 1.8; color: #E2E8F0;">
1313
+ {result['summary']}
1314
+ </p>
1315
+ </div>
1316
+ <div style="display: flex; justify-content: space-between; margin-top: 1.5rem;">
1317
+ <span class="cyber-text">Confidence: {result['confidence']}%</span>
1318
+ <span class="cyber-text">Method: {result['method']}</span>
1319
+ <span class="cyber-text">Type: {result['type']}</span>
1320
+ </div>
1321
+ </div>
1322
+ """, unsafe_allow_html=True)
1323
+
1324
+ # Download section
1325
+ st.markdown("### Download Summary")
1326
+ col_download1, col_download2, col_download3 = st.columns(3)
1327
+
1328
+ # Prepare file content
1329
+ file_content = f"""DOCUVERSE AI - SUMMARY REPORT
1330
+ Generated: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
1331
+ Type: {result['type']}
1332
+ Method: {result['method']}
1333
+ Confidence: {result['confidence']}%
1334
+
1335
+ SUMMARY:
1336
+ {result['summary']}
1337
+
1338
+ ---
1339
+ © 2025 DocuVerse AI - Revolutionary PDF Intelligence Platform"""
1340
+
1341
+ with col_download1:
1342
+ st.download_button(
1343
+ label="Download TXT",
1344
+ data=file_content,
1345
+ file_name=f"summary_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt",
1346
+ mime="text/plain",
1347
+ key="download_txt_btn"
1348
+ )
1349
+
1350
+ with col_download2:
1351
+ st.download_button(
1352
+ label="Download PDF",
1353
+ data=file_content,
1354
+ file_name=f"summary_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf",
1355
+ mime="text/plain",
1356
+ key="download_pdf_btn"
1357
+ )
1358
+
1359
+ # Clipboard option removed as requested
1360
+
1361
+ st.markdown("---")
1362
+ if st.button("Reset", key="reset_summary"):
1363
+ st.session_state.last_summary = None
1364
+ st.rerun()
1365
+ st.markdown('</div>', unsafe_allow_html=True)
1366
+ else:
1367
+ st.info("🌌 Please upload and extract a document first")
1368
+
1369
+ if st.session_state.active_page == 'qa':
1370
+ if st.session_state.document_text:
1371
+ st.markdown('<div class="content-section">', unsafe_allow_html=True)
1372
+ st.markdown('<h2 class="section-title">Neuro Question & Answer</h2>', unsafe_allow_html=True)
1373
+
1374
+ question = st.text_input(
1375
+ "Ask the neural network:",
1376
+ placeholder="What is the main principle discussed in this document?",
1377
+ help="Ask any question about your document",
1378
+ key="neural_question"
1379
+ )
1380
+
1381
+ col1, col2, col3 = st.columns([1, 2, 1])
1382
+ with col2:
1383
+ if st.button("Run Q&A", key="neural_qa_btn") and question:
1384
+ with st.spinner("Processing (document-grounded)..."):
1385
+ # Ensure QA pipeline (lazy import with fallback)
1386
+ if st.session_state.hf_qa is None:
1387
+ try:
1388
+ from transformers import pipeline as hf_pipeline
1389
+ st.session_state.hf_qa = hf_pipeline("question-answering", model=st.session_state.hf_qa_name)
1390
+ except Exception:
1391
+ st.session_state.hf_qa = None
1392
+
1393
+ # Chunk doc and retrieve best chunk by token overlap
1394
+ sentences = [s.strip() for s in st.session_state.document_text.split('.') if s.strip()]
1395
+ chunks = []
1396
+ chunk = []
1397
+ for s in sentences:
1398
+ chunk.append(s)
1399
+ if len(' '.join(chunk).split()) > 180:
1400
+ chunks.append('. '.join(chunk))
1401
+ chunk = []
1402
+ if chunk:
1403
+ chunks.append('. '.join(chunk))
1404
+ q_words = set(re.findall(r'\b[a-zA-Z]{3,}\b', question.lower()))
1405
+ scored = []
1406
+ for ch in chunks:
1407
+ ch_words = set(re.findall(r'\b[a-zA-Z]{3,}\b', ch.lower()))
1408
+ scored.append((len(q_words.intersection(ch_words)), ch))
1409
+ best_context = max(scored, key=lambda x: x[0])[1] if scored else st.session_state.document_text
1410
+ if st.session_state.hf_qa is not None:
1411
+ qa_out = st.session_state.hf_qa(question=question, context=best_context)
1412
+ answer = qa_out.get('answer','')
1413
+ score = float(qa_out.get('score',0))*100
1414
+ method = f'hf_qa_{st.session_state.hf_qa_name}'
1415
+ else:
1416
+ # Fallback: use heuristic sentence match from existing NeuroQA
1417
+ fallback = st.session_state.neuro_qa.neural_answer(question, best_context)
1418
+ answer = fallback['answer']
1419
+ score = fallback['confidence']
1420
+ method = 'neural_synthesis_fallback'
1421
+ result = { 'answer': (answer + '.' if not answer.endswith('.') else answer), 'confidence': round(score,1), 'method': method, 'neural_pathways': 1 }
1422
+
1423
+ # Add to neural history
1424
+ st.session_state.neural_history.append({
1425
+ 'question': question,
1426
+ 'answer': result['answer'],
1427
+ 'confidence': result['confidence'],
1428
+ 'method': result.get('method', 'neural'),
1429
+ 'timestamp': datetime.now().strftime("%H:%M:%S")
1430
+ })
1431
+
1432
+ st.markdown(f"""
1433
+ <div class="cyber-card">
1434
+ <h4 class="cyber-text">Neural Response</h4>
1435
+ <div style="background: rgba(78, 205, 196, 0.05); padding: 2rem; border-radius: 15px; margin: 1rem 0; border-left: 4px solid #4ECDC4;">
1436
+ <p><strong>Query:</strong> {question}</p>
1437
+ <p><strong>Answer:</strong> {result['answer']}</p>
1438
+ </div>
1439
+ <div style="display: flex; justify-content: space-between; margin-top: 1.5rem;">
1440
+ <span class="cyber-text">Confidence: {result['confidence']}%</span>
1441
+ <span class="cyber-text">Method: {result.get('method', 'neural')}</span>
1442
+ <span class="cyber-text">Pathways: {result.get('neural_pathways', 1)}</span>
1443
+ </div>
1444
+ </div>
1445
+ """, unsafe_allow_html=True)
1446
+
1447
+ # Neural History
1448
+ if st.session_state.neural_history:
1449
+ st.markdown("### 🕒 Neural Processing History")
1450
+
1451
+ for i, qa in enumerate(reversed(st.session_state.neural_history[-5:])):
1452
+ with st.expander(f"💭 {qa['question'][:50]}... ({qa['timestamp']})",
1453
+ expanded=(i==0)):
1454
+ st.markdown(f"""
1455
+ <div class="cyber-card">
1456
+ <p><strong>❓ Question:</strong> {qa['question']}</p>
1457
+ <p><strong>🤖 Answer:</strong> {qa['answer']}</p>
1458
+ <div style="margin-top: 1rem;">
1459
+ <span class="cyber-text">Confidence: {qa['confidence']}%</span> •
1460
+ <span class="cyber-text">Method: {qa['method']}</span> •
1461
+ <span class="cyber-text">Time: {qa['timestamp']}</span>
1462
+ </div>
1463
+ </div>
1464
+ """, unsafe_allow_html=True)
1465
+
1466
+ st.markdown("---")
1467
+ if st.button("Reset", key="reset_qa"):
1468
+ st.session_state.neural_history = []
1469
+ st.rerun()
1470
+ st.markdown('</div>', unsafe_allow_html=True)
1471
+ else:
1472
+ st.info("🌌 Please upload and extract a document first")
1473
+
1474
+ # Revolutionary Footer - Fixed HTML Rendering
1475
+ st.markdown("---")
1476
+
1477
+ # Create footer using HTML components instead of raw HTML
1478
+ st.markdown("""
1479
+ <div class="footer-container">
1480
+ <h3 class="footer-title">🌟 DOCUVERSE AI - THE QUANTUM FUTURE</h3>
1481
+ <p class="footer-subtitle">Revolutionary PDF Intelligence • Quantum Processing • Neural Networks • Beyond Reality</p>
1482
+ </div>
1483
+ """, unsafe_allow_html=True)
1484
+
1485
+ # Feature tags using columns instead of raw HTML
1486
+ col1, col2, col3, col4 = st.columns(4)
1487
+
1488
+ with col1:
1489
+ st.markdown("""
1490
+ <div class="footer-tag footer-tag-1">⚡ Quantum Speed</div>
1491
+ """, unsafe_allow_html=True)
1492
+
1493
+ with col2:
1494
+ st.markdown("""
1495
+ <div class="footer-tag footer-tag-2">🧠 Neural Intelligence</div>
1496
+ """, unsafe_allow_html=True)
1497
+
1498
+ with col3:
1499
+ st.markdown("""
1500
+ <div class="footer-tag footer-tag-3">🌟 Revolutionary Tech</div>
1501
+ """, unsafe_allow_html=True)
1502
+
1503
+ with col4:
1504
+ st.markdown("""
1505
+ <div class="footer-tag footer-tag-4">🌌 Infinite Possibilities</div>
1506
+ """, unsafe_allow_html=True)
1507
+
1508
+ # Copyright information
1509
+ st.markdown("""
1510
+ <div class="footer-copyright">
1511
+ <p><strong>© 2025 Justine & Krishna. All Rights Reserved.</strong></p>
1512
+ <p>DocuVerse AI™ - Revolutionary PDF Intelligence Platform</p>
1513
+ </div>
1514
+ """, unsafe_allow_html=True)
1515
+
1516
+
1517
+ if __name__ == "__main__":
1518
+ main()
1519
+
requirements.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ streamlit>=1.28.0
2
+ transformers>=4.30.0
3
+ torch>=2.0.0
4
+ PyPDF2>=3.0.1
5
+ tokenizers>=0.13.3
6
+ sentencepiece>=0.1.99
7
+ protobuf>=3.20.0
8
+ numpy>=1.21.0
9
+ pandas>=1.3.0
10
+ Pillow>=9.0.0
11
+ requests>=2.28.0
12
+ accelerate>=0.20.0
13
+ flask>=2.0.0
14
+ werkzeug>=2.2.0
15
+ textstat>=0.7.0
16
+ nltk>=3.8.0
17
+ plotly>=5.0.0
run.bat ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @echo off
2
+ echo.
3
+ echo ==================================================
4
+ echo DOCUVERSE AI - REVOLUTIONARY PDF ASSISTANT
5
+ echo ==================================================
6
+ echo.
7
+
8
+ REM Check if Python is installed
9
+ python --version >nul 2>&1
10
+ if %errorlevel% neq 0 (
11
+ echo [ERROR] Python is not installed or not in PATH
12
+ echo [INFO] Please install Python 3.8+ and try again
13
+ pause
14
+ exit /b 1
15
+ )
16
+
17
+ echo [INFO] Python found, checking version...
18
+ python -c "import sys; print(f'[INFO] Using Python {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')"
19
+
20
+ REM Check if app.py exists
21
+ if not exist "app.py" (
22
+ echo [ERROR] app.py not found!
23
+ echo [INFO] Please run this script from the project directory
24
+ pause
25
+ exit /b 1
26
+ )
27
+
28
+ REM Check if requirements are installed
29
+ echo [INFO] Checking dependencies...
30
+ python -c "import streamlit, PyPDF2, transformers, torch" >nul 2>&1
31
+ if %errorlevel% neq 0 (
32
+ echo [WARNING] Some dependencies may be missing
33
+ echo [INFO] Installing requirements...
34
+ pip install -r requirements.txt
35
+ if %errorlevel% neq 0 (
36
+ echo [ERROR] Error installing requirements
37
+ echo [INFO] Try running manually: pip install -r requirements.txt
38
+ pause
39
+ exit /b 1
40
+ )
41
+ )
42
+
43
+ echo [SUCCESS] All dependencies verified!
44
+ echo.
45
+ echo [INFO] Starting DocuVerse AI...
46
+ echo [INFO] The application will open in your default browser
47
+ echo [INFO] Local URL: http://localhost:8501
48
+ echo.
49
+ echo [INFO] To stop the application, press Ctrl+C
50
+ echo ==================================================
51
+ echo.
52
+
53
+ REM Start the Streamlit application
54
+ streamlit run app.py --server.headless false --server.port 8501 --server.address localhost --browser.gatherUsageStats false
55
+
56
+ echo.
57
+ echo [INFO] Thank you for using DocuVerse AI!
58
+ pause
run.sh ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # DocuVerse AI - Launcher Script for Unix/Linux/Mac
4
+ # © 2025 Justine & Krishna. All Rights Reserved.
5
+
6
+ echo "=================================================="
7
+ echo " DOCUVERSE AI - REVOLUTIONARY PDF ASSISTANT"
8
+ echo "=================================================="
9
+ echo ""
10
+
11
+ # Colors for output
12
+ RED='\033[0;31m'
13
+ GREEN='\033[0;32m'
14
+ YELLOW='\033[1;33m'
15
+ BLUE='\033[0;34m'
16
+ PURPLE='\033[0;35m'
17
+ CYAN='\033[0;36m'
18
+ NC='\033[0m' # No Color
19
+
20
+ # Check if Python is installed
21
+ if ! command -v python3 &> /dev/null && ! command -v python &> /dev/null; then
22
+ echo -e "${RED}[ERROR] Python is not installed or not in PATH${NC}"
23
+ echo -e "${YELLOW}[INFO] Please install Python 3.8+ and try again${NC}"
24
+ exit 1
25
+ fi
26
+
27
+ # Use python3 if available, otherwise use python
28
+ if command -v python3 &> /dev/null; then
29
+ PYTHON_CMD="python3"
30
+ else
31
+ PYTHON_CMD="python"
32
+ fi
33
+
34
+ # Check Python version
35
+ PYTHON_VERSION=$($PYTHON_CMD -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
36
+ echo -e "${BLUE}[INFO] Using Python ${PYTHON_VERSION}${NC}"
37
+
38
+ # Check if app.py exists
39
+ if [ ! -f "app.py" ]; then
40
+ echo -e "${RED}[ERROR] app.py not found!${NC}"
41
+ echo -e "${YELLOW}[INFO] Please run this script from the project directory${NC}"
42
+ exit 1
43
+ fi
44
+
45
+ # Check if requirements.txt exists
46
+ if [ ! -f "requirements.txt" ]; then
47
+ echo -e "${YELLOW}[WARNING] requirements.txt not found${NC}"
48
+ else
49
+ echo -e "${CYAN}[INFO] Checking dependencies...${NC}"
50
+
51
+ # Check if streamlit is installed
52
+ if ! $PYTHON_CMD -c "import streamlit" &> /dev/null; then
53
+ echo -e "${YELLOW}[INFO] Installing missing dependencies...${NC}"
54
+ $PYTHON_CMD -m pip install -r requirements.txt
55
+
56
+ if [ $? -ne 0 ]; then
57
+ echo -e "${RED}[ERROR] Error installing requirements${NC}"
58
+ echo -e "${YELLOW}[INFO] Try running manually: pip install -r requirements.txt${NC}"
59
+ exit 1
60
+ fi
61
+ fi
62
+ fi
63
+
64
+ # Verify all key dependencies
65
+ echo -e "${CYAN}[INFO] Verifying dependencies...${NC}"
66
+ $PYTHON_CMD -c "
67
+ try:
68
+ import streamlit
69
+ import PyPDF2
70
+ import transformers
71
+ import torch
72
+ print('[SUCCESS] All key dependencies found!')
73
+ except ImportError as e:
74
+ print(f'[ERROR] Missing dependency: {e}')
75
+ print('[INFO] Please run: pip install -r requirements.txt')
76
+ exit(1)
77
+ " || exit 1
78
+
79
+ echo ""
80
+ echo -e "${GREEN}[INFO] Starting DocuVerse AI...${NC}"
81
+ echo -e "${PURPLE}[INFO] The application will open in your default browser${NC}"
82
+ echo -e "${CYAN}[INFO] Local URL: http://localhost:8501${NC}"
83
+ echo ""
84
+ echo -e "${YELLOW}[INFO] To stop the application, press Ctrl+C${NC}"
85
+ echo "=================================================="
86
+ echo ""
87
+
88
+ # Make script executable
89
+ chmod +x "$0" 2>/dev/null
90
+
91
+ # Start the Streamlit application
92
+ trap 'echo -e "\n\n[INFO] Shutting down DocuVerse AI..."; echo -e "[INFO] Thank you for using DocuVerse AI!"; exit 0' INT
93
+
94
+ $PYTHON_CMD -m streamlit run app.py \
95
+ --server.headless false \
96
+ --server.port 8501 \
97
+ --server.address localhost \
98
+ --browser.gatherUsageStats false
99
+
100
+ echo ""
101
+ echo -e "${GREEN}[INFO] Thank you for using DocuVerse AI!${NC}"