PageSourceSearch

https://dreamy-truffle-77db6e.netlify.app/uccelli_cittadini%20definifivo/

html dreamy-truffle-77db6e.netlify.app collected 2026-10-03 10:40:00 UTC 37,856 bytes, 690 lines download raw bytes

1<!DOCTYPE html>
2<html lang="it">
3<head>
4  <meta charset="utf-8">
5  <meta name="viewport" content="width=device-width, initial-scale=1">
6  <title>Area Metropolitana di Milano — Scheda Uccelli</title>
7  <link rel="stylesheet" href="styles.css?v=3">
8  
8<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/heic2any.min.js"></script>
8
9</head>
10<body>
11  <div class="page">
12    
13<div class="card">
14  <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px;">
15    <button type="button" onclick="if(confirm('Vuoi davvero uscire? I dati inseriti andranno persi.')) window.location.href='../index.html'" style="background: transparent; border: none; cursor: pointer; padding: 0;" aria-label="Torna indietro">
16      <svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#12458c" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
17        <line x1="19" y1="12" x2="5" y2="12"></line>
18        <polyline points="12 19 5 12 12 5"></polyline>
19      </svg>
20    </button>
21    <h1 style="margin: 0; font-size: 24px; text-align: center; flex-grow: 1;">Area Metropolitana di Milano</h1>
22    <div style="width: 28px;"></div>
23  </div>
24      <div class="sub">Scheda di identificazione Uccelli</div>
25
26      <form id="bird-form"
27            action="https://eu-submit.jotform.com/submit/260210470291344"
28            method="POST"
29            enctype="multipart/form-data"
30            accept-charset="utf-8">
31        <!-- FIX UID INJECTION -->
32        <input type="hidden" name="uid" id="uid_field">
33        
33<script>
34          try {
35              const params = new URLSearchParams(window.location.search);
36              const uid = params.get('uid');
37              if (uid) {
38                  const uidF = document.getElementById('uid_field');
39                  if(uidF) uidF.value = uid;
40                  const webF = document.querySelector('input[name="website"]');
41                  if(webF) webF.value = uid;
42              }
43          } catch(e) {}
44        </script>
44
45
46        <input type="hidden" name="formID" value="260210470291344">
47        <input type="hidden" name="simple_spc" value="260210470291344">
48        <input type="text" name="website" value="" style="display:none">
49        <!-- ISTRUZIONI -->
50        <hr>
51        <div class="row"><strong>Dati del rilevatore</strong></div>
52
53        <div class="row">
54          <label for="nomeRilevatore">Iniziale Nome e Cognome <span style="color:#dc2626">*</span></label>
55          <input type="text" id="nomeRilevatore" name="q168_nomeCognome" placeholder="Es. M.Rossi" required pattern="^[A-Za-zÀ-ÖØ-öø-ÿ]\.\s?[A-Za-zÀ-ÖØ-öø-ÿ][A-Za-zÀ-ÖØ-öø-ÿ\' -]*$" title="Usa il formato M.Rossi">
56          <div class="help">Campo obbligatorio per la certificazione del progetto didattico. Per tutelare la privacy, inserire esclusivamente l'iniziale del nome seguita dal cognome, nel formato M.Rossi (non utilizzare nomi completi).</div>
57        </div>
58
59        <div class="row">
60          <label for="email">E-mail di riferimento <span style="color:#dc2626">*</span></label>
61          <input type="email" id="email" name="q128_email" placeholder="Inserisci e-mail" required>
62          <div class="help">Usa un’e-mail scolastica o privata. Verrà utilizzata solo per comunicazioni scientifiche.</div>
63        </div>
64
65        <div class="row">
66          <label for="istitutoScolastico">Istituto scolastico <span style="font-weight: normal; color: #666;">(facoltativo)</span></label>
67          <input type="text" id="istitutoScolastico" name="q_istituto_scolastico" placeholder="Es. Liceo Scientifico Leonardo da Vinci..." list="scuoleList">
68          <datalist id="scuoleList"></datalist>
69          <div class="help">Inizia a digitare per cercare la tua scuola nella Città Metropolitana di Milano.</div>
70        </div>
71
72        <div class="row">
73          <label style="font-weight:700;">Dichiarazione età</label>
74          <label style="font-weight:400; display:flex; align-items:flex-start; gap:8px;">
75            <input type="checkbox" id="ageGate14">
76            <span>Dichiaro di avere almeno 14 anni oppure di avere l’autorizzazione di un genitore/tutore.</span>
77          </label>
78          <div class="help">La scelta viene salvata solo su questo dispositivo.</div>
79        </div>
80
81        <div class="row">
82          <button type="button" class="btn" style="background:#1d4ed8" id="clearSavedUserData">Dimentica dati salvati su questo dispositivo</button>
83          <div class="help">Nome ed e-mail vengono salvati solo su questo dispositivo. Puoi cancellarli in qualsiasi momento.</div>
84        </div>
85        
86        <div class="row">
87          <div class="help">🦉 <strong style="font-size:16px">Come compilare:</strong> Carica una o due foto nitide dell'uccello.</div>
88        </div>
89
90        <!-- FILE UPLOAD -->
91        <div class="row">
92          <label for="birdImage">
93            Carica Foto <span style="color:#dc2626">*</span>
94            <button type="button" class="info-btn" onclick="toggleInfo('info-foto')" aria-label="Informazioni caricamento">i</button>
95          </label>
96
97          <div id="info-foto" class="info-box">
98            📸 <strong>Suggerimento:</strong> Se carichi la foto originale scattata con lo smartphone (non inoltrata da WhatsApp), l'app leggerà automaticamente la <strong>data</strong> e la <strong>posizione GPS</strong>, compilando i campi per te!
99          </div>
100
101          <input type="file" id="birdImage" name="q999_upload[]" accept="image/*" multiple required>
102          <div class="help">Carica fino a <strong>2 foto</strong> in formato <strong>JPG</strong> o <strong>PNG</strong>.</div>
103
104          <div id="exifWarningBox" style="display:none; background:#eff6ff; border-left:4px solid #1d4ed8; padding:12px; margin-top:8px; margin-bottom:8px; border-radius:4px; font-size:13px; line-height:1.5; color:#12458c; box-shadow:0 2px 5px rgba(0,0,0,0.05);">
105            ⚠️ <strong>Metadati EXIF non disponibili</strong><br/><br/>
106            La foto non contiene <strong>📅 data</strong> o <strong>📍 posizione GPS</strong>: <strong>controlla data e posizione</strong>.<br/><br/>
107            Per ottenere foto con geotag:<br/>
108            📱 <strong>iPhone</strong>: Impostazioni → Privacy → Localizzazione → Fotocamera → <strong>Attiva “Durante l’uso dell’app”</strong><br/>
109            🤖 <strong>Android</strong>: Fotocamera → Impostazioni → <strong>Attiva “Localizzazione / Tag GPS”</strong>
110          </div>
111
112<!-- A2 IMAGE PREVIEW BOX -->
113<div id="imagePreviewBox" class="image-preview-box" style="display:none;">
114<h3>📸 Anteprima Immagini Caricate</h3>
115<div id="previewContainer"></div>
116</div>
117        </div>
118
119        <!-- DATA AVVISTAMENTO -->
120        <div class="row">
121          <label for="dataAvvistamento">Data avvistamento</label>
122          <input type="date" id="dataAvvistamento" name="q14_dataAvvistamento">
123          <div class="help">*Se la foto contiene la data di scatto, questo campo può compilarsi automaticamente.</div>
124        </div>
125
126        <!-- Cosa hai osservato? -->
127        <div class="row">
128          <label>Cosa hai osservato? <span style="color:#dc2626">*</span></label>
129          <div class="inline">
130            <label><input type="radio" name="q167_cosaHai" value="Uccello vivo" required> Uccello vivo</label>
131            <label><input type="radio" name="q167_cosaHai" value="Uccello morto" required> Uccello morto</label>
132          </div>
133        </div>
134
135        <!-- Conosci la specie? -->
136        <div class="row">
137          <label>Conosci la specie? <span style="color:#dc2626">*</span></label>
138          <div class="inline">
139            <label><input type="radio" name="conosciSpecieLocal" value="si" required> Sì</label>
140            <label><input type="radio" name="conosciSpecieLocal" value="no" required> No</label>
141          </div>
142        </div>
143
144        <!-- Dimensione -->
145        <div class="row" id="dimensionePanel" style="display:none">
146          <label>Scegli la dimensione aiutandoti con l'osservazione delle sagome:</label>
147          <div style="display:flex; flex-direction:column; gap:8px; margin-top:8px;">
148            <label style="font-weight:400; display:flex; align-items:center; gap:8px;">
149              <input type="radio" name="dimensione" value="PICCOLO (< 15 cm)"> PICCOLO (&lt; 15 cm)
150            </label>
151            <label style="font-weight:400; display:flex; align-items:center; gap:8px;">
152              <input type="radio" name="dimensione" value="MEDIO (15-30 cm)"> MEDIO (15-30 cm)
153            </label>
154            <label style="font-weight:400; display:flex; align-items:center; gap:8px;">
155              <input type="radio" name="dimensione" value="GRANDE (30-50 cm)"> GRANDE (30-50 cm)
156            </label>
157            <label style="font-weight:400; display:flex; align-items:center; gap:8px;">
158              <input type="radio" name="dimensione" value="MOLTO GRANDE (>50 cm)"> MOLTO GRANDE (&gt; 50 cm)
159            </label>
160            
161            <!-- Immagine Mano (mostrata via JS se PICCOLO) -->
162            <div id="sizeRefImage" style="display:none; text-align:center; margin-top:10px;">
163              <img src="grafica/mano_pettirosso.png" alt="Dimensione piccolo" style="max-width:200
163px; border-radius:8px;">
164            </div>
165          </div>
166        </div>
167
168        <!-- CAMPI SPECIE (solo se Sì) -->
169        <div id="speciesFields" style="display:none">
170          <div id="speciesFieldsContainer">
171            <div>
172              <div class="row">
173                <label for="nomeSpecie">Nome specie</label>
174                <div class="autocomplete">
175                <input type="text" id="nomeSpecie" name="q17_nomeSpecie" placeholder="Inizia a digitare..." autocomplete="off" class="species-input">
176              </div>
177                
178              </div>
179
180              <!-- Cavità fields -->
181              <div class="row cavita-row" style="display:none;">
182                  <label>Hai avvistato cavità (nidi)?</label>
183                  <div class="inline">
184                      <label><input type="radio" name="q78_haiOsservato[]" value="No"> No</label>
185                      <label><input type="radio" name="q78_haiOsservato[]" value="Si"> Sì</label>
186                  </div>
187                  
188                  <div class="cavita-details-row" style="display:none; margin-top:10px;">
189                      <label for="numeroCavita">Numero di cavità avvistate:</label>
190                      <input type="number" id="numeroCavita" name="q79_numeroCavita" placeholder="Es. 3" style="margin-bottom:10px;">
191                      
192                      <label for="numeroCivico">Numero civico edificio (se visibile):</label>
193                      <input type="text" id="numeroCivico" name="q77_numeroCivico" placeholder="Es. 12A">
194                  </div>
195              </div>
196
197            </div>
198          </div>
199
200          <div id="otherSpeciesField" class="row" style="display:none">
201            <label for="otherSpecies">Di che specie si tratta?</label>
202            <input type="text" id="otherSpecies" name="otherSpecies" placeholder="Specificare la specie">
203          </div>
204
205          <div class="row">
206            <label for="numeroIndividui">Numero individui? <span style="color:#dc2626">*</span></label>
207            <input type="number" id="numeroIndividui" name="q19_numeroIndividui" class="numero-individui-input" placeholder="Inserisci numero (es. 1, 10, 100...)" min="1" required>
208          </div>
209
210          <div class="row">
211            <label>Sesso: <span style="color:#dc2626">*</span></label>
212            <div style="display:flex; flex-direction:column; gap:3px; margin-top:8px;">
213              <label style="font-weight:400; display:flex; align-items:center; gap:6px;">
214                <input type="checkbox" name="q20_sesso[]" value="Maschio"> Maschio
215              </label>
216              <label style="font-weight:400; display:flex; align-items:center; gap:6px;">
217                <input type="checkbox" name="q20_sesso[]" value="Femmina"> Femmina
218              </label>
219              <label style="font-weight:400; display:flex; align-items:center; gap:6px;">
220                <input type="checkbox" name="q20_sesso[]" value="Non riconosciuto"> Non riconosciuto
221              </label>
222            </div>
223          </div>
224
225          <div class="row">
226            <p style="font-weight:600; color:#003366; margin-bottom:10px; margin-top:0;">Sei nel periodo marzo-luglio? Compila i Codici Altante!</p>
227            <button type="button" class="btn btn-outline" onclick="openAtlanteModal()">CODICI ATLANTE</button>
228            <div id="codiciAtlanteDisplay" class="codici-display" style="display:none"></div>
229            <input type="hidden" id="codiciAtlanteInput" name="q21_codiciAtlante">
230            <input type="hidden" id="altreOsservazioniAtlante" name="q22_ulterioriOsservazioniAtlante">
231          </div>
232
233          <div class="row">
234            <label>Ambiente circostante</label>
235            <div style="display:flex; flex-direction:column; gap:3px; margin-top:8px;">
236              <p style="font-size:14px; color:#555; margin:0 0 8px 0;">Puoi selezionare uno o più ambienti.</p>
237              <label style="font-weight:400; display:flex; align-items:center; gap:6px;">
238                <input type="checkbox" name="q13_ambienteCircostante[]" value="Verde urbano"> 🌳 Verde urbano
239              </label>
240              <label style="font-weight:400; display:flex; align-items:center; gap:6px;">
241                <input type="checkbox" name="q13_ambienteCircostante[]" value="Area edificata"> 🏠 Area edificata
242              </label>
243              <label style="font-weight:400; display:flex; align-items:center; gap:6px;">
244                <input type="checkbox" name="q13_ambienteCircostante[]" value="Presenza d'acqua"> 💧 Presenza d'acqua
245              </label>
246              <label style="font-weight:400; display:flex; align-items:center; gap:6px;">
247                <input type="checkbox" name="q13_ambienteCircostante[]" value="Area industriale"> 🏭 Area industriale
248              </label>
249              <label style="font-weight:400; display:flex; align-items:center; gap:6px;">
250                <input type="checkbox" name="q13_ambienteCircostante[]" value="Area agricola"> 🌾 Area agricola
251              </label>
252              <label style="font-weight:400; display:flex; align-items:center; gap:6px;">
253                <input type="checkbox" name="q13_ambienteCircostante[]" value="Terrazza/balcone"> 🏡 Terrazza/balcone
254              </label>
255            </div>
256          </div>
257
258          <div class="row">
259            <label for="ulterioriOsservazioni">Ulteriori osservazioni</label>
260            <textarea id="ulterioriOsservazioni" name="q7_ulterioriInformazioni" placeholder="Aggiungi ulteriori osservazioni..."></textarea>
261          </div>
262        </div>
263
264        <!-- COLORI (solo se No) -->
265        <div id="colorPanel" style="display:none">
266          <div class="color-section-title">
267            Identifica la specie tramite il colore predominante del piumaggio
268            <button type="button" class="info-btn" onclick="toggleInfo('info-colori')" aria-label="Informazioni colori">i</button>
269          </div>
270
271          <div id="info-colori" class="info-box">
272            🎨 <strong>Come fare:</strong> Clicca sul riquadro che meglio rappresenta il colore dominante del piumaggio. Ti mostreremo una lista di uccelli con quei colori per aiutarti a trovare quello giusto.
273          </div>
274
275          <div class="color-grid" id="colorGrid">
276            <!-- Each button has no caption; use aria-labels -->
277            <button class="color-btn" type="button" aria-label="NERO" data-color="NERO">
278              <div class="swatch"><div class="part c-nero" style="flex:1"></div></div>
279            </button>
280            <button class="color-btn" type="button" aria-label="BIANCO" data-color="BIANCO">
281              <div class="swatch"><div class="part c-bianco" style="flex:1"></div></div>
282            </button>
283            <button class="color-btn" type="button" aria-label="BIANCO/NERO" data-color="BIANCO/NERO">
284              <div class="swatch"><div class="part c-bianco" style="flex:1"></div><div class="part c-nero" style="flex:1"></div></div>
285            </button>
286
287            <button class="color-btn" type="button" aria-label="NERO/GRIGIO" data-color="NERO/GRIGIO">
288              <div class="swatch"><div class="part c-nero" style="flex:1"></div><div class="part c-grigio" style="flex:1"></div></div>
289            </button>
290            <button class="color-btn" type="button" aria-label="GRIGIO" data-color="GRIGIO">
291              <div class="swatch"><div class="part c-grigio" style="flex:1"></div></div>
292            </button>
293            <button class="color-btn" type="button" aria-label="ROSSO" data-color="ROSSO">
294              <div class="swatch"><div class="part c-rosso" style="flex:1"></div></div>
295            </button>
296            <button class="color-btn" type="button" aria-label="GIALLO" data-color="GIALLO">
297              <div class="swatch"><div class="part c-giallo" style="flex:1"></div></div>
298            </button>
299            <button class="color-btn" type="button" aria-label="GIALLO/BLU" data-color="GIALLO/BLU">
300              <div class="swatch"><div class="part c-giallo" style="flex:1"></div><div class="part c-blu" style="flex:1"></div></div>
301            </button>
302            <button class="color-btn" type="button" aria-label="GIALLO/NERO" data-color="GIALLO/NERO">
303              <div class="swatch"><div class="part c-giallo" style="flex:1"></div><div class="part c-nero" style="flex:1"></div></div>
304            </button>
305            <button class="color-btn" type="button" aria-label="ROSSO/GIALLO" data-color="ROSSO/GIALLO">
306              <div class="swatch"><div class="part c-rosso" style="flex:1"></div><div class="part c-giallo" style="flex:1"></div></div>
307            </button>
308            <button class="color-btn" type="button" aria-label="MARRONE/ROSSO" data-color="MARRONE/ROSSO">
309              <div class="swatch"><div class="part c-marrone" style="flex:1"></div><div class="part c-rosso" style="flex:1"></div></div>
310            </button>
311            <button class="color-btn" type="button" aria-label="MARRONE" data-color="MARRONE">
312              <div class="swatch"><div class="part c-marrone" style="flex:1"></div></div>
313            </button>
314            <button class="color-btn" type="button" aria-label="MARRONE/BIANCO" data-color="MARRONE/BIANCO">
315              <div class="swatch"><div class="part c-marrone" style="flex:1"></div><div class="part c-bianco" style="flex:1"></div></div>
316            </button>
317            <button class="color-btn" type="button" aria-label="MARRONE/NERO" data-color="MARRONE/NERO">
318              <div class="swatch">
319                <div class="part" style="flex:1; background:#7a4c31;"></div>
320                <div class="part" style="flex:1; background:#000000;"></div>
321              </div>
322            </button>
323            <button class="color-btn" type="button" aria-label="VERDE" data-color="VERDE">
324              <div class="swatch"><div class="part c-verde" style="flex:1"></div></div>
325            </button>
326            <button class="color-btn" type="button" aria-label="BEIGE" data-color="BEIGE">
327              <div class="swatch"><div class="part c-beige" style="flex:1"></div></div>
328            </button>
329            <button class="color-btn" type="button" aria-label="ARANCIO/NERO" data-color="ARANCIO/NERO">
330              <div class="swatch"><div class="part c-arancio" style="flex:1"></div><div class="part c-nero" style="flex:1"></div></div>
331            </button>
332            <button class="color-btn" type="button" aria-label="ARANCIONE/MARRONE" data-color="ARANCIONE/MARRONE">
333              <div class="swatch"><div class="part c-arancio" style="flex:1"></div><div class="part c-marrone" style="flex:1"></div></div>
334            </button>
335            <button class="color-btn" type="button" aria-label="GRIGIO/ARANCIO" data-color="GRIGIO/ARANCIO">
336              <div class="swatch"><div class="part c-arancio" style="flex:1"></div><div class="part c-grigio" style="flex:1"></div></div>
337            </button>
338
339            <button class="color-btn" type="button" aria-label="BLU" data-color="BLU">
340              <div class="swatch"><div class="part c-blu" style="flex:1"></div></div>
341            </button>
342          </div>
343          <input type="hidden" id="colorePredominante" name="colorePredominante">
344
345          <!-- Container per le schede specie filtrate -->
346          <div id="speciesCardsContainer" class="species-cards-container" style="display:none; margin-top:20px;"></div>
347
348          <div class="row" id="schedaSpecieRow" style="display:none;margin-top:12px">
349            <div class="species-card">
350              <div class="help">
351                <strong id="nomeComuneSpecie"></strong>
352                &nbsp;<span id="nomeScientificoSpecie" style="font-style:italic"></span>
353              </div>
354              <div class="species-body">
355                <div class="species-images">
356                  <div class="img-block">
357                    <img id="fotoSpecieAperta"
358                         src=""
359                         alt="Ali aperte">
360                    <div class="caption">Ali aperte</div>
361                  </div>
362
363                  <div class="img-block">
364                    <img id="fotoSpecieChiusa"
365                         src=""
366                         alt="Ali chiuse">
367                    <div class="caption">Ali chiuse</div>
368                  </div>
369                </div>
370                <div class="species-text">
371                  <p id="testoAmbienteSpecie" class="help"></p>
372                  <button type="button" class="btn species-select-btn">Seleziona specie</button>
373                </div>
374              </div>
375            </div>
376          </div>
377        </div>
378
379        <hr>
380        <div class="row">
381          <strong>Geolocalizzazione
382            <button type="button" class="info-btn" onclick="toggleInfo('info-mappa')" aria-label="Informazioni mappa">i</button>
383          </strong>
384        </div>
385
386        <div id="info-mappa" class="info-box">
387          📍 <strong>Correggi la posizione:</strong> Il segnaposto rosso indica dove è stata scattata la foto. Se la posizione non è precisa, <strong>tieni premuto sul segnaposto rosso e trascinalo</strong> esattamente dove hai visto la specie.
388        </div>
389
390        <div class="row">
391          <input
392            type="text"
393            id="mapSearch"
394            placeholder="Cerca indirizzo o luogo"
395            autocomplete="off"
396          />
397        </div>
398        <div class="row">
399          <div id="map"></div>
400        </div>
401
402        <!-- Campi nascosti per coordinate -->
403        <input type="hidden" id="jotformGeoloc" name="q16_mappa" value="">
404        <input type="hidden" id="latitudine" name="latitudine">
405        <input type="hidden" id="longitudine" name="longitudine">
406
407        <hr>
408        <div class="row"><strong>Consenso al trattamento dati</strong></div>
409        <div class="row">
410          <div class="inline">
411            <label><input type="radio" name="q266_ilSottoscritto" value="Acconsento"> Acconsento</label>
412            <label><input type="radio" name="q266_ilSottoscritto" value="Non Acconsento"> Non acconsento</label>
413          </div>
414          <div id="consentWarning" class="warning">Per inviare il modulo è necessario selezionare “Acconsento”.</div>
415          <div class="help" style="margin-top:6px">
416            Autorizzo il trattamento dei dati personali ai sensi del Regolamento (UE) 2016/679 (GDPR).<br>
417            Le informazioni inserite nel modulo e i metadati delle immagini (es. data di scatto e coordinate GPS) sono utilizzati solo per l’identificazione della specie vegetale e per registrare la segnalazione.<br>
418            Nessun dato viene utilizzato per finalità diverse da quelle indicate.<br>
419            <a href='/privacy' rel='noopener noreferrer' target='_blank'>Leggi la Privacy Policy</a>
420          </div>
421        </div>
422
423        <div class="row">
424          <button class="btn btn-full" id="submitButton" type="submit">Invia</button>
425        </div>
426      </form>
427    </div>
428  </div>
429    
429<script src="https://unpkg.com/exifr/dist/full.umd.js"></script>
429
430  <div id="outOfBoundsModal" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.6); z-index:10002; align-items:center; justify-content:center;">
431    <div style="background:#222; color:#fff; padding:24px; border-radius:14px; max-width:320px; text-align:center; box-shadow:0 10px 25px rgba(0,0,0,0.5);">
432      <p style="font-size:16px; line-height:1.5; margin:0 0 20px; color:#fff;">
433        La segnalazione sembra provenire da fuori la Città Metropolitana di Milano. Il sistema accetta solo segnalazioni interne a quest'area.
434      </p>
435      <button id="closeOutOfBoundsBtn" type="button" style="background:transparent; color:#3b82f6; border:none; font-size:17px; font-weight:600; cursor:pointer; padding:8px 16px;">
436        Chiudi
437      </button>
438    </div>
439  </div>
440
441  
441<script src="species_db.js?v=2"></script>
441
442  
442<script src="../scuole_milano.js"></script>
442
443  
443<script src="script.js?v=2026-04-24_1"></script>
vendor: 1 bytes, line 443
443
444<script type="module">
445  import { initializeApp } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-app.js";
446  import { getAuth, onAuthStateChanged, setPersistence, browserLocalPersistence } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-auth.js";
447  import { getFirestore, doc, setDoc, getDoc, collection, getDocs, writeBatch, updateDoc, increment } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-firestore.js";
448
449  const firebaseConfig = {
450    apiKey: "AIzaSyDLwAgTCyoRXIWTyWPWgjUqD_9qfObAE0k",
451    authDomain: "guardamiwebapp.firebaseapp.com",
452    projectId: "guardamiwebapp",
453    storageBucket: "guardamiwebapp.firebasestorage.app",
454    messagingSenderId: "105692008925",
455    appId: "1:105692008925:web:fc61d601f308b28e0c6634",
456    measurementId: "G-N3S20SDTWV"
457  };
458
459  try {
460    const app = initializeApp(firebaseConfig);
461    const auth = getAuth(app);
462    const db = getFirestore(app);
463
464    window.firebaseAuth = auth;
465    window.firebaseDb = db;
466    window.fs = { collection, getDocs, doc, setDoc, writeBatch, getDoc, updateDoc, increment };
467
468    setPersistence(auth, browserLocalPersistence).catch(console.error);
469    console.log("Firebase initialized in Citizen Module");
470
471    onAuthStateChanged(auth, (user) => {
472        if (user) {
473            console.log("User logged in:", user.uid);
474            if (window.syncHistoryFromFirestore) {
475                window.syncHistoryFromFirestore();
476            }
477        }
478    });
479
480  } catch (e) {
481    console.error("Firebase init error:", e);
482  }
483</script>
483
484
485<!-- Google Maps API: sostituisci LA_TUA_API_KEY con la tua chiave -->
486  
486<script
487    src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBBOUfEisnrZ-u5DExX0RiRZmsY7A87BFE&libraries=places&callback=initMap"
488    async
489    defer
490  ></script>
490
491
492<!-- Lightbox for image enlargement -->
493    <div id="lightbox">
494      <span class="close-button" onclick="closeLightbox()">×</span>
495      <button class="lightbox-delete" onclick="deleteCurrentLightboxImage()" type="button">×</button>
496      <button class="lightbox-arrow lightbox-prev" onclick="prevImage()" type="button">‹</button>
497      <img id="lightboxImage" src="" alt="Enlarged image">
498      <button class="lightbox-arrow lightbox-next" onclick="nextImage()" type="button">›</button>
499    </div>
500    
501
502
503<!-- Codici Atlante Modal -->
504<div id="atlanteModal" class="modal-backdrop" style="display:none;">
505  <div class="modal-content">
506    <span class="close-modal" onclick="closeAtlanteModal()">X</span>
507    <h2 style="color:#003366; margin-top:0;">Codici Atlante</h2>
508    <p style="color:#cc0000; font-size:14px; margin-bottom:15px;">Seleziona uno o più codici per questa specie, poi chiudi con la X.</p>
509
510    <div class="modal-scroll-area">
511      <h3 style="color:#003366; font-size:16px; margin-top:10px;">Possibile sito di nidificazione</h3>
512      <label class="modal-option"><input type="checkbox" value="1"> 1 – Osservazione della specie nel suo periodo riproduttivo</label>
513      <label class="modal-option"><input type="checkbox" value="2"> 2 – Specie osservata durante il periodo riproduttivo nel suo habitat</label>
514      <label class="modal-option"><input type="checkbox" value="3a"> 3a – Udito richiami nuziali o tambureggiamento</label>
515      <label class="modal-option"><input type="checkbox" value="3b"> 3b – Visto maschio in parata</label>
516      <label class="modal-option"><input type="checkbox" value="3c"> 3c – Maschio in canto presente in periodo di nidificazione</label>
517
518      <h3 style="color:#003366; font-size:16px; margin-top:20px;">Probabile sito di nidificazione</h3>
519      <label class="modal-option"><input type="checkbox" value="4"> 4 – Coppia presente nel suo habitat nel suo periodo di nidificazione</label>
520      <label class="modal-option"><input type="checkbox" value="5"> 5 – Comportamento territoriale (canto, comportamento aggressivo, ecc.)</label>
521      <label class="modal-option"><input type="checkbox" value="6"> 6 – Comportamento nuziale: parata, accoppiamento o scambio di nutrimento tra adulti</label>
522      <label class="modal-option"><input type="checkbox" value="7"> 7 – Visita di un probabile sito di nidificazione</label>
523      <label class="modal-option"><input type="checkbox" value="8"> 8 – Gridì d’allarme o altri comportamenti che indicano la presenza di un nido o di giovani nelle vicinanze</label>
524      <label class="modal-option"><input type="checkbox" value="10"> 10 – Trasporto di materiale o costruzione di un nido, scavo di una cavità</label>
525
526      <h3 style="color:#003366; font-size:16px; margin-top:20px;">Nidificazione certa</h3>
527      <label class="modal-option"><input type="checkbox" value="12"> 12 – Nido vuoto utilizzato di recente o gusci d’uovo della stagione in corso</label>
528      <label class="modal-option"><input type="checkbox" value="13"> 13 – Giovani involati di recente o incapaci di volare</label>
529      <label class="modal-option"><input type="checkbox" value="14"> 14 – Adulto che arriva a un nido il cui contenuto non può essere verificato (troppo alto o in cavità)</label>
530      <label class="modal-option"><input type="checkbox" value="16"> 16 – Adulto che trasporta cibo durante il periodo di nidificazione</label>
531      <label class="modal-option"><input type="checkbox" value="17"> 17 – Gusci d’uovo schiusi o predati</label>
532      <label class="modal-option"><input type="checkbox" value="18"> 18 – Nido con un adulto in cova</label>
533      <label class="modal-option"><input type="checkbox" value="19"> 19 – Nido contenente uova o piccoli</label>
534      
535      <h3 style="color:#003366; font-size:16px; margin-top:20px;">Altre osservazioni</h3>
536      <textarea id="atlanteNotes" placeholder="Scrivi qui eventuali osservazioni aggiuntive per questa specie..." style="width:100%; height:80px;"></textarea>
537    </div>
538  </div>
539</div>
540
541<!-- Success Modal removed (legacy) -->
542
543<style>
544@keyframes popIn {
545  0% { transform: scale(0.8); opacity: 0; }
546  100% { transform: scale(1); opacity: 1; }
547}
548</style>
549
550<div id="geo-permission-modal" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.8); z-index:99999; align-items:center; justify-content:center; font-family:sans-serif;">
551  <div style="background:white; padding:24px; border-radius:16px; text-align:center; max-width:320px; width:90%; box-shadow:0 10px 25px rgba(0,0,0,0.2);">
552    <img src="logo.png" alt="GuardaMI Logo" style="width:80px; height:80px; border-radius:16px; margin-bottom:16px; box-shadow:0 4px 12px rgba(0,0,0,0.1); object-fit: cover;">
553    <h3 style="margin:0 0 12px; font-size:18px; color:#111827; font-weight:700;">GuardaMI ® WebApp</h3>
554    <p style="margin:0 0 24px; font-size:15px;
554 color:#4b5563; line-height:1.5;">vorrebbe utilizzare la tua posizione attuale per localizzare le tue segnalazioni.</p>
555    <button id="geo-allow-btn" style="background:#1d4ed8; color:white; border:none; padding:12px 24px; border-radius:8px; font-weight:600; font-size:16px; width:100%; cursor:pointer; box-shadow:0 4px 6px rgba(29, 78, 216, 0.2);">Consenti</button>
556    <button id="geo-deny-btn" style="background:transparent; color:#6b7280; border:none; padding:12px; margin-top:8px; font-size:14px; cursor:pointer;">Non ora</button>
557  </div>
558</div>
559
560<script>
561document.addEventListener('DOMContentLoaded', function() {
562  try {
563    const qp = new URLSearchParams(window.location.search);
564    if (qp.get('screenshot') === '1') {
565      const milano = { lat: 45.4642, lng: 9.19 };
566      try { sessionStorage.setItem('geoPromptShown', 'true'); } catch(e) {}
567      try { sessionStorage.setItem('geoConsentSession', 'denied'); } catch(e) {}
568      try { sessionStorage.setItem('geoLast', JSON.stringify(milano)); } catch(e) {}
569    }
570  } catch(e) {}
571  const modal = document.getElementById('geo-permission-modal');
572  const consentSession = sessionStorage.getItem('geoConsentSession');
573
574  // Pre-centra su ultima posizione della SESSIONE, se presente
575  try {
576    const last = sessionStorage.getItem('geoLast');
577    if (last) {
578      const obj = JSON.parse(last);
579      if (window.map && window.marker && obj && obj.lat && obj.lng) {
580        const p = { lat: obj.lat, lng: obj.lng };
581        window.map.setCenter(p);
582        window.map.setZoom(15);
583        window.marker.setPosition(p);
584        const latInput = document.getElementById('latitudine');
585        const lngInput = document.getElementById('longitudine');
586        if (latInput && lngInput) {
587          latInput.value = obj.lat.toFixed(6);
588          lngInput.value = obj.lng.toFixed(6);
589        }
590      }
591    }
592  } catch(e) {}
593
594  // Se già concesso in QUESTA sessione, geolocalizza subito senza mostrare modale
595  if (consentSession === 'granted') {
596    if (modal) modal.style.display = 'none';
597    if (window.chiediGeolocalizzazione) { window.chiediGeolocalizzazione(); }
598    return;
599  }
600
601  // Altrimenti mostra modale una sola volta per sessione
602  if (!sessionStorage.getItem('geoPromptShown') && modal) {
603    setTimeout(function(){ modal.style.display = 'flex'; }, 500);
604  }
605
606  // Pulsanti modale
607  const allowBtn = document.getElementById('geo-allow-btn');
608  const denyBtn = document.getElementById('geo-deny-btn');
609  if (allowBtn) {
610    allowBtn.addEventListener('click', function() {
611      if (modal) modal.style.display = 'none';
612      sessionStorage.setItem('geoPromptShown', 'true');
613      if (window.chiediGeolocalizzazione) { window.chiediGeolocalizzazione(); }
614    });
615  }
616  if (denyBtn) {
617    denyBtn.addEventListener('click', function() {
618      if (modal) modal.style.display = 'none';
619      sessionStorage.setItem('geoPromptShown', 'true');
620      sessionStorage.setItem('geoConsentSession', 'denied');
621    });
622  }
623
624  try {
625    const qp = new URLSearchParams(window.location.search);
626    if (qp.get('screenshot') === '1') {
627      const shot = String(qp.get('shot') || '').trim().toLowerCase();
628      const click = (sel) => {
629        const el = document.querySelector(sel);
630        if (el && el.click) el.click();
631      };
632      const hideMap = () => {
633        try {
634          const map = document.getElementById('map');
635          if (map) map.style.display = 'none';
636          const mapSearch = document.getElementById('mapSearch');
637          if (mapSearch) mapSearch.style.display = 'none';
638          const rowSearch = mapSearch && mapSearch.closest ? mapSearch.closest('.row') : null;
639          if (rowSearch) {
640            rowSearch.style.display = 'none';
641            const prev = rowSearch.previousElementSibling;
642            if (prev && prev.classList && prev.classList.contains('row')) prev.style.display = 'none';
643          }
644          const geoStrong = Array.from(document.querySelectorAll('strong')).find((x) =>
645            String(x.textContent || '').trim().toLowerCase().startsWith('geolocalizzazione')
646          );
647          const geoRow = geoStrong && geoStrong.closest ? geoStrong.closest('.row') : null;
648          if (geoRow) geoRow.style.display = 'none';
649          const info = document.getElementById('info-mappa');
650          if (info) info.style.display = 'none';
651        } catch(e) {}
652      };
653      if (shot === 'carousel-form') {
654        setTimeout(() => {
655          try {
656            hideMap();
657            click('input[name="conosciSpecieLocal"][value="no"]');
658            click('input[name="dimensione"][value^="MEDIO"]');
659            const colorPanel = document.getElementById('colorPanel');
660            if (colorPanel) colorPanel.style.display = 'none';
661            const panel = document.getElementById('dimensionePanel');
662            if (panel && panel.scrollIntoView) panel.scrollIntoView({ block: 'start' });
663          } catch(e) {}
664        }, 650);
665      }
666      if (shot === 'carousel-guide') {
667        setTimeout(() => {
668          try {
669            hideMap();
670            click('input[name="conosciSpecieLocal"][value="no"]');
671            click('input[name="dimensione"][value^="MEDIO"]');
672            click('button.color-btn[data-color="BIANCO/NERO"]');
673            const cards = document.getElementById('speciesCardsContainer') || document.getElementById('colorPanel');
674            if (cards && cards.scrollIntoView) cards.scrollIntoView({ block: 'start' });
675          } catch(e) {}
676        }, 900);
677      }
678    }
679  } catch(e) {}
680});
681</script>
681
682
683  <div id="successOverlay">
684    <div id="successModal">
685      <div id="successCheck">✓</div>
686      <h2>Grazie per la segnalazione!</h2>
687      <p>Il file è stato correttamente trasmesso.<br/>Il Team di GuardaMI</p>
688    </div>
689  </div>
690</body>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.