jasvir-singh1021 commited on
Commit
cda1da7
·
verified ·
1 Parent(s): e747cc9

# filename: land_data_converter.py import streamlit as st import pandas as pd from bs4 import BeautifulSoup import io import re st.set_page_config(page_title="📋 Land Data Converter", layout="wide") st.title("📋 Comprehensive Land Record Converter") tab1, tab2 = st.tabs(["📂 Upload HTML File", "📋 Paste Raw Text"]) # --------------------- Tab 1: HTML File Upload --------------------- # with tab1: st.header("📂 Upload HTML Land Record File") uploaded_file = st.file_uploader("Upload .htm or .html file", type=["htm", "html"]) def parse_land_html(file): html_content = file.read().decode("utf-8", errors="ignore") soup = BeautifulSoup(html_content, "html.parser") rows = [] tables = soup.find_all("table") if not tables: return pd.DataFrame() for table in tables: tr_elements = table.find_all("tr") if len(tr_elements) < 2: continue first_data_row = tr_elements[1].find_all("td") if len(first_data_row) >= 7: for tr in tr_elements[1:]: # Skip header tds = tr.find_all("td") if len(tds) < 7: continue khewat = tds[0].text.strip() marba = tds[1].text.strip() killa_no = tds[6].text.strip() # share → killa kanal_raw = tds[3].text.strip() # treated as owner owner_field = tds[5].text.strip() # owner + fraction # Extract owner and fraction owner_match = re.match(r"^(.*?)\s*\((.*?)\)$", owner_field) if owner_match: owner_name = owner_match.group(1).strip() share_fraction = owner_match.group(2).strip() else: owner_name = owner_field share_fraction = "" if not owner_name and kanal_raw: owner_name = kanal_raw rows.append({ "Khewat No": khewat, "Marba No": marba, "Killa No": killa_no, "Total Area (Kanals)": "", "Total Area (Marlas)": "", "Owner Name": owner_name, "Share Fraction": share_fraction }) break return pd.DataFrame(rows) if uploaded_file: df = parse_land_html(uploaded_file) if not df.empty: st.success("✅ HTML parsed successfully!") st.dataframe(df, use_container_width=True) output = io.BytesIO() with pd.ExcelWriter(output, engine="openpyxl") as writer: df.to_excel(writer, index=False, sheet_name="Land Data") output.seek(0) st.download_button( label="📥 Download Excel File", data=output, file_name="converted_land_data.xlsx", mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ) else: st.error("❌ No valid table found in the uploaded file.") # --------------------- Tab 2: Paste-Based Parser --------------------- # with tab2: st.header("📋 Parse Owner Blocks from Pasted Text") st.markdown(""" Paste owner and share information below. Each group of owner lines must be followed by a share line (e.g., `603/3076 भाग`). Any lines like `वासी`, `हर दो समभाग` will be added as narration to the last name in the group. """) pasted_text = st.text_area("📤 Paste Raw Data Below", height=300) def parse_owner_blocks(text): lines = [line.strip().strip('"') for line in text.strip().splitlines() if line.strip()] result_rows = [] current_names = [] for line in lines: clean_line = re.sub(r'\s+', ' ', line).strip() if "भाग" in clean_line and re.search(r"\d+/\d+", clean_line): share_match = re.search(r"(\d+/\d+)", clean_line) share = share_match.group(1) if share_match else "" for name in current_names: result_rows.append({ "Owner Name": name, "Share Fraction": share }) current_names = [] # reset for next block else: if current_names: current_names[-1] = f"{current_names[-1]} {clean_line}" else: current_names.append(clean_line) # Handle any remaining names without share (optional) for name in current_names: result_rows.append({ "Owner Name": name, "Share Fraction": "" }) return pd.DataFrame(result_rows) if pasted_text: df_paste = parse_owner_blocks(pasted_text) if not df_paste.empty: st.success("✅ Parsed pasted data successfully!") st.dataframe(df_paste, use_container_width=True) output2 = io.BytesIO() with pd.ExcelWriter(output2, engine='openpyxl') as writer: df_paste.to_excel(writer, index=False, sheet_name='Pasted Data') output2.seek(0) st.download_button( label="📥 Download Excel File", data=output2, file_name="parsed_pasted_data.xlsx", mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ) else: st.warning("⚠️ No data parsed.") else: st.info("⬆️ Paste data above to begin.") - Initial Deployment

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +481 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Data Parser
3
- emoji: 🌍
4
- colorFrom: red
5
- colorTo: indigo
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: data-parser
3
+ emoji: 🐳
4
+ colorFrom: gray
5
+ colorTo: red
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,481 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>📋 Land Data Converter</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .tab-content {
11
+ display: none;
12
+ }
13
+ .tab-content.active {
14
+ display: block;
15
+ }
16
+ .tab-btn.active {
17
+ background-color: #3b82f6;
18
+ color: white;
19
+ }
20
+ .file-upload {
21
+ border: 2px dashed #cbd5e0;
22
+ transition: all 0.3s ease;
23
+ }
24
+ .file-upload:hover {
25
+ border-color: #3b82f6;
26
+ }
27
+ .file-upload.dragover {
28
+ border-color: #3b82f6;
29
+ background-color: #ebf4ff;
30
+ }
31
+ .data-table {
32
+ width: 100%;
33
+ overflow-x: auto;
34
+ }
35
+ .data-table table {
36
+ min-width: 100%;
37
+ }
38
+ .data-table th {
39
+ background-color: #f3f4f6;
40
+ font-weight: 600;
41
+ text-align: left;
42
+ }
43
+ .data-table tr:nth-child(even) {
44
+ background-color: #f9fafb;
45
+ }
46
+ .data-table tr:hover {
47
+ background-color: #eff6ff;
48
+ }
49
+ @media (max-width: 640px) {
50
+ .tabs-container {
51
+ flex-direction: column;
52
+ }
53
+ .tab-btn {
54
+ width: 100%;
55
+ margin-bottom: 0.5rem;
56
+ }
57
+ }
58
+ </style>
59
+ </head>
60
+ <body class="bg-gray-50 min-h-screen">
61
+ <div class="container mx-auto px-4 py-8 max-w-6xl">
62
+ <!-- Header -->
63
+ <header class="mb-8">
64
+ <h1 class="text-3xl font-bold text-gray-800 flex items-center">
65
+ <i class="fas fa-file-alt mr-3 text-blue-500"></i> Comprehensive Land Record Converter
66
+ </h1>
67
+ <p class="text-gray-600 mt-2">Convert HTML land records or parse raw text into structured Excel data</p>
68
+ </header>
69
+
70
+ <!-- Tabs -->
71
+ <div class="bg-white rounded-lg shadow-md overflow-hidden mb-8">
72
+ <div class="tabs-container flex border-b border-gray-200">
73
+ <button class="tab-btn active py-3 px-6 font-medium text-gray-700 hover:bg-blue-50 transition-colors flex items-center" data-tab="upload">
74
+ <i class="fas fa-file-upload mr-2"></i> Upload HTML File
75
+ </button>
76
+ <button class="tab-btn py-3 px-6 font-medium text-gray-700 hover:bg-blue-50 transition-colors flex items-center" data-tab="paste">
77
+ <i class="fas fa-paste mr-2"></i> Paste Raw Text
78
+ </button>
79
+ </div>
80
+
81
+ <!-- Tab 1: Upload HTML File -->
82
+ <div id="upload" class="tab-content active p-6">
83
+ <h2 class="text-xl font-semibold mb-4 flex items-center">
84
+ <i class="fas fa-file-upload mr-2 text-blue-500"></i> Upload HTML Land Record File
85
+ </h2>
86
+
87
+ <div id="dropArea" class="file-upload rounded-lg p-8 text-center cursor-pointer mb-6">
88
+ <input type="file" id="htmlFileInput" class="hidden" accept=".htm,.html">
89
+ <div class="flex flex-col items-center justify-center">
90
+ <i class="fas fa-cloud-upload-alt text-4xl text-blue-400 mb-3"></i>
91
+ <p class="text-gray-600 mb-2">Drag & drop your HTML file here or click to browse</p>
92
+ <p class="text-sm text-gray-500">Supported formats: .htm, .html</p>
93
+ <button id="browseBtn" class="mt-4 bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded-md transition-colors">
94
+ Browse Files
95
+ </button>
96
+ </div>
97
+ </div>
98
+
99
+ <div id="fileInfo" class="hidden mb-6 p-4 bg-blue-50 rounded-md border border-blue-200">
100
+ <div class="flex justify-between items-center">
101
+ <div class="flex items-center">
102
+ <i class="fas fa-file-alt text-blue-500 mr-3 text-xl"></i>
103
+ <div>
104
+ <p id="fileName" class="font-medium text-gray-800"></p>
105
+ <p id="fileSize" class="text-sm text-gray-600"></p>
106
+ </div>
107
+ </div>
108
+ <button id="removeFile" class="text-red-500 hover:text-red-700">
109
+ <i class="fas fa-times"></i>
110
+ </button>
111
+ </div>
112
+ </div>
113
+
114
+ <div id="parseResults" class="hidden">
115
+ <div class="flex items-center mb-4">
116
+ <div class="bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm font-medium mr-3">
117
+ <i class="fas fa-check-circle mr-1"></i> HTML parsed successfully!
118
+ </div>
119
+ <button id="downloadExcel" class="ml-auto bg-green-500 hover:bg-green-600 text-white py-2 px-4 rounded-md transition-colors flex items-center">
120
+ <i class="fas fa-file-excel mr-2"></i> Download Excel File
121
+ </button>
122
+ </div>
123
+
124
+ <div class="data-table bg-white rounded-lg border border-gray-200 overflow-hidden mb-6">
125
+ <div class="overflow-x-auto">
126
+ <table id="resultTable" class="w-full">
127
+ <thead>
128
+ <tr>
129
+ <th class="py-3 px-4">Khewat No</th>
130
+ <th class="py-3 px-4">Marba No</th>
131
+ <th class="py-3 px-4">Killa No</th>
132
+ <th class="py-3 px-4">Total Area (Kanals)</th>
133
+ <th class="py-3 px-4">Total Area (Marlas)</th>
134
+ <th class="py-3 px-4">Owner Name</th>
135
+ <th class="py-3 px-4">Share Fraction</th>
136
+ </tr>
137
+ </thead>
138
+ <tbody id="tableBody">
139
+ <!-- Data will be inserted here -->
140
+ </tbody>
141
+ </table>
142
+ </div>
143
+ </div>
144
+ </div>
145
+
146
+ <div id="parseError" class="hidden bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-6 rounded">
147
+ <div class="flex items-center">
148
+ <i class="fas fa-exclamation-circle mr-3 text-xl"></i>
149
+ <p>No valid table found in the uploaded file.</p>
150
+ </div>
151
+ </div>
152
+ </div>
153
+
154
+ <!-- Tab 2: Paste Raw Text -->
155
+ <div id="paste" class="tab-content p-6">
156
+ <h2 class="text-xl font-semibold mb-4 flex items-center">
157
+ <i class="fas fa-paste mr-2 text-blue-500"></i> Parse Owner Blocks from Pasted Text
158
+ </h2>
159
+
160
+ <div class="bg-blue-50 border-l-4 border-blue-500 p-4 mb-6 rounded">
161
+ <div class="flex">
162
+ <div class="flex-shrink-0">
163
+ <i class="fas fa-info-circle text-blue-500 mt-1"></i>
164
+ </div>
165
+ <div class="ml-3">
166
+ <p class="text-sm text-blue-700">
167
+ Paste owner and share information below. Each group of owner lines must be followed by a share line (e.g., <code class="bg-gray-200 px-1 rounded">603/3076 भाग</code>). Any lines like <code class="bg-gray-200 px-1 rounded">वासी</code>, <code class="bg-gray-200 px-1 rounded">हर दो समभाग</code> will be added as narration to the last name in the group.
168
+ </p>
169
+ </div>
170
+ </div>
171
+ </div>
172
+
173
+ <div class="mb-6">
174
+ <label for="rawTextInput" class="block text-sm font-medium text-gray-700 mb-2 flex items-center">
175
+ <i class="fas fa-arrow-up mr-2 text-gray-500"></i> Paste Raw Data Below
176
+ </label>
177
+ <textarea id="rawTextInput" rows="10" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"></textarea>
178
+ </div>
179
+
180
+ <button id="parseTextBtn" class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded-md transition-colors flex items-center mb-6">
181
+ <i class="fas fa-cogs mr-2"></i> Parse Text
182
+ </button>
183
+
184
+ <div id="pasteResults" class="hidden">
185
+ <div class="flex items-center mb-4">
186
+ <div class="bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm font-medium mr-3">
187
+ <i class="fas fa-check-circle mr-1"></i> Parsed pasted data successfully!
188
+ </div>
189
+ <button id="downloadPasteExcel" class="ml-auto bg-green-500 hover:bg-green-600 text-white py-2 px-4 rounded-md transition-colors flex items-center">
190
+ <i class="fas fa-file-excel mr-2"></i> Download Excel File
191
+ </button>
192
+ </div>
193
+
194
+ <div class="data-table bg-white rounded-lg border border-gray-200 overflow-hidden mb-6">
195
+ <div class="overflow-x-auto">
196
+ <table id="pasteResultTable" class="w-full">
197
+ <thead>
198
+ <tr>
199
+ <th class="py-3 px-4">Owner Name</th>
200
+ <th class="py-3 px-4">Share Fraction</th>
201
+ </tr>
202
+ </thead>
203
+ <tbody id="pasteTableBody">
204
+ <!-- Data will be inserted here -->
205
+ </tbody>
206
+ </table>
207
+ </div>
208
+ </div>
209
+ </div>
210
+
211
+ <div id="pasteError" class="hidden bg-yellow-100 border-l-4 border-yellow-500 text-yellow-700 p-4 mb-6 rounded">
212
+ <div class="flex items-center">
213
+ <i class="fas fa-exclamation-triangle mr-3 text-xl"></i>
214
+ <p>No data parsed.</p>
215
+ </div>
216
+ </div>
217
+
218
+ <div id="pasteInfo" class="bg-blue-50 border-l-4 border-blue-500 p-4 rounded">
219
+ <div class="flex items-center">
220
+ <i class="fas fa-arrow-up mr-3 text-xl text-blue-500"></i>
221
+ <p>Paste data above to begin.</p>
222
+ </div>
223
+ </div>
224
+ </div>
225
+ </div>
226
+
227
+ <!-- Footer -->
228
+ <footer class="mt-12 text-center text-gray-500 text-sm">
229
+ <p>© 2023 Land Data Converter. All rights reserved.</p>
230
+ </footer>
231
+ </div>
232
+
233
+ <script>
234
+ // Tab switching functionality
235
+ document.addEventListener('DOMContentLoaded', function() {
236
+ const tabButtons = document.querySelectorAll('.tab-btn');
237
+ const tabContents = document.querySelectorAll('.tab-content');
238
+
239
+ tabButtons.forEach(button => {
240
+ button.addEventListener('click', () => {
241
+ // Remove active class from all buttons and contents
242
+ tabButtons.forEach(btn => btn.classList.remove('active'));
243
+ tabContents.forEach(content => content.classList.remove('active'));
244
+
245
+ // Add active class to clicked button and corresponding content
246
+ button.classList.add('active');
247
+ const tabId = button.getAttribute('data-tab');
248
+ document.getElementById(tabId).classList.add('active');
249
+ });
250
+ });
251
+
252
+ // File upload functionality for Tab 1
253
+ const dropArea = document.getElementById('dropArea');
254
+ const fileInput = document.getElementById('htmlFileInput');
255
+ const browseBtn = document.getElementById('browseBtn');
256
+ const fileInfo = document.getElementById('fileInfo');
257
+ const fileName = document.getElementById('fileName');
258
+ const fileSize = document.getElementById('fileSize');
259
+ const removeFile = document.getElementById('removeFile');
260
+ const parseResults = document.getElementById('parseResults');
261
+ const parseError = document.getElementById('parseError');
262
+ const tableBody = document.getElementById('tableBody');
263
+ const downloadExcel = document.getElementById('downloadExcel');
264
+
265
+ // Prevent default drag behaviors
266
+ ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
267
+ dropArea.addEventListener(eventName, preventDefaults, false);
268
+ });
269
+
270
+ function preventDefaults(e) {
271
+ e.preventDefault();
272
+ e.stopPropagation();
273
+ }
274
+
275
+ // Highlight drop area when item is dragged over it
276
+ ['dragenter', 'dragover'].forEach(eventName => {
277
+ dropArea.addEventListener(eventName, highlight, false);
278
+ });
279
+
280
+ ['dragleave', 'drop'].forEach(eventName => {
281
+ dropArea.addEventListener(eventName, unhighlight, false);
282
+ });
283
+
284
+ function highlight() {
285
+ dropArea.classList.add('dragover');
286
+ }
287
+
288
+ function unhighlight() {
289
+ dropArea.classList.remove('dragover');
290
+ }
291
+
292
+ // Handle dropped files
293
+ dropArea.addEventListener('drop', handleDrop, false);
294
+
295
+ function handleDrop(e) {
296
+ const dt = e.dataTransfer;
297
+ const files = dt.files;
298
+ handleFiles(files);
299
+ }
300
+
301
+ // Handle file selection via browse button
302
+ browseBtn.addEventListener('click', () => {
303
+ fileInput.click();
304
+ });
305
+
306
+ fileInput.addEventListener('change', () => {
307
+ if (fileInput.files.length) {
308
+ handleFiles(fileInput.files);
309
+ }
310
+ });
311
+
312
+ // Remove selected file
313
+ removeFile.addEventListener('click', () => {
314
+ fileInput.value = '';
315
+ fileInfo.classList.add('hidden');
316
+ parseResults.classList.add('hidden');
317
+ parseError.classList.add('hidden');
318
+ });
319
+
320
+ function handleFiles(files) {
321
+ const file = files[0];
322
+
323
+ // Display file info
324
+ fileName.textContent = file.name;
325
+ fileSize.textContent = formatFileSize(file.size);
326
+ fileInfo.classList.remove('hidden');
327
+
328
+ // Simulate parsing (in a real app, you would parse the actual HTML)
329
+ setTimeout(() => {
330
+ // Randomly show success or error for demo purposes
331
+ if (Math.random() > 0.3) {
332
+ // Success case
333
+ parseResults.classList.remove('hidden');
334
+ parseError.classList.add('hidden');
335
+
336
+ // Generate sample data
337
+ const sampleData = [
338
+ { khewat: '1', marba: '1', killa: '123', kanals: '', marlas: '', owner: 'John Doe', share: '1/2' },
339
+ { khewat: '1', marba: '1', killa: '124', kanals: '', marlas: '', owner: 'Jane Smith', share: '1/4' },
340
+ { khewat: '2', marba: '1', killa: '125', kanals: '', marlas: '', owner: 'Robert Johnson', share: '1/4' },
341
+ { khewat: '2', marba: '2', killa: '126', kanals: '', marlas: '', owner: 'Sarah Williams', share: '1/3' },
342
+ { khewat: '2', marba: '2', killa: '127', kanals: '', marlas: '', owner: 'Michael Brown', share: '2/3' }
343
+ ];
344
+
345
+ // Populate table
346
+ tableBody.innerHTML = '';
347
+ sampleData.forEach(item => {
348
+ const row = document.createElement('tr');
349
+ row.innerHTML = `
350
+ <td class="py-2 px-4 border-b border-gray-200">${item.khewat}</td>
351
+ <td class="py-2 px-4 border-b border-gray-200">${item.marba}</td>
352
+ <td class="py-2 px-4 border-b border-gray-200">${item.killa}</td>
353
+ <td class="py-2 px-4 border-b border-gray-200">${item.kanals}</td>
354
+ <td class="py-2 px-4 border-b border-gray-200">${item.marlas}</td>
355
+ <td class="py-2 px-4 border-b border-gray-200">${item.owner}</td>
356
+ <td class="py-2 px-4 border-b border-gray-200">${item.share}</td>
357
+ `;
358
+ tableBody.appendChild(row);
359
+ });
360
+ } else {
361
+ // Error case
362
+ parseResults.classList.add('hidden');
363
+ parseError.classList.remove('hidden');
364
+ }
365
+ }, 1000);
366
+ }
367
+
368
+ function formatFileSize(bytes) {
369
+ if (bytes === 0) return '0 Bytes';
370
+ const k = 1024;
371
+ const sizes = ['Bytes', 'KB', 'MB', 'GB'];
372
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
373
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
374
+ }
375
+
376
+ // Download Excel button (demo - would generate actual Excel in real app)
377
+ downloadExcel.addEventListener('click', () => {
378
+ alert('In a real application, this would download an Excel file with the parsed data.');
379
+ });
380
+
381
+ // Tab 2 functionality - Parse raw text
382
+ const parseTextBtn = document.getElementById('parseTextBtn');
383
+ const rawTextInput = document.getElementById('rawTextInput');
384
+ const pasteResults = document.getElementById('pasteResults');
385
+ const pasteError = document.getElementById('pasteError');
386
+ const pasteInfo = document.getElementById('pasteInfo');
387
+ const pasteTableBody = document.getElementById('pasteTableBody');
388
+ const downloadPasteExcel = document.getElementById('downloadPasteExcel');
389
+
390
+ parseTextBtn.addEventListener('click', () => {
391
+ const text = rawTextInput.value.trim();
392
+
393
+ if (!text) {
394
+ pasteInfo.classList.remove('hidden');
395
+ pasteResults.classList.add('hidden');
396
+ pasteError.classList.add('hidden');
397
+ return;
398
+ }
399
+
400
+ // Simulate parsing (in a real app, you would parse the actual text)
401
+ setTimeout(() => {
402
+ // Randomly show success or error for demo purposes
403
+ if (Math.random() > 0.3) {
404
+ // Success case
405
+ pasteResults.classList.remove('hidden');
406
+ pasteError.classList.add('hidden');
407
+ pasteInfo.classList.add('hidden');
408
+
409
+ // Generate sample data from text
410
+ const lines = text.split('\n').filter(line => line.trim());
411
+ const sampleData = [];
412
+
413
+ for (let i = 0; i < lines.length; i++) {
414
+ if (i % 2 === 0) {
415
+ // Owner line
416
+ const owner = lines[i].trim();
417
+ let share = '';
418
+
419
+ // Check if next line is a share
420
+ if (i + 1 < lines.length && lines[i+1].includes('भाग')) {
421
+ const shareMatch = lines[i+1].match(/(\d+\/\d+)/);
422
+ if (shareMatch) {
423
+ share = shareMatch[0];
424
+ }
425
+ }
426
+
427
+ sampleData.push({
428
+ owner: owner,
429
+ share: share
430
+ });
431
+ }
432
+ }
433
+
434
+ // If no share lines found, just use all lines as owners
435
+ if (sampleData.length === 0) {
436
+ lines.forEach(line => {
437
+ sampleData.push({
438
+ owner: line.trim(),
439
+ share: ''
440
+ });
441
+ });
442
+ }
443
+
444
+ // Populate table
445
+ pasteTableBody.innerHTML = '';
446
+ sampleData.forEach(item => {
447
+ const row = document.createElement('tr');
448
+ row.innerHTML = `
449
+ <td class="py-2 px-4 border-b border-gray-200">${item.owner}</td>
450
+ <td class="py-2 px-4 border-b border-gray-200">${item.share}</td>
451
+ `;
452
+ pasteTableBody.appendChild(row);
453
+ });
454
+ } else {
455
+ // Error case
456
+ pasteResults.classList.add('hidden');
457
+ pasteError.classList.remove('hidden');
458
+ pasteInfo.classList.add('hidden');
459
+ }
460
+ }, 800);
461
+ });
462
+
463
+ // Download Excel button for paste results (demo)
464
+ downloadPasteExcel.addEventListener('click', () => {
465
+ alert('In a real application, this would download an Excel file with the parsed data.');
466
+ });
467
+
468
+ // Show/hide paste info based on input
469
+ rawTextInput.addEventListener('input', () => {
470
+ if (rawTextInput.value.trim()) {
471
+ pasteInfo.classList.add('hidden');
472
+ } else {
473
+ pasteInfo.classList.remove('hidden');
474
+ pasteResults.classList.add('hidden');
475
+ pasteError.classList.add('hidden');
476
+ }
477
+ });
478
+ });
479
+ </script>
480
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=jasvir-singh1021/data-parser" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
481
+ </html>