Spaces:
Running
Running
Add 2 files
Browse files- index.html +402 -353
- prompts.txt +2 -1
index.html
CHANGED
@@ -3,343 +3,319 @@
|
|
3 |
<head>
|
4 |
<meta charset="UTF-8">
|
5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6 |
-
<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 |
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tf.min.js"></script>
|
10 |
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/[email protected]"></script>
|
11 |
<style>
|
12 |
-
.
|
13 |
-
|
14 |
-
|
15 |
-
.plastic-card:hover {
|
16 |
-
transform: translateY(-5px);
|
17 |
-
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
18 |
}
|
19 |
-
.
|
20 |
-
|
21 |
}
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
100% { transform: translateY(0px); }
|
26 |
}
|
27 |
-
.
|
28 |
-
|
29 |
-
.plastic-type-3 { background-color: #3357FF; }
|
30 |
-
.plastic-type-4 { background-color: #F3FF33; }
|
31 |
-
.plastic-type-5 { background-color: #FF33F3; }
|
32 |
-
.plastic-type-6 { background-color: #33FFF3; }
|
33 |
-
.plastic-type-7 { background-color: #8A33FF; }
|
34 |
-
#previewContainer {
|
35 |
-
display: none;
|
36 |
-
position: relative;
|
37 |
}
|
38 |
-
|
39 |
-
|
40 |
-
max-height: 300px;
|
41 |
border-radius: 8px;
|
|
|
|
|
|
|
|
|
42 |
}
|
43 |
-
|
44 |
-
|
|
|
45 |
}
|
46 |
-
|
47 |
-
|
48 |
-
|
|
|
|
|
49 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
.progress-bar {
|
51 |
-
height:
|
52 |
background-color: #e0e0e0;
|
53 |
-
border-radius:
|
54 |
overflow: hidden;
|
55 |
}
|
56 |
.progress-bar-fill {
|
57 |
height: 100%;
|
58 |
-
background-color: #
|
59 |
transition: width 0.3s ease;
|
60 |
}
|
61 |
-
.drop-zone {
|
62 |
-
border: 2px dashed #ccc;
|
63 |
-
border-radius: 8px;
|
64 |
-
padding: 40px;
|
65 |
-
text-align: center;
|
66 |
-
cursor: pointer;
|
67 |
-
transition: all 0.3s;
|
68 |
-
}
|
69 |
-
.drop-zone.highlight {
|
70 |
-
border-color: #4ade80;
|
71 |
-
background-color: rgba(74, 222, 128, 0.1);
|
72 |
-
}
|
73 |
</style>
|
74 |
</head>
|
75 |
-
<body class="bg-gray-
|
76 |
-
<!--
|
77 |
-
<
|
78 |
-
<div class="
|
79 |
-
<div class="flex
|
80 |
-
<
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
<
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
<
|
91 |
-
|
92 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
</div>
|
94 |
</div>
|
95 |
-
</
|
96 |
|
97 |
-
<!--
|
98 |
-
<
|
99 |
-
<div class="
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
<
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
<
|
128 |
-
<h3 class="text-xl font-semibold mb-2">Arraste e solte a imagem aqui</h3>
|
129 |
-
<p class="text-gray-500 mb-6">ou clique para selecionar um arquivo</p>
|
130 |
-
<button id="selectFileBtn" class="bg-blue-500 hover:bg-blue-600 text-white px-6 py-2 rounded-full font-medium transition">
|
131 |
Selecionar arquivo
|
132 |
</button>
|
133 |
<input type="file" id="fileInput" accept="image/*" class="hidden">
|
134 |
</div>
|
135 |
|
136 |
-
<div id="previewContainer" class="
|
137 |
-
<
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
|
|
|
|
|
|
|
|
144 |
</button>
|
145 |
</div>
|
146 |
|
147 |
-
<div id="loadingIndicator" class="
|
148 |
-
<div class="inline-block animate-spin rounded-full h-
|
149 |
-
<p>Analisando
|
150 |
-
|
151 |
-
|
152 |
-
<div id="resultsContainer" class="mt-6">
|
153 |
-
<h3 class="text-xl font-semibold mb-3">Resultados da Análise</h3>
|
154 |
-
<div id="resultsContent">
|
155 |
-
<!-- Results will be inserted here by JavaScript -->
|
156 |
-
</div>
|
157 |
-
</div>
|
158 |
-
</div>
|
159 |
-
</div>
|
160 |
-
</div>
|
161 |
-
</div>
|
162 |
-
</section>
|
163 |
-
|
164 |
-
<!-- Plastic Types Section -->
|
165 |
-
<section id="plastics" class="py-20 bg-white">
|
166 |
-
<div class="container mx-auto px-4">
|
167 |
-
<h2 class="text-3xl font-bold text-center mb-16">Tipos de Plástico que Podemos Identificar</h2>
|
168 |
-
|
169 |
-
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
170 |
-
<!-- Plastic Type 1 -->
|
171 |
-
<div class="plastic-card bg-gray-50 rounded-xl overflow-hidden shadow-md transition duration-300">
|
172 |
-
<div class="plastic-type-1 h-32 flex items-center justify-center">
|
173 |
-
<i class="fas fa-mobile-alt text-white text-5xl"></i>
|
174 |
-
</div>
|
175 |
-
<div class="p-6">
|
176 |
-
<h3 class="text-xl font-bold mb-2">ABS (Acrilonitrila Butadieno Estireno)</h3>
|
177 |
-
<p class="text-gray-600 mb-4">Comum em teclados, carcaças de computadores e eletrodomésticos. Resistente ao impacto e fácil de moldar.</p>
|
178 |
-
<div class="flex justify-between items-center">
|
179 |
-
<span class="bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm font-medium">Código 7</span>
|
180 |
-
<span class="text-gray-500 font-medium">Densidade: 1.04-1.06 g/cm³</span>
|
181 |
-
</div>
|
182 |
-
</div>
|
183 |
-
</div>
|
184 |
-
|
185 |
-
<!-- Plastic Type 2 -->
|
186 |
-
<div class="plastic-card bg-gray-50 rounded-xl overflow-hidden shadow-md transition duration-300">
|
187 |
-
<div class="plastic-type-2 h-32 flex items-center justify-center">
|
188 |
-
<i class="fas fa-plug text-white text-5xl"></i>
|
189 |
-
</div>
|
190 |
-
<div class="p-6">
|
191 |
-
<h3 class="text-xl font-bold mb-2">PC (Policarbonato)</h3>
|
192 |
-
<p class="text-gray-600 mb-4">Encontrado em CDs, DVDs, lentes e componentes ópticos. Transparente e altamente resistente.</p>
|
193 |
-
<div class="flex justify-between items-center">
|
194 |
-
<span class="bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm font-medium">Código 7</span>
|
195 |
-
<span class="text-gray-500 font-medium">Densidade: 1.20-1.22 g/cm³</span>
|
196 |
-
</div>
|
197 |
-
</div>
|
198 |
-
</div>
|
199 |
-
|
200 |
-
<!-- Plastic Type 3 -->
|
201 |
-
<div class="plastic-card bg-gray-50 rounded-xl overflow-hidden shadow-md transition duration-300">
|
202 |
-
<div class="plastic-type-3 h-32 flex items-center justify-center">
|
203 |
-
<i class="fas fa-tv text-white text-5xl"></i>
|
204 |
-
</div>
|
205 |
-
<div class="p-6">
|
206 |
-
<h3 class="text-xl font-bold mb-2">HIPS (Poliestireno de Alto Impacto)</h3>
|
207 |
-
<p class="text-gray-600 mb-4">Usado em monitores, TVs e embalagens. Reconhecível pelo som metálico quando batido.</p>
|
208 |
-
<div class="flex justify-between items-center">
|
209 |
-
<span class="bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm font-medium">Código 6</span>
|
210 |
-
<span class="text-gray-500 font-medium">Densidade: 1.03-1.06 g/cm³</span>
|
211 |
</div>
|
212 |
</div>
|
213 |
</div>
|
214 |
|
215 |
-
<!--
|
216 |
-
<div
|
217 |
-
<div class="
|
218 |
-
<
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
<span class="bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm font-medium">Código 5</span>
|
225 |
-
<span class="text-gray-500 font-medium">Densidade: 0.89-0.91 g/cm³</span>
|
226 |
-
</div>
|
227 |
-
</div>
|
228 |
-
</div>
|
229 |
-
|
230 |
-
<!-- Plastic Type 5 -->
|
231 |
-
<div class="plastic-card bg-gray-50 rounded-xl overflow-hidden shadow-md transition duration-300">
|
232 |
-
<div class="plastic-type-5 h-32 flex items-center justify-center">
|
233 |
-
<i class="fas fa-headphones text-white text-5xl"></i>
|
234 |
-
</div>
|
235 |
-
<div class="p-6">
|
236 |
-
<h3 class="text-xl font-bold mb-2">PVC (Policloreto de Vinila)</h3>
|
237 |
-
<p class="text-gray-600 mb-4">Usado em fios, cabos e revestimentos. Flexível e resistente à chama.</p>
|
238 |
-
<div class="flex justify-between items-center">
|
239 |
-
<span class="bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm font-medium">Código 3</span>
|
240 |
-
<span class="text-gray-500 font-medium">Densidade: 1.30-1.45 g/cm³</span>
|
241 |
</div>
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
<div class="plastic-type-6 h-32 flex items-center justify-center">
|
248 |
-
<i class="fas fa-microchip text-white text-5xl"></i>
|
249 |
-
</div>
|
250 |
-
<div class="p-6">
|
251 |
-
<h3 class="text-xl font-bold mb-2">PBT (Politereftalato de Butileno)</h3>
|
252 |
-
<p class="text-gray-600 mb-4">Encontrado em conectores, componentes elétricos e peças de precisão. Boa estabilidade dimensional.</p>
|
253 |
-
<div class="flex justify-between items-center">
|
254 |
-
<span class="bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm font-medium">Código 7</span>
|
255 |
-
<span class="text-gray-500 font-medium">Densidade: 1.30-1.38 g/cm³</span>
|
256 |
</div>
|
257 |
</div>
|
258 |
</div>
|
259 |
</div>
|
260 |
-
</div>
|
261 |
-
</section>
|
262 |
-
|
263 |
-
<!-- Footer -->
|
264 |
-
<footer class="bg-gray-900 text-white py-12">
|
265 |
-
<div class="container mx-auto px-4">
|
266 |
-
<div class="grid md:grid-cols-4 gap-12 mb-12">
|
267 |
-
<!-- Footer Column 1 -->
|
268 |
-
<div>
|
269 |
-
<div class="flex items-center space-x-2 mb-4">
|
270 |
-
<i class="fas fa-recycle text-2xl text-green-400"></i>
|
271 |
-
<h3 class="text-xl font-bold">EcoPlast</h3>
|
272 |
-
</div>
|
273 |
-
<p class="text-gray-400">Transformando e-lixo em oportunidades sustentáveis através da tecnologia e inovação.</p>
|
274 |
-
</div>
|
275 |
-
|
276 |
-
<!-- Footer Column 2 -->
|
277 |
-
<div>
|
278 |
-
<h4 class="text-lg font-semibold mb-4">Links Rápidos</h4>
|
279 |
-
<ul class="space-y-2">
|
280 |
-
<li><a href="#" class="text-gray-400 hover:text-white transition">Início</a></li>
|
281 |
-
<li><a href="#features" class="text-gray-400 hover:text-white transition">Recursos</a></li>
|
282 |
-
<li><a href="#process" class="text-gray-400 hover:text-white transition">Processo</a></li>
|
283 |
-
<li><a href="#plastics" class="text-gray-400 hover:text-white transition">Tipos de Plástico</a></li>
|
284 |
-
<li><a href="#contact" class="text-gray-400 hover:text-white transition">Contato</a></li>
|
285 |
-
</ul>
|
286 |
-
</div>
|
287 |
-
|
288 |
-
<!-- Footer Column 3 -->
|
289 |
-
<div>
|
290 |
-
<h4 class="text-lg font-semibold mb-4">Recursos</h4>
|
291 |
-
<ul class="space-y-2">
|
292 |
-
<li><a href="#" class="text-gray-400 hover:text-white transition">Identificador de Plásticos</a></li>
|
293 |
-
<li><a href="#" class="text-gray-400 hover:text-white transition">Mercado de Reciclados</a></li>
|
294 |
-
<li><a href="#" class="text-gray-400 hover:text-white transition">Guia de Separação</a></li>
|
295 |
-
<li><a href="#" class="text-gray-400 hover:text-white transition">Treinamentos</a></li>
|
296 |
-
<li><a href="#" class="text-gray-400 hover:text-white transition">Blog</a></li>
|
297 |
-
</ul>
|
298 |
-
</div>
|
299 |
-
|
300 |
-
<!-- Footer Column 4 -->
|
301 |
-
<div>
|
302 |
-
<h4 class="text-lg font-semibold mb-4">Newsletter</h4>
|
303 |
-
<p class="text-gray-400 mb-4">Assine para receber novidades e dicas sobre reciclagem de plásticos.</p>
|
304 |
-
<form class="flex">
|
305 |
-
<input type="email" placeholder="Seu email" class="px-4 py-2 rounded-l-lg focus:outline-none text-gray-900 w-full">
|
306 |
-
<button type="submit" class="bg-green-500 hover:bg-green-600 px-4 py-2 rounded-r-lg">
|
307 |
-
<i class="fas fa-paper-plane"></i>
|
308 |
-
</button>
|
309 |
-
</form>
|
310 |
-
<div class="flex space-x-4 mt-4">
|
311 |
-
<a href="#" class="w-10 h-10 rounded-full bg-gray-800 hover:bg-gray-700 flex items-center justify-center">
|
312 |
-
<i class="fab fa-facebook-f"></i>
|
313 |
-
</a>
|
314 |
-
<a href="#" class="w-10 h-10 rounded-full bg-gray-800 hover:bg-gray-700 flex items-center justify-center">
|
315 |
-
<i class="fab fa-twitter"></i>
|
316 |
-
</a>
|
317 |
-
<a href="#" class="w-10 h-10 rounded-full bg-gray-800 hover:bg-gray-700 flex items-center justify-center">
|
318 |
-
<i class="fab fa-instagram"></i>
|
319 |
-
</a>
|
320 |
-
<a href="#" class="w-10 h-10 rounded-full bg-gray-800 hover:bg-gray-700 flex items-center justify-center">
|
321 |
-
<i class="fab fa-linkedin-in"></i>
|
322 |
-
</a>
|
323 |
-
</div>
|
324 |
-
</div>
|
325 |
-
</div>
|
326 |
|
327 |
-
|
328 |
-
|
329 |
-
<
|
330 |
-
|
331 |
-
<
|
332 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
333 |
</div>
|
334 |
</div>
|
335 |
</div>
|
336 |
-
</footer>
|
337 |
-
|
338 |
-
<!-- Floating Action Button -->
|
339 |
-
<div class="fixed bottom-8 right-8">
|
340 |
-
<button class="floating-btn w-16 h-16 rounded-full bg-green-500 text-white shadow-xl flex items-center justify-center text-2xl">
|
341 |
-
<i class="fas fa-comment-dots"></i>
|
342 |
-
</button>
|
343 |
</div>
|
344 |
|
345 |
<script>
|
@@ -348,6 +324,9 @@
|
|
348 |
let imageToAnalyze;
|
349 |
|
350 |
// DOM elements
|
|
|
|
|
|
|
351 |
const dropZone = document.getElementById('dropZone');
|
352 |
const fileInput = document.getElementById('fileInput');
|
353 |
const selectFileBtn = document.getElementById('selectFileBtn');
|
@@ -358,8 +337,20 @@
|
|
358 |
const loadingIndicator = document.getElementById('loadingIndicator');
|
359 |
const resultsContainer = document.getElementById('resultsContainer');
|
360 |
const resultsContent = document.getElementById('resultsContent');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
361 |
|
362 |
-
//
|
363 |
selectFileBtn.addEventListener('click', () => fileInput.click());
|
364 |
fileInput.addEventListener('change', handleFileSelect);
|
365 |
analyzeBtn.addEventListener('click', analyzeImage);
|
@@ -416,6 +407,7 @@
|
|
416 |
imageToAnalyze = imagePreview;
|
417 |
previewContainer.style.display = 'block';
|
418 |
dropZone.style.display = 'none';
|
|
|
419 |
};
|
420 |
|
421 |
reader.readAsDataURL(file);
|
@@ -444,21 +436,23 @@
|
|
444 |
resultsContainer.style.display = 'none';
|
445 |
|
446 |
// Wait a bit to show the loading indicator (simulate processing time)
|
447 |
-
await new Promise(resolve => setTimeout(resolve,
|
448 |
|
449 |
// Classify the image
|
450 |
const predictions = await model.classify(imageToAnalyze);
|
451 |
|
452 |
// Process results - in a real app, we would have a custom model trained on plastic types
|
453 |
-
// For this demo, we'll simulate plastic type detection based on the MobileNet predictions
|
454 |
const plasticType = simulatePlasticTypeDetection(predictions);
|
455 |
|
456 |
// Display results
|
457 |
displayResults(plasticType, predictions);
|
458 |
|
|
|
|
|
|
|
459 |
} catch (error) {
|
460 |
console.error('Error analyzing image:', error);
|
461 |
-
|
462 |
resetTool();
|
463 |
}
|
464 |
}
|
@@ -468,6 +462,11 @@
|
|
468 |
// In a real application, this would be replaced with a custom model trained on plastic types
|
469 |
// Here we're just simulating based on the MobileNet predictions
|
470 |
|
|
|
|
|
|
|
|
|
|
|
471 |
// Check if the predictions contain words related to electronics (higher chance of ABS, PC, etc.)
|
472 |
const hasElectronics = predictions.some(p =>
|
473 |
p.className.toLowerCase().includes('computer') ||
|
@@ -489,39 +488,79 @@
|
|
489 |
p.className.toLowerCase().includes('wire')
|
490 |
);
|
491 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
492 |
// Determine the most likely plastic type based on these checks
|
493 |
if (hasElectronics) {
|
494 |
return {
|
495 |
-
type: 'ABS
|
|
|
496 |
code: '7',
|
497 |
description: 'Comum em teclados, carcaças de computadores e eletrodomésticos. Resistente ao impacto e fácil de moldar.',
|
498 |
density: '1.04-1.06 g/cm³',
|
499 |
-
confidence: Math.random() * 0.
|
|
|
|
|
|
|
|
|
500 |
};
|
501 |
} else if (hasPackaging) {
|
502 |
return {
|
503 |
-
type: 'PP
|
|
|
504 |
code: '5',
|
505 |
description: 'Presente em baterias, componentes internos e isolantes. Resistente a produtos químicos.',
|
506 |
density: '0.89-0.91 g/cm³',
|
507 |
-
confidence: Math.random() * 0.
|
|
|
|
|
|
|
|
|
508 |
};
|
509 |
} else if (hasCables) {
|
510 |
return {
|
511 |
-
type: 'PVC
|
|
|
512 |
code: '3',
|
513 |
description: 'Usado em fios, cabos e revestimentos. Flexível e resistente à chama.',
|
514 |
density: '1.30-1.45 g/cm³',
|
515 |
-
confidence: Math.random() * 0.
|
|
|
|
|
|
|
|
|
516 |
};
|
517 |
-
} else {
|
518 |
-
// Default to PC (Policarbonato) if no specific matches
|
519 |
return {
|
520 |
-
type: 'PC
|
|
|
521 |
code: '7',
|
522 |
description: 'Encontrado em CDs, DVDs, lentes e componentes ópticos. Transparente e altamente resistente.',
|
523 |
density: '1.20-1.22 g/cm³',
|
524 |
-
confidence: Math.random() * 0.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
525 |
};
|
526 |
}
|
527 |
}
|
@@ -529,71 +568,80 @@
|
|
529 |
// Display the analysis results
|
530 |
function displayResults(plasticType, predictions) {
|
531 |
loadingIndicator.style.display = 'none';
|
|
|
532 |
|
533 |
// Create results HTML
|
534 |
let html = `
|
535 |
-
<div class="bg-
|
536 |
-
<div class="flex items-
|
537 |
-
<div
|
538 |
-
<
|
|
|
539 |
</div>
|
540 |
-
<
|
541 |
</div>
|
542 |
|
543 |
-
<
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
<div>
|
549 |
-
<h5 class="font-medium text-gray-700 mb-1">Código de Identificação</h5>
|
550 |
-
<span class="bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm font-medium">Código ${plasticType.code}</span>
|
551 |
-
</div>
|
552 |
-
<div>
|
553 |
-
<h5 class="font-medium text-gray-700 mb-1">Densidade</h5>
|
554 |
-
<p>${plasticType.density}</p>
|
555 |
-
</div>
|
556 |
-
<div>
|
557 |
-
<h5 class="font-medium text-gray-700 mb-1">Confiança da Análise</h5>
|
558 |
<div class="progress-bar">
|
559 |
<div class="progress-bar-fill" style="width: ${Math.round(plasticType.confidence * 100)}%"></div>
|
560 |
</div>
|
561 |
-
<p class="text-sm text-gray-600 mt-1">${Math.round(plasticType.confidence * 100)}% de certeza</p>
|
562 |
</div>
|
|
|
563 |
</div>
|
564 |
|
565 |
-
<div class="
|
566 |
-
|
567 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
568 |
</div>
|
569 |
</div>
|
570 |
|
571 |
-
<div class="bg-
|
572 |
-
<h4 class="
|
573 |
-
<
|
574 |
-
<
|
575 |
-
<
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
<
|
585 |
-
</
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
592 |
</div>
|
593 |
-
|
594 |
-
<button class="mt-6 w-full bg-blue-500 hover:bg-blue-600 text-white py-3 rounded-full font-semibold transition">
|
595 |
-
<i class="fas fa-map-marker-alt mr-2"></i> Encontrar pontos de coleta próximos
|
596 |
-
</button>
|
597 |
</div>
|
598 |
`;
|
599 |
|
@@ -608,6 +656,7 @@
|
|
608 |
loadingIndicator.style.display = 'none';
|
609 |
resultsContainer.style.display = 'none';
|
610 |
dropZone.style.display = 'block';
|
|
|
611 |
imageToAnalyze = null;
|
612 |
}
|
613 |
|
|
|
3 |
<head>
|
4 |
<meta charset="UTF-8">
|
5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6 |
+
<title>Ferramenta de Identificação - ReciclaTech</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 |
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tf.min.js"></script>
|
10 |
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/[email protected]"></script>
|
11 |
<style>
|
12 |
+
.sidebar {
|
13 |
+
width: 280px;
|
14 |
+
transition: all 0.3s;
|
|
|
|
|
|
|
15 |
}
|
16 |
+
.sidebar-collapsed {
|
17 |
+
width: 80px;
|
18 |
}
|
19 |
+
.main-content {
|
20 |
+
margin-left: 280px;
|
21 |
+
transition: all 0.3s;
|
|
|
22 |
}
|
23 |
+
.main-content-expanded {
|
24 |
+
margin-left: 80px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
}
|
26 |
+
.drop-zone {
|
27 |
+
border: 2px dashed #ccc;
|
|
|
28 |
border-radius: 8px;
|
29 |
+
padding: 40px;
|
30 |
+
text-align: center;
|
31 |
+
cursor: pointer;
|
32 |
+
transition: all 0.3s;
|
33 |
}
|
34 |
+
.drop-zone.highlight {
|
35 |
+
border-color: #3b82f6;
|
36 |
+
background-color: rgba(59, 130, 246, 0.1);
|
37 |
}
|
38 |
+
.plastic-badge {
|
39 |
+
font-size: 12px;
|
40 |
+
padding: 2px 8px;
|
41 |
+
border-radius: 10px;
|
42 |
+
font-weight: bold;
|
43 |
}
|
44 |
+
.plastic-1 { background-color: #FF5733; color: white; }
|
45 |
+
.plastic-2 { background-color: #33FF57; color: #111; }
|
46 |
+
.plastic-3 { background-color: #3357FF; color: white; }
|
47 |
+
.plastic-4 { background-color: #F3FF33; color: #111; }
|
48 |
+
.plastic-5 { background-color: #FF33F3; color: white; }
|
49 |
+
.plastic-6 { background-color: #33FFF3; color: #111; }
|
50 |
+
.plastic-7 { background-color: #8A33FF; color: white; }
|
51 |
.progress-bar {
|
52 |
+
height: 8px;
|
53 |
background-color: #e0e0e0;
|
54 |
+
border-radius: 4px;
|
55 |
overflow: hidden;
|
56 |
}
|
57 |
.progress-bar-fill {
|
58 |
height: 100%;
|
59 |
+
background-color: #3b82f6;
|
60 |
transition: width 0.3s ease;
|
61 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
</style>
|
63 |
</head>
|
64 |
+
<body class="bg-gray-100 font-sans flex">
|
65 |
+
<!-- Sidebar -->
|
66 |
+
<div id="sidebar" class="sidebar bg-gray-800 text-white h-screen fixed">
|
67 |
+
<div class="p-4 flex items-center justify-between border-b border-gray-700">
|
68 |
+
<div class="flex items-center space-x-2">
|
69 |
+
<i class="fas fa-recycle text-2xl text-blue-400"></i>
|
70 |
+
<span id="logo-text" class="font-bold text-lg">ReciclaTech</span>
|
71 |
+
</div>
|
72 |
+
<button id="toggle-sidebar" class="text-gray-400 hover:text-white">
|
73 |
+
<i class="fas fa-bars"></i>
|
74 |
+
</button>
|
75 |
+
</div>
|
76 |
+
|
77 |
+
<nav class="p-4">
|
78 |
+
<div class="mb-8">
|
79 |
+
<div class="text-gray-400 text-xs uppercase font-bold mb-2" id="nav-section-title">Menu Principal</div>
|
80 |
+
<ul class="space-y-2">
|
81 |
+
<li>
|
82 |
+
<a href="#" class="flex items-center space-x-3 p-2 rounded bg-gray-700 text-white">
|
83 |
+
<i class="fas fa-home w-6 text-center"></i>
|
84 |
+
<span id="nav-dashboard" class="font-medium">Dashboard</span>
|
85 |
+
</a>
|
86 |
+
</li>
|
87 |
+
<li>
|
88 |
+
<a href="#" class="flex items-center space-x-3 p-2 rounded hover:bg-gray-700 text-gray-300 hover:text-white">
|
89 |
+
<i class="fas fa-tasks w-6 text-center"></i>
|
90 |
+
<span id="nav-processos" class="font-medium">Processos</span>
|
91 |
+
</a>
|
92 |
+
</li>
|
93 |
+
<li>
|
94 |
+
<a href="#" class="flex items-center space-x-3 p-2 rounded hover:bg-gray-700 text-gray-300 hover:text-white">
|
95 |
+
<i class="fas fa-warehouse w-6 text-center"></i>
|
96 |
+
<span id="nav-estoque" class="font-medium">Estoque</span>
|
97 |
+
</a>
|
98 |
+
</li>
|
99 |
+
<li>
|
100 |
+
<a href="#" class="flex items-center space-x-3 p-2 rounded hover:bg-gray-700 text-gray-300 hover:text-white">
|
101 |
+
<i class="fas fa-chart-line w-6 text-center"></i>
|
102 |
+
<span id="nav-relatorios" class="font-medium">Relatórios</span>
|
103 |
+
</a>
|
104 |
+
</li>
|
105 |
+
</ul>
|
106 |
+
</div>
|
107 |
+
|
108 |
+
<div>
|
109 |
+
<div class="text-gray-400 text-xs uppercase font-bold mb-2" id="tools-section-title">Ferramentas</div>
|
110 |
+
<ul class="space-y-2">
|
111 |
+
<li>
|
112 |
+
<a href="#" class="flex items-center space-x-3 p-2 rounded bg-blue-900 text-white">
|
113 |
+
<i class="fas fa-camera w-6 text-center"></i>
|
114 |
+
<span id="nav-identificador" class="font-medium">Identificador</span>
|
115 |
+
</a>
|
116 |
+
</li>
|
117 |
+
<li>
|
118 |
+
<a href="#" class="flex items-center space-x-3 p-2 rounded hover:bg-gray-700 text-gray-300 hover:text-white">
|
119 |
+
<i class="fas fa-barcode w-6 text-center"></i>
|
120 |
+
<span id="nav-etiquetas" class="font-medium">Gerar Etiquetas</span>
|
121 |
+
</a>
|
122 |
+
</li>
|
123 |
+
<li>
|
124 |
+
<a href="#" class="flex items-center space-x-3 p-2 rounded hover:bg-gray-700 text-gray-300 hover:text-white">
|
125 |
+
<i class="fas fa-weight w-6 text-center"></i>
|
126 |
+
<span id="nav-pesagem" class="font-medium">Registro de Pesagem</span>
|
127 |
+
</a>
|
128 |
+
</li>
|
129 |
+
</ul>
|
130 |
+
</div>
|
131 |
+
</nav>
|
132 |
+
|
133 |
+
<div class="absolute bottom-0 left-0 right-0 p-4 border-t border-gray-700">
|
134 |
+
<div class="flex items-center space-x-3 p-2 rounded hover:bg-gray-700 text-gray-300 hover:text-white cursor-pointer">
|
135 |
+
<i class="fas fa-user-circle w-6 text-center"></i>
|
136 |
+
<span id="nav-perfil" class="font-medium">Perfil do Usuário</span>
|
137 |
+
</div>
|
138 |
+
<div class="flex items-center space-x-3 p-2 rounded hover:bg-gray-700 text-gray-300 hover:text-white cursor-pointer">
|
139 |
+
<i class="fas fa-sign-out-alt w-6 text-center"></i>
|
140 |
+
<span id="nav-sair" class="font-medium">Sair do Sistema</span>
|
141 |
</div>
|
142 |
</div>
|
143 |
+
</div>
|
144 |
|
145 |
+
<!-- Main Content -->
|
146 |
+
<div id="main-content" class="main-content flex-1 p-6">
|
147 |
+
<div class="bg-white rounded-lg shadow-md p-6">
|
148 |
+
<!-- Header -->
|
149 |
+
<div class="flex justify-between items-center mb-6">
|
150 |
+
<div>
|
151 |
+
<h1 class="text-2xl font-bold text-gray-800">Identificador de Plásticos</h1>
|
152 |
+
<p class="text-gray-600">Ferramenta de classificação automática para materiais eletrônicos</p>
|
153 |
+
</div>
|
154 |
+
<div class="flex space-x-3">
|
155 |
+
<button class="bg-gray-200 hover:bg-gray-300 text-gray-800 px-4 py-2 rounded-lg font-medium flex items-center">
|
156 |
+
<i class="fas fa-history mr-2"></i> Histórico
|
157 |
+
</button>
|
158 |
+
<button class="bg-blue-50 hover:bg-blue-100 text-blue-700 px-4 py-2 rounded-lg font-medium flex items-center">
|
159 |
+
<i class="fas fa-question-circle mr-2"></i> Ajuda
|
160 |
+
</button>
|
161 |
+
</div>
|
162 |
+
</div>
|
163 |
+
|
164 |
+
<!-- Tool Section -->
|
165 |
+
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
166 |
+
<!-- Upload Section -->
|
167 |
+
<div class="lg:col-span-2">
|
168 |
+
<div class="bg-gray-50 rounded-lg p-6">
|
169 |
+
<h2 class="text-lg font-semibold mb-4">Enviar imagem para análise</h2>
|
170 |
+
|
171 |
+
<div id="dropZone" class="drop-zone mb-6">
|
172 |
+
<i class="fas fa-cloud-upload-alt text-4xl text-gray-400 mb-3"></i>
|
173 |
+
<h3 class="text-lg font-medium mb-1">Arraste e solte a imagem aqui</h3>
|
174 |
+
<p class="text-gray-500 mb-4">ou clique para selecionar um arquivo</p>
|
175 |
+
<button id="selectFileBtn" class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg font-medium transition">
|
|
|
|
|
|
|
176 |
Selecionar arquivo
|
177 |
</button>
|
178 |
<input type="file" id="fileInput" accept="image/*" class="hidden">
|
179 |
</div>
|
180 |
|
181 |
+
<div id="previewContainer" class="hidden">
|
182 |
+
<div class="flex justify-between items-center mb-3">
|
183 |
+
<h3 class="text-lg font-medium">Pré-visualização</h3>
|
184 |
+
<button id="cancelBtn" class="text-gray-500 hover:text-gray-700">
|
185 |
+
<i class="fas fa-times"></i> Cancelar
|
186 |
+
</button>
|
187 |
+
</div>
|
188 |
+
<div class="border border-gray-200 rounded-lg p-4">
|
189 |
+
<img id="imagePreview" src="#" alt="Pré-visualização da imagem" class="max-w-full h-auto rounded mx-auto">
|
190 |
+
</div>
|
191 |
+
<button id="analyzeBtn" class="mt-4 w-full bg-blue-600 hover:bg-blue-700 text-white py-3 rounded-lg font-semibold transition">
|
192 |
+
<i class="fas fa-search mr-2"></i> Analisar Material
|
193 |
</button>
|
194 |
</div>
|
195 |
|
196 |
+
<div id="loadingIndicator" class="hidden text-center py-8">
|
197 |
+
<div class="inline-block animate-spin rounded-full h-10 w-10 border-t-2 border-b-2 border-blue-500 mb-4"></div>
|
198 |
+
<p class="text-gray-600">Analisando o material plástico...</p>
|
199 |
+
<p class="text-sm text-gray-500 mt-2">Isso pode levar alguns segundos</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
</div>
|
201 |
</div>
|
202 |
</div>
|
203 |
|
204 |
+
<!-- Results Section -->
|
205 |
+
<div>
|
206 |
+
<div class="bg-gray-50 rounded-lg p-6 h-full">
|
207 |
+
<h2 class="text-lg font-semibold mb-4">Resultados da Análise</h2>
|
208 |
+
|
209 |
+
<div id="resultsContainer" class="hidden">
|
210 |
+
<div id="resultsContent" class="space-y-4">
|
211 |
+
<!-- Results will be inserted here by JavaScript -->
|
212 |
+
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
</div>
|
214 |
+
|
215 |
+
<div id="emptyState" class="text-center py-8">
|
216 |
+
<i class="fas fa-microscope text-4xl text-gray-300 mb-3"></i>
|
217 |
+
<h3 class="text-gray-500 font-medium">Nenhuma análise realizada</h3>
|
218 |
+
<p class="text-sm text-gray-400 mt-1">Envie uma imagem para identificar o tipo de plástico</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
219 |
</div>
|
220 |
</div>
|
221 |
</div>
|
222 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
223 |
|
224 |
+
<!-- Recent Analyses -->
|
225 |
+
<div class="mt-8">
|
226 |
+
<h2 class="text-lg font-semibold mb-4">Análises Recentes</h2>
|
227 |
+
<div class="bg-gray-50 rounded-lg p-4 overflow-x-auto">
|
228 |
+
<table class="min-w-full divide-y divide-gray-200">
|
229 |
+
<thead class="bg-gray-100">
|
230 |
+
<tr>
|
231 |
+
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Data/Hora</th>
|
232 |
+
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tipo de Plástico</th>
|
233 |
+
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Confiança</th>
|
234 |
+
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Origem</th>
|
235 |
+
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Ações</th>
|
236 |
+
</tr>
|
237 |
+
</thead>
|
238 |
+
<tbody class="bg-white divide-y divide-gray-200">
|
239 |
+
<tr>
|
240 |
+
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">15/06 14:32</td>
|
241 |
+
<td class="px-6 py-4 whitespace-nowrap">
|
242 |
+
<span class="plastic-badge plastic-1">ABS</span>
|
243 |
+
</td>
|
244 |
+
<td class="px-6 py-4 whitespace-nowrap">
|
245 |
+
<div class="flex items-center">
|
246 |
+
<div class="w-16 mr-2">
|
247 |
+
<div class="progress-bar">
|
248 |
+
<div class="progress-bar-fill" style="width: 87%"></div>
|
249 |
+
</div>
|
250 |
+
</div>
|
251 |
+
<span class="text-sm text-gray-500">87%</span>
|
252 |
+
</div>
|
253 |
+
</td>
|
254 |
+
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">Teclado Dell</td>
|
255 |
+
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
256 |
+
<button class="text-blue-600 hover:text-blue-800 mr-3">
|
257 |
+
<i class="fas fa-eye"></i>
|
258 |
+
</button>
|
259 |
+
<button class="text-green-600 hover:text-green-800">
|
260 |
+
<i class="fas fa-tag"></i>
|
261 |
+
</button>
|
262 |
+
</td>
|
263 |
+
</tr>
|
264 |
+
<tr>
|
265 |
+
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">15/06 13:15</td>
|
266 |
+
<td class="px-6 py-4 whitespace-nowrap">
|
267 |
+
<span class="plastic-badge plastic-3">PVC</span>
|
268 |
+
</td>
|
269 |
+
<td class="px-6 py-4 whitespace-nowrap">
|
270 |
+
<div class="flex items-center">
|
271 |
+
<div class="w-16 mr-2">
|
272 |
+
<div class="progress-bar">
|
273 |
+
<div class="progress-bar-fill" style="width: 92%"></div>
|
274 |
+
</div>
|
275 |
+
</div>
|
276 |
+
<span class="text-sm text-gray-500">92%</span>
|
277 |
+
</div>
|
278 |
+
</td>
|
279 |
+
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">Cabo de rede</td>
|
280 |
+
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
281 |
+
<button class="text-blue-600 hover:text-blue-800 mr-3">
|
282 |
+
<i class="fas fa-eye"></i>
|
283 |
+
</button>
|
284 |
+
<button class="text-green-600 hover:text-green-800">
|
285 |
+
<i class="fas fa-tag"></i>
|
286 |
+
</button>
|
287 |
+
</td>
|
288 |
+
</tr>
|
289 |
+
<tr>
|
290 |
+
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">15/06 11:42</td>
|
291 |
+
<td class="px-6 py-4 whitespace-nowrap">
|
292 |
+
<span class="plastic-badge plastic-7">PC</span>
|
293 |
+
</td>
|
294 |
+
<td class="px-6 py-4 whitespace-nowrap">
|
295 |
+
<div class="flex items-center">
|
296 |
+
<div class="w-16 mr-2">
|
297 |
+
<div class="progress-bar">
|
298 |
+
<div class="progress-bar-fill" style="width: 78%"></div>
|
299 |
+
</div>
|
300 |
+
</div>
|
301 |
+
<span class="text-sm text-gray-500">78%</span>
|
302 |
+
</div>
|
303 |
+
</td>
|
304 |
+
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">Tela LCD</td>
|
305 |
+
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
306 |
+
<button class="text-blue-600 hover:text-blue-800 mr-3">
|
307 |
+
<i class="fas fa-eye"></i>
|
308 |
+
</button>
|
309 |
+
<button class="text-green-600 hover:text-green-800">
|
310 |
+
<i class="fas fa-tag"></i>
|
311 |
+
</button>
|
312 |
+
</td>
|
313 |
+
</tr>
|
314 |
+
</tbody>
|
315 |
+
</table>
|
316 |
</div>
|
317 |
</div>
|
318 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
319 |
</div>
|
320 |
|
321 |
<script>
|
|
|
324 |
let imageToAnalyze;
|
325 |
|
326 |
// DOM elements
|
327 |
+
const sidebar = document.getElementById('sidebar');
|
328 |
+
const mainContent = document.getElementById('main-content');
|
329 |
+
const toggleSidebarBtn = document.getElementById('toggle-sidebar');
|
330 |
const dropZone = document.getElementById('dropZone');
|
331 |
const fileInput = document.getElementById('fileInput');
|
332 |
const selectFileBtn = document.getElementById('selectFileBtn');
|
|
|
337 |
const loadingIndicator = document.getElementById('loadingIndicator');
|
338 |
const resultsContainer = document.getElementById('resultsContainer');
|
339 |
const resultsContent = document.getElementById('resultsContent');
|
340 |
+
const emptyState = document.getElementById('emptyState');
|
341 |
+
|
342 |
+
// Toggle sidebar
|
343 |
+
toggleSidebarBtn.addEventListener('click', () => {
|
344 |
+
sidebar.classList.toggle('sidebar-collapsed');
|
345 |
+
mainContent.classList.toggle('main-content-expanded');
|
346 |
+
|
347 |
+
// Toggle text elements in sidebar
|
348 |
+
document.querySelectorAll('[id$="-text"], [id^="nav-"], [id$="-title"]').forEach(el => {
|
349 |
+
el.classList.toggle('hidden');
|
350 |
+
});
|
351 |
+
});
|
352 |
|
353 |
+
// File selection events
|
354 |
selectFileBtn.addEventListener('click', () => fileInput.click());
|
355 |
fileInput.addEventListener('change', handleFileSelect);
|
356 |
analyzeBtn.addEventListener('click', analyzeImage);
|
|
|
407 |
imageToAnalyze = imagePreview;
|
408 |
previewContainer.style.display = 'block';
|
409 |
dropZone.style.display = 'none';
|
410 |
+
emptyState.style.display = 'none';
|
411 |
};
|
412 |
|
413 |
reader.readAsDataURL(file);
|
|
|
436 |
resultsContainer.style.display = 'none';
|
437 |
|
438 |
// Wait a bit to show the loading indicator (simulate processing time)
|
439 |
+
await new Promise(resolve => setTimeout(resolve, 1500));
|
440 |
|
441 |
// Classify the image
|
442 |
const predictions = await model.classify(imageToAnalyze);
|
443 |
|
444 |
// Process results - in a real app, we would have a custom model trained on plastic types
|
|
|
445 |
const plasticType = simulatePlasticTypeDetection(predictions);
|
446 |
|
447 |
// Display results
|
448 |
displayResults(plasticType, predictions);
|
449 |
|
450 |
+
// Add to recent analyses (simulated)
|
451 |
+
addToRecentAnalyses(plasticType);
|
452 |
+
|
453 |
} catch (error) {
|
454 |
console.error('Error analyzing image:', error);
|
455 |
+
showError('Erro ao analisar a imagem. Por favor, tente novamente.');
|
456 |
resetTool();
|
457 |
}
|
458 |
}
|
|
|
462 |
// In a real application, this would be replaced with a custom model trained on plastic types
|
463 |
// Here we're just simulating based on the MobileNet predictions
|
464 |
|
465 |
+
// Get current time for the analysis
|
466 |
+
const now = new Date();
|
467 |
+
const timeString = `${now.getHours()}:${now.getMinutes().toString().padStart(2, '0')}`;
|
468 |
+
const dateString = `${now.getDate()}/${now.getMonth()+1}`;
|
469 |
+
|
470 |
// Check if the predictions contain words related to electronics (higher chance of ABS, PC, etc.)
|
471 |
const hasElectronics = predictions.some(p =>
|
472 |
p.className.toLowerCase().includes('computer') ||
|
|
|
488 |
p.className.toLowerCase().includes('wire')
|
489 |
);
|
490 |
|
491 |
+
// Check if the predictions contain words related to screens (higher chance of PC)
|
492 |
+
const hasScreens = predictions.some(p =>
|
493 |
+
p.className.toLowerCase().includes('screen') ||
|
494 |
+
p.className.toLowerCase().includes('monitor') ||
|
495 |
+
p.className.toLowerCase().includes('display')
|
496 |
+
);
|
497 |
+
|
498 |
// Determine the most likely plastic type based on these checks
|
499 |
if (hasElectronics) {
|
500 |
return {
|
501 |
+
type: 'ABS',
|
502 |
+
fullName: 'Acrilonitrila Butadieno Estireno',
|
503 |
code: '7',
|
504 |
description: 'Comum em teclados, carcaças de computadores e eletrodomésticos. Resistente ao impacto e fácil de moldar.',
|
505 |
density: '1.04-1.06 g/cm³',
|
506 |
+
confidence: Math.random() * 0.15 + 0.85, // Random confidence between 85% and 100%
|
507 |
+
origin: predictions[0].className,
|
508 |
+
date: dateString,
|
509 |
+
time: timeString,
|
510 |
+
badgeClass: 'plastic-1'
|
511 |
};
|
512 |
} else if (hasPackaging) {
|
513 |
return {
|
514 |
+
type: 'PP',
|
515 |
+
fullName: 'Polipropileno',
|
516 |
code: '5',
|
517 |
description: 'Presente em baterias, componentes internos e isolantes. Resistente a produtos químicos.',
|
518 |
density: '0.89-0.91 g/cm³',
|
519 |
+
confidence: Math.random() * 0.15 + 0.85,
|
520 |
+
origin: predictions[0].className,
|
521 |
+
date: dateString,
|
522 |
+
time: timeString,
|
523 |
+
badgeClass: 'plastic-4'
|
524 |
};
|
525 |
} else if (hasCables) {
|
526 |
return {
|
527 |
+
type: 'PVC',
|
528 |
+
fullName: 'Policloreto de Vinila',
|
529 |
code: '3',
|
530 |
description: 'Usado em fios, cabos e revestimentos. Flexível e resistente à chama.',
|
531 |
density: '1.30-1.45 g/cm³',
|
532 |
+
confidence: Math.random() * 0.15 + 0.85,
|
533 |
+
origin: predictions[0].className,
|
534 |
+
date: dateString,
|
535 |
+
time: timeString,
|
536 |
+
badgeClass: 'plastic-3'
|
537 |
};
|
538 |
+
} else if (hasScreens) {
|
|
|
539 |
return {
|
540 |
+
type: 'PC',
|
541 |
+
fullName: 'Policarbonato',
|
542 |
code: '7',
|
543 |
description: 'Encontrado em CDs, DVDs, lentes e componentes ópticos. Transparente e altamente resistente.',
|
544 |
density: '1.20-1.22 g/cm³',
|
545 |
+
confidence: Math.random() * 0.15 + 0.85,
|
546 |
+
origin: predictions[0].className,
|
547 |
+
date: dateString,
|
548 |
+
time: timeString,
|
549 |
+
badgeClass: 'plastic-7'
|
550 |
+
};
|
551 |
+
} else {
|
552 |
+
// Default to HIPS if no specific matches
|
553 |
+
return {
|
554 |
+
type: 'HIPS',
|
555 |
+
fullName: 'Poliestireno de Alto Impacto',
|
556 |
+
code: '6',
|
557 |
+
description: 'Usado em monitores, TVs e embalagens. Reconhecível pelo som metálico quando batido.',
|
558 |
+
density: '1.03-1.06 g/cm³',
|
559 |
+
confidence: Math.random() * 0.15 + 0.85,
|
560 |
+
origin: predictions[0].className,
|
561 |
+
date: dateString,
|
562 |
+
time: timeString,
|
563 |
+
badgeClass: 'plastic-2'
|
564 |
};
|
565 |
}
|
566 |
}
|
|
|
568 |
// Display the analysis results
|
569 |
function displayResults(plasticType, predictions) {
|
570 |
loadingIndicator.style.display = 'none';
|
571 |
+
emptyState.style.display = 'none';
|
572 |
|
573 |
// Create results HTML
|
574 |
let html = `
|
575 |
+
<div class="bg-white border border-gray-200 rounded-lg p-4 mb-4">
|
576 |
+
<div class="flex justify-between items-start mb-3">
|
577 |
+
<div>
|
578 |
+
<span class="${plasticType.badgeClass} plastic-badge">${plasticType.type}</span>
|
579 |
+
<span class="ml-2 text-sm text-gray-500">Código ${plasticType.code}</span>
|
580 |
</div>
|
581 |
+
<div class="text-sm text-gray-500">${plasticType.date} ${plasticType.time}</div>
|
582 |
</div>
|
583 |
|
584 |
+
<h3 class="font-bold text-lg mb-1">${plasticType.fullName}</h3>
|
585 |
+
<p class="text-sm text-gray-600 mb-3">${plasticType.description}</p>
|
586 |
+
|
587 |
+
<div class="flex items-center mb-2">
|
588 |
+
<div class="w-full mr-2">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
589 |
<div class="progress-bar">
|
590 |
<div class="progress-bar-fill" style="width: ${Math.round(plasticType.confidence * 100)}%"></div>
|
591 |
</div>
|
|
|
592 |
</div>
|
593 |
+
<span class="text-sm font-medium">${Math.round(plasticType.confidence * 100)}%</span>
|
594 |
</div>
|
595 |
|
596 |
+
<div class="text-xs text-gray-500 mb-3">Origem identificada: ${plasticType.origin}</div>
|
597 |
+
|
598 |
+
<div class="grid grid-cols-2 gap-2">
|
599 |
+
<button class="bg-blue-50 hover:bg-blue-100 text-blue-700 px-3 py-2 rounded text-sm font-medium">
|
600 |
+
<i class="fas fa-tag mr-1"></i> Etiquetar
|
601 |
+
</button>
|
602 |
+
<button class="bg-gray-50 hover:bg-gray-100 text-gray-700 px-3 py-2 rounded text-sm font-medium">
|
603 |
+
<i class="fas fa-box mr-1"></i> Armazenar
|
604 |
+
</button>
|
605 |
</div>
|
606 |
</div>
|
607 |
|
608 |
+
<div class="bg-white border border-gray-200 rounded-lg p-4">
|
609 |
+
<h4 class="font-semibold mb-2">Próximos passos recomendados</h4>
|
610 |
+
<ul class="space-y-2 text-sm">
|
611 |
+
<li class="flex items-start">
|
612 |
+
<i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
|
613 |
+
<span>Separar na área de plásticos tipo ${plasticType.code}</span>
|
614 |
+
</li>
|
615 |
+
<li class="flex items-start">
|
616 |
+
<i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
|
617 |
+
<span>Registrar no sistema como ${plasticType.type}</span>
|
618 |
+
</li>
|
619 |
+
<li class="flex items-start">
|
620 |
+
<i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
|
621 |
+
<span>Encaminhar para processo de trituração</span>
|
622 |
+
</li>
|
623 |
+
</ul>
|
624 |
+
</div>
|
625 |
+
`;
|
626 |
+
|
627 |
+
resultsContent.innerHTML = html;
|
628 |
+
resultsContainer.style.display = 'block';
|
629 |
+
}
|
630 |
+
|
631 |
+
// Simulate adding to recent analyses
|
632 |
+
function addToRecentAnalyses(plasticType) {
|
633 |
+
// In a real app, this would be saved to a database
|
634 |
+
console.log('Analysis saved:', plasticType);
|
635 |
+
}
|
636 |
+
|
637 |
+
// Show error message
|
638 |
+
function showError(message) {
|
639 |
+
const html = `
|
640 |
+
<div class="bg-red-50 border border-red-200 rounded-lg p-4 text-red-700">
|
641 |
+
<div class="flex items-center">
|
642 |
+
<i class="fas fa-exclamation-circle mr-2"></i>
|
643 |
+
<span>${message}</span>
|
644 |
</div>
|
|
|
|
|
|
|
|
|
645 |
</div>
|
646 |
`;
|
647 |
|
|
|
656 |
loadingIndicator.style.display = 'none';
|
657 |
resultsContainer.style.display = 'none';
|
658 |
dropZone.style.display = 'block';
|
659 |
+
emptyState.style.display = 'block';
|
660 |
imageToAnalyze = null;
|
661 |
}
|
662 |
|
prompts.txt
CHANGED
@@ -1 +1,2 @@
|
|
1 |
-
preciso que seja capaz de identificar o plástico e auxiliar na separação do material através da foto , e que isso seja funcional por favor
|
|
|
|
1 |
+
preciso que seja capaz de identificar o plástico e auxiliar na separação do material através da foto , e que isso seja funcional por favor
|
2 |
+
mude a estrutura para algo que seja como uma especie de ferramenta dentro do sistema de uma empresa de reciclagem do lixo eletronico, e nao um site institucional com essa funcionalidade,
|