🐝

ARILIK OS

Koloni • Besleme • Ana Arı • Varroa • Hasat • Hava • Veri

Arılık Kontrol Merkezi

Bugün ne var, hangi kovanı kontrol etmelisin, son durum ne?

Toplam kovan
0
Güçlü koloni
0
Bekleyen iş
0
Toplam bal hasadı
0 kg

⏰ Bugün / Yaklaşan

🌦️ Arılık Havası

📌 Son Kayıtlar

Kovanlar

Her kovanın kimliği, fotoğrafı, ana arısı, ekipmanı ve geçmişi burada.

🔍 Kovan Muayenesi

Yumurta, yavru, ana arı, çerçeve ve koloni gözlemlerini tek kayıtta tut. Yanlış girilen kayıtları sonradan ✏️ düzenleyebilirsin.

🔗 Aynı muayenede yapılan işlemler
Buraya yalnızca gerçekten yaptığın işlemi gir. Kaydettiğinde Besleme, Varroa/Uygulama ve Kovan geçmişine otomatik olarak da işlenecek.

Kayıt geçmişi

TarihKovanGüçÇerçevelerYumurta/YavruKaliteNot

🍯 Besleme ve Tüketim Takibi

Şurup, kek, su, destek ve özel beslemelerin ne zaman verildiğini ve ne kadar sürede tüketildiğini kaydet.

Besleme geçmişi

TarihKovanTürMiktarİçerikTüketimSonuç

🧪 Varroa / Uygulama Kayıtları

Doğal, mekanik veya ruhsatlı uygulamaları yöntem ve sonuçlarıyla arşivle. Bu bölüm kayıt içindir; uygulamanın etkinliği/güvenliği hakkında otomatik onay vermez.

⚠️ Portakal kabuğu, defne, okaliptüs, ısırgan, kekik yağı vb. doğal maddelerin duman/uygulama yoluyla kullanılmasının doz, arı sağlığı, bal kalıntısı ve etkinlik açısından güvenli olduğu varsayılmamalıdır. Bu sistemi yalnızca ne yaptığını kaydetmek için kullan; gıda üretimi yapan kolonilerde yerel mevzuat ve veteriner/arı sağlığı rehberlerini esas al.

Uygulama geçmişi

TarihKovanKategoriYöntemMateryalÖnce/SonraNot

🧱 Temel Petek • Ham Petek • Bal Hasadı

Hangi kovana hangi petek verildi, ne kadar süre kullanıldı ve hangi kovandan ne kadar bal alındı?

🧱 Petek Hareketi

🍯 Bal Hasadı

Petek kayıtları

TarihKovanTürAdetİşlemSüre

Bal hasat geçmişi

TarihKovanÇerçeveNet kgTürParti

⏰ Arılık Planı

Kontrol, besleme, ana arı, petek, hasat ve sezonluk işleri tek yerde takip et.

🌦️ Arılık Hava Durumu

Koordinatını bir kez kaydet; güncel ve 7 günlük veriyi gör.

📈 Koloni Analizi

Muayene kayıtların biriktikçe koloni gelişimini sayısal olarak gör.

🐝 Koloni gelişimi

👑 Ana arı performansı

Yumurtalı çerçeve ve yumurta düzenini birlikte gösteren göreli göstergedir; tek başına ana arı kalitesi kararı değildir.

🍯 Kaynaklar

📦 Verimlilik / hasat

🧪 Uygulama ve Varroa geçmişi

📜 Kovan işlemleri

📊 Kovan özeti

⚙️ Sistem Ayarları

Bu bölümün amacı sistemi sabit bir uygulama olmaktan çıkarmak. Yeni seçenekleri sen ekleyebil.

💡 Örneğin “Besleme türleri”ne yeni bir seçenek, “Varroa yöntemi”ne yeni bir yöntem veya “İşlem türleri”ne yeni bir işlem ekleyebilirsin. Mevcut kayıtlar silinmez.

Muayene seçenekleri

Besleme türleri

Uygulama kategorileri

Uygulama yöntemleri

Petek türleri

Petek işlemleri

Sezonlar

Kat / ızgara işlemleri

Izgara konumları

💾 Veri Merkezi

Yeni sürümlere geçerken veri kaybetmemen için burada özellikle güçlü bir yedekleme sistemi var.

📤 Tam yedek

Kovanlar, kayıtlar, fotoğraflar, ayarlar ve hava konumu.

📥 Yeni sürüme aktar

Önceki V2 JSON yedeğini veya bu sistemin yedeğini yükleyebilirsin. Eski alanlar mümkün olduğunca korunur.

📊 CSV

Muayene, besleme, uygulama ve hasat kayıtlarını Excel'e aktar.

🖨️ Yazdır

⚠️ Sıfırla

Önce JSON yedeğini al. Bu işlem geri alınamaz.

