Update Next.js configuration and package dependencies
All checks were successful
Deploy / deploy (push) Successful in 9m29s

- Modified redirects in next.config.ts to change the destination for "/sohbet" to "/listem".
- Added new dependencies in package.json: marked, motion, react-markdown, remark-breaks, remark-gfm, shiki, and use-stick-to-bottom.
- Updated pnpm-lock.yaml to reflect the new package versions and dependencies.
- Removed obsolete stack files for Flutter, Nuxt, Nuxt.js, React Native, and Svelte from the UI/UX Pro Max skill data.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
bilalgursen
2026-07-26 04:26:52 +03:00
parent 1d0328d8eb
commit 209d203fe8
59 changed files with 6599 additions and 1446 deletions

View File

@@ -23,11 +23,15 @@ const TercihSchema = z.object({
const RaporSchema = z.object({
tercihler: z.array(TercihSchema),
genelDegerlendirme: z.string(),
uyarilar: z.array(z.string()).min(2).max(3),
});
export type RaporSonuc = z.infer<typeof RaporSchema> & {
// uyarilar şemada zorunlu ama eski kayıtlı raporlarda yok → tipte opsiyonel
export type RaporSonuc = Omit<z.infer<typeof RaporSchema>, "uyarilar"> & {
uyarilar?: string[];
// Render için havuzdan zenginleştirilmiş program bilgisi
// efektifSira: COALESCE(sira2025, sira2024) — eski kayıtlı raporlarda yok
// siraGecmisi: [2021..2025] taban sıralamaları — deterministik trend oku
programlar: Record<
string,
{
@@ -36,6 +40,7 @@ export type RaporSonuc = z.infer<typeof RaporSchema> & {
il: string | null;
unitur: string | null;
efektifSira?: number | null;
siraGecmisi?: (number | null)[];
}
>;
};
@@ -50,17 +55,104 @@ KURALLAR (kesin):
- Liste yapısı: en üstte 4-6 hayal, ortada 12-14 dengeli, sonda 5-7 garanti.
Tercih sırası MUTLAKA iyi taban sıralamasından kötüye doğru gitmeli
(küçük taban sıralaması = daha zor bölüm üstte).
- gerekce: bu programın bu aday için neden mantıklı olduğu (1-2 cümle, Türkçe).
- riskNotu: yerleşme ihtimali değerlendirmesi. ASLA "garanti", "kesin",
"yüzde yüz" deme; "yüksek/orta/düşük ihtimal" dili kullan.
- trendOzeti: son 4 yılın taban sıralaması hareketi (ör. "2022'den beri taban
sıralaması 45B'den 38B'ye indi, bölüm zorlaşıyor").
- METİN DİYETİ: aday 24 satır okuyacak; her alan TEK kısa cümle, dolgu söz yok.
- gerekce: bu programın bu aday için neden mantıklı olduğu (TEK cümle,
en fazla ~15 kelime, Türkçe).
- riskNotu: yerleşme ihtimali değerlendirmesi (TEK kısa cümle). ASLA "garanti",
"kesin", "yüzde yüz" deme; "yüksek/orta/düşük ihtimal" dili kullan.
- trendOzeti: son 4 yılın taban sıralaması hareketi, TEK cümle (ör. "2022'den
beri taban 45B'den 38B'ye indi, bölüm zorlaşıyor").
- Kontenjan artışı/azalışı ve yerleşen sayısını değerlendirmene kat.
- Adayın notlarındaki şehir/bölüm tercihlerine saygı göster ama dengeyi bozma.
- genelDegerlendirme: listenin genel stratejisi + adaya 2-3 pratik uyarı (Türkçe).`;
- genelDegerlendirme: listenin genel stratejisi, EN FAZLA 2 cümle. Uyarıları
buraya yazma.
- uyarilar: adaya 2-3 pratik, eyleme dönük uyarı; her biri tek kısa cümle.`;
export class RaporUretimHatasi extends Error {}
/** Havuz programını render için gereken bilgiye indirger. */
function programBilgisi(p: AdayProgram): RaporSonuc["programlar"][string] {
const gecmis = [p.sira2021, p.sira2022, p.sira2023, p.sira2024, p.sira2025];
return {
isim: p.isim,
universite: p.universite,
il: p.il,
unitur: p.unitur,
efektifSira: p.sira2025 ?? p.sira2024,
siraGecmisi: gecmis.some((s) => s != null) ? gecmis : undefined,
};
}
// --- Dev mock: API key yokken (yalnızca development) gerçek havuzdan sahte
// ama tutarlı bir rapor üret. Akış (kredi, blur, risk renkleri, revizyon)
// gerçek AI olmadan uçtan uca test edilebilsin diye. Prod'da asla çalışmaz.
function mockAktif(): boolean {
return (
process.env.NODE_ENV !== "production" &&
!process.env.ANTHROPIC_API_KEY &&
!process.env.ANTHROPIC_AUTH_TOKEN
);
}
function mockRapor(
havuz: AdayProgram[],
params: RaporParams,
revizyonNotu?: string,
): RaporSonuc {
const efektif = (p: AdayProgram) => p.sira2025 ?? p.sira2024 ?? 0;
const dilimden = (dilim: AdayProgram["dilim"], adet: number) =>
havuz
.filter((p) => p.dilim === dilim)
.sort((a, b) => efektif(a) - efektif(b))
.slice(0, adet);
// 5 hayal + 13 dengeli + 6 garanti; eksik dilim varsa havuzdan tamamla
const secilen = [
...dilimden("hayal", 5),
...dilimden("dengeli", 13),
...dilimden("garanti", 6),
];
for (const p of havuz) {
if (secilen.length >= 24) break;
if (!secilen.includes(p)) secilen.push(p);
}
const tercihler = secilen.slice(0, 24).map((p, i) => ({
programId: p.id,
sira: i + 1,
dilim: p.dilim,
gerekce: `(Dev mock) ${p.isim}, seçtiğin ilgi alanlarıyla ve ${params.sira.toLocaleString("tr-TR")}. sıralamanla uyumlu bir aday.`,
riskNotu:
p.dilim === "hayal"
? "(Dev mock) Taban sıralaması senin üstünde kapandı; düşük ihtimal ama listenin başında yeri var."
: p.dilim === "dengeli"
? "(Dev mock) Taban sıralaması senin civarında; orta-yüksek ihtimalle yerleşilebilir."
: "(Dev mock) Taban sıralaması senin belirgin altında; yüksek ihtimalle yerleşirsin.",
trendOzeti:
"(Dev mock) Son 4 yılda taban sıralaması görece stabil seyretti.",
}));
const programlar: RaporSonuc["programlar"] = {};
for (const p of secilen.slice(0, 24)) {
programlar[p.id] = programBilgisi(p);
}
return {
tercihler,
genelDegerlendirme: `(Dev mock — ANTHROPIC_API_KEY tanımlı değil, bu rapor gerçek AI çıktısı değildir.) ${params.sira.toLocaleString(
"tr-TR",
)}. sıra için hayal/dengeli/garanti dağılımlı 24 tercihlik örnek liste kuruldu.${
revizyonNotu ? ` Revizyon isteğin not alındı: "${revizyonNotu}".` : ""
}`,
uyarilar: [
"(Dev mock) Tercih dönemi kapanmadan listeyi ÖSYM sistemine kendin gir.",
"(Dev mock) Garanti dilimindeki son 3 tercihi asla silme.",
],
programlar,
};
}
export async function raporUret(
params: RaporParams,
revizyonNotu?: string,
@@ -91,6 +183,12 @@ export async function raporUret(
);
}
// Dev'de API key yoksa gerçek AI yerine mock rapor (üretim gecikmesi taklidi)
if (mockAktif()) {
await new Promise((r) => setTimeout(r, 1500));
return mockRapor(havuz, params, revizyonNotu);
}
const client = getAnthropic();
const havuzJson = havuzuKompaktJson(havuz);
const kullaniciMesaji = [
@@ -165,13 +263,7 @@ export async function raporUret(
const programlar: RaporSonuc["programlar"] = {};
for (const p of havuz) {
programlar[p.id] = {
isim: p.isim,
universite: p.universite,
il: p.il,
unitur: p.unitur,
efektifSira: p.sira2025 ?? p.sira2024,
};
programlar[p.id] = programBilgisi(p);
}
return { ...sonuc, programlar };
}

59
src/lib/harita.ts Normal file
View File

@@ -0,0 +1,59 @@
// turkey-map-react SVG uzayı (viewBox 0 0 1050 585) ile coğrafi koordinatlar
// arasındaki dönüşüm ve üniversite konum çözümü.
//
// Afin katsayılar, 81 il path'inin bbox merkezleri ile il merkezlerinin
// (lat, lng) değerleri arasında en küçük kareler uyumuyla hesaplanıp
// sabitlendi; ölçek doğrulaması: ~0.6 px/km her iki eksende de tutarlı.
import { UNI_KOORDINAT, IL_MERKEZ, type LatLng } from "./uni-koordinatlar";
export const HARITA_GENISLIK = 1050;
export const HARITA_YUKSEKLIK = 585;
export function latLngToXy([lat, lng]: LatLng): { x: number; y: number } {
return {
x: 52.5215 * lng - 1332.1743,
y: -65.4185 * lat + 2917.4061,
};
}
/** Harita il adını DB formatına çevirir: "Hakkâri" → "HAKKARİ". */
export function normalizeIlAdi(name: string): string {
return name
.toLocaleUpperCase("tr-TR")
.replace(/Â/g, "A")
.replace(/Î/g, "İ")
.replace(/Û/g, "U");
}
/** DB'deki üniversite adının "(İL)" ekini ayıklar. */
export function uniAdiNormalize(ad: string): string {
return ad.replace(/\s*\([^)]*\)\s*$/, "").trim();
}
export type UniKonum = {
x: number;
y: number;
/** true: kampüs koordinatı; false: il merkezine düşen yaklaşık konum */
kesin: boolean;
};
/**
* Üniversitenin harita üzerindeki konumu. Sıra: "AD|İL" → "AD" → il merkezi.
* KKTC ve yurtdışı kampüsler için null (harita dışı).
*/
export function uniKonum(universite: string, il: string | null): UniKonum | null {
const ad = uniAdiNormalize(universite);
const koord =
(il ? UNI_KOORDINAT[`${ad}|${il}`] : undefined) ?? UNI_KOORDINAT[ad];
if (koord) return { ...latLngToXy(koord), kesin: true };
const merkez = il ? IL_MERKEZ[il] : undefined;
if (merkez) return { ...latLngToXy(merkez), kesin: false };
return null;
}
/** İl merkezinin harita konumu (kilitli/adsız pinler için). */
export function ilKonum(il: string | null): { x: number; y: number } | null {
const merkez = il ? IL_MERKEZ[il] : undefined;
return merkez ? latLngToXy(merkez) : null;
}

73
src/lib/rapor-maske.ts Normal file
View File

@@ -0,0 +1,73 @@
// Paketsiz kullanıcıya giden raporun sunucu tarafı maskesi.
// Blur yalnızca CSS olduğundan kilitli satırların gerçek içeriği client'a
// hiç inmemeli: ilk ACIK_SATIR tercih gerçek kalır, gerisinin metinleri
// makul görünen placeholder'larla değiştirilir. Risk rengini besleyen
// dilim + il gerçek kalır ki blur altındaki dağılım adayı yansıtsın;
// taban sıralaması (efektifSira) sızdırılmaz.
import type { RaporSonuc } from "./ai/rapor";
export const ACIK_SATIR = 3;
const SAHTE_ISIMLER = [
"Bilgisayar Mühendisliği (İngilizce)",
"Elektrik-Elektronik Mühendisliği",
"Endüstri Mühendisliği",
"Yazılım Mühendisliği (Burslu)",
"Makine Mühendisliği",
"İşletme (İngilizce)",
"Psikoloji",
"Mimarlık",
];
const SAHTE_GEREKCE =
"Sıralamana ve seçtiğin önceliklere göre dengeli bir aday; ayrıntılı gerekçe kilidin ardında.";
const SAHTE_RISK =
"Yerleşme ihtimali değerlendirmesi paketi aktive edince görünür.";
const SAHTE_TREND =
"Son 4 yılın taban sıralaması hareketi paketi aktive edince görünür.";
/** genelDegerlendirme'nin yalnızca ilk 1-2 cümlesini bırakır. */
function degerlendirmeKirp(metin: string): string {
const cumleler = metin.match(/[^.!?]+[.!?]+/g);
if (!cumleler || cumleler.length <= 2) return metin;
return `${cumleler.slice(0, 2).join(" ").trim()}`;
}
export function raporMaskele(rapor: RaporSonuc): RaporSonuc {
const tercihler = rapor.tercihler.map((t, i) =>
i < ACIK_SATIR
? t
: {
...t,
gerekce: SAHTE_GEREKCE,
riskNotu: SAHTE_RISK,
trendOzeti: SAHTE_TREND,
},
);
const programlar: RaporSonuc["programlar"] = {};
rapor.tercihler.forEach((t, i) => {
const p = rapor.programlar[t.programId];
if (!p) return;
programlar[t.programId] =
i < ACIK_SATIR
? p
: {
isim: SAHTE_ISIMLER[i % SAHTE_ISIMLER.length],
universite: "•••••••• Üniversitesi",
il: p.il,
unitur: p.unitur,
efektifSira: null,
};
});
return {
tercihler,
genelDegerlendirme: degerlendirmeKirp(rapor.genelDegerlendirme),
// Uyarılar liste geneline dair, satır sırrı taşımaz: paketsizde de kalır.
// Satır bazlı siraGecmisi ise kilitli satırlarda hiç kopyalanmaz (üstte).
uyarilar: rapor.uyarilar,
programlar,
};
}

249
src/lib/uni-koordinatlar.ts Normal file
View File

@@ -0,0 +1,249 @@
// Üniversite kampüsü ve il merkezi koordinatları (lat, lng).
// Kaynak: kamuya açık kampüs konumları; hassasiyet il-içi pin göstermeye
// yeterli olacak düzeyde tutuldu (birkaç yüz metre sapma önemsiz).
//
// Anahtar biçimi: DB'deki üniversite adının "(İL)" eki ayıklanmış hali.
// Aynı ad birden çok ilde kampüs taşıyorsa (ör. Sağlık Bilimleri Üni.)
// "AD|İL" biçimindeki anahtar önceliklidir. Burada olmayan üniversiteler
// il merkezine (IL_MERKEZ) düşer; o da yoksa (KKTC, yurtdışı) harita dışıdır.
export type LatLng = readonly [number, number];
export const UNI_KOORDINAT: Record<string, LatLng> = {
// ── İstanbul ──────────────────────────────────────────────
"ACIBADEM MEHMET ALİ AYDINLAR ÜNİVERSİTESİ": [40.973, 29.129],
"ALTINBAŞ ÜNİVERSİTESİ": [41.058, 28.807],
"ATAŞEHİR ADIGÜZEL MESLEK YÜKSEKOKULU": [40.993, 29.123],
"BAHÇEŞEHİR ÜNİVERSİTESİ": [41.042, 29.009],
"BEYKOZ ÜNİVERSİTESİ": [41.093, 29.093],
"BEZM-İ ÂLEM VAKIF ÜNİVERSİTESİ": [41.017, 28.945],
"BOĞAZİÇİ ÜNİVERSİTESİ": [41.083, 29.051],
"BİRUNİ ÜNİVERSİTESİ": [40.989, 28.899],
"DEMİROĞLU BİLİM ÜNİVERSİTESİ": [41.06, 28.988],
"DOĞUŞ ÜNİVERSİTESİ": [41.018, 29.157],
"FATİH SULTAN MEHMET VAKIF ÜNİVERSİTESİ": [41.041, 28.945],
"FENERBAHÇE ÜNİVERSİTESİ": [40.983, 29.099],
"GALATASARAY ÜNİVERSİTESİ": [41.047, 29.026],
"HALİÇ ÜNİVERSİTESİ": [41.048, 28.945],
"IŞIK ÜNİVERSİTESİ": [41.109, 29.61],
"KADİR HAS ÜNİVERSİTESİ": [41.025, 28.958],
"KOÇ ÜNİVERSİTESİ": [41.204, 29.073],
"MALTEPE ÜNİVERSİTESİ": [40.943, 29.13],
"MARMARA ÜNİVERSİTESİ": [40.987, 29.053],
"MEF ÜNİVERSİTESİ": [41.107, 29.011],
"MİMAR SİNAN GÜZEL SANATLAR ÜNİVERSİTESİ": [41.031, 28.992],
"PİRİ REİS ÜNİVERSİTESİ": [40.811, 29.269],
"SABANCI ÜNİVERSİTESİ": [40.891, 29.379],
"SAĞLIK BİLİMLERİ ÜNİVERSİTESİ|İSTANBUL": [41.007, 29.016],
"TÜRK-ALMAN ÜNİVERSİTESİ": [41.148, 29.1],
"YEDİTEPE ÜNİVERSİTESİ": [40.973, 29.15],
"YILDIZ TEKNİK ÜNİVERSİTESİ": [41.021, 28.888],
"ÖZYEĞİN ÜNİVERSİTESİ": [41.031, 29.259],
"ÜSKÜDAR ÜNİVERSİTESİ": [41.022, 29.024],
"İBN HALDUN ÜNİVERSİTESİ": [41.107, 28.762],
"İSTANBUL 29 MAYIS ÜNİVERSİTESİ": [41.031, 29.098],
"İSTANBUL AREL ÜNİVERSİTESİ": [41.061, 28.532],
"İSTANBUL ATLAS ÜNİVERSİTESİ": [41.086, 28.978],
"İSTANBUL AYDIN ÜNİVERSİTESİ": [40.992, 28.797],
"İSTANBUL BEYKENT ÜNİVERSİTESİ": [41.111, 29.02],
"İSTANBUL BİLGİ ÜNİVERSİTESİ": [41.062, 28.947],
"İSTANBUL ESENYURT ÜNİVERSİTESİ": [41.034, 28.68],
"İSTANBUL GALATA ÜNİVERSİTESİ": [41.028, 28.974],
"İSTANBUL GEDİK ÜNİVERSİTESİ": [40.906, 29.23],
"İSTANBUL GELİŞİM ÜNİVERSİTESİ": [40.995, 28.708],
"İSTANBUL KENT ÜNİVERSİTESİ": [41.037, 28.972],
"İSTANBUL KÜLTÜR ÜNİVERSİTESİ": [40.991, 28.822],
"İSTANBUL MEDENİYET ÜNİVERSİTESİ": [40.999, 29.068],
"İSTANBUL MEDİPOL ÜNİVERSİTESİ": [41.089, 29.086],
"İSTANBUL NİŞANTAŞI ÜNİVERSİTESİ": [41.111, 29.023],
"İSTANBUL OKAN ÜNİVERSİTESİ": [40.94, 29.32],
"İSTANBUL RUMELİ ÜNİVERSİTESİ": [41.117, 28.204],
"İSTANBUL SABAHATTİN ZAİM ÜNİVERSİTESİ": [41.031, 28.783],
"İSTANBUL TEKNİK ÜNİVERSİTESİ": [41.105, 29.025],
"İSTANBUL TOPKAPI ÜNİVERSİTESİ": [41.021, 28.917],
"İSTANBUL TİCARET ÜNİVERSİTESİ": [41.048, 28.947],
"İSTANBUL YENİ YÜZYIL ÜNİVERSİTESİ": [41.004, 28.911],
"İSTANBUL ÜNİVERSİTESİ": [41.013, 28.964],
"İSTANBUL ÜNİVERSİTESİ-CERRAHPAŞA": [41.003, 28.725],
"İSTANBUL ŞİŞLİ MESLEK YÜKSEKOKULU": [41.06, 28.987],
"İSTİNYE ÜNİVERSİTESİ": [41.023, 28.925],
// ── Ankara ────────────────────────────────────────────────
"ANKARA HACI BAYRAM VELİ ÜNİVERSİTESİ": [39.938, 32.822],
"ANKARA MEDİPOL ÜNİVERSİTESİ": [39.943, 32.854],
"ANKARA SOSYAL BİLİMLER ÜNİVERSİTESİ": [39.943, 32.854],
"ANKARA YILDIRIM BEYAZIT ÜNİVERSİTESİ": [40.058, 32.947],
"ANKARA ÜNİVERSİTESİ": [39.938, 32.836],
"ATILIM ÜNİVERSİTESİ": [39.813, 32.729],
"BAŞKENT ÜNİVERSİTESİ": [39.888, 32.658],
"GAZİ ÜNİVERSİTESİ": [39.941, 32.822],
"HACETTEPE ÜNİVERSİTESİ": [39.867, 32.735],
"LOKMAN HEKİM ÜNİVERSİTESİ": [39.911, 32.799],
"ORTA DOĞU TEKNİK ÜNİVERSİTESİ": [39.891, 32.783],
"OSTİM TEKNİK ÜNİVERSİTESİ": [39.972, 32.758],
"SAĞLIK BİLİMLERİ ÜNİVERSİTESİ|ANKARA": [39.967, 32.887],
"TED ÜNİVERSİTESİ": [39.918, 32.867],
"TOBB EKONOMİ VE TEKNOLOJİ ÜNİVERSİTESİ": [39.919, 32.799],
"TÜRK HAVA KURUMU ÜNİVERSİTESİ": [39.949, 32.688],
"UFUK ÜNİVERSİTESİ": [39.892, 32.815],
"ÇANKAYA ÜNİVERSİTESİ": [39.818, 32.565],
"İHSAN DOĞRAMACI BİLKENT ÜNİVERSİTESİ": [39.868, 32.748],
// ── İzmir ─────────────────────────────────────────────────
"DOKUZ EYLÜL ÜNİVERSİTESİ": [38.368, 27.203],
"EGE ÜNİVERSİTESİ": [38.457, 27.23],
"YAŞAR ÜNİVERSİTESİ": [38.454, 27.2],
"İZMİR BAKIRÇAY ÜNİVERSİTESİ": [38.588, 27.06],
"İZMİR DEMOKRASİ ÜNİVERSİTESİ": [38.383, 27.096],
"İZMİR EKONOMİ ÜNİVERSİTESİ": [38.389, 27.049],
"İZMİR KATİP ÇELEBİ ÜNİVERSİTESİ": [38.483, 27.055],
"İZMİR KAVRAM MESLEK YÜKSEKOKULU": [38.415, 27.14],
"İZMİR TINAZTEPE ÜNİVERSİTESİ": [38.352, 27.185],
"İZMİR YÜKSEK TEKNOLOJİ ENSTİTÜSÜ": [38.319, 26.64],
// ── İlçe kampüsleri (il merkezinden belirgin uzakta) ──────
"ALANYA ALAADDİN KEYKUBAT ÜNİVERSİTESİ": [36.545, 31.996],
"ALANYA ÜNİVERSİTESİ": [36.552, 32.012],
"BANDIRMA ONYEDİ EYLÜL ÜNİVERSİTESİ": [40.352, 27.973],
"GEBZE TEKNİK ÜNİVERSİTESİ": [40.808, 29.359],
"TARSUS ÜNİVERSİTESİ": [36.919, 34.892],
"İSKENDERUN TEKNİK ÜNİVERSİTESİ": [36.577, 36.172],
"HATAY MUSTAFA KEMAL ÜNİVERSİTESİ": [36.32, 36.194],
"KAPADOKYA ÜNİVERSİTESİ": [38.446, 34.855],
// ── Diğer büyük kampüsler ─────────────────────────────────
"ABDULLAH GÜL ÜNİVERSİTESİ": [38.738, 35.472],
"ADANA ALPARSLAN TÜRKEŞ BİLİM VE TEKNOLOJİ ÜNİVERSİTESİ": [37.058, 35.442],
"AKDENİZ ÜNİVERSİTESİ": [36.897, 30.65],
"ANADOLU ÜNİVERSİTESİ": [39.79, 30.502],
"ANTALYA BELEK ÜNİVERSİTESİ": [36.897, 30.749],
"ANTALYA BİLİM ÜNİVERSİTESİ": [36.916, 30.795],
"ATATÜRK ÜNİVERSİTESİ": [39.902, 41.24],
"AYDIN ADNAN MENDERES ÜNİVERSİTESİ": [37.855, 27.851],
"BOLU ABANT İZZET BAYSAL ÜNİVERSİTESİ": [40.712, 31.523],
"BURSA TEKNİK ÜNİVERSİTESİ": [40.229, 29.009],
"BURSA ULUDAĞ ÜNİVERSİTESİ": [40.226, 28.87],
"ÇUKUROVA ÜNİVERSİTESİ": [37.058, 35.358],
"DİCLE ÜNİVERSİTESİ": [37.888, 40.276],
"ERCİYES ÜNİVERSİTESİ": [38.703, 35.526],
"ERZURUM TEKNİK ÜNİVERSİTESİ": [39.945, 41.181],
"ESKİŞEHİR OSMANGAZİ ÜNİVERSİTESİ": [39.751, 30.483],
"ESKİŞEHİR TEKNİK ÜNİVERSİTESİ": [39.814, 30.531],
"FIRAT ÜNİVERSİTESİ": [38.679, 39.199],
"GAZİANTEP ÜNİVERSİTESİ": [37.106, 37.362],
"GAZİANTEP İSLAM BİLİM VE TEKNOLOJİ ÜNİVERSİTESİ": [37.11, 37.42],
"HARRAN ÜNİVERSİTESİ": [37.008, 38.828],
"HASAN KALYONCU ÜNİVERSİTESİ": [37.14, 37.483],
"KAHRAMANMARAŞ SÜTÇÜ İMAM ÜNİVERSİTESİ": [37.629, 36.822],
"KARADENİZ TEKNİK ÜNİVERSİTESİ": [40.994, 39.766],
"KOCAELİ ÜNİVERSİTESİ": [40.822, 29.923],
"KONYA GIDA VE TARIM ÜNİVERSİTESİ": [37.939, 32.516],
"KONYA TEKNİK ÜNİVERSİTESİ": [38.026, 32.51],
"KTO KARATAY ÜNİVERSİTESİ": [37.884, 32.494],
"MANİSA CELÂL BAYAR ÜNİVERSİTESİ": [38.679, 27.311],
"MERSİN ÜNİVERSİTESİ": [36.786, 34.525],
"MUĞLA SITKI KOÇMAN ÜNİVERSİTESİ": [37.16, 28.372],
"NECMETTİN ERBAKAN ÜNİVERSİTESİ": [37.936, 32.504],
"NUH NACİ YAZGAN ÜNİVERSİTESİ": [38.756, 35.517],
"ONDOKUZ MAYIS ÜNİVERSİTESİ": [41.368, 36.2],
"PAMUKKALE ÜNİVERSİTESİ": [37.741, 29.101],
"SAKARYA ÜNİVERSİTESİ": [40.741, 30.331],
"SANKO ÜNİVERSİTESİ": [37.076, 37.331],
"SELÇUK ÜNİVERSİTESİ": [38.023, 32.512],
"SÜLEYMAN DEMİREL ÜNİVERSİTESİ": [37.83, 30.526],
"SİVAS CUMHURİYET ÜNİVERSİTESİ": [39.727, 37.05],
"TOROS ÜNİVERSİTESİ": [36.786, 34.583],
"TRABZON ÜNİVERSİTESİ": [40.999, 39.65],
"TRAKYA ÜNİVERSİTESİ": [41.66, 26.554],
"VAN YÜZÜNCÜ YIL ÜNİVERSİTESİ": [38.567, 43.276],
"ÇAĞ ÜNİVERSİTESİ": [36.925, 34.955],
"ÇANAKKALE ONSEKİZ MART ÜNİVERSİTESİ": [40.117, 26.42],
"İNÖNÜ ÜNİVERSİTESİ": [38.318, 38.435],
"ZONGULDAK BÜLENT ECEVİT ÜNİVERSİTESİ": [41.448, 31.767],
};
// İl merkezi koordinatları — DB'deki il adı biçimiyle (büyük harf, Türkçe).
// Koordinatı bilinmeyen üniversiteler bu noktaya düşer.
export const IL_MERKEZ: Record<string, LatLng> = {
ADANA: [37.0, 35.32],
ADIYAMAN: [37.76, 38.28],
AFYONKARAHİSAR: [38.76, 30.54],
AĞRI: [39.72, 43.05],
AKSARAY: [38.37, 34.03],
AMASYA: [40.65, 35.83],
ANKARA: [39.93, 32.86],
ANTALYA: [36.9, 30.7],
ARDAHAN: [41.11, 42.7],
ARTVİN: [41.18, 41.82],
AYDIN: [37.85, 27.85],
BALIKESİR: [39.65, 27.89],
BARTIN: [41.63, 32.34],
BATMAN: [37.88, 41.13],
BAYBURT: [40.26, 40.22],
BİLECİK: [40.15, 29.98],
BİNGÖL: [38.88, 40.5],
BİTLİS: [38.4, 42.11],
BOLU: [40.74, 31.61],
BURDUR: [37.72, 30.29],
BURSA: [40.18, 29.07],
ÇANAKKALE: [40.15, 26.41],
ÇANKIRI: [40.6, 33.62],
ÇORUM: [40.55, 34.95],
DENİZLİ: [37.77, 29.09],
DİYARBAKIR: [37.91, 40.24],
DÜZCE: [40.84, 31.16],
EDİRNE: [41.68, 26.56],
ELAZIĞ: [38.68, 39.22],
ERZİNCAN: [39.75, 39.49],
ERZURUM: [39.9, 41.27],
ESKİŞEHİR: [39.78, 30.52],
GAZİANTEP: [37.07, 37.38],
GİRESUN: [40.91, 38.39],
GÜMÜŞHANE: [40.46, 39.48],
HAKKARİ: [37.57, 43.74],
HATAY: [36.2, 36.16],
IĞDIR: [39.92, 44.04],
ISPARTA: [37.76, 30.56],
İSTANBUL: [41.01, 28.98],
İZMİR: [38.42, 27.14],
KAHRAMANMARAŞ: [37.58, 36.93],
KARABÜK: [41.2, 32.63],
KARAMAN: [37.18, 33.22],
KARS: [40.6, 43.1],
KASTAMONU: [41.38, 33.78],
KAYSERİ: [38.72, 35.49],
KIRIKKALE: [39.85, 33.51],
KIRKLARELİ: [41.73, 27.22],
KIRŞEHİR: [39.15, 34.16],
KİLİS: [36.72, 37.12],
KOCAELİ: [40.77, 29.94],
KONYA: [37.87, 32.48],
KÜTAHYA: [39.42, 29.98],
MALATYA: [38.35, 38.31],
MANİSA: [38.61, 27.43],
MARDİN: [37.31, 40.74],
MERSİN: [36.8, 34.63],
MUĞLA: [37.22, 28.36],
MUŞ: [38.75, 41.5],
NEVŞEHİR: [38.62, 34.71],
NİĞDE: [37.97, 34.68],
ORDU: [40.98, 37.88],
OSMANİYE: [37.07, 36.25],
RİZE: [41.02, 40.52],
SAKARYA: [40.77, 30.4],
SAMSUN: [41.29, 36.33],
SİİRT: [37.93, 41.94],
SİNOP: [42.03, 35.15],
SİVAS: [39.75, 37.02],
ŞANLIURFA: [37.16, 38.79],
ŞIRNAK: [37.52, 42.46],
TEKİRDAĞ: [40.98, 27.51],
TOKAT: [40.31, 36.55],
TRABZON: [41.0, 39.72],
TUNCELİ: [39.11, 39.55],
UŞAK: [38.68, 29.4],
VAN: [38.5, 43.38],
YALOVA: [40.65, 29.27],
YOZGAT: [39.82, 34.81],
ZONGULDAK: [41.45, 31.79],
};