Spaces:
Running
Running
AA commited on
Add 3 files
Browse files- README.md +6 -4
- index.html +821 -19
- prompts.txt +1 -0
README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji:
|
| 4 |
colorFrom: yellow
|
| 5 |
-
colorTo:
|
| 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: beta3
|
| 3 |
+
emoji: 🐳
|
| 4 |
colorFrom: yellow
|
| 5 |
+
colorTo: green
|
| 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,821 @@
|
|
| 1 |
-
<!
|
| 2 |
-
<html>
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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>WaterHub - Your Local Water Quality Report</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 |
+
<link href="https://api.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.css" rel="stylesheet">
|
| 10 |
+
<script src="https://api.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.js"></script>
|
| 11 |
+
<style>
|
| 12 |
+
.gradient-bg {
|
| 13 |
+
background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%);
|
| 14 |
+
}
|
| 15 |
+
.water-wave {
|
| 16 |
+
position: relative;
|
| 17 |
+
overflow: hidden;
|
| 18 |
+
}
|
| 19 |
+
.water-wave::after {
|
| 20 |
+
content: "";
|
| 21 |
+
position: absolute;
|
| 22 |
+
bottom: 0;
|
| 23 |
+
left: 0;
|
| 24 |
+
right: 0;
|
| 25 |
+
height: 20px;
|
| 26 |
+
background: url('data:image/svg+xml;utf8,<svg viewBox="0 0 1200 120" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none"><path d="M0,0V46.29c47.79,22.2,103.59,32.17,158,28,70.36-5.37,136.33-33.31,206.8-37.5C438.64,32.43,512.34,53.67,583,72.05c69.27,18,138.3,24.88,209.4,13.08,36.15-6,69.85-17.84,104.45-29.34C989.49,25,1113-14.29,1200,52.47V0Z" fill="%23f8fafc" opacity=".25"/><path d="M0,0V15.81C13,36.92,27.64,56.86,47.69,72.05,99.41,111.27,165,111,224.58,91.58c31.15-10.15,60.09-26.07,89.67-39.8,40.92-19,84.73-46,130.83-49.67,36.26-2.85,70.9,9.42,98.6,31.56,31.77,25.39,62.32,62,103.63,73,40.44,10.79,81.35-6.69,119.13-24.28s75.16-39,116.92-43.05c59.73-5.85,113.28,22.88,168.9,38.84,30.2,8.66,59,6.17,87.09-7.5,22.43-10.89,48-26.93,60.65-49.24V0Z" fill="%23f8fafc" opacity=".5"/><path d="M0,0V5.63C149.93,59,314.09,71.32,475.83,42.57c43-7.64,84.23-20.12,127.61-26.46,59-8.63,112.48,12.24,165.56,35.4C827.93,77.22,886,95.24,951.2,90c86.53-7,172.46-45.71,248.8-84.81V0Z" fill="%23f8fafc"/></svg>');
|
| 27 |
+
background-size: cover;
|
| 28 |
+
}
|
| 29 |
+
.score-ring {
|
| 30 |
+
stroke-dasharray: 440;
|
| 31 |
+
transform: rotate(-90deg);
|
| 32 |
+
transform-origin: 50% 50%;
|
| 33 |
+
}
|
| 34 |
+
.contaminant-bar {
|
| 35 |
+
transition: width 0.5s ease-in-out;
|
| 36 |
+
}
|
| 37 |
+
.map-container {
|
| 38 |
+
height: 300px;
|
| 39 |
+
border-radius: 0.5rem;
|
| 40 |
+
position: relative;
|
| 41 |
+
overflow: hidden;
|
| 42 |
+
}
|
| 43 |
+
.gradient-bar {
|
| 44 |
+
background: linear-gradient(90deg, #ef4444 0%, #f59e0b 50%, #10b981 100%);
|
| 45 |
+
}
|
| 46 |
+
.location-search {
|
| 47 |
+
position: relative;
|
| 48 |
+
}
|
| 49 |
+
.location-dropdown {
|
| 50 |
+
position: absolute;
|
| 51 |
+
top: 100%;
|
| 52 |
+
left: 0;
|
| 53 |
+
right: 0;
|
| 54 |
+
background: white;
|
| 55 |
+
border: 1px solid #e5e7eb;
|
| 56 |
+
border-radius: 0.375rem;
|
| 57 |
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
| 58 |
+
z-index: 10;
|
| 59 |
+
max-height: 200px;
|
| 60 |
+
overflow-y: auto;
|
| 61 |
+
}
|
| 62 |
+
.location-dropdown-item {
|
| 63 |
+
padding: 0.5rem 1rem;
|
| 64 |
+
cursor: pointer;
|
| 65 |
+
}
|
| 66 |
+
.location-dropdown-item:hover {
|
| 67 |
+
background-color: #f3f4f6;
|
| 68 |
+
}
|
| 69 |
+
#map {
|
| 70 |
+
width: 100%;
|
| 71 |
+
height: 100%;
|
| 72 |
+
}
|
| 73 |
+
.map-marker {
|
| 74 |
+
background-color: #ef4444;
|
| 75 |
+
border-radius: 50%;
|
| 76 |
+
width: 20px;
|
| 77 |
+
height: 20px;
|
| 78 |
+
border: 2px solid white;
|
| 79 |
+
box-shadow: 0 0 0 10px rgba(239, 68, 68, 0.3);
|
| 80 |
+
animation: pulse 2s infinite;
|
| 81 |
+
}
|
| 82 |
+
@keyframes pulse {
|
| 83 |
+
0% {
|
| 84 |
+
box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
|
| 85 |
+
}
|
| 86 |
+
70% {
|
| 87 |
+
box-shadow: 0 0 0 15px rgba(239, 68, 68, 0);
|
| 88 |
+
}
|
| 89 |
+
100% {
|
| 90 |
+
box-shadow: 0 0 0 0 rgba(239, 68, 68, 0);
|
| 91 |
+
}
|
| 92 |
+
}
|
| 93 |
+
.map-radius {
|
| 94 |
+
border-radius: 50%;
|
| 95 |
+
background-color: rgba(239, 68, 68, 0.2);
|
| 96 |
+
border: 2px solid #ef4444;
|
| 97 |
+
}
|
| 98 |
+
</style>
|
| 99 |
+
</head>
|
| 100 |
+
<body class="bg-gray-50 font-sans">
|
| 101 |
+
<!-- Header -->
|
| 102 |
+
<header class="gradient-bg text-white water-wave">
|
| 103 |
+
<div class="container mx-auto px-4 py-8">
|
| 104 |
+
<div class="flex justify-center">
|
| 105 |
+
<img src="https://waterhub.co/wp-content/uploads/2025/04/WaterHub-Updated-Logo.png" alt="WaterHub Logo" class="h-16">
|
| 106 |
+
</div>
|
| 107 |
+
|
| 108 |
+
<div class="mt-12 mb-16 text-center">
|
| 109 |
+
<h2 class="text-4xl font-bold mb-4">Your Local Water Quality</h2>
|
| 110 |
+
<p class="text-xl max-w-2xl mx-auto">See how clean and safe your drinking water is based on your location in Southern Ontario</p>
|
| 111 |
+
</div>
|
| 112 |
+
</div>
|
| 113 |
+
</header>
|
| 114 |
+
|
| 115 |
+
<!-- Main Content -->
|
| 116 |
+
<main class="container mx-auto px-4 py-12 -mt-10">
|
| 117 |
+
<div class="bg-white rounded-xl shadow-lg overflow-hidden">
|
| 118 |
+
<!-- Location Info -->
|
| 119 |
+
<div class="p-6 border-b border-gray-200">
|
| 120 |
+
<div class="flex flex-col md:flex-row justify-between items-start md:items-center">
|
| 121 |
+
<div class="w-full md:w-auto">
|
| 122 |
+
<h3 class="text-2xl font-semibold text-gray-800">Water Quality Report For:</h3>
|
| 123 |
+
<div class="location-search mt-2 w-full md:w-96">
|
| 124 |
+
<div class="flex items-center">
|
| 125 |
+
<i class="fas fa-map-marker-alt text-blue-500 mr-2"></i>
|
| 126 |
+
<input type="text" id="location-input" class="flex-1 border-b border-gray-300 py-1 px-2 focus:outline-none focus:border-blue-500" placeholder="Enter your location...">
|
| 127 |
+
<button id="use-my-location" class="ml-2 text-blue-600 hover:text-blue-800">
|
| 128 |
+
<i class="fas fa-location-arrow"></i>
|
| 129 |
+
</button>
|
| 130 |
+
</div>
|
| 131 |
+
<div id="location-dropdown" class="location-dropdown hidden"></div>
|
| 132 |
+
</div>
|
| 133 |
+
<p id="location-display" class="mt-2 text-lg text-gray-600 hidden"></p>
|
| 134 |
+
</div>
|
| 135 |
+
<button id="refresh-btn" class="mt-4 md:mt-0 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition flex items-center">
|
| 136 |
+
<i class="fas fa-sync-alt mr-2"></i> Refresh
|
| 137 |
+
</button>
|
| 138 |
+
</div>
|
| 139 |
+
</div>
|
| 140 |
+
|
| 141 |
+
<!-- Water Quality Dashboard -->
|
| 142 |
+
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8 p-6">
|
| 143 |
+
<!-- Score Card -->
|
| 144 |
+
<div class="bg-gray-50 p-6 rounded-lg">
|
| 145 |
+
<h4 class="text-lg font-medium text-gray-700 mb-4">Overall Water Quality Score</h4>
|
| 146 |
+
<div class="relative w-40 h-40 mx-auto mb-6">
|
| 147 |
+
<svg class="w-full h-full" viewBox="0 0 100 100">
|
| 148 |
+
<circle cx="50" cy="50" r="45" fill="none" stroke="#e5e7eb" stroke-width="8"/>
|
| 149 |
+
<circle id="score-circle" cx="50" cy="50" r="45" fill="none" stroke="#3b82f6" stroke-width="8" stroke-linecap="round" class="score-ring" stroke-dashoffset="440"/>
|
| 150 |
+
</svg>
|
| 151 |
+
<div class="absolute inset-0 flex items-center justify-center flex-col">
|
| 152 |
+
<span id="score-value" class="text-4xl font-bold text-gray-800">--</span>
|
| 153 |
+
<span class="text-gray-500">out of 100</span>
|
| 154 |
+
</div>
|
| 155 |
+
</div>
|
| 156 |
+
<div id="score-message" class="text-center text-gray-600">
|
| 157 |
+
Loading your water quality score...
|
| 158 |
+
</div>
|
| 159 |
+
</div>
|
| 160 |
+
|
| 161 |
+
<!-- Contaminants Breakdown -->
|
| 162 |
+
<div class="lg:col-span-2">
|
| 163 |
+
<h4 class="text-lg font-medium text-gray-700 mb-4">Contaminants Breakdown</h4>
|
| 164 |
+
<div id="contaminants-container" class="space-y-4">
|
| 165 |
+
<div class="animate-pulse space-y-4">
|
| 166 |
+
<div class="h-4 bg-gray-200 rounded w-3/4"></div>
|
| 167 |
+
<div class="h-4 bg-gray-200 rounded"></div>
|
| 168 |
+
<div class="h-4 bg-gray-200 rounded w-5/6"></div>
|
| 169 |
+
<div class="h-4 bg-gray-200 rounded w-2/3"></div>
|
| 170 |
+
</div>
|
| 171 |
+
</div>
|
| 172 |
+
|
| 173 |
+
<div class="mt-8">
|
| 174 |
+
<h4 class="text-lg font-medium text-gray-700 mb-4">Safety Information</h4>
|
| 175 |
+
<div id="safety-info" class="bg-blue-50 border-l-4 border-blue-500 p-4 rounded-r">
|
| 176 |
+
<p class="text-blue-800">Your water meets Health Canada's safety standards. No immediate health risks detected.</p>
|
| 177 |
+
</div>
|
| 178 |
+
</div>
|
| 179 |
+
</div>
|
| 180 |
+
</div>
|
| 181 |
+
|
| 182 |
+
<!-- Map and Additional Info -->
|
| 183 |
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 p-6 border-t border-gray-200">
|
| 184 |
+
<div class="map-container">
|
| 185 |
+
<div id="map"></div>
|
| 186 |
+
</div>
|
| 187 |
+
|
| 188 |
+
<div>
|
| 189 |
+
<h4 class="text-lg font-medium text-gray-700 mb-4">How to Improve Your Water Quality</h4>
|
| 190 |
+
<div class="space-y-4">
|
| 191 |
+
<div class="flex items-start">
|
| 192 |
+
<div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 mr-4">
|
| 193 |
+
<i class="fas fa-filter"></i>
|
| 194 |
+
</div>
|
| 195 |
+
<div>
|
| 196 |
+
<h5 class="font-medium text-gray-800">Install a Water Filter</h5>
|
| 197 |
+
<p class="text-gray-600 mt-1">Our advanced filtration systems can remove up to 99.9% of contaminants.</p>
|
| 198 |
+
</div>
|
| 199 |
+
</div>
|
| 200 |
+
|
| 201 |
+
<div class="flex items-start">
|
| 202 |
+
<div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 mr-4">
|
| 203 |
+
<i class="fas fa-tint"></i>
|
| 204 |
+
</div>
|
| 205 |
+
<div>
|
| 206 |
+
<h5 class="font-medium text-gray-800">Test Your Water Regularly</h5>
|
| 207 |
+
<p class="text-gray-600 mt-1">Water quality can change. Regular testing ensures ongoing safety.</p>
|
| 208 |
+
</div>
|
| 209 |
+
</div>
|
| 210 |
+
|
| 211 |
+
<div class="flex items-start">
|
| 212 |
+
<div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 mr-4">
|
| 213 |
+
<i class="fas fa-info-circle"></i>
|
| 214 |
+
</div>
|
| 215 |
+
<div>
|
| 216 |
+
<h5 class="font-medium text-gray-800">Learn About Your Water</h5>
|
| 217 |
+
<p class="text-gray-600 mt-1">Understanding contaminants helps you make informed decisions.</p>
|
| 218 |
+
</div>
|
| 219 |
+
</div>
|
| 220 |
+
</div>
|
| 221 |
+
|
| 222 |
+
<div class="mt-8">
|
| 223 |
+
<a href="https://waterhub.co/shop" class="inline-flex items-center px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition">
|
| 224 |
+
Shop Water Solutions
|
| 225 |
+
<i class="fas fa-arrow-right ml-2"></i>
|
| 226 |
+
</a>
|
| 227 |
+
</div>
|
| 228 |
+
</div>
|
| 229 |
+
</div>
|
| 230 |
+
</div>
|
| 231 |
+
</main>
|
| 232 |
+
|
| 233 |
+
<!-- Footer -->
|
| 234 |
+
<footer class="bg-gray-800 text-white py-12">
|
| 235 |
+
<div class="container mx-auto px-4">
|
| 236 |
+
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
|
| 237 |
+
<div>
|
| 238 |
+
<img src="https://waterhub.co/wp-content/uploads/2025/04/WaterHub-Updated-Logo.png" alt="WaterHub Logo" class="h-10 mb-4">
|
| 239 |
+
<p class="text-gray-400">Providing clean, safe water solutions for Southern Ontario homes and businesses.</p>
|
| 240 |
+
</div>
|
| 241 |
+
<div>
|
| 242 |
+
<h5 class="text-lg font-medium mb-4">Quick Links</h5>
|
| 243 |
+
<ul class="space-y-2">
|
| 244 |
+
<li><a href="https://waterhub.co/" class="text-gray-400 hover:text-white transition">Home</a></li>
|
| 245 |
+
<li><a href="https://waterhub.co/shop" class="text-gray-400 hover:text-white transition">Shop</a></li>
|
| 246 |
+
<li><a href="https://waterhub.co/about" class="text-gray-400 hover:text-white transition">About Us</a></li>
|
| 247 |
+
<li><a href="https://waterhub.co/contact" class="text-gray-400 hover:text-white transition">Contact</a></li>
|
| 248 |
+
</ul>
|
| 249 |
+
</div>
|
| 250 |
+
<div>
|
| 251 |
+
<h5 class="text-lg font-medium mb-4">Resources</h5>
|
| 252 |
+
<ul class="space-y-2">
|
| 253 |
+
<li><a href="https://waterhub.co/blog" class="text-gray-400 hover:text-white transition">Blog</a></li>
|
| 254 |
+
<li><a href="https://waterhub.co/water-quality" class="text-gray-400 hover:text-white transition">Water Quality Guide</a></li>
|
| 255 |
+
<li><a href="https://waterhub.co/faq" class="text-gray-400 hover:text-white transition">FAQs</a></li>
|
| 256 |
+
</ul>
|
| 257 |
+
</div>
|
| 258 |
+
<div>
|
| 259 |
+
<h5 class="text-lg font-medium mb-4">Contact Us</h5>
|
| 260 |
+
<ul class="space-y-2 text-gray-400">
|
| 261 |
+
<li class="flex items-center"><i class="fas fa-phone-alt mr-2"></i> +1 (647) 560-2795</li>
|
| 262 |
+
<li class="flex items-center"><i class="fas fa-envelope mr-2"></i> info@waterhub.co</li>
|
| 263 |
+
<li class="flex items-center"><i class="fas fa-map-marker-alt mr-2"></i> Toronto, ON</li>
|
| 264 |
+
</ul>
|
| 265 |
+
</div>
|
| 266 |
+
</div>
|
| 267 |
+
<div class="border-t border-gray-700 mt-8 pt-8 text-center text-gray-400">
|
| 268 |
+
<p>© 2023 WaterHub. All rights reserved.</p>
|
| 269 |
+
</div>
|
| 270 |
+
</div>
|
| 271 |
+
</footer>
|
| 272 |
+
|
| 273 |
+
<script>
|
| 274 |
+
// Database of Southern Ontario water quality data with coordinates
|
| 275 |
+
const waterQualityData = {
|
| 276 |
+
"toronto": {
|
| 277 |
+
score: 87,
|
| 278 |
+
contaminants: [
|
| 279 |
+
{ name: "Chlorine", level: 0.8, safeLevel: 4, unit: "mg/L" },
|
| 280 |
+
{ name: "Lead", level: 0.002, safeLevel: 0.005, unit: "mg/L" },
|
| 281 |
+
{ name: "Fluoride", level: 0.7, safeLevel: 1.5, unit: "mg/L" },
|
| 282 |
+
{ name: "Nitrates", level: 2.1, safeLevel: 10, unit: "mg/L" }
|
| 283 |
+
],
|
| 284 |
+
message: "Toronto's water meets all provincial and federal standards. Chlorine levels are slightly elevated but within safe limits.",
|
| 285 |
+
coordinates: [-79.3832, 43.6532]
|
| 286 |
+
},
|
| 287 |
+
"mississauga": {
|
| 288 |
+
score: 92,
|
| 289 |
+
contaminants: [
|
| 290 |
+
{ name: "Chlorine", level: 0.5, safeLevel: 4, unit: "mg/L" },
|
| 291 |
+
{ name: "Lead", level: 0.001, safeLevel: 0.005, unit: "mg/L" },
|
| 292 |
+
{ name: "Fluoride", level: 0.6, safeLevel: 1.5, unit: "mg/L" },
|
| 293 |
+
{ name: "Nitrates", level: 1.8, safeLevel: 10, unit: "mg/L" }
|
| 294 |
+
],
|
| 295 |
+
message: "Mississauga has good water quality with all contaminants well below safety thresholds.",
|
| 296 |
+
coordinates: [-79.6441, 43.5890]
|
| 297 |
+
},
|
| 298 |
+
"brampton": {
|
| 299 |
+
score: 85,
|
| 300 |
+
contaminants: [
|
| 301 |
+
{ name: "Chlorine", level: 1.2, safeLevel: 4, unit: "mg/L" },
|
| 302 |
+
{ name: "Lead", level: 0.003, safeLevel: 0.005, unit: "mg/L" },
|
| 303 |
+
{ name: "Fluoride", level: 0.8, safeLevel: 1.5, unit: "mg/L" },
|
| 304 |
+
{ name: "Nitrates", level: 3.5, safeLevel: 10, unit: "mg/L" }
|
| 305 |
+
],
|
| 306 |
+
message: "Brampton's water is safe to drink. Chlorine levels are higher than average but still within safe limits.",
|
| 307 |
+
coordinates: [-79.7593, 43.7315]
|
| 308 |
+
},
|
| 309 |
+
"hamilton": {
|
| 310 |
+
score: 72,
|
| 311 |
+
contaminants: [
|
| 312 |
+
{ name: "Chlorine", level: 1.5, safeLevel: 4, unit: "mg/L" },
|
| 313 |
+
{ name: "Lead", level: 0.004, safeLevel: 0.005, unit: "mg/L" },
|
| 314 |
+
{ name: "Fluoride", level: 1.1, safeLevel: 1.5, unit: "mg/L" },
|
| 315 |
+
{ name: "Nitrates", level: 5.2, safeLevel: 10, unit: "mg/L" }
|
| 316 |
+
],
|
| 317 |
+
message: "Hamilton's water meets safety standards but has elevated levels of several contaminants. Consider filtration for improved taste.",
|
| 318 |
+
coordinates: [-79.8711, 43.2557]
|
| 319 |
+
},
|
| 320 |
+
"london": {
|
| 321 |
+
score: 83,
|
| 322 |
+
contaminants: [
|
| 323 |
+
{ name: "Chlorine", level: 1.0, safeLevel: 4, unit: "mg/L" },
|
| 324 |
+
{ name: "Lead", level: 0.002, safeLevel: 0.005, unit: "mg/L" },
|
| 325 |
+
{ name: "Fluoride", level: 0.7, safeLevel: 1.5, unit: "mg/L" },
|
| 326 |
+
{ name: "Nitrates", level: 4.1, safeLevel: 10, unit: "mg/L" }
|
| 327 |
+
],
|
| 328 |
+
message: "London's water quality is fair with all contaminants within safe levels. Nitrates are slightly elevated but not concerning.",
|
| 329 |
+
coordinates: [-81.2453, 42.9849]
|
| 330 |
+
},
|
| 331 |
+
"markham": {
|
| 332 |
+
score: 89,
|
| 333 |
+
contaminants: [
|
| 334 |
+
{ name: "Chlorine", level: 0.7, safeLevel: 4, unit: "mg/L" },
|
| 335 |
+
{ name: "Lead", level: 0.002, safeLevel: 0.005, unit: "mg/L" },
|
| 336 |
+
{ name: "Fluoride", level: 0.6, safeLevel: 1.5, unit: "mg/L" },
|
| 337 |
+
{ name: "Nitrates", level: 2.8, safeLevel: 10, unit: "mg/L" }
|
| 338 |
+
],
|
| 339 |
+
message: "Markham's water quality is excellent with all contaminants well within safe limits.",
|
| 340 |
+
coordinates: [-79.3297, 43.8561]
|
| 341 |
+
},
|
| 342 |
+
"vaughan": {
|
| 343 |
+
score: 88,
|
| 344 |
+
contaminants: [
|
| 345 |
+
{ name: "Chlorine", level: 0.9, safeLevel: 4, unit: "mg/L" },
|
| 346 |
+
{ name: "Lead", level: 0.002, safeLevel: 0.005, unit: "mg/L" },
|
| 347 |
+
{ name: "Fluoride", level: 0.7, safeLevel: 1.5, unit: "mg/L" },
|
| 348 |
+
{ name: "Nitrates", level: 3.0, safeLevel: 10, unit: "mg/L" }
|
| 349 |
+
],
|
| 350 |
+
message: "Vaughan's water quality is very good with all contaminants within safe levels.",
|
| 351 |
+
coordinates: [-79.4985, 43.8361]
|
| 352 |
+
},
|
| 353 |
+
"ajax": {
|
| 354 |
+
score: 86,
|
| 355 |
+
contaminants: [
|
| 356 |
+
{ name: "Chlorine", level: 1.0, safeLevel: 4, unit: "mg/L" },
|
| 357 |
+
{ name: "Lead", level: 0.003, safeLevel: 0.005, unit: "mg/L" },
|
| 358 |
+
{ name: "Fluoride", level: 0.8, safeLevel: 1.5, unit: "mg/L" },
|
| 359 |
+
{ name: "Nitrates", level: 3.2, safeLevel: 10, unit: "mg/L" }
|
| 360 |
+
],
|
| 361 |
+
message: "Ajax's water quality is good with all contaminants within safe levels.",
|
| 362 |
+
coordinates: [-79.0207, 43.8509]
|
| 363 |
+
},
|
| 364 |
+
"peterborough": {
|
| 365 |
+
score: 81,
|
| 366 |
+
contaminants: [
|
| 367 |
+
{ name: "Chlorine", level: 1.3, safeLevel: 4, unit: "mg/L" },
|
| 368 |
+
{ name: "Lead", level: 0.004, safeLevel: 0.005, unit: "mg/L" },
|
| 369 |
+
{ name: "Fluoride", level: 1.0, safeLevel: 1.5, unit: "mg/L" },
|
| 370 |
+
{ name: "Nitrates", level: 4.5, safeLevel: 10, unit: "mg/L" }
|
| 371 |
+
],
|
| 372 |
+
message: "Peterborough's water meets safety standards but has slightly elevated levels of some contaminants.",
|
| 373 |
+
coordinates: [-78.3168, 44.3091]
|
| 374 |
+
},
|
| 375 |
+
"newmarket": {
|
| 376 |
+
score: 87,
|
| 377 |
+
contaminants: [
|
| 378 |
+
{ name: "Chlorine", level: 0.8, safeLevel: 4, unit: "mg/L" },
|
| 379 |
+
{ name: "Lead", level: 0.002, safeLevel: 0.005, unit: "mg/L" },
|
| 380 |
+
{ name: "Fluoride", level: 0.7, safeLevel: 1.5, unit: "mg/L" },
|
| 381 |
+
{ name: "Nitrates", level: 3.0, safeLevel: 10, unit: "mg/L" }
|
| 382 |
+
],
|
| 383 |
+
message: "Newmarket's water quality is very good with all contaminants within safe levels.",
|
| 384 |
+
coordinates: [-79.4593, 44.0553]
|
| 385 |
+
},
|
| 386 |
+
"barrie": {
|
| 387 |
+
score: 84,
|
| 388 |
+
contaminants: [
|
| 389 |
+
{ name: "Chlorine", level: 1.1, safeLevel: 4, unit: "mg/L" },
|
| 390 |
+
{ name: "Lead", level: 0.003, safeLevel: 0.005, unit: "mg/L" },
|
| 391 |
+
{ name: "Fluoride", level: 0.9, safeLevel: 1.5, unit: "mg/L" },
|
| 392 |
+
{ name: "Nitrates", level: 3.8, safeLevel: 10, unit: "mg/L" }
|
| 393 |
+
],
|
| 394 |
+
message: "Barrie's water quality is good with all contaminants within safe levels.",
|
| 395 |
+
coordinates: [-79.6900, 44.3894]
|
| 396 |
+
},
|
| 397 |
+
"milton": {
|
| 398 |
+
score: 90,
|
| 399 |
+
contaminants: [
|
| 400 |
+
{ name: "Chlorine", level: 0.6, safeLevel: 4, unit: "mg/L" },
|
| 401 |
+
{ name: "Lead", level: 0.001, safeLevel: 0.005, unit: "mg/L" },
|
| 402 |
+
{ name: "Fluoride", level: 0.6, safeLevel: 1.5, unit: "mg/L" },
|
| 403 |
+
{ name: "Nitrates", level: 2.5, safeLevel: 10, unit: "mg/L" }
|
| 404 |
+
],
|
| 405 |
+
message: "Milton's water quality is excellent with all contaminants well within safe limits.",
|
| 406 |
+
coordinates: [-79.8770, 43.5183]
|
| 407 |
+
},
|
| 408 |
+
"waterloo": {
|
| 409 |
+
score: 85,
|
| 410 |
+
contaminants: [
|
| 411 |
+
{ name: "Chlorine", level: 1.0, safeLevel: 4, unit: "mg/L" },
|
| 412 |
+
{ name: "Lead", level: 0.003, safeLevel: 0.005, unit: "mg/L" },
|
| 413 |
+
{ name: "Fluoride", level: 0.8, safeLevel: 1.5, unit: "mg/L" },
|
| 414 |
+
{ name: "Nitrates", level: 3.5, safeLevel: 10, unit: "mg/L" }
|
| 415 |
+
],
|
| 416 |
+
message: "Waterloo's water quality is good with all contaminants within safe levels.",
|
| 417 |
+
coordinates: [-80.5204, 43.4643]
|
| 418 |
+
},
|
| 419 |
+
"kitchener": {
|
| 420 |
+
score: 83,
|
| 421 |
+
contaminants: [
|
| 422 |
+
{ name: "Chlorine", level: 1.2, safeLevel: 4, unit: "mg/L" },
|
| 423 |
+
{ name: "Lead", level: 0.003, safeLevel: 0.005, unit: "mg/L" },
|
| 424 |
+
{ name: "Fluoride", level: 0.9, safeLevel: 1.5, unit: "mg/L" },
|
| 425 |
+
{ name: "Nitrates", level: 4.0, safeLevel: 10, unit: "mg/L" }
|
| 426 |
+
],
|
| 427 |
+
message: "Kitchener's water quality is fair with all contaminants within safe levels.",
|
| 428 |
+
coordinates: [-80.4926, 43.4516]
|
| 429 |
+
},
|
| 430 |
+
"st. catharines": {
|
| 431 |
+
score: 80,
|
| 432 |
+
contaminants: [
|
| 433 |
+
{ name: "Chlorine", level: 1.4, safeLevel: 4, unit: "mg/L" },
|
| 434 |
+
{ name: "Lead", level: 0.004, safeLevel: 0.005, unit: "mg/L" },
|
| 435 |
+
{ name: "Fluoride", level: 1.1, safeLevel: 1.5, unit: "mg/L" },
|
| 436 |
+
{ name: "Nitrates", level: 4.8, safeLevel: 10, unit: "mg/L" }
|
| 437 |
+
],
|
| 438 |
+
message: "St. Catharines' water meets safety standards but has elevated levels of some contaminants.",
|
| 439 |
+
coordinates: [-79.2461, 43.1594]
|
| 440 |
+
},
|
| 441 |
+
"collingwood": {
|
| 442 |
+
score: 82,
|
| 443 |
+
contaminants: [
|
| 444 |
+
{ name: "Chlorine", level: 1.2, safeLevel: 4, unit: "mg/L" },
|
| 445 |
+
{ name: "Lead", level: 0.003, safeLevel: 0.005, unit: "mg/L" },
|
| 446 |
+
{ name: "Fluoride", level: 0.9, safeLevel: 1.5, unit: "mg/L" },
|
| 447 |
+
{ name: "Nitrates", level: 4.2, safeLevel: 10, unit: "mg/L" }
|
| 448 |
+
],
|
| 449 |
+
message: "Collingwood's water quality is fair with all contaminants within safe levels.",
|
| 450 |
+
coordinates: [-80.2164, 44.5008]
|
| 451 |
+
},
|
| 452 |
+
"bowmanville": {
|
| 453 |
+
score: 86,
|
| 454 |
+
contaminants: [
|
| 455 |
+
{ name: "Chlorine", level: 0.9, safeLevel: 4, unit: "mg/L" },
|
| 456 |
+
{ name: "Lead", level: 0.002, safeLevel: 0.005, unit: "mg/L" },
|
| 457 |
+
{ name: "Fluoride", level: 0.7, safeLevel: 1.5, unit: "mg/L" },
|
| 458 |
+
{ name: "Nitrates", level: 3.1, safeLevel: 10, unit: "mg/L" }
|
| 459 |
+
],
|
| 460 |
+
message: "Bowmanville's water quality is good with all contaminants within safe levels.",
|
| 461 |
+
coordinates: [-78.6833, 43.9167]
|
| 462 |
+
},
|
| 463 |
+
"kingston": {
|
| 464 |
+
score: 79,
|
| 465 |
+
contaminants: [
|
| 466 |
+
{ name: "Chlorine", level: 1.5, safeLevel: 4, unit: "mg/L" },
|
| 467 |
+
{ name: "Lead", level: 0.004, safeLevel: 0.005, unit: "mg/L" },
|
| 468 |
+
{ name: "Fluoride", level: 1.2, safeLevel: 1.5, unit: "mg/L" },
|
| 469 |
+
{ name: "Nitrates", level: 5.0, safeLevel: 10, unit: "mg/L" }
|
| 470 |
+
],
|
| 471 |
+
message: "Kingston's water meets safety standards but has elevated levels of several contaminants.",
|
| 472 |
+
coordinates: [-76.4850, 44.2312]
|
| 473 |
+
},
|
| 474 |
+
"ottawa": {
|
| 475 |
+
score: 88,
|
| 476 |
+
contaminants: [
|
| 477 |
+
{ name: "Chlorine", level: 0.7, safeLevel: 4, unit: "mg/L" },
|
| 478 |
+
{ name: "Lead", level: 0.002, safeLevel: 0.005, unit: "mg/L" },
|
| 479 |
+
{ name: "Fluoride", level: 0.6, safeLevel: 1.5, unit: "mg/L" },
|
| 480 |
+
{ name: "Nitrates", level: 2.9, safeLevel: 10, unit: "mg/L" }
|
| 481 |
+
],
|
| 482 |
+
message: "Ottawa's water quality is excellent with all contaminants well within safe limits.",
|
| 483 |
+
coordinates: [-75.6972, 45.4215]
|
| 484 |
+
},
|
| 485 |
+
"default": {
|
| 486 |
+
score: 82,
|
| 487 |
+
contaminants: [
|
| 488 |
+
{ name: "Chlorine", level: 0.9, safeLevel: 4, unit: "mg/L" },
|
| 489 |
+
{ name: "Lead", level: 0.002, safeLevel: 0.005, unit: "mg/L" },
|
| 490 |
+
{ name: "Fluoride", level: 0.7, safeLevel: 1.5, unit: "mg/L" },
|
| 491 |
+
{ name: "Nitrates", level: 3.8, safeLevel: 10, unit: "mg/L" }
|
| 492 |
+
],
|
| 493 |
+
message: "Your water meets all safety standards. No immediate health risks detected.",
|
| 494 |
+
coordinates: [-79.3832, 43.6532] // Default to Toronto
|
| 495 |
+
}
|
| 496 |
+
};
|
| 497 |
+
|
| 498 |
+
// Initialize map
|
| 499 |
+
mapboxgl.accessToken = 'pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw';
|
| 500 |
+
const map = new mapboxgl.Map({
|
| 501 |
+
container: 'map',
|
| 502 |
+
style: 'mapbox://styles/mapbox/satellite-v9',
|
| 503 |
+
center: [-79.3832, 43.6532], // Default to Toronto
|
| 504 |
+
zoom: 8
|
| 505 |
+
});
|
| 506 |
+
|
| 507 |
+
// Add navigation controls
|
| 508 |
+
map.addControl(new mapboxgl.NavigationControl());
|
| 509 |
+
|
| 510 |
+
let marker = null;
|
| 511 |
+
let radiusCircle = null;
|
| 512 |
+
|
| 513 |
+
// Function to update the map with marker and radius
|
| 514 |
+
function updateMap(lngLat) {
|
| 515 |
+
// Remove existing marker and radius if they exist
|
| 516 |
+
if (marker) marker.remove();
|
| 517 |
+
if (radiusCircle) radiusCircle.remove();
|
| 518 |
+
|
| 519 |
+
// Add new marker
|
| 520 |
+
const el = document.createElement('div');
|
| 521 |
+
el.className = 'map-marker';
|
| 522 |
+
|
| 523 |
+
marker = new mapboxgl.Marker(el)
|
| 524 |
+
.setLngLat(lngLat)
|
| 525 |
+
.addTo(map);
|
| 526 |
+
|
| 527 |
+
// Add radius circle (50km)
|
| 528 |
+
radiusCircle = new mapboxgl.Popup({ closeButton: false, closeOnClick: false })
|
| 529 |
+
.setLngLat(lngLat)
|
| 530 |
+
.setHTML('<div class="map-radius" style="width: 100px; height: 100px;"></div>')
|
| 531 |
+
.addTo(map);
|
| 532 |
+
|
| 533 |
+
// Fly to the location
|
| 534 |
+
map.flyTo({
|
| 535 |
+
center: lngLat,
|
| 536 |
+
zoom: 9,
|
| 537 |
+
essential: true
|
| 538 |
+
});
|
| 539 |
+
}
|
| 540 |
+
|
| 541 |
+
// Function to update the UI with water quality data
|
| 542 |
+
function updateWaterQuality(city) {
|
| 543 |
+
const cityLower = city.toLowerCase();
|
| 544 |
+
const data = waterQualityData[cityLower] || waterQualityData["default"];
|
| 545 |
+
|
| 546 |
+
// Update score
|
| 547 |
+
document.getElementById('score-value').textContent = data.score;
|
| 548 |
+
const circle = document.getElementById('score-circle');
|
| 549 |
+
const offset = 440 - (440 * data.score / 100);
|
| 550 |
+
circle.style.strokeDashoffset = offset;
|
| 551 |
+
|
| 552 |
+
// Update score message
|
| 553 |
+
document.getElementById('score-message').textContent = getScoreMessage(data.score);
|
| 554 |
+
|
| 555 |
+
// Update safety info with recommendation
|
| 556 |
+
const safetyRating = data.score >= 95 ? "Excellent" :
|
| 557 |
+
data.score >= 90 ? "Fair" : "Poor";
|
| 558 |
+
|
| 559 |
+
document.getElementById('safety-info').innerHTML = `
|
| 560 |
+
<p class="text-blue-800">${data.message}</p>
|
| 561 |
+
<p class="mt-2 font-medium">Safety Rating: ${safetyRating}</p>
|
| 562 |
+
<p class="mt-2">${getRecommendation(data.score)}</p>
|
| 563 |
+
`;
|
| 564 |
+
|
| 565 |
+
// Update contaminants
|
| 566 |
+
const container = document.getElementById('contaminants-container');
|
| 567 |
+
container.innerHTML = '';
|
| 568 |
+
|
| 569 |
+
data.contaminants.forEach(contaminant => {
|
| 570 |
+
const percentage = Math.min(100, (contaminant.level / contaminant.safeLevel) * 100);
|
| 571 |
+
const isSafe = percentage <= 100;
|
| 572 |
+
|
| 573 |
+
const contaminantEl = document.createElement('div');
|
| 574 |
+
contaminantEl.className = 'space-y-2';
|
| 575 |
+
contaminantEl.innerHTML = `
|
| 576 |
+
<div class="flex justify-between">
|
| 577 |
+
<span class="font-medium">${contaminant.name}</span>
|
| 578 |
+
<span class="text-sm ${isSafe ? 'text-green-600' : 'text-red-600'}">
|
| 579 |
+
${contaminant.level} ${contaminant.unit} / ${contaminant.safeLevel} ${contaminant.unit}
|
| 580 |
+
</span>
|
| 581 |
+
</div>
|
| 582 |
+
<div class="w-full bg-gray-200 rounded-full h-2.5">
|
| 583 |
+
<div class="contaminant-bar gradient-bar h-2.5 rounded-full"
|
| 584 |
+
style="width: ${percentage}%"></div>
|
| 585 |
+
</div>
|
| 586 |
+
`;
|
| 587 |
+
container.appendChild(contaminantEl);
|
| 588 |
+
});
|
| 589 |
+
|
| 590 |
+
// Update map
|
| 591 |
+
updateMap(data.coordinates);
|
| 592 |
+
}
|
| 593 |
+
|
| 594 |
+
// Get appropriate message based on score
|
| 595 |
+
function getScoreMessage(score) {
|
| 596 |
+
if (score >= 95) return "Excellent Water Quality";
|
| 597 |
+
if (score >= 90) return "Fair Water Quality";
|
| 598 |
+
if (score >= 80) return "Poor Water Quality";
|
| 599 |
+
return "Very Poor Water Quality";
|
| 600 |
+
}
|
| 601 |
+
|
| 602 |
+
// Get recommendation based on score
|
| 603 |
+
function getRecommendation(score) {
|
| 604 |
+
if (score >= 95) return "Your water is excellent quality. Consider water softening solutions from <a href='https://waterhub.co/' class='text-blue-600 hover:underline'>WaterHub.co</a> for ideal conditions.";
|
| 605 |
+
if (score >= 90) return "Your water is fair quality. A filter is recommended to ensure ideal conditions. Check <a href='https://waterhub.co/' class='text-blue-600 hover:underline'>WaterHub.co</a> for solutions.";
|
| 606 |
+
if (score >= 80) return "Your water is poor quality. We recommend solutions from <a href='https://waterhub.co/' class='text-blue-600 hover:underline'>WaterHub.co</a>.";
|
| 607 |
+
return "Your water quality is very poor. You need a water filter solution. Visit <a href='https://waterhub.co/' class='text-blue-600 hover:underline'>WaterHub.co</a> for options.";
|
| 608 |
+
}
|
| 609 |
+
|
| 610 |
+
// Function to get user's location via IP
|
| 611 |
+
async function getLocationByIP() {
|
| 612 |
+
try {
|
| 613 |
+
const response = await fetch('https://ipapi.co/json/');
|
| 614 |
+
const data = await response.json();
|
| 615 |
+
|
| 616 |
+
// Check if the location is in Ontario
|
| 617 |
+
if (data.region === "Ontario") {
|
| 618 |
+
// Find the closest city in our database
|
| 619 |
+
let closestCity = "toronto";
|
| 620 |
+
let minDistance = Infinity;
|
| 621 |
+
|
| 622 |
+
for (const city in waterQualityData) {
|
| 623 |
+
if (city === "default") continue;
|
| 624 |
+
|
| 625 |
+
const cityData = waterQualityData[city];
|
| 626 |
+
const distance = Math.sqrt(
|
| 627 |
+
Math.pow(data.longitude - cityData.coordinates[0], 2) +
|
| 628 |
+
Math.pow(data.latitude - cityData.coordinates[1], 2)
|
| 629 |
+
);
|
| 630 |
+
|
| 631 |
+
if (distance < minDistance) {
|
| 632 |
+
minDistance = distance;
|
| 633 |
+
closestCity = city;
|
| 634 |
+
}
|
| 635 |
+
}
|
| 636 |
+
|
| 637 |
+
return closestCity;
|
| 638 |
+
} else {
|
| 639 |
+
return "toronto"; // Default to Toronto if not in Ontario
|
| 640 |
+
}
|
| 641 |
+
} catch (error) {
|
| 642 |
+
console.error("Error getting location by IP:", error);
|
| 643 |
+
return "toronto"; // Default to Toronto on error
|
| 644 |
+
}
|
| 645 |
+
}
|
| 646 |
+
|
| 647 |
+
// Function to get user's precise location via geolocation API
|
| 648 |
+
function getPreciseLocation() {
|
| 649 |
+
return new Promise((resolve, reject) => {
|
| 650 |
+
if (navigator.geolocation) {
|
| 651 |
+
navigator.geolocation.getCurrentPosition(
|
| 652 |
+
(position) => {
|
| 653 |
+
// Find the closest city in our database
|
| 654 |
+
let closestCity = "toronto";
|
| 655 |
+
let minDistance = Infinity;
|
| 656 |
+
|
| 657 |
+
for (const city in waterQualityData) {
|
| 658 |
+
if (city === "default") continue;
|
| 659 |
+
|
| 660 |
+
const cityData = waterQualityData[city];
|
| 661 |
+
const distance = Math.sqrt(
|
| 662 |
+
Math.pow(position.coords.longitude - cityData.coordinates[0], 2) +
|
| 663 |
+
Math.pow(position.coords.latitude - cityData.coordinates[1], 2)
|
| 664 |
+
);
|
| 665 |
+
|
| 666 |
+
if (distance < minDistance) {
|
| 667 |
+
minDistance = distance;
|
| 668 |
+
closestCity = city;
|
| 669 |
+
}
|
| 670 |
+
}
|
| 671 |
+
|
| 672 |
+
resolve(closestCity);
|
| 673 |
+
},
|
| 674 |
+
(error) => {
|
| 675 |
+
console.error("Geolocation error:", error);
|
| 676 |
+
resolve("toronto"); // Default to Toronto on error
|
| 677 |
+
}
|
| 678 |
+
);
|
| 679 |
+
} else {
|
| 680 |
+
resolve("toronto"); // Default to Toronto if geolocation not supported
|
| 681 |
+
}
|
| 682 |
+
});
|
| 683 |
+
}
|
| 684 |
+
|
| 685 |
+
// Function to search for locations as user types
|
| 686 |
+
function searchLocations(query) {
|
| 687 |
+
const results = [];
|
| 688 |
+
const queryLower = query.toLowerCase();
|
| 689 |
+
|
| 690 |
+
for (const city in waterQualityData) {
|
| 691 |
+
if (city === "default") continue;
|
| 692 |
+
|
| 693 |
+
if (city.includes(queryLower)) {
|
| 694 |
+
results.push({
|
| 695 |
+
name: city.charAt(0).toUpperCase() + city.slice(1),
|
| 696 |
+
key: city
|
| 697 |
+
});
|
| 698 |
+
}
|
| 699 |
+
}
|
| 700 |
+
|
| 701 |
+
return results;
|
| 702 |
+
}
|
| 703 |
+
|
| 704 |
+
// Initialize
|
| 705 |
+
document.addEventListener('DOMContentLoaded', async () => {
|
| 706 |
+
// Set default to Toronto
|
| 707 |
+
let currentLocation = "toronto";
|
| 708 |
+
document.getElementById('location-input').value = "Toronto";
|
| 709 |
+
document.getElementById('location-display').textContent = "Toronto, ON";
|
| 710 |
+
document.getElementById('location-display').classList.remove('hidden');
|
| 711 |
+
updateWaterQuality(currentLocation);
|
| 712 |
+
|
| 713 |
+
// Try to get more accurate location
|
| 714 |
+
try {
|
| 715 |
+
const preciseLocation = await getPreciseLocation();
|
| 716 |
+
if (preciseLocation !== "toronto") {
|
| 717 |
+
currentLocation = preciseLocation;
|
| 718 |
+
const displayName = preciseLocation.charAt(0).toUpperCase() + preciseLocation.slice(1);
|
| 719 |
+
document.getElementById('location-input').value = displayName;
|
| 720 |
+
document.getElementById('location-display').textContent = `${displayName}, ON`;
|
| 721 |
+
updateWaterQuality(currentLocation);
|
| 722 |
+
} else {
|
| 723 |
+
// Fall back to IP-based location if precise location not available
|
| 724 |
+
const ipLocation = await getLocationByIP();
|
| 725 |
+
if (ipLocation !== "toronto") {
|
| 726 |
+
currentLocation = ipLocation;
|
| 727 |
+
const displayName = ipLocation.charAt(0).toUpperCase() + ipLocation.slice(1);
|
| 728 |
+
document.getElementById('location-input').value = displayName;
|
| 729 |
+
document.getElementById('location-display').textContent = `${displayName}, ON`;
|
| 730 |
+
updateWaterQuality(currentLocation);
|
| 731 |
+
}
|
| 732 |
+
}
|
| 733 |
+
} catch (error) {
|
| 734 |
+
console.error("Error getting location:", error);
|
| 735 |
+
}
|
| 736 |
+
|
| 737 |
+
// Location input event listeners
|
| 738 |
+
const locationInput = document.getElementById('location-input');
|
| 739 |
+
const locationDropdown = document.getElementById('location-dropdown');
|
| 740 |
+
|
| 741 |
+
locationInput.addEventListener('input', () => {
|
| 742 |
+
const query = locationInput.value.trim();
|
| 743 |
+
|
| 744 |
+
if (query.length > 1) {
|
| 745 |
+
const results = searchLocations(query.toLowerCase());
|
| 746 |
+
|
| 747 |
+
if (results.length > 0) {
|
| 748 |
+
locationDropdown.innerHTML = '';
|
| 749 |
+
|
| 750 |
+
results.forEach(result => {
|
| 751 |
+
const item = document.createElement('div');
|
| 752 |
+
item.className = 'location-dropdown-item';
|
| 753 |
+
item.textContent = result.name;
|
| 754 |
+
item.addEventListener('click', () => {
|
| 755 |
+
locationInput.value = result.name;
|
| 756 |
+
document.getElementById('location-display').textContent = `${result.name}, ON`;
|
| 757 |
+
document.getElementById('location-display').classList.remove('hidden');
|
| 758 |
+
locationDropdown.classList.add('hidden');
|
| 759 |
+
updateWaterQuality(result.key);
|
| 760 |
+
});
|
| 761 |
+
|
| 762 |
+
locationDropdown.appendChild(item);
|
| 763 |
+
});
|
| 764 |
+
|
| 765 |
+
locationDropdown.classList.remove('hidden');
|
| 766 |
+
} else {
|
| 767 |
+
locationDropdown.classList.add('hidden');
|
| 768 |
+
}
|
| 769 |
+
} else {
|
| 770 |
+
locationDropdown.classList.add('hidden');
|
| 771 |
+
}
|
| 772 |
+
});
|
| 773 |
+
|
| 774 |
+
locationInput.addEventListener('focus', () => {
|
| 775 |
+
if (locationInput.value.trim().length > 1 && locationDropdown.children.length > 0) {
|
| 776 |
+
locationDropdown.classList.remove('hidden');
|
| 777 |
+
}
|
| 778 |
+
});
|
| 779 |
+
|
| 780 |
+
document.addEventListener('click', (e) => {
|
| 781 |
+
if (!locationInput.contains(e.target) && !locationDropdown.contains(e.target)) {
|
| 782 |
+
locationDropdown.classList.add('hidden');
|
| 783 |
+
}
|
| 784 |
+
});
|
| 785 |
+
|
| 786 |
+
// Use my location button
|
| 787 |
+
document.getElementById('use-my-location').addEventListener('click', async () => {
|
| 788 |
+
locationInput.value = "Detecting your location...";
|
| 789 |
+
document.getElementById('location-display').classList.add('hidden');
|
| 790 |
+
|
| 791 |
+
try {
|
| 792 |
+
const location = await getPreciseLocation();
|
| 793 |
+
const displayName = location.charAt(0).toUpperCase() + location.slice(1);
|
| 794 |
+
locationInput.value = displayName;
|
| 795 |
+
document.getElementById('location-display').textContent = `${displayName}, ON`;
|
| 796 |
+
document.getElementById('location-display').classList.remove('hidden');
|
| 797 |
+
updateWaterQuality(location);
|
| 798 |
+
} catch (error) {
|
| 799 |
+
console.error("Error getting location:", error);
|
| 800 |
+
locationInput.value = "Toronto";
|
| 801 |
+
document.getElementById('location-display').textContent = "Toronto, ON";
|
| 802 |
+
document.getElementById('location-display').classList.remove('hidden');
|
| 803 |
+
updateWaterQuality("toronto");
|
| 804 |
+
}
|
| 805 |
+
});
|
| 806 |
+
|
| 807 |
+
// Refresh button
|
| 808 |
+
document.getElementById('refresh-btn').addEventListener('click', () => {
|
| 809 |
+
const currentValue = locationInput.value.trim();
|
| 810 |
+
if (currentValue && waterQualityData[currentValue.toLowerCase()]) {
|
| 811 |
+
updateWaterQuality(currentValue.toLowerCase());
|
| 812 |
+
} else {
|
| 813 |
+
updateWaterQuality("toronto");
|
| 814 |
+
locationInput.value = "Toronto";
|
| 815 |
+
document.getElementById('location-display').textContent = "Toronto, ON";
|
| 816 |
+
}
|
| 817 |
+
});
|
| 818 |
+
});
|
| 819 |
+
</script>
|
| 820 |
+
<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=Pandafacewin/beta3" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
|
| 821 |
+
</html>
|
prompts.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
Use the provided html code to built ontop of, everything is perfect but I need you to ensure it has a full database of all southern Ontario cities and municipalities for example "Markham" "Vaughan" "Ajax" "Peterborough" "Newmarket" "Barrie" "Milton" "Waterloo" "Kitchener" "St.Catherines" "Collingwood" "Bomanville" "Kingston" "Ottawa", all of these cities should also be included in the database, addtionally the App MUST grab the user IP address or geolocation inorder to work, ensure that this functionality is working on the backend. Addtionally the default location should be "Toronto, Ontario" and there should also be a selectable text for the user to be able to click an manually enter their location, when the user is writing their location you must draw recommendations from the database as they type , allowing the option for them to select one of the database pre-entry locations. Addtionally the map showing the water quality, use a real satellite image from Google maps or any map showing southern Ontario, the red dot and 50km radius measurement should also be functional and move around the map as the user is address or geolocation changes.
|