let db=loadDB();; function baseDB(){ return { version:3, hives:[ {id:"KT-001",breed:"",queenYear:"",queenId:"",location:"",status:"Orta",photo:"",notes:""}, {id:"KT-002",breed:"",queenYear:"",queenId:"",location:"",status:"Orta",photo:"",notes:""}, {id:"KT-003",breed:"",queenYear:"",queenId:"",location:"",status:"Orta",photo:"",notes:""} ], inspections:[], feedings:[], treatments:[], combs:[], harvests:[], reminders:[], hiveEvents:[], weatherLocation:{name:"",latitude:"",longitude:""}, weather:null, settings:structuredClone(DEFAULT_SETTINGS) }; } function loadDB(){ try{ const keys=[KEY,"arilikOS_v3_1","arilikOS_v3_1_2","arilikOS_v3_1_2_fixed","arilikDataV2"]; for(const k of keys){ const raw=(window.safeStorage?window.safeStorage.get(k):localStorage.getItem(k)); if(!raw) continue; const parsed=JSON.parse(raw); const dbx=(parsed&&parsed.version>=3)?mergeDB(parsed):migrateOld(parsed); if(k!==KEY) saveRecovered(dbx); return dbx; } }catch(e){console.warn("Veri yükleme hatası",e)} try{ if(window.ARILIK_SEED_DATA){ const seeded=mergeDB(window.ARILIK_SEED_DATA); saveRecovered(seeded); return seeded; } }catch(e){console.warn("Hazır veri yükleme hatası",e)} return baseDB(); } function saveRecovered(data){ try{const raw=JSON.stringify(data);if(window.safeStorage)window.safeStorage.set(KEY,raw);else localStorage.setItem(KEY,raw)}catch(e){console.warn(e)} } function mergeDB(x){ const b=baseDB(); const out={...b,...x}; out.settings={...b.settings,...(x.settings||{})}; for(const k of Object.keys(b.settings)) if(!Array.isArray(out.settings[k])) out.settings[k]=b.settings[k]; ["hives","inspections","feedings","treatments","combs","harvests","reminders","hiveEvents"].forEach(k=>{if(!Array.isArray(out[k]))out[k]=[]}); return out; } function migrateOld(old){ const n=baseDB(); if(Array.isArray(old.hives) && old.hives.length) n.hives=old.hives.map(h=>({ id:h.id||h.code||("KT-"+String(Date.now()).slice(-3)), breed:h.breed||"",queenYear:h.queenYear||"",queenId:h.queenId||"", location:h.location||"",status:h.status||"Orta",photo:h.photo||"",notes:h.notes||"" })); if(Array.isArray(old.records)){ n.inspections=old.records.map(r=>({ id:r.id||Date.now()+Math.random(),date:r.date||"",hive:r.hive||"", strength:r.strength||"Orta",beeFrames:r.beeFrames||"",eggFrames:"", openBrood:r.broodFrames||"",cappedBrood:"",honeyFrames:r.honeyFrames||"", pollenFrames:r.pollenFrames||"",foundationFrames:"",foundationCondition:"", eggQuality:"",broodQuality:"",queenSeen:r.queenSeen||"",queenStatus:"", queenCell:r.queenCell||"",swarm:"",varroa:r.varroa||"", note:r.observation||"",photo:r.photo||"",next:r.nextCheck||"" })); /* V2 besleme kayıtlarını ayır */ old.records.filter(r=>["Şeker Şurubu","Kek Besleme"].includes(r.type)).forEach(r=>{ n.feedings.push({ id:r.id||Date.now()+Math.random(),date:r.date,hive:r.hive,type:r.type, amount:r.feedAmount||"",unit:r.type==="Şeker Şurubu"?"Litre":"gram", recipe:"",start:r.date,end:"",days:"",result:"",note:r.observation||"" }); }); } if(Array.isArray(old.reminders)) n.reminders=old.reminders.map(r=>({...r})); if(old.weatherLocation) n.weatherLocation={...n.weatherLocation,...old.weatherLocation}; if(old.weather) n.weather=old.weather; return n; } function save(){const data=JSON.stringify(db); if(window.safeStorage){window.safeStorage.set(KEY,data)}else{try{localStorage.setItem(KEY,data)}catch(e){console.warn(e)}}} function today(){return new Date().toISOString().slice(0,10)} function esc(v){return String(v??"").replace(/[&<>"']/g,m=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[m]))} function go(id){ const target=document.getElementById(id); if(!target)return; document.querySelectorAll(".section").forEach(sec=>sec.classList.remove("active")); document.querySelectorAll(".nav button").forEach(b=>b.classList.toggle("active",b.dataset.section===id)); target.classList.add("active"); /* Mobil tarayıcılarda sekme tıklamasını render hatalarından ayır. */ setTimeout(()=>{try{renderAll()}catch(err){console.error("Sekme render hatası",err)}},0); try{window.scrollTo(0,0)}catch(e){} } document.querySelectorAll(".nav button").forEach(b=>{ const handler=function(e){ e.preventDefault(); e.stopPropagation(); go(b.dataset.section); }; b.addEventListener("click",handler,{passive:false}); b.addEventListener("touchend",handler,{passive:false}); }); document.getElementById("topDate").textContent=new Date().toLocaleDateString("tr-TR",{weekday:"long",day:"2-digit",month:"long",year:"numeric"}); function fillSelect(id,arr,keep=true){ const el=document.getElementById(id); if(!el)return; const old=el.value; el.innerHTML=(arr||[]).map(x=>``).join(""); if(keep && Array.isArray(arr) && arr.includes(old)) el.value=old; } function hiveSelects(){ const ids=["iHive","fHive","tHive","cHive","hHive","rHive","aHive"]; ids.forEach(id=>fillSelect(id,db.hives.map(h=>h.id))); fillSelect("iStrength",db.settings.strengths); fillSelect("iFoundationCondition",db.settings.foundationCondition); fillSelect("iEggQuality",db.settings.eggQuality); fillSelect("iBroodQuality",db.settings.broodQuality); fillSelect("iQueenSeen",db.settings.queenSeen); fillSelect("iQueenStatus",db.settings.queenStatus); fillSelect("iQueenCell",db.settings.queenCell); fillSelect("iSwarm",db.settings.swarm); fillSelect("iVarroa",db.settings.varroa); fillSelect("iType",db.settings.inspectionTypes); fillSelect("iFeedType",db.settings.feedingTypes); fillSelect("iFeedUnit",db.settings.feedingUnits); fillSelect("iTreatmentCategory",db.settings.treatmentCategories); fillSelect("iTreatmentMethod",db.settings.treatmentMethods); fillSelect("iHiveAction",db.settings.hiveActions); fillSelect("iExcluderPosition",db.settings.excluderPositions); fillSelect("fType",db.settings.feedingTypes); fillSelect("fUnit",db.settings.feedingUnits); fillSelect("fResult",db.settings.feedingResults); fillSelect("tCategory",db.settings.treatmentCategories); fillSelect("tMethod",db.settings.treatmentMethods); fillSelect("tRoute",db.settings.treatmentRoutes); fillSelect("tBefore",db.settings.treatmentBefore); fillSelect("tAfter",db.settings.treatmentAfter); fillSelect("cType",db.settings.combTypes); fillSelect("cAction",db.settings.combActions); fillSelect("rSeason",db.settings.seasons); } function daysBetween(a,b){ if(!a||!b)return ""; const x=new Date(a+"T00:00:00"),y=new Date(b+"T00:00:00"); return Math.max(0,Math.round((y-x)/86400000)); } function readFileCompressed(file,max=900,quality=.65){ return new Promise(resolve=>{ if(!file)return resolve(""); const rd=new FileReader(); rd.onload=e=>{ const img=new Image(); img.onload=()=>{ let w=img.width,h=img.height; if(w>max){h*=max/w;w=max} if(h>max){w*=max/h;h=max} const c=document.createElement("canvas");c.width=Math.round(w);c.height=Math.round(h); c.getContext("2d").drawImage(img,0,0,c.width,c.height); resolve(c.toDataURL("image/jpeg",quality)); }; img.src=e.target.result; }; rd.readAsDataURL(file); }); } /* KOVANLAR */ function renderHives(){ const box=document.getElementById("hiveList"); if(!db.hives.length){box.innerHTML='
Henüz kovan yok.
';return} box.innerHTML=db.hives.map(h=>{ const last=db.inspections.filter(x=>x.hive===h.id).sort((a,b)=>b.date.localeCompare(a.date))[0]; const honey=db.harvests.filter(x=>x.hive===h.id).reduce((s,x)=>s+(Number(x.kg)||0),0); return `
${h.photo?`${esc(h.id)}`:`
🐝
`}

${esc(h.id)}

${esc(h.status)}
Irk${esc(h.breed)||"-"}
Ana arı${esc(h.queenYear)||"-"} / ${esc(h.queenId)||"-"}
Son muayene${last?.date||"-"}
Toplam hasat${honey.toFixed(2)} kg

${esc(h.location)||"Konum belirtilmedi"}

`; }).join(""); } function openHiveModal(id=""){ const d=document.getElementById("hiveDialog");document.getElementById("hiveForm").reset(); document.getElementById("hId").value=id; document.getElementById("hiveDialogTitle").textContent=id?"Kovanı Düzenle":"Yeni Kovan"; fillSelect("hStatus",db.settings.strengths,false); if(id){ const h=db.hives.find(x=>x.id===id);if(!h)return; ["hCode","hBreed","hQueenYear","hQueenId","hLocation","hNotes"].forEach((dom,i)=>document.getElementById(dom).value=[h.id,h.breed,h.queenYear,h.queenId,h.location,h.notes][i]||""); document.getElementById("hStatus").value=h.status; }else document.getElementById("hCode").value="KT-"+String(db.hives.length+1).padStart(3,"0"); d.showModal(); } function closeHiveModal(){document.getElementById("hiveDialog").close()} async function saveHive(e){ e.preventDefault(); const id=document.getElementById("hId").value, code=document.getElementById("hCode").value.trim(); if(!code)return; const photo=await readFileCompressed(document.getElementById("hPhoto").files[0]); if(id){ const h=db.hives.find(x=>x.id===id); const newCode=code; h.id=newCode;h.breed=document.getElementById("hBreed").value;h.queenYear=document.getElementById("hQueenYear").value; h.queenId=document.getElementById("hQueenId").value;h.location=document.getElementById("hLocation").value; h.status=document.getElementById("hStatus").value;h.notes=document.getElementById("hNotes").value;if(photo)h.photo=photo; }else{ if(db.hives.some(h=>h.id===code)){alert("Bu kovan kodu zaten var.");return} db.hives.push({id:code,breed:document.getElementById("hBreed").value,queenYear:document.getElementById("hQueenYear").value,queenId:document.getElementById("hQueenId").value,location:document.getElementById("hLocation").value,status:document.getElementById("hStatus").value,photo,notes:document.getElementById("hNotes").value}); } save();closeHiveModal();renderAll(); } document.getElementById("hiveForm").addEventListener("submit",saveHive); function editHive(id){openHiveModal(id)} function deleteHive(id){ if(!confirm(`${id} silinsin mi? Kayıt geçmişleri silinmez, sadece kovan kartı kaldırılır.`))return; db.hives=db.hives.filter(h=>h.id!==id);save();renderAll(); } function hiveDetail(id){ const h=db.hives.find(x=>x.id===id);if(!h)return; const ins=db.inspections.filter(x=>x.hive===id).sort((a,b)=>b.date.localeCompare(a.date)); const feed=db.feedings.filter(x=>x.hive===id).sort((a,b)=>b.date.localeCompare(a.date)); const tr=db.treatments.filter(x=>x.hive===id).sort((a,b)=>b.date.localeCompare(a.date)); const har=db.harvests.filter(x=>x.hive===id).sort((a,b)=>b.date.localeCompare(a.date)); const events=db.hiveEvents.filter(x=>x.hive===id).sort((a,b)=>b.date.localeCompare(a.date)); const last=ins[0]; const honey=har.reduce((s,x)=>s+(Number(x.kg)||0),0); const w=document.createElement("div"); w.innerHTML=`

🐝 ${esc(h.id)}

${esc(h.breed)||"Irk belirtilmemiş"} • Ana arı ${esc(h.queenYear)||"-"} / ${esc(h.queenId)||"-"}

${h.photo?``:`
🐝
`}

Teknik kart

Konum${esc(h.location)||"-"}
Durum${esc(h.status)}
Son kontrol${last?.date||"-"}
Toplam bal${honey.toFixed(2)} kg

${esc(h.notes)||""}

🔲 QR kod

QR içine bu sayfanın kovan kimliği gömülür. Dosya telefonda erişilebilir bir web adresinde yayınlanırsa doğrudan ilgili kovana yönlendirme yapılabilir.

📜 Son muayeneler

${ins.slice(0,8).map(x=>`
${x.date}
Güç: ${esc(x.strength)} • Yumurta: ${esc(x.eggQuality)}
Arı ${x.beeFrames||0} / Yumurta ${x.eggFrames||0} / Açık yavru ${x.openBrood||0} / Kapalı yavru ${x.cappedBrood||0}

${esc(x.note)||""}

`).join("")||'
Kayıt yok.
'}

🧪 Uygulamalar

${tr.slice(0,8).map(x=>`
${x.date}
${esc(x.method)} • ${esc(x.category)}

${esc(x.note)||""}

`).join("")||'
Kayıt yok.
'}

🍯 Besleme

${feed.slice(0,8).map(x=>`
${x.date}
${esc(x.type)}: ${esc(x.amount)} ${esc(x.unit)}
Tüketim: ${x.days||"-"} gün
`).join("")||'
Kayıt yok.
'}

🍯 Hasat

${har.slice(0,8).map(x=>`
${x.date}
${x.kg||0} kg • ${x.frames||0} çerçeve
${esc(x.type)||""}
`).join("")||'
Kayıt yok.
'}

🔧 Kat / Izgara geçmişi

${events.slice(0,12).map(x=>`
${x.date}
${esc(x.action)}${x.count&&x.action==="Kat verildi"?` • ${esc(x.count)} kat`:""}${x.position&&x.position!=="Belirtilmedi"?` • ${esc(x.position)}`:""}${x.note?`
${esc(x.note)}`:""}
`).join("")||'
Kayıt yok.
'}
`; document.getElementById("hives").appendChild(w); /* Ayrı detay sayfası yerine kovanlar bölümünün altına eklenir. */ w.scrollIntoView({behavior:"smooth"}); const qr=document.getElementById("qrBox"); if(window.QRCode) new QRCode(qr,{text:location.href.split("#")[0]+"#kovan="+encodeURIComponent(id),width:180,height:180}); } function prefillHive(id,section){ go(section); const map={inspection:"iHive",feeding:"fHive",treatment:"tHive"};document.getElementById(map[section]).value=id; } /* MUAYENE */ document.getElementById("inspectionForm").addEventListener("submit",async e=>{ e.preventDefault(); const editId=v("iEditId"); const old=editId?db.inspections.find(x=>String(x.id)===String(editId)):null; let photo=old?.photo||""; const file=document.getElementById("iPhoto").files[0]; if(file) photo=await readFileCompressed(file); const r={ id:old?old.id:Date.now(), date:v("iDate"),hive:v("iHive"),strength:v("iStrength"), beeFrames:v("iBeeFrames"),eggFrames:v("iEggFrames"), openBrood:v("iOpenBrood"),cappedBrood:v("iCappedBrood"), honeyFrames:v("iHoneyFrames"),pollenFrames:v("iPollenFrames"), foundationFrames:v("iFoundationFrames"),foundationCondition:v("iFoundationCondition"), eggQuality:v("iEggQuality"),broodQuality:v("iBroodQuality"), queenSeen:v("iQueenSeen"),queenStatus:v("iQueenStatus"), queenCell:v("iQueenCell"),swarm:v("iSwarm"),varroa:v("iVarroa"), inspectionType:v("iType"),note:v("iNote"),photo,next:v("iNext"), feedEnabled:v("iFeedEnabled"),feedType:v("iFeedType"),feedAmount:v("iFeedAmount"),feedUnit:v("iFeedUnit"),feedNote:v("iFeedNote"), treatmentEnabled:v("iTreatmentEnabled"),treatmentCategory:v("iTreatmentCategory"),treatmentMethod:v("iTreatmentMethod"), treatmentDose:v("iTreatmentDose"),treatmentCount:v("iTreatmentCount"),treatmentNote:v("iTreatmentNote"), hiveAction:v("iHiveAction"),hiveActionCount:v("iHiveActionCount"),excluderPosition:v("iExcluderPosition"),hiveActionNote:v("iHiveActionNote") }; /* Muayeneye bağlı otomatik kayıtlar: düzenleme sırasında eski bağlı kayıtları temizle. */ if(old){ const idx=db.inspections.findIndex(x=>String(x.id)===String(editId)); if(idx>=0) db.inspections[idx]=r; db.reminders=db.reminders.filter(x=>String(x.sourceInspectionId||"")!==String(editId)); db.feedings=db.feedings.filter(x=>String(x.sourceInspectionId||"")!==String(editId)); db.treatments=db.treatments.filter(x=>String(x.sourceInspectionId||"")!==String(editId)); db.hiveEvents=db.hiveEvents.filter(x=>String(x.sourceInspectionId||"")!==String(editId)); }else{ db.inspections.push(r); } const h=db.hives.find(x=>x.id===r.hive); if(h)h.status=r.strength; if(r.next){ db.reminders.push({ id:Date.now()+1,date:r.next,hive:r.hive,season:seasonNow(), text:"Muayene sonrası kontrol: "+r.hive,done:false, sourceInspectionId:r.id }); } /* Muayeneden girilen kek/şurup vb. Besleme sekmesine otomatik düşer. */ if(r.feedEnabled==="Evet" && (r.feedAmount!=="" || r.feedNote)){ db.feedings.push({ id:Date.now()+2,date:r.date,hive:r.hive,type:r.feedType,amount:r.feedAmount,unit:r.feedUnit, recipe:"",start:r.date,end:"",days:"",result:"",note:r.feedNote||"Muayene sırasında verildi.", sourceInspectionId:r.id }); } /* Muayeneden girilen Varroa / uygulama kaydı Uygulama sekmesine otomatik düşer. */ if(r.treatmentEnabled==="Evet" && (r.treatmentMethod || r.treatmentDose || r.treatmentNote)){ db.treatments.push({ id:Date.now()+3,date:r.date,hive:r.hive,category:r.treatmentCategory,method:r.treatmentMethod, material:"",dose:r.treatmentDose,route:"",count:r.treatmentCount||1,before:r.varroa,after:"", withdrawal:"",note:r.treatmentNote||"Muayene sırasında yapıldı.",sourceInspectionId:r.id }); } /* Kat/ızgara işlemi ayrıca kronolojik kovan geçmişine düşer. */ if(r.hiveAction && r.hiveAction!=="İşlem yok"){ db.hiveEvents.push({ id:Date.now()+4,date:r.date,hive:r.hive,action:r.hiveAction,count:r.hiveActionCount||1, position:r.excluderPosition,note:r.hiveActionNote||"",sourceInspectionId:r.id }); } save(); cancelInspectionEdit(); renderAll(); alert(old?"Muayene kaydı güncellendi.":"Muayene kaydedildi."); }); function editInspection(id){ const r=db.inspections.find(x=>String(x.id)===String(id)); if(!r)return; go("inspection"); document.getElementById("iEditId").value=r.id; [ ["iDate",r.date],["iHive",r.hive],["iStrength",r.strength], ["iBeeFrames",r.beeFrames],["iEggFrames",r.eggFrames], ["iOpenBrood",r.openBrood],["iCappedBrood",r.cappedBrood], ["iHoneyFrames",r.honeyFrames],["iPollenFrames",r.pollenFrames], ["iFoundationFrames",r.foundationFrames],["iFoundationCondition",r.foundationCondition], ["iEggQuality",r.eggQuality],["iBroodQuality",r.broodQuality], ["iQueenSeen",r.queenSeen],["iQueenStatus",r.queenStatus], ["iQueenCell",r.queenCell],["iSwarm",r.swarm],["iVarroa",r.varroa], ["iType",r.inspectionType],["iFeedEnabled",r.feedEnabled],["iFeedType",r.feedType],["iFeedAmount",r.feedAmount],["iFeedUnit",r.feedUnit],["iFeedNote",r.feedNote], ["iTreatmentEnabled",r.treatmentEnabled],["iTreatmentCategory",r.treatmentCategory],["iTreatmentMethod",r.treatmentMethod],["iTreatmentDose",r.treatmentDose],["iTreatmentCount",r.treatmentCount],["iTreatmentNote",r.treatmentNote], ["iHiveAction",r.hiveAction],["iHiveActionCount",r.hiveActionCount],["iExcluderPosition",r.excluderPosition],["iHiveActionNote",r.hiveActionNote], ["iNote",r.note],["iNext",r.next] ].forEach(([id,val])=>{ const el=document.getElementById(id); if(el)el.value=val??""; }); document.getElementById("iPhoto").value=""; document.getElementById("inspectionSubmitBtn").textContent="💾 Değişiklikleri Kaydet"; document.getElementById("inspectionCancelEdit").style.display="inline-flex"; document.getElementById("inspectionForm").scrollIntoView({behavior:"smooth",block:"start"}); } function cancelInspectionEdit(){ const form=document.getElementById("inspectionForm"); if(!form)return; form.reset(); document.getElementById("iEditId").value=""; document.getElementById("iPhoto").value=""; document.getElementById("inspectionSubmitBtn").textContent="💾 Muayeneyi Kaydet"; document.getElementById("inspectionCancelEdit").style.display="none"; setDefaults(); } function renderInspectionTable(){ const q=(document.getElementById("inspectionSearch").value||"").toLowerCase(); const rows=db.inspections.slice().sort((a,b)=>b.date.localeCompare(a.date)) .filter(r=>(r.hive+" "+r.note+" "+r.date).toLowerCase().includes(q)); document.getElementById("inspectionTable").innerHTML=rows.map(r=>` ${esc(r.date)} ${esc(r.hive)} ${esc(r.strength)} Arı ${r.beeFrames||0}
Bal ${r.honeyFrames||0}
Polen ${r.pollenFrames||0}
Temel ${r.foundationFrames||0} Yumurta ${r.eggFrames||0}
Açık ${r.openBrood||0}
Kapalı ${r.cappedBrood||0} ${esc(r.eggQuality)}
${esc(r.broodQuality)} ${r.photo?`
`:""}${esc(r.note)} ${r.feedEnabled==="Evet"?`
🍯 ${esc(r.feedAmount)} ${esc(r.feedUnit)} ${esc(r.feedType)}`:""} ${r.treatmentEnabled==="Evet"?`
🧪 ${esc(r.treatmentCount||1)} × ${esc(r.treatmentMethod)}`:""} ${r.hiveAction&&r.hiveAction!=="İşlem yok"?`
🔧 ${esc(r.hiveAction)}`:""} `).join("")||`
Kayıt yok.
`; } /* BESLEME */ ["fStart","fEnd"].forEach(id=>document.getElementById(id).addEventListener("change",()=>document.getElementById("fDays").value=daysBetween(v("fStart"),v("fEnd")))); document.getElementById("feedingForm").addEventListener("submit",e=>{ e.preventDefault(); const start=v("fStart")||v("fDate"),end=v("fEnd"); db.feedings.push({id:Date.now(),date:v("fDate"),hive:v("fHive"),type:v("fType"),amount:v("fAmount"),unit:v("fUnit"),recipe:v("fRecipe"),start,end,days:daysBetween(start,end),result:v("fResult"),note:v("fNote")}); save();e.target.reset();setDefaults();renderAll();alert("Besleme kaydedildi."); }); function renderFeeding(){ document.getElementById("feedingTable").innerHTML=db.feedings.slice().sort((a,b)=>b.date.localeCompare(a.date)).map(r=>`${r.date}${esc(r.hive)}${esc(r.type)}${esc(r.amount)} ${esc(r.unit)}${esc(r.recipe)}${r.days||"-"} gün${esc(r.result)}`).join("")||`
Kayıt yok.
`; } /* UYGULAMA */ document.getElementById("treatmentForm").addEventListener("submit",e=>{ e.preventDefault(); db.treatments.push({id:Date.now(),date:v("tDate"),hive:v("tHive"),category:v("tCategory"),method:v("tMethod"),material:v("tMaterial"),dose:v("tDose"),route:v("tRoute"),count:v("tCount"),before:v("tBefore"),after:v("tAfter"),withdrawal:v("tWithdrawal"),note:v("tNote")}); save();e.target.reset();setDefaults();renderAll();alert("Uygulama kaydedildi."); }); function renderTreatments(){ document.getElementById("treatmentTable").innerHTML=db.treatments.slice().sort((a,b)=>b.date.localeCompare(a.date)).map(r=>`${r.date}${esc(r.hive)}${esc(r.category)}${esc(r.method)}${esc(r.material)}
${esc(r.dose)}${esc(r.before)} → ${esc(r.after)}${esc(r.note)}`).join("")||`
Kayıt yok.
`; } /* PETEK */ ["cDate","cOut"].forEach(id=>document.getElementById(id).addEventListener("change",()=>document.getElementById("cDays").value=daysBetween(v("cDate"),v("cOut")))); document.getElementById("combForm").addEventListener("submit",e=>{ e.preventDefault();db.combs.push({id:Date.now(),date:v("cDate"),hive:v("cHive"),type:v("cType"),count:v("cCount"),action:v("cAction"),source:v("cSource"),out:v("cOut"),days:daysBetween(v("cDate"),v("cOut")),note:v("cNote")}); save();e.target.reset();setDefaults();renderAll();alert("Petek kaydedildi."); }); document.getElementById("harvestForm").addEventListener("submit",e=>{ e.preventDefault();db.harvests.push({id:Date.now(),date:v("hDate"),hive:v("hHive"),frames:v("hFrames"),kg:v("hKg"),type:v("hType"),batch:v("hBatch"),note:v("hNote")}); save();e.target.reset();setDefaults();renderAll();alert("Bal hasadı kaydedildi."); }); function renderComb(){ document.getElementById("combTable").innerHTML=db.combs.slice().sort((a,b)=>b.date.localeCompare(a.date)).map(r=>`${r.date}${esc(r.hive)}${esc(r.type)}${r.count}${esc(r.action)}${r.days||"-"} gün`).join("")||`
Kayıt yok.
`; document.getElementById("harvestTable").innerHTML=db.harvests.slice().sort((a,b)=>b.date.localeCompare(a.date)).map(r=>`${r.date}${esc(r.hive)}${r.frames||0}${Number(r.kg||0).toFixed(2)}${esc(r.type)}${esc(r.batch)}`).join("")||`
Hasat yok.
`; } /* PLAN */ document.getElementById("reminderForm").addEventListener("submit",e=>{ e.preventDefault();db.reminders.push({id:Date.now(),date:v("rDate"),hive:v("rHive"),season:v("rSeason"),text:v("rText"),done:false});save();e.target.reset();setDefaults();renderAll(); }); function renderReminders(){ const arr=db.reminders.slice().sort((a,b)=>a.date.localeCompare(b.date)); document.getElementById("reminderList").innerHTML=arr.map(r=>`
${esc(r.date)} • ${esc(r.hive)} ${esc(r.season)}

${esc(r.text)}

${r.done?'Tamamlandı':``}
`).join("")||`
Planlanmış iş yok.
`; } function completeReminder(id){const r=db.reminders.find(x=>x.id===id);if(r)r.done=true;save();renderAll()} /* HAVA */ function saveWeatherLocation(){db.weatherLocation={name:v("wName"),latitude:v("wLat"),longitude:v("wLon")};save();loadWeather()} async function loadWeather(){ const l=db.weatherLocation;if(!l.latitude||!l.longitude){renderWeather();return} try{ const url=`https://api.open-meteo.com/v1/forecast?latitude=${encodeURIComponent(l.latitude)}&longitude=${encodeURIComponent(l.longitude)}¤t=temperature_2m,relative_humidity_2m,apparent_temperature,precipitation,weather_code,wind_speed_10m,wind_gusts_10m&daily=weather_code,temperature_2m_max,temperature_2m_min,precipitation_probability_max,precipitation_sum,wind_speed_10m_max,sunrise,sunset&timezone=auto&forecast_days=7`; const r=await fetch(url);db.weather=await r.json();save();renderWeather(); }catch(e){document.getElementById("weatherContent").innerHTML='
Hava durumu alınamadı. İnternet bağlantısını kontrol et.
'} } function weatherText(c){const m={0:"☀️ Açık",1:"🌤️ Çoğunlukla açık",2:"⛅ Parçalı bulutlu",3:"☁️ Kapalı",45:"🌫️ Sis",48:"🌫️ Sis",51:"🌦️ Çiseleme",53:"🌦️ Çiseleme",55:"🌧️ Çiseleme",61:"🌧️ Hafif yağmur",63:"🌧️ Yağmur",65:"🌧️ Kuvvetli yağmur",71:"🌨️ Hafif kar",73:"🌨️ Kar",75:"❄️ Yoğun kar",80:"🌦️ Sağanak",81:"🌧️ Sağanak",82:"⛈️ Kuvvetli sağanak",95:"⛈️ Gök gürültüsü",96:"⛈️ Dolu ihtimali",99:"⛈️ Kuvvetli dolu"};return m[c]||"🌦️ Değişken"} function weatherWarnings(w){ const c=w.current,m=[]; if(c.wind_speed_10m>=30)m.push("⚠️ Rüzgâr yüksek: kovan/kapak sabitlemesini kontrol et."); if(c.wind_gusts_10m>=45)m.push("🚨 Ani rüzgâr çok yüksek: devrilmeye karşı kontrol yap."); if(c.temperature_2m<10)m.push("🥶 Hava serin: gereksiz uzun kovan açılışlarından kaçın."); if(c.temperature_2m>35)m.push("🔥 Çok sıcak: gölgeleme, havalandırma ve su erişimini kontrol et."); if(c.weather_code>=51)m.push("🌧️ Yağışlı koşullar var: arazi ve uçuş faaliyetlerini hava durumuna göre planla."); return m.length?m.map(x=>`

${x}

`).join(""):"🟢 Belirgin bir operasyon uyarısı yok."; } function renderWeather(){ const l=db.weatherLocation;document.getElementById("wName").value=l.name||"";document.getElementById("wLat").value=l.latitude||"";document.getElementById("wLon").value=l.longitude||""; if(!db.weather){document.getElementById("weatherContent").innerHTML='
Koordinatları kaydet ve hava durumunu getir.
';return} const w=db.weather,c=w.current,d=w.daily; const forecast=d.time.map((t,i)=>`
${new Date(t).toLocaleDateString("tr-TR",{weekday:"short",day:"2-digit",month:"2-digit"})}

${weatherText(d.weather_code[i])}

${d.temperature_2m_max[i]}° / ${d.temperature_2m_min[i]}°
Yağış ${d.precipitation_probability_max[i]}%
Rüzgâr ${d.wind_speed_10m_max[i]} km/h
`).join(""); document.getElementById("weatherContent").innerHTML=`

📍 ${esc(l.name)||"Arılık"}

Durum
${weatherText(c.weather_code)}
Sıcaklık
${c.temperature_2m}°C
Hissedilen
${c.apparent_temperature}°C
Nem
${c.relative_humidity_2m}%
Rüzgâr
${c.wind_speed_10m} km/h
Hamle
${c.wind_gusts_10m} km/h

🐝 Operasyon notu

${weatherWarnings(w)}

📅 7 günlük tahmin

${forecast}

☀️ Güneş

Doğuş: ${new Date(d.sunrise[0]).toLocaleTimeString("tr-TR",{hour:"2-digit",minute:"2-digit"})} • Batış: ${new Date(d.sunset[0]).toLocaleTimeString("tr-TR",{hour:"2-digit",minute:"2-digit"})}
`; document.getElementById("dashWeather").innerHTML=`${weatherText(c.weather_code)}
${c.temperature_2m}°C • Nem ${c.relative_humidity_2m}% • Rüzgâr ${c.wind_speed_10m} km/h`; } /* GRAFİKLER */ function chartDestroy(c){try{if(c&&typeof c.destroy==="function")c.destroy()}catch(e){}} function qualityScore(q){ return {"Çok iyi / sık ve düzenli":100,"İyi":80,"Orta":60,"Dağınık":35,"Kötü / düzensiz":15,"Kontrol edilmedi":null}[q]??null; } function renderCharts(){ const id=v("aHive"),range=v("aRange"),cut=range==="all"?null:new Date(Date.now()-Number(range)*86400000); const rs=db.inspections.filter(r=>r.hive===id&&(!cut||new Date(r.date+"T00:00:00")>=cut)).sort((a,b)=>a.date.localeCompare(b.date)); const labels=rs.map(r=>r.date); chartDestroy(chartColony);chartDestroy(chartQueen);chartDestroy(chartResources);chartDestroy(chartProductivity); chartColony=chartQueen=chartResources=chartProductivity=null; chartColony=new Chart(document.getElementById("chartColony"),{type:"line",data:{labels,datasets:[ {label:"Arılı çerçeve",data:rs.map(r=>+r.beeFrames||0),tension:.25}, {label:"Yumurtalı",data:rs.map(r=>+r.eggFrames||0),tension:.25}, {label:"Açık yavru",data:rs.map(r=>+r.openBrood||0),tension:.25}, {label:"Kapalı yavru",data:rs.map(r=>+r.cappedBrood||0),tension:.25} ]},options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{position:"bottom"}}}}); chartQueen=new Chart(document.getElementById("chartQueen"),{type:"line",data:{labels,datasets:[ {label:"Yumurtalı çerçeve",data:rs.map(r=>+r.eggFrames||0),tension:.25}, {label:"Yumurta düzeni göstergesi / 100",data:rs.map(r=>qualityScore(r.eggQuality)),tension:.25} ]},options:{responsive:true,maintainAspectRatio:false,scales:{y:{beginAtZero:true,max:100}},plugins:{legend:{position:"bottom"}}}}); chartResources=new Chart(document.getElementById("chartResources"),{type:"line",data:{labels,datasets:[ {label:"Bal çerçevesi",data:rs.map(r=>+r.honeyFrames||0),tension:.25}, {label:"Polen çerçevesi",data:rs.map(r=>+r.pollenFrames||0),tension:.25}, {label:"Temel petek",data:rs.map(r=>+r.foundationFrames||0),tension:.25} ]},options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{position:"bottom"}}}}); const har=db.harvests.filter(r=>r.hive===id&&(!cut||new Date(r.date+"T00:00:00")>=cut)).sort((a,b)=>a.date.localeCompare(b.date)); const harvestLabels=har.map(r=>r.date),harvestKg=har.map(r=>+r.kg||0); chartProductivity=new Chart(document.getElementById("chartProductivity"),{type:"bar",data:{labels:harvestLabels,datasets:[ {label:"Hasat (kg)",data:harvestKg} ]},options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{position:"bottom"}}}}); const tr=db.treatments.filter(r=>r.hive===id).sort((a,b)=>b.date.localeCompare(a.date)).slice(0,10); document.getElementById("analysisTreatments").innerHTML=tr.map(r=>`
${r.date} • ${esc(r.method)}
${esc(r.before)} → ${esc(r.after)}${r.count?` • ${esc(r.count)} uygulama`:""}
`).join("")||'
Uygulama yok.
'; const events=db.hiveEvents.filter(r=>r.hive===id).sort((a,b)=>b.date.localeCompare(a.date)).slice(0,12); document.getElementById("analysisHiveEvents").innerHTML=events.map(r=>`
${r.date}
${esc(r.action)}${r.count&&r.action==="Kat verildi"?` • ${esc(r.count)} kat`:""}${r.position&&r.position!=="Belirtilmedi"?` • ${esc(r.position)}`:""}${r.note?`
${esc(r.note)}`:""}
`).join("")||'
Kat / ızgara işlemi yok.
'; const h=db.hives.find(x=>x.id===id),harAll=db.harvests.filter(r=>r.hive===id),kg=harAll.reduce((sum,r)=>sum+(+r.kg||0),0),fd=db.feedings.filter(r=>r.hive===id); const avgEgg=rs.length?rs.reduce((sum,r)=>sum+(+r.eggFrames||0),0)/rs.length:0; const latest=rs[rs.length-1]; document.getElementById("analysisSummary").innerHTML=h?`
Son güç${esc(h.status)}
Muayene${rs.length}
Son yumurtalı çerçeve${latest?.eggFrames||0}
Ortalama yumurtalı${avgEgg.toFixed(1)}
Toplam bal${kg.toFixed(2)} kg
Besleme kaydı${fd.length}
`:'
Kovan seç.
'; } /* AYARLAR: yeni seçenek ekle / sil */ const settingLabels={ inspectionTypes:"Muayene türleri",feedingTypes:"Besleme türleri",treatmentCategories:"Uygulama kategorileri",treatmentMethods:"Uygulama yöntemleri",combTypes:"Petek türleri",combActions:"Petek işlemleri",seasons:"Sezonlar",hiveActions:"Kat / ızgara işlemleri",excluderPositions:"Izgara konumları" }; function renderSettings(){ Object.entries(settingLabels).forEach(([key,label])=>{ const box=document.getElementById("setting"+key.charAt(0).toUpperCase()+key.slice(1).replace(/([A-Z])/g,"$1")); /* id eşlemesi aşağıdaki manuel fonksiyonda yapılır */ }); const map={inspectionTypes:"settingInspection",feedingTypes:"settingFeeding",treatmentCategories:"settingTreatmentCategory",treatmentMethods:"settingTreatmentMethod",combTypes:"settingCombType",combActions:"settingCombAction",seasons:"settingSeasons",hiveActions:"settingHiveActions",excluderPositions:"settingExcluderPositions"}; Object.entries(map).forEach(([key,id])=>{ const box=document.getElementById(id); box.innerHTML=`
${db.settings[key].map((x,i)=>`${esc(x)} `).join("")}
`; }); } function addSetting(key){const el=document.getElementById("new_"+key),x=el.value.trim();if(!x)return;if(!db.settings[key].includes(x))db.settings[key].push(x);el.value="";save();renderAll()} function removeSetting(key,i){if(db.settings[key].length<=1){alert("En az bir seçenek kalmalı.");return}if(confirm("Bu seçenek listeden çıkarılsın mı? Eski kayıtlar silinmez.")){db.settings[key].splice(i,1);save();renderAll()}} /* DASHBOARD */ function renderDashboard(){ const total=db.hives.length,strong=db.hives.filter(h=>h.status==="Güçlü").length,tasks=db.reminders.filter(r=>!r.done).length,honey=db.harvests.reduce((s,r)=>s+(+r.kg||0),0); document.getElementById("statHives").textContent=total;document.getElementById("statStrong").textContent=strong;document.getElementById("statTasks").textContent=tasks;document.getElementById("statHoney").textContent=honey.toFixed(2)+" kg"; const tasksArr=db.reminders.filter(r=>!r.done).sort((a,b)=>a.date.localeCompare(b.date)).slice(0,5); document.getElementById("dashTasks").innerHTML=tasksArr.map(r=>`
${r.date} • ${esc(r.hive)}

${esc(r.text)}

`).join("")||'
Bekleyen iş yok.
'; const recent=[...db.inspections.map(x=>({...x,kind:"Muayene"})),...db.feedings.map(x=>({...x,kind:"Besleme"})),...db.treatments.map(x=>({...x,kind:"Uygulama"})),...db.harvests.map(x=>({...x,kind:"Hasat"})),...db.hiveEvents.map(x=>({...x,kind:"Kovan işlemi"}))].sort((a,b)=>b.date.localeCompare(a.date)).slice(0,7); document.getElementById("dashRecent").innerHTML=recent.map(r=>`

${r.date} • ${esc(r.hive)} • ${esc(r.kind)}

`).join("")||'
Kayıt yok.
'; if(db.weather)renderWeather();else document.getElementById("dashWeather").innerHTML='
Hava konumu girilmedi.
'; } /* YARDIMCI */ function v(id){return document.getElementById(id)?.value||""} function seasonNow(){const m=new Date().getMonth()+1;return m<=2?"Kış":m<=5?"İlkbahar":m<=8?"Yaz":"Sonbahar"} function setDefaults(){ const dates=["iDate","fDate","fStart","tDate","cDate","hDate","rDate"];dates.forEach(id=>{if(document.getElementById(id))document.getElementById(id).value=today()}); const yr=new Date().getFullYear();if(!v("hQueenYear"))document.getElementById("hQueenYear").value=yr; } function del(key,id){if(!confirm("Bu kayıt silinsin mi?"))return;db[key]=db[key].filter(x=>x.id!==id);save();renderAll()} /* JSON / CSV */ function exportJSON(){ const blob=new Blob([JSON.stringify(db,null,2)],{type:"application/json"}),a=document.createElement("a"); a.href=URL.createObjectURL(blob);a.download="arilik-os-v3-"+today()+".json";a.click();setTimeout(()=>URL.revokeObjectURL(a.href),500); } function importJSON(){ const f=document.getElementById("importFile").files[0];if(!f){alert("Önce JSON dosyası seç.");return} const rd=new FileReader();rd.onload=e=>{try{ const x=JSON.parse(e.target.result); db=x.version>=3?mergeDB(x):migrateOld(x);save();renderAll();alert("Veriler aktarıldı."); }catch(err){alert("Geçersiz JSON dosyası.")}};rd.readAsText(f); } function exportCSV(){ const rows=[["Tip","Tarih","Kovan","Detay","Miktar","Birim","Not"]]; db.inspections.forEach(r=>rows.push(["Muayene",r.date,r.hive,`Güç ${r.strength}; Arı ${r.beeFrames}; Yumurta ${r.eggFrames}; Açık ${r.openBrood}; Kapalı ${r.cappedBrood}`, "", "",r.note])); db.feedings.forEach(r=>rows.push(["Besleme",r.date,r.hive,r.type,r.amount,r.unit,`${r.days||"-"} gün; ${r.note||""}`])); db.treatments.forEach(r=>rows.push(["Uygulama",r.date,r.hive,`${r.category} / ${r.method} / ${r.material}`,r.dose,"",r.note])); db.combs.forEach(r=>rows.push(["Petek",r.date,r.hive,`${r.type} / ${r.action}`,r.count,"adet",r.note])); db.harvests.forEach(r=>rows.push(["Hasat",r.date,r.hive,r.type,r.kg,"kg",r.note])); db.hiveEvents.forEach(r=>rows.push(["Kovan işlemi",r.date,r.hive,`${r.action}${r.position?" / "+r.position:""}`,r.count,"adet",r.note])); const csv="\ufeff"+rows.map(row=>row.map(x=>`"${String(x??"").replace(/"/g,'""')}"`).join(";")).join("\n"); const blob=new Blob([csv],{type:"text/csv;charset=utf-8"}),a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="arilik-os-"+today()+".csv";a.click(); } function resetData(){if(!confirm("TÜM ARILIK VERİLERİ SİLİNECEK. Önce yedek aldın mı?"))return;if(window.safeStorage)window.safeStorage.remove(KEY);else localStorage.removeItem(KEY);location.reload()} /* RENDER */ function renderAll(){ const jobs=[hiveSelects,renderHives,renderInspectionTable,renderFeeding,renderTreatments,renderComb,renderReminders,renderDashboard,renderCharts,renderSettings]; jobs.forEach(fn=>{try{fn()}catch(err){console.error("Render hatası:",fn.name,err)}}); } function setFormDatesOnce(){ ["iDate","fDate","fStart","tDate","cDate","hDate","rDate"].forEach(id=>{if(document.getElementById(id))document.getElementById(id).value=today()}); } setFormDatesOnce();renderAll(); /* QR hash */ if(location.hash.startsWith("#kovan=")){ const id=decodeURIComponent(location.hash.slice(7)); setTimeout(()=>{if(db.hives.some(h=>h.id===id))hiveDetail(id)},200); }