1 2<!DOCTYPE html> 3<html lang="tr"> 4 5<head> 6 <meta charset="UTF-8" /> 7 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 8 <meta name="csrf-token" content="2Cre8kAVjB10nTdr0n7SKNglW0I8Bh6Qlid0XCZp7Ki04H7rPwJDi7PXOBjKRF2C" /> 9 <title>Parsel Sorgula â Ada Parsel Harita Sorgulama | ProParcel</title> 10 <meta name="description" content="Ada ve parsel numarası girerek ücretsiz parsel sorgulama yapın. Uydu haritasında parsel sınırlarını görün, ProSorgu ile detaylı analiz alın."> 11 12<link rel="canonical" href="https://proparcel.com/harita/"> 13<meta property="og:locale" content="tr_TR"> 14<meta property="og:title" content="Parsel Sorgula â Ada Parsel Harita Sorgulama | ProParcel"> 15<meta property="og:description" content="Ada ve parsel numarası girerek ücretsiz parsel sorgulama yapın. Uydu haritasında parsel sınırlarını görün, ProSorgu ile detaylı analiz alın."> 16<meta property="og:url" content="https://proparcel.com/harita/"> 17<meta property="og:site_name" content="ProParcel"> 18<meta property="og:type" content="website"> 19<meta property="og:image" content="https://proparcel.com/static/img/favicon.ico"> 20<meta name="twitter:card" content="summary_large_image"> 21<meta name="twitter:title" content="Parsel Sorgula â Ada Parsel Harita Sorgulama | ProParcel"> 22<meta name="twitter:description" content="Ada ve parsel numarası girerek ücretsiz parsel sorgulama yapın. Uydu haritasında parsel sınırlarını görün, ProSorgu ile detaylı analiz alın."> 23<meta name="twitter:image" content="https://proparcel.com/static/img/favicon.ico"> 24 25
26<script type="application/ld+json">{"@context": "https://schema.org", "@type": "Organization", "name": "ProParcel", "url": "https://proparcel.com", "logo": "https://proparcel.com/static/img/favicon.ico", "email": "[email protected]", "address": {"@type": "PostalAddress", "streetAddress": "Nilüferköy Mahallesi, Nilüfer Cad. No: 98-100/2, Osmangazi / Bursa", "addressCountry": "TR"}}</script>
26 27
28<script type="application/ld+json">{"@context": "https://schema.org", "@type": "WebApplication", "name": "ProParcel Parsel Sorgulama", "url": "https://proparcel.com/harita/", "applicationCategory": "BusinessApplication", "operatingSystem": "Web", "offers": {"@type": "Offer", "price": "0", "priceCurrency": "TRY", "description": "Ãcretsiz ada parsel sorgulama"}}</script>
28 29 30 31 32 33 34 35 36<link rel="icon" type="image/x-icon" href="/static/img/favicon.ico" /> 37 38
38<script> 39 // Loader Three.js sayfa acilisinda degil; yalnizca Pro Sorgu show() sirasinda 40 // lazy init + hide()'da dispose (Mapbox context ile surekli carpismasin). 41 window.__ppLoaderAutoShow = false; 42 window.__PP_DISABLE_LOADER_WEBGL = false; 43 window.__PP_FORCE_DISABLE_LOADER_WEBGL = false; 44 window.__ppUseAnimatedLoader = false; 45 </script>
45 46 47 <!-- DNS Preconnect - DıŠkaynaklar için erken baÄlantı --> 48 <link rel="preconnect" href="https://api.mapbox.com" crossorigin> 49 <link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin> 50 <link rel="preconnect" href="https://fonts.googleapis.com" crossorigin> 51 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 52 <link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin> 53 <link rel="preconnect" href="https://code.jquery.com" crossorigin> 54 55 <!-- Static URL Configuration - Proje taÅındıÄında dinamik çalıÅması için --> 56
56<script> 57 // Django static URL'ini global olarak tanımla 58 // /static/models/house/ kullanarak base URL'i al, sonra 'models/house/' kısmını çıkar 59 (function() { 60 try { 61 var testUrl = '/static/models/house/'; 62 // EÄer testUrl '/static/models/house/' formatındaysa, '/static' kısmını al 63 var match = testUrl.match(/^(.+?)\/models\/house\/$/); 64 if (match && match[1]) { 65 window.STATIC_URL = match[1]; 66 } else { 67 // Fallback: window.location'dan türet 68 var base = window.location.origin; 69 var pathMatch = window.location.pathname.match(/^(.+?)\/static\//); 70 if (pathMatch && pathMatch[1]) { 71 window.STATIC_URL = pathMatch[1] + '/static'; 72 } else { 73 window.STATIC_URL = '/static'; 74 } 75 } 76 // Sonunda '/' olmamalı 77 window.STATIC_URL = window.STATIC_URL.replace(/\/$/, ''); 78 } catch (e) { 79 // Hata durumunda varsayılan deÄer 80 window.STATIC_URL = '/static'; 81 } 82 })(); 83 </script>
83 84 85 <!-- API keys are injected from settings/env. --> 86
86<script> 87 window.CESIUM_ION_TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIyOWUwODRjNy0yNjQ2LTQyMmItYWM1Yy00MzJkZTkyMmU4YmUiLCJpZCI6MzI5NDE5LCJpYXQiOjE3NTQ0OTM1OTB9.p5JsFAeQ9eP7MZD3EPqXAmmuudDMPRVGLyW7tAMCjQE'; 88 window.GOOGLE_MAPS_API_KEY = 'AIzaSyBjVhbRZSqby77ou2yDpJn\u002DPFNFbLFfNHU'; 89 </script>
89 90 <!-- PP_OPEN_REPORT_V2 mesajı app.js içindeki listener tarafından iÅleniyor (çift listener sorunu giderildi) --> 91 92 <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" /> 93 94<link rel="icon" type="image/x-icon" href="/static/img/favicon.ico" /> 95 96 97 <!-- Modern Layout System (YENİ - EN ÃNCE YÃKLENMELİ) --> 98 <link rel="stylesheet" href="/static/css/layout.css?v=20260704-tile-proxy-cursor"> 99 100 <!-- Existing Styles --> 101 <link rel="stylesheet" href="/static/css/style.css?v=20260810-mode-overlay"> 102 <link rel="stylesheet" href="/static/css/report_background.css"> 103 <link rel="stylesheet" href="/static/css/layer_style.css"> 104 <link rel="stylesheet" href="/static/css/graphics_side_bar.css"> 105 <link rel="stylesheet" href="/static/css/parameters_buttons.css"> 106 <link rel="stylesheet" href="/static/css/sidebar.css?v=20260711-daire-btn-style"> 107 <style id="pp-sidebar-tab-dropdown-critical"> 108 /* Sidebar sekme dropdown â template içi; eski cache CSS çakıÅmasını kırar */ 109 #pp-sidebar-tab-dropdown { position: relative; margin: 22px 12px 10px; flex-shrink: 0; z-index: 8; } 110 #pp-sidebar-tab-trigger { 111 display: flex !important; align-items: center; gap: 8px; width: 100%; box-sizing: border-box; 112 height: 42px; min-height: 42px; padding: 0 12px; margin: 0; 113 border: 1px solid #e5e7eb; border-radius: 8px; background: #fff; color: #111827; 114 font-weight: 600; font-size: 14px; cursor: pointer; 115 } 116 #pp-sidebar-tab-trigger .pp-sidebar-tab-trigger__text { flex: 1; text-align: left; } 117 #pp-sidebar-tab-trigger .pp-sidebar-tab-trigger__chevron { margin-left: auto; font-size: 11px; color: #64748b; } 118 #pp-sidebar-tab-menu, 119 #pp-sidebar-tab-menu[hidden] { 120 display: none !important; visibility: hidden !important; pointer-events: none !important; 121 list-style: none; margin: 0; padding: 6px; position: absolute; top: calc(100% + 6px); left: 0; right: 0; 122 background: #fff; border: 1px solid #e5e7eb; border-radius: 8px; 123 box-shadow: 0 12px 28px rgba(15, 23, 42, 0.14); flex-direction: column; gap: 4px; z-index: 30; 124 } 125 #pp-sidebar-tab-dropdown.is-open #pp-sidebar-tab-menu:not([hidden]) { 126 display: flex !important; visibility: visible !important; pointer-events: auto !important; 127 } 128 /* Eski yatay sekme Åeridi â dropdown varken asla gösterme */ 129 #sidebar > ul.sidebar-tabs { display: none !important; } 130 </style> 131 <link rel="stylesheet" href="/static/css/components/_collapsible.css"> 132 <link rel="stylesheet" href="/static/css/components/_capture_overlay.css?v=20260518-capture-menu-fixed"> 133 <link rel="stylesheet" href="/static/css/toggle_button.css?v=20260815-kentsel"> 134 <link rel="stylesheet" href="/static/css/user_adding.css"> 135 <link rel="stylesheet" href="/static/css/toggle_button_drawing.css"> 136 <link rel="stylesheet" href="/static/css/camera_control.css"> 137 <!-- 3D Model Editörü CSS'leri /3d-editor/ sayfasına taÅındı --> 138 <!-- Mapbox GL JS only (2D and 3D maps) --> 139 <!-- Font Awesome yüklü deÄilse Åunu ekle --> 140 141 142 <!-- GPU capability: yalnızca WebGL yoksa Mapbox atlanır; software/eski GPU â minimal_gpu + Mapbox --> 143
143<script> 144 (function () { 145 var FULL = 'full_gpu'; 146 var MINIMAL = 'minimal_gpu'; 147 var NO_GPU = 'no_gpu'; 148 function setMode(mode, reason) { 149 window.__PP_GPU_MODE = mode; 150 window.__PP_GPU_REASON = reason || ''; 151 window.__PP_SKIP_MAPBOX_GL = mode === NO_GPU; 152 window.__PP_EARLY_WEBGL_DISABLED = mode === NO_GPU; 153 window.__PP_ALLOW_MAPBOX_GL = mode !== NO_GPU; 154 try { 155 if (window.sessionStorage) { 156 window.sessionStorage.setItem('pp_gpu_mode', mode); 157 window.sessionStorage.setItem('pp_gpu_reason', reason || ''); 158 } 159 if (window.localStorage) { 160 window.localStorage.setItem('pp_gpu_mode', mode); 161 window.localStorage.setItem('pp_gpu_reason', reason || ''); 162 } 163 } catch (e) {} 164 } 165 function tryCtx(canvas, name, strictCaveat) { 166 try { 167 return canvas.getContext(name, { 168 alpha: false, antialias: false, depth: true, 169 failIfMajorPerformanceCaveat: !!strictCaveat, 170 preserveDrawingBuffer: false, stencil: false 171 }); 172 } catch (e) { return null; } 173 } 174 try { 175 var q = window.location.search || ''; 176 if (/(?:\?|&)(pp_force_legacy_map|pp_leaflet_only|pp_skip_mapbox)=1(?:&|$)/.test(q)) { 177 setMode(NO_GPU, 'forced_query'); 178 return; 179 } 180 if (/(?:\?|&)pp_force_full_gpu=1(?:&|$)/.test(q)) { 181 setMode(FULL, 'forced_full_gpu'); 182 return; 183 } 184 if (/(?:\?|&)pp_force_minimal_gpu=1(?:&|$)/.test(q)) { 185 setMode(MINIMAL, 'forced_minimal_gpu'); 186 return; 187 } 188 } catch (e) {} 189 try { 190 var canvasGl1 = document.createElement('canvas'); 191 var canvasGl2 = document.createElement('canvas'); 192 var canvasGl2Strict = document.createElement('canvas'); 193 var gl = null; 194 var gl2 = null; 195 try { gl = tryCtx(canvasGl1, 'webgl') || tryCtx(canvasGl1, 'experimental-webgl'); } catch (e) {} 196 try { gl2 = tryCtx(canvasGl2, 'webgl2'); } catch (e) {} 197 var safeGl2 = null; 198 try { safeGl2 = tryCtx(canvasGl2Strict, 'webgl2', true); } catch (e) {} 199 window.__PP_MAJOR_PERFORMANCE_CAVEAT = !!gl2 && !safeGl2; 200 window.__PP_EARLY_WEBGL_AVAILABLE = !!(gl || gl2); 201 if (gl || gl2) { 202 setMode(MINIMAL, 'early_webgl_ok'); 203 try { 204 var lose = (gl2 || gl).getExtension('WEBGL_lose_context'); 205 if (lose && typeof lose.loseContext === 'function') lose.loseContext(); 206 } catch (e) {} 207 } else { 208 window.__PP_EARLY_WEBGL_AVAILABLE = false; 209 setMode(NO_GPU, 'webgl_unavailable'); 210 } 211 } catch (e) { 212 window.__PP_EARLY_WEBGL_AVAILABLE = false; 213 setMode(NO_GPU, 'early_probe_exception'); 214 } 215 })(); 216 </script>
216 217 <style> 218 .pp-mapbox-capable #pp-static-map-backdrop, 219 .pp-mapbox-capable #pp-static-leaflet-fallback, 220 .pp-mapbox-capable #pp-static-satellite-tiles { 221 display: none !important; 222 } 223 </style> 224
224<script> 225 (function () { 226 try { 227 if (window.__PP_ALLOW_MAPBOX_GL !== false && !window.__PP_SKIP_MAPBOX_GL && !window.__PP_EARLY_WEBGL_DISABLED) { 228 document.documentElement.className += ' pp-mapbox-capable'; 229 window.__PP_HIDE_STATIC_MAP_FALLBACK = true; 230 } 231 } catch (e) {} 232 })(); 233 </script>
233 234 <link href="https://api.mapbox.com/mapbox-gl-js/v3.2.0/mapbox-gl.css" rel="stylesheet" /> 235
235<script> 236 (function () { 237 if (!window.__PP_SKIP_MAPBOX_GL && !window.__PP_EARLY_WEBGL_DISABLED && window.__PP_ALLOW_MAPBOX_GL !== false) return; 238 document.write('<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css">'); 239 })(); 240 </script>
240 241
241<script src="/static/js/core/map/index_legacy_bootstrap.js?v=20260520-no-stale-storage"></script>
241 242 <!-- Google Maps CORS + EventTarget passive patch (tek override) --> 243
243<script> 244 (function() { 245 // Google Maps tile CORS uyarılarını filtrele 246 var _origError = console.error; 247 console.error = function() { 248 var msg = Array.prototype.join.call(arguments, ' '); 249 if (msg.indexOf('mt1.google.com') !== -1 || msg.indexOf('mt0.google.com') !== -1 || 250 (msg.indexOf('google.com/vt') !== -1 && msg.indexOf('CORS') !== -1)) return; 251 _origError.apply(console, arguments); 252 }; 253 254 // Unhandled fetch rejection filtresi (Google Maps tile CORS) 255 window.addEventListener('unhandledrejection', function(event) { 256 var err = event.reason; 257 var errMsg = err && (err.message || String(err)); 258 if (errMsg && (errMsg.indexOf('mt1.google.com') !== -1 || errMsg.indexOf('mt0.google.com') !== -1 || errMsg.indexOf('google.com/vt') !== -1)) { 259 event.preventDefault(); 260 return; 261 } 262 }); 263 264 // EventTarget.prototype.addEventListener tek seferlik override 265 var _origAEL = EventTarget.prototype.addEventListener; 266 var touchmovePatchCount = 0; 267 var MAX_TOUCHMOVE_PATCHES = 5; 268 269 EventTarget.prototype.addEventListener = function(type, listener, options) { 270 if (type === 'touchmove' && touchmovePatchCount < MAX_TOUCHMOVE_PATCHES) { 271 if (typeof options === 'object' && options !== null) { 272 if (!options.passive && !options.capture) { options.passive = true; touchmovePatchCount++; } 273 } else if (options == null) { options = { passive: true }; touchmovePatchCount++; } 274 } 275 if (type === 'wheel' && this.classList) { 276 var isSel2 = this.classList.contains('select2-container') || 277 this.classList.contains('select2-results__options') || 278 (this.closest && this.closest('.select2-container')); 279 if (isSel2) { 280 if (typeof options === 'object' && options !== null) { options.passive = true; } 281 else if (typeof options === 'boolean') { options = { capture: options, passive: true }; } 282 else { options = { passive: true }; } 283 } 284 } 285 return _origAEL.call(this, type, listener, options); 286 }; 287 })(); 288 </script>
288 289 290 <!-- DiÄer ihtiyacın olanlar --> 291
291<script src="https://cdn.jsdelivr.net/npm/@turf/[email protected]/turf.min.js"></script>
291 292 <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&family=Inter:wght@500;600;700&display=swap" rel="stylesheet"> 293 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> 294 295 <!-- jQuery + Select2 (Mahalle select için geliÅmiÅ arama) --> 296
296<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
296 297 <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" /> 298
298<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.full.min.js"></script>
298 299 300 301 302 303 304 <!-- Hata yakalama ve görsel bildirim --> 305
305<script src="/static/js/initialization/error_overlay.js"></script>
305 306 307 <!-- Google Fonts zaten head'de yüklü --> 308 <style> 309 @keyframes spin { 310 0% { transform: rotate(0deg); } 311 100% { transform: rotate(360deg); } 312 } 313 .pp-seo-page-title { 314 position: absolute; 315 width: 1px; 316 height: 1px; 317 padding: 0; 318 margin: -1px; 319 overflow: hidden; 320 clip: rect(0, 0, 0, 0); 321 white-space: nowrap; 322 border: 0; 323 } 324 </style> 325 326 <style> 327 /* Select2 için güvenli geniÅlik ve üstte görünme düzeltmesi */ 328 .sidebar .select2-container { 329 width: 100% !important; 330 } 331 332 .pp-sidebar-saved-queries { 333 display: flex; 334 flex-direction: column; 335 gap: 10px; 336 width: 100%; 337 } 338 339 .pp-sidebar-saved-queries__header { 340 display: flex; 341 flex-direction: column; 342 gap: 2px; 343 padding: 2px 0 6px; 344 color: #0f172a; 345 font-family: 'Inter', Arial, sans-serif; 346 } 347 348 .pp-sidebar-saved-queries__header span { 349 color: #64748b; 350 font-size: 12px; 351 } 352 353 .pp-sidebar-saved-query-list { 354 display: flex; 355 flex-direction: column; 356 gap: 8px; 357 max-height: calc(100vh - 230px); 358 overflow-y: auto; 359 padding-right: 2px; 360 } 361 362 .pp-sidebar-saved-query-item { 363 align-items: center; 364 display: flex; 365 gap: 8px; 366 width: 100%; 367 border: 1px solid #dbeaf7; 368 border-radius: 10px; 369 background: #ffffff; 370 box-shadow: 0 1px 6px rgba(37, 99, 235, 0.08); 371 color: #0f172a; 372 padding: 10px 12px; 373 text-align: left; 374 transition: border-color 0.18s, box-shadow 0.18s, transform 0.18s; 375 } 376 377 .pp-sidebar-saved-query-item:hover { 378 border-color: #93c5fd; 379 box-shadow: 0 4px 14px rgba(37, 99, 235, 0.12); 380 transform: translateY(-1px); 381 } 382 383 .pp-sidebar-saved-query-main { 384 background: transparent; 385 border: 0; 386 color: inherit; 387 cursor: pointer; 388 flex: 1; 389 min-width: 0; 390 padding: 0; 391 text-align: left; 392 } 393 394 .pp-sidebar-saved-query-check { 395 accent-color: #2563eb; 396 flex: 0 0 auto; 397 height: 16px; 398 width: 16px; 399 } 400 401 .pp-sidebar-saved-query-delete { 402 align-items: center; 403 background: #fef2f2; 404 border: 1px solid #fecaca; 405 border-radius: 9px; 406 color: #dc2626; 407 cursor: pointer; 408 display: inline-flex; 409 flex: 0 0 auto; 410 height: 32px; 411 justify-content: center; 412 width: 32px; 413 } 414 415 .pp-sidebar-saved-query-delete:hover { 416 background: #fee2e2; 417 } 418 419 .pp-sidebar-saved-query-title { 420 display: flex; 421 align-items: center; 422 justify-content: space-between; 423 gap: 8px; 424 font-size: 14px; 425 font-weight: 700; 426 margin-bottom: 4px; 427 } 428 429 .pp-sidebar-saved-query-meta, 430 .pp-sidebar-saved-query-sub { 431 color: #64748b; 432 display: block; 433 font-size: 12px; 434 line-height: 1.35; 435 } 436 437 .pp-sidebar-saved-query-mode { 438 border-radius: 999px; 439 background: #eff6ff; 440 color: #2563eb; 441 flex: 0 0 auto; 442 font-size: 10px; 443 font-weight: 700; 444 padding: 2px 7px; 445 text-transform: uppercase; 446 } 447 448 .pp-sidebar-saved-query-empty { 449 border: 1px dashed #cbd5e1; 450 border-radius: 10px; 451 color: #64748b; 452 font-size: 13px; 453 padding: 14px 12px; 454 text-align: center; 455 } 456 457 .pp-sidebar-saved-query-actions { 458 align-items: center; 459 display: flex; 460 gap: 8px; 461 justify-content: space-between; 462 margin-bottom: 8px; 463 } 464 465 .pp-sidebar-saved-query-action { 466 border: 1px solid #dbeaf7; 467 border-radius: 9px; 468 background: #fff; 469 color: #334155; 470 cursor: pointer; 471 font-size: 12px; 472 font-weight: 700; 473 padding: 7px 9px; 474 } 475 476 .pp-sidebar-saved-query-action.danger { 477 border-color: #fecaca; 478 color: #dc2626; 479 } 480 481 .pp-sidebar-saved-query-action:disabled { 482 cursor: not-allowed; 483 opacity: .55; 484 } 485 486 /* Clear (x) ikonunu gizle */ 487 .select2-selection__clear { 488 display: none !important; 489 } 490 491 /* Sidebar Select2 Modern Stil */ 492 .sidebar .select2-container--default .select2-selection--single { 493 height: 42px; 494 border: 1.5px solid #dbeaf7; 495 border-radius: 8px; 496 background-color: #fff; 497 display: flex; 498 align-items: center; 499 box-shadow: 0 1px 6px rgba(37, 99, 235, 0.08); 500 transition: border 0.2s, box-shadow 0.2s; 501 } 502 503 .sidebar .select2-container--default .select2-selection--single .select2-selection__rendered { 504 padding-left: 12px; 505 padding-right: 32px; 506 line-height: 40px; 507 color: #222; 508 font-size: 15px; 509 font-family: 'Inter', Arial, sans-serif; 510 } 511 512 .sidebar .select2-container--default .select2-selection--single .select2-selection__placeholder { 513 color: #9ca3af; 514 } 515 516 .sidebar .select2-container--default .select2-selection--single .select2-selection__arrow { 517 height: 40px; 518 right: 10px; 519 } 520 521 .sidebar .select2-container--default .select2-selection--single .select2-selection__arrow b { 522 border-color: #6b7280 transparent transparent transparent; 523 } 524 525 /* Dropdown stili - dropdown body'ye ekleniyor, sidebar dıÅında */ 526 .select2-dropdown { 527 z-index: 2147483000 !important; 528 border: 1.5px solid #dbeaf7; 529 border-radius: 8px; 530 box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12); 531 background: #fff; 532 } 533 534 .select2-results__option { 535 padding: 10px 14px; 536 font-size: 14px; 537 color: #222; 538 transition: background 0.15s; 539 } 540 541 .select2-container--default .select2-results__option--highlighted.select2-results__option--selectable { 542 background: #2563eb; 543 color: #fff; 544 } 545 546 .select2-container--default .select2-results__option--selected { 547 background: #f3f4f6; 548 color: #222; 549 } 550 551 /* Select2 arama kutusu stili */ 552 .select2-search--dropdown .select2-search__field { 553 padding: 10px 12px; 554 border: 1.5px solid #dbeaf7; 555 border-radius: 6px; 556 font-size: 14px; 557 font-family: 'Inter', Arial, sans-serif; 558 transition: border 0.2s, box-shadow 0.2s; 559 } 560 561 .select2-search--dropdown .select2-search__field:focus { 562 border-color: #2563eb; 563 outline: 0; 564 box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2); 565 } 566 567 /* Select2 hover ve focus efekti */ 568 .sidebar .select2-container--default .select2-selection--single:hover { 569 border-color: #2563eb; 570 } 571 572 .sidebar .select2-container--default.select2-container--focus .select2-selection--single, 573 .sidebar .select2-container--default.select2-container--open .select2-selection--single { 574 border-color: #2563eb; 575 box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2); 576 } 577 578 .sidebar .select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b { 579 border-color: transparent transparent #2563eb transparent; 580 } 581 </style> 582 583 <style> 584 body.pp-app #modeSwitchBtn::before { 585 border-radius: 0 !important; 586 } 587 </style> 588 <link rel="stylesheet" href="/static/css/components/_annotation_tools.css"> 589 <link rel="stylesheet" href="/static/css/inline_styles.css"> 590
590<script src="/static/js/core/layer/layer_style.js"></script>
590 591 592 593</head> 594 595<body class="pp-app"> 596 597 <h1 class="pp-seo-page-title">Parsel Sorgula</h1> 598 599 600<style> 601 /* === LOADING OVERLAY (loadingScreen.html'den) === */ 602 #pp-loader-bg3d { 603 position: fixed; 604 inset: 0; 605 z-index: 9998; 606 overflow: hidden; 607 display: none; /* show() açar; varsayılan kapalı â aksi halde z-index haritayı örter */ 608 } 609 610 .pp-loader-overlay { 611 position: fixed; 612 inset: 0; 613 z-index: 9999; 614 display: flex; 615 align-items: center; 616 justify-content: center; 617 background: transparent; 618 backdrop-filter: none; 619 color: #e5e7eb; 620 font-family: 'IBM Plex Sans', sans-serif; 621 transition: opacity 0.5s ease; 622 } 623 .pp-loader-overlay.pp-loader-hidden { 624 opacity: 0; 625 pointer-events: none; 626 } 627 628 .pp-loader-panel { 629 width: min(900px, 92vw); 630 max-height: 90vh; 631 background: rgba(15, 23, 42, 0.96); 632 border-radius: 14px; 633 box-shadow: 0 28px 80px rgba(0, 0, 0, 0.65); 634 padding: 20px 24px 18px; 635 border: 1px solid rgba(148, 163, 184, 0.35); 636 display: flex; 637 flex-direction: column; 638 gap: 14px; 639 } 640 641 .pp-loader-header { 642 display: flex; 643 flex-direction: column; 644 gap: 6px; 645 } 646 .pp-loader-logo { 647 display: inline-flex; 648 align-items: center; 649 justify-content: center; 650 align-self: flex-start; 651 padding: 3px 10px; 652 border-radius: 999px; 653 font-size: 11px; 654 letter-spacing: 0.08em; 655 text-transform: uppercase; 656 background: rgba(15, 118, 110, 0.15); 657 border: 1px solid rgba(45, 212, 191, 0.7); 658 color: #a5f3fc; 659 } 660 .pp-loader-title { 661 font-size: 17px; 662 font-weight: 600; 663 color: #f9fafb; 664 } 665 .pp-loader-subtitle { 666 font-size: 13px; 667 color: #9ca3af; 668 } 669 .pp-loader-timer { 670 font-size: 11px; 671 color: #6b7280; 672 } 673 674 .pp-loader-body { 675 display: grid; 676 grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.3fr); 677 gap: 16px; 678 } 679 @media (max-width: 768px) { 680 .pp-loader-body { 681 grid-template-columns: minmax(0, 1fr); 682 } 683 } 684 685 .pp-loader-map { 686 position: relative; 687 height: 170px; 688 border-radius: 12px; 689 overflow: hidden; 690 background: radial-gradient(circle at 10% 0, #22c55e 0, transparent 45%), 691 radial-gradient(circle at 90% 100%, #0ea5e9 0, transparent 50%), 692 #020617; 693 border: 1px solid rgba(148, 163, 184, 0.5); 694 } 695 .pp-loader-map-layer { 696 position: absolute; 697 inset: 0; 698 background-image: 699 linear-gradient(90deg, rgba(148,163,184,0.28) 1px, transparent 1px), 700 linear-gradient(180deg, rgba(148,163,184,0.28) 1px, transparent 1px); 701 background-size: 26px 26px; 702 opacity: 0.9; 703 animation: ppGridDrift 14s linear infinite; 704 } 705 .pp-loader-map-pulse { 706 position: absolute; 707 inset: 22% 20%; 708 border-radius: 18px; 709 border: 1px solid rgba(56,189,248,0.8); 710 box-shadow: 0 0 20px rgba(56,189,248,0.4); 711 animation: ppPulse 1.8s ease-in-out infinite; 712 } 713 714 @keyframes ppGridDrift { 715 0% { transform: translate(0, 0) scale(1); } 716 50% { transform: translate(-8px, -6px) scale(1.03); } 717 100% { transform: translate(0, 0) scale(1); } 718 } 719 @keyframes ppPulse { 720 0% { transform: scale(1); opacity: 0.85; } 721 50% { transform: scale(1.05); opacity: 1; } 722 100% { transform: scale(1); opacity: 0.85; } 723 } 724 725 /* Aktif adım kartı */ 726 .pp-loader-active-card { 727 display: flex; 728 align-items: flex-start; 729 gap: 12px; 730 padding: 14px 14px; 731 border-radius: 12px; 732 border: 1px solid rgba(148, 163, 184, 0.35); 733 background: rgba(2, 6, 23, 0.35); 734 min-height: 86px; 735 } 736 .pp-loader-active-icon { 737 width: 34px; 738 height: 34px; 739 border-radius: 999px; 740 display: flex; 741 align-items: center; 742 justify-content: center; 743 font-size: 18px; 744 flex-shrink: 0; 745 background: rgba(15,23,42,0.9); 746 border: 1px solid rgba(148,163,184,0.7); 747 } 748 .pp-loader-active-content { 749 display: flex; 750 flex-direction: column; 751 gap: 4px; 752 text-align: left; 753 } 754 .pp-loader-active-title { 755 font-size: 14px; 756 color: #f9fafb; 757 font-weight: 650; 758 line-height: 1.25; 759 transition: opacity 220ms ease, transform 220ms ease; 760 } 761 .pp-loader-active-title.fadeOut { 762 opacity: 0; 763 transform: translateY(4px); 764 } 765 .pp-loader-active-desc { 766 font-size: 12px; 767 color: #cbd5e1; 768 line-height: 1.35; 769 min-height: 18px; 770 } 771 772 .pp-loader-progress { 773 margin-top: 4px; 774 display: flex; 775 flex-direction: column; 776 gap: 4px; 777 } 778 .pp-loader-progress-bar { 779 position: relative; 780 width: 100%; 781 height: 5px; 782 border-radius: 999px; 783 background: rgba(30,41,59,1); 784 overflow: hidden; 785 } 786 .pp-loader-progress-fill { 787 position: absolute; 788 inset: 0; 789 width: 100%; 790 border-radius: inherit; 791 background: linear-gradient(90deg, #22c55e, #22d3ee, #38bdf8); 792 background-size: 200% 100%; 793 animation: ppShimmer 2.2s linear infinite; 794 } 795 @keyframes ppShimmer { 796 0% { background-position: 0% 50%; } 797 100% { background-position: -200% 50%; } 798 } 799 .pp-loader-progress-text { 800 font-size: 11px; 801 color: #9ca3af; 802 text-align: right; 803 } 804 805 /* WebGL yok / baÄlam limiti: Three sahnesi yerine statik arka plan */ 806 .pp-bg3d--fallback { 807 background: radial-gradient(ellipse 120% 80% at 50% 100%, #0c1929 0%, #041026 45%, #020617 100%); 808 } 809</style> 810 811<!-- 3D terrain arka plan; WebGL modülleri kapalıysa CSS gradient fallback --> 812<div id="pp-loader-bg3d"></div> 813 814<!-- ProParcel Loader Overlay --> 815<div id="pp-loader-overlay" class="pp-loader-overlay"> 816 <div class="pp-loader-panel"> 817 <div class="pp-loader-header"> 818 <div class="pp-loader-logo">ProParcel</div> 819 <div class="pp-loader-title">Arazi deÄerleme analizi hazırlanıyorâ¦</div> 820 <div class="pp-loader-subtitle" id="pp-loader-subtitle"> 821 Arazi deÄerleme analizi hazırlanıyor⦠822 </div> 823 <div class="pp-loader-timer" id="pp-loader-timer"> 824 Süre: 0 sn 825 </div> 826 </div> 827 828 <div class="pp-loader-body"> 829 <div class="pp-loader-map"> 830 <div class="pp-loader-map-layer"></div> 831 <div class="pp-loader-map-pulse">
832 <canvas id="pp-inner-canvas" data-engine="three.js r181" width="1545" height="868" style="display: block; width: 100%; height: 100%; touch-action: none;"></canvas> 833 </div> 834 </div> 835 836 <div class="pp-loader-active-card" id="pp-loader-active-card" aria-live="polite" aria-atomic="true"> 837 <div class="pp-loader-active-icon" id="pp-loader-active-icon">âï¸</div> 838 <div class="pp-loader-active-content"> 839 <div class="pp-loader-active-title" id="pp-loader-active-title">Arazi deÄerleme analizi hazırlanıyorâ¦</div> 840 <div class="pp-loader-active-desc" id="pp-loader-active-desc">Lütfen bekleyin.</div> 841 </div> 842 </div> 843 </div> 844 845 <div class="pp-loader-progress"> 846 <div class="pp-loader-progress-bar"> 847 <div class="pp-loader-progress-fill" id="pp-loader-progress-fill"></div> 848 </div> 849 <div class="pp-loader-progress-text" id="pp-loader-progress-text"> 850 İÅleniyor⦠851 </div> 852 </div> 853 </div> 854</div> 855 856<!-- Loading Overlay JS: Statik mesaj + backend progress, indeterminate bar, zamanlayıcı -->
857<script> 858(function() { 859 'use strict'; 860 861 var __ppTimerStart = null; 862 var __ppTimerInterval = null; 863 var __ppHideTimeout = null; 864 var STATIC_MSG = 'Arazi deÄerleme analizi hazırlanıyorâ¦'; 865 866 function initStaticMessage() { 867 var titleEl = document.getElementById('pp-loader-active-title'); 868 var subtitleEl = document.getElementById('pp-loader-subtitle'); 869 var descEl = document.getElementById('pp-loader-active-desc'); 870 if (titleEl) titleEl.textContent = STATIC_MSG; 871 if (subtitleEl) subtitleEl.textContent = STATIC_MSG; 872 if (descEl) descEl.textContent = 'Lütfen bekleyin.'; 873 } 874 875 function startTimer() { 876 __ppTimerStart = Date.now(); 877 var el = document.getElementById('pp-loader-timer'); 878 if (el) el.textContent = 'Süre: 0 sn'; 879 __ppTimerInterval = window.setInterval(function() { 880 if (!__ppTimerStart) return; 881 var diffMs = Date.now() - __ppTimerStart; 882 var sec = Math.floor(diffMs / 1000); 883 if (el) el.textContent = 'Süre: ' + sec + ' sn'; 884 }, 1000); 885 } 886 887 function ensureBg3dFallback(bg) { 888 if (!bg) return; 889 var webglDisabled = false; 890 try { 891 webglDisabled = window.__PP_FORCE_DISABLE_LOADER_WEBGL === true 892 || window.__PP_DISABLE_LOADER_WEBGL === true; 893 } catch (_) {} 894 if (webglDisabled) { 895 bg.classList.add('pp-bg3d--fallback'); 896 return; 897 } 898 // WebGL yolu açık: canvas yoksa (init henüz yok / baÅarısız) CSS gradient yedek 899 var hasCanvas = false; 900 try { hasCanvas = !!(bg.querySelector && bg.querySelector('canvas')); } catch (_) {} 901 if (!hasCanvas) { 902 bg.classList.add('pp-bg3d--fallback'); 903 } 904 } 905 906 function softRecoverIndexMap() { 907 try { 908 var m = window.mapManager && window.mapManager.maps && window.mapManager.maps['3d']; 909 if (!m) return; 910 if (typeof m.resize === 'function') m.resize(); 911 if (typeof m.triggerRepaint === 'function') m.triggerRepaint(); 912 } catch (_) {} 913 } 914 915 function disposeLoaderWebGLScenes() { 916 try { 917 if (typeof window.disposeLoaderTerrainBg === 'function') window.disposeLoaderTerrainBg(); 918 } catch (_) {} 919 try { 920 if (typeof window.disposeForestHouse === 'function') window.disposeForestHouse(); 921 } catch (_) {} 922 } 923 924 window.ProParcelLoader = { 925 show: function() { 926 if (__ppHideTimeout) { clearTimeout(__ppHideTimeout); __ppHideTimeout = null; } 927 var overlay = document.getElementById('pp-loader-overlay'); 928 var bg = document.getElementById('pp-loader-bg3d'); 929 if (overlay) { 930 overlay.classList.remove('pp-loader-hidden'); 931 overlay.style.display = 'flex'; 932 } 933 if (bg) { 934 bg.style.display = 'block'; 935 ensureBg3dFallback(bg); 936 } 937 initStaticMessage(); 938 startTimer(); 939 try { 940 if (window.__PP_FORCE_DISABLE_LOADER_WEBGL === true) return; 941 if (window.__PP_DISABLE_LOADER_WEBGL === true) return; 942 } catch (_) {} 943 // Lazy Three.js: yalnızca loader görünürken context aç 944 if (typeof window.ensureLoaderTerrainBg === 'function') { 945 try { window.ensureLoaderTerrainBg(); } catch (_) {} 946 } 947 if (typeof window.ensureForestHouse === 'function') { 948 try { window.ensureForestHouse(); } catch(_) {} 949 } 950 if (bg) { 951 try { 952 if (bg.querySelector && bg.querySelector('canvas')) { 953 bg.classList.remove('pp-bg3d--fallback'); 954 } 955 } catch (_) {} 956 } 957 }, 958 hide: function() { 959 var overlay = document.getElementById('pp-loader-overlay'); 960 var bg = document.getElementById('pp-loader-bg3d'); 961 if (__ppTimerInterval) { clearInterval(__ppTimerInterval); __ppTimerInterval = null; } 962 if (__ppHideTimeout) { clearTimeout(__ppHideTimeout); __ppHideTimeout = null; } 963 // Mapbox ile carpismayi bitir: fade sirasinda WebGL context'leri serbest birak 964 disposeLoaderWebGLScenes(); 965 if (overlay) { 966 overlay.classList.add('pp-loader-hidden'); 967 __ppHideTimeout = setTimeout(function() { 968 __ppHideTimeout = null; 969 if (overlay && overlay.classList.contains('pp-loader-hidden')) { 970 overlay.style.display = 'none'; 971 } 972 if (bg && !window.ProParcelLoader.isVisible()) bg.style.display = 'none'; 973 softRecoverIndexMap(); 974 }, 600); 975 } else { 976 if (bg) bg.style.display = 'none'; 977 softRecoverIndexMap(); 978 } 979 }, 980 isVisible: function() {
981 var overlay = document.getElementById('pp-loader-overlay'); 982 return overlay && overlay.style.display !== 'none' && !overlay.classList.contains('pp-loader-hidden'); 983 } 984 }; 985 986 var shouldAutoShow = true; 987 try { 988 shouldAutoShow = window.__ppLoaderAutoShow !== false; 989 } catch (_) {} 990 if (shouldAutoShow) { 991 if (document.readyState === 'loading') { 992 document.addEventListener('DOMContentLoaded', function() { 993 window.ProParcelLoader.show(); 994 }); 995 } else { 996 window.ProParcelLoader.show(); 997 } 998 } else { 999 var _ov = document.getElementById('pp-loader-overlay'); 1000 var _bg = document.getElementById('pp-loader-bg3d'); 1001 if (_ov) { _ov.classList.add('pp-loader-hidden'); _ov.style.display = 'none'; } 1002 if (_bg) _bg.style.display = 'none'; 1003 } 1004 1005 window.addEventListener('message', function(ev) { 1006 try { 1007 var data = ev.data || {}; 1008 if (data.type === 'PP_REPORT_V3_PROGRESS') { 1009 var logs = Array.isArray(data.valuationProgress) ? data.valuationProgress : []; 1010 if (logs.length > 0) { 1011 var lastLog = logs[logs.length - 1]; 1012 var msg = lastLog.message || lastLog.step || ''; 1013 if (msg) { 1014 var titleEl = document.getElementById('pp-loader-active-title'); 1015 var subtitleEl = document.getElementById('pp-loader-subtitle'); 1016 if (titleEl) { 1017 titleEl.classList.add('fadeOut'); 1018 setTimeout(function() { 1019 titleEl.textContent = msg; 1020 titleEl.classList.remove('fadeOut'); 1021 }, 220); 1022 } 1023 if (subtitleEl) subtitleEl.textContent = msg; 1024 } 1025 } 1026 } 1027 } catch(_) {} 1028 }); 1029})(); 1030</script>
1030 1031 1032 1033<!-- Three.js 3D terrain arka plan -->
1034<script type="module"> 1035 import * as THREE from 'https://esm.sh/[email protected]'; 1036 import { ImprovedNoise } from 'https://esm.sh/[email protected]/examples/jsm/math/ImprovedNoise.js'; 1037 1038 let camera, scene, renderer, mesh; 1039 const worldWidth = 256, worldDepth = 256; 1040 const clock = new THREE.Clock(); 1041 1042 const _terrainGlOpts = { failIfMajorPerformanceCaveat: false }; 1043 1044 function shouldSkipLoaderWebGL() { 1045 try { 1046 if (window.__PP_FORCE_DISABLE_LOADER_WEBGL === true) return true; 1047 if (window.__PP_DISABLE_LOADER_WEBGL === true) return true; 1048 } catch (_) {} 1049 try { 1050 if (window.PPWebGLCompat && typeof window.PPWebGLCompat.supports === 'function' && !window.PPWebGLCompat.supports('heavy_animation')) { 1051 return true; 1052 } 1053 } catch (_) {} 1054 try { 1055 if (window.__PP_GPU_MODE === 'no_gpu') return true; 1056 } catch (_) {} 1057 try { 1058 const canvas = document.createElement('canvas'); 1059 const gl = canvas.getContext('webgl', _terrainGlOpts) || canvas.getContext('experimental-webgl', _terrainGlOpts); 1060 if (!gl) return true; 1061 try { gl.getExtension('WEBGL_lose_context')?.loseContext?.(); } catch (_) {} 1062 return false; 1063 } catch (_) { 1064 return true; 1065 } 1066 } 1067 1068 function disposeTerrainBg3D() { 1069 window.removeEventListener('resize', onWindowResize3D); 1070 if (renderer) { 1071 try { renderer.setAnimationLoop(null); } catch (_) {} 1072 try { 1073 var el = renderer.domElement; 1074 if (el && el.parentNode) el.parentNode.removeChild(el); 1075 } catch (_) {} 1076 try { renderer.dispose(); } catch (_) {} 1077 try { renderer.forceContextLoss(); } catch (_) {} 1078 } 1079 renderer = null; 1080 if (mesh) { 1081 try { 1082 if (mesh.geometry) mesh.geometry.dispose(); 1083 if (mesh.material) { 1084 if (mesh.material.map) mesh.material.map.dispose(); 1085 mesh.material.dispose(); 1086 } 1087 } catch (_) {} 1088 mesh = null; 1089 } 1090 scene = null; 1091 camera = null; 1092 } 1093 1094 function createTerrainWebGLRenderer() { 1095 if (shouldSkipLoaderWebGL()) return null; 1096 try { 1097 return new THREE.WebGLRenderer({ antialias: true, ..._terrainGlOpts }); 1098 } catch (_) { 1099 try { 1100 return new THREE.WebGLRenderer({ antialias: false, ..._terrainGlOpts }); 1101 } catch (_) { 1102 return null; 1103 } 1104 } 1105 } 1106 1107 // Sayfa acilisinda WebGL acma â Mapbox ile carpismasin. show() â ensureLoaderTerrainBg. 1108 window.ensureLoaderTerrainBg = function ensureLoaderTerrainBg() { 1109 const container = document.getElementById('pp-loader-bg3d'); 1110 if (!container) return; 1111 if (shouldSkipLoaderWebGL()) { 1112 container.classList.add('pp-bg3d--fallback'); 1113 return; 1114 } 1115 if (renderer) return; 1116 init3D(); 1117 }; 1118 1119 window.disposeLoaderTerrainBg = function disposeLoaderTerrainBg() { 1120 disposeTerrainBg3D(); 1121 const container = document.getElementById('pp-loader-bg3d'); 1122 if (container) { 1123 try { 1124 while (container.firstChild) container.removeChild(container.firstChild); 1125 } catch (_) {} 1126 container.classList.add('pp-bg3d--fallback'); 1127 } 1128 }; 1129 1130 function init3D() { 1131 const container = document.getElementById('pp-loader-bg3d'); 1132 if (!container) return; 1133 1134 camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 10000); 1135 1136 scene = new THREE.Scene(); 1137 scene.background = new THREE.Color(0x041026); 1138 scene.fog = new THREE.FogExp2(0x041026, 0.0014); 1139 1140 const data = generateHeight(worldWidth, worldDepth); 1141 1142 const geometry = new THREE.PlaneGeometry(8000, 8000, worldWidth - 1, worldDepth - 1); 1143 geometry.rotateX(-Math.PI / 2); 1144 1145 const vertices = geometry.attributes.position.array; 1146 for (let i = 0, j = 0, l = vertices.length; i < l; i++, j += 3) { 1147 vertices[j + 1] = data[i] * 12; 1148 } 1149 1150 const texture = new THREE.CanvasTexture(generateTexture(data, worldWidth, worldDepth)); 1151 texture.wrapS = THREE.ClampToEdgeWrapping; 1152 texture.wrapT = THREE.ClampToEdgeWrapping; 1153 texture.colorSpace = THREE.SRGBColorSpace; 1154 1155 const material = new THREE.MeshBasicMaterial({ map: texture }); 1156 mesh = new THREE.Mesh(geometry, material); 1157 scene.add(mesh); 1158 1159 camera.position.set(900, 900, 900); 1160 camera.lookAt(0, 0, 0); 1161 1162 renderer = createTerrainWebGLRenderer(); 1163 if (!renderer) { 1164 disposeTerrainBg3D(); 1165 container.classList.add('pp-bg3d--fallback');
1166 try { console.warn('[ProParcelLoader] 3D arka plan WebGL baÅlatılamadı (sabit gradient kullanılıyor).'); } catch (_) {} 1167 return; 1168 } 1169 1170 renderer.setPixelRatio(window.devicePixelRatio); 1171 renderer.setSize(window.innerWidth, window.innerHeight); 1172 renderer.setAnimationLoop(animate3D); 1173 1174 container.appendChild(renderer.domElement); 1175 container.classList.remove('pp-bg3d--fallback'); 1176 1177 window.addEventListener('resize', onWindowResize3D); 1178 } 1179 1180 function onWindowResize3D() { 1181 if (!camera || !renderer) return; 1182 camera.aspect = window.innerWidth / window.innerHeight; 1183 camera.updateProjectionMatrix(); 1184 renderer.setSize(window.innerWidth, window.innerHeight); 1185 } 1186 1187 function generateHeight(width, height) { 1188 let seed = Math.PI / 4; 1189 const rand = () => { 1190 const x = Math.sin(seed++) * 10000; 1191 return x - Math.floor(x); 1192 }; 1193 1194 const size = width * height; 1195 const data = new Uint8Array(size); 1196 const perlin = new ImprovedNoise(); 1197 const z = rand() * 100; 1198 let quality = 1; 1199 1200 for (let j = 0; j < 4; j++) { 1201 for (let i = 0; i < size; i++) { 1202 const x = i % width, y = ~~(i / width); 1203 data[i] += Math.abs(perlin.noise(x / quality, y / quality, z) * quality * 1.75); 1204 } 1205 quality *= 4.5; 1206 } 1207 return data; 1208 } 1209 1210 function generateTexture(data, width, height) { 1211 let context, image, imageData; 1212 1213 const vector3 = new THREE.Vector3(0, 0, 0); 1214 const sun = new THREE.Vector3(1, 1, 1).normalize(); 1215 1216 const canvas = document.createElement('canvas'); 1217 canvas.width = width; 1218 canvas.height = height; 1219 1220 context = canvas.getContext('2d'); 1221 context.fillStyle = '#000'; 1222 context.fillRect(0, 0, width, height); 1223 1224 image = context.getImageData(0, 0, canvas.width, canvas.height); 1225 imageData = image.data; 1226 1227 for (let i = 0, j = 0, l = imageData.length; i < l; i += 4, j++) { 1228 const left = data[j - 1] || data[j]; 1229 const right = data[j + 1] || data[j]; 1230 const down = data[j + width] || data[j]; 1231 const up = data[j - width] || data[j]; 1232 1233 const v3 = vector3; 1234 v3.x = left - right; 1235 v3.y = 16; 1236 v3.z = up - down; 1237 v3.normalize(); 1238 1239 const shade = v3.dot(sun); 1240 const h = data[j]; 1241 1242 const heightFactor = 0.65 + h * 0.006; 1243 1244 let r = (18 + shade * 50) * heightFactor; 1245 let g = (110 + shade * 150) * heightFactor; 1246 let b = (170 + shade * 190) * heightFactor; 1247 1248 r = Math.max(0, Math.min(255, r)); 1249 g = Math.max(0, Math.min(255, g)); 1250 b = Math.max(0, Math.min(255, b)); 1251 1252 imageData[i] = r; 1253 imageData[i + 1] = g; 1254 imageData[i + 2] = b; 1255 } 1256 1257 context.putImageData(image, 0, 0); 1258 1259 const canvasScaled = document.createElement('canvas'); 1260 canvasScaled.width = width * 4; 1261 canvasScaled.height = height * 4; 1262 context = canvasScaled.getContext('2d'); 1263 context.scale(4, 4); 1264 context.drawImage(canvas, 0, 0); 1265 1266 image = context.getImageData(0, 0, canvasScaled.width, canvasScaled.height); 1267 imageData = image.data; 1268 1269 for (let i = 0, l = imageData.length; i < l; i += 4) { 1270 const v = ~~(Math.random() * 6); 1271 imageData[i] += v; 1272 imageData[i + 1] += v; 1273 imageData[i + 2] += v; 1274 } 1275 1276 context.putImageData(image, 0, 0); 1277 return canvasScaled; 1278 } 1279 1280 function animate3D() { 1281 if (!camera || !renderer) return; 1282 const t = clock.getElapsedTime(); 1283 1284 const radius = 900; 1285 const y = 650 + Math.sin(t * 0.3) * 80; 1286 1287 camera.position.x = Math.cos(t * 0.12) * radius; 1288 camera.position.z = Math.sin(t * 0.12) * radius; 1289 camera.position.y = y; 1290 camera.lookAt(0, 120, 0); 1291 1292 renderer.render(scene, camera); 1293 } 1294</script>
1294 1295 1296<!-- Forest House mini sahnesi: Ortadaki kutu içindeki canvas -->
1297<script type="module"> 1298 import * as THREE from 'https://esm.sh/[email protected]'; 1299 import { OrbitControls } from 'https://esm.sh/[email protected]/examples/jsm/controls/OrbitControls.js'; 1300 import { GLTFLoader } from 'https://esm.sh/[email protected]/examples/jsm/loaders/GLTFLoader.js'; 1301 import { DRACOLoader } from 'https://esm.sh/[email protected]/examples/jsm/loaders/DRACOLoader.js'; 1302 1303 let cameraFH, sceneFH, rendererFH, houseRoot, controlsFH; 1304 let forestHouseInitialized = false; 1305 let forestHouseAnimating = false; 1306 let forestHouseDisabled = false; 1307 1308 function shouldSkipForestHouseWebGL() { 1309 try { 1310 if (window.__PP_FORCE_DISABLE_LOADER_WEBGL === true) return true; 1311 if (window.__PP_DISABLE_LOADER_WEBGL === true) return true; 1312 } catch (_) {} 1313 try { 1314 if (window.PPWebGLCompat && typeof window.PPWebGLCompat.supports === 'function' && !window.PPWebGLCompat.supports('heavy_animation')) { 1315 return true; 1316 } 1317 } catch (_) {} 1318 try { 1319 if (window.__PP_GPU_MODE === 'no_gpu') return true; 1320 } catch (_) {} 1321 try { 1322 const canvas = document.createElement('canvas'); 1323 const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); 1324 if (!gl) return true; 1325 try { gl.getExtension('WEBGL_lose_context')?.loseContext?.(); } catch (_) {} 1326 return false; 1327 } catch (_) { 1328 return true; 1329 } 1330 } 1331 1332 window.ensureForestHouse = function ensureForestHouse() { 1333 if (shouldSkipForestHouseWebGL()) { 1334 forestHouseDisabled = true; 1335 return; 1336 } 1337 forestHouseDisabled = false; 1338 if (forestHouseInitialized && rendererFH && sceneFH && cameraFH) { 1339 if (!forestHouseAnimating) { 1340 forestHouseAnimating = true; 1341 animateForestHouse(); 1342 } 1343 return; 1344 } 1345 const ok = initForestHouse(); 1346 if (!ok) return; 1347 forestHouseInitialized = true; 1348 if (!forestHouseAnimating) { 1349 forestHouseAnimating = true; 1350 animateForestHouse(); 1351 } 1352 }; 1353 1354 function getFreshForestHouseCanvas() { 1355 const canvas = document.getElementById('pp-inner-canvas'); 1356 if (!canvas) return null; 1357 1358 // Replace the node so Three always receives a fresh canvas after any prior context usage. 1359 const replacement = canvas.cloneNode(false); 1360 replacement.width = canvas.width; 1361 replacement.height = canvas.height; 1362 canvas.replaceWith(replacement); 1363 return replacement; 1364 } 1365 1366 function disposeForestHouse() { 1367 forestHouseAnimating = false; 1368 window.removeEventListener('resize', onForestHouseResize); 1369 if (controlsFH && typeof controlsFH.dispose === 'function') { 1370 try { controlsFH.dispose(); } catch (_) {} 1371 } 1372 controlsFH = null; 1373 if (rendererFH) { 1374 try { rendererFH.dispose(); } catch (_) {} 1375 try { rendererFH.forceContextLoss(); } catch (_) {} 1376 } 1377 rendererFH = null; 1378 cameraFH = null; 1379 sceneFH = null; 1380 houseRoot = null; 1381 forestHouseInitialized = false; 1382 } 1383 1384 window.disposeForestHouse = disposeForestHouse; 1385 1386 function initForestHouse() { 1387 if (shouldSkipForestHouseWebGL()) { 1388 forestHouseDisabled = true; 1389 return false; 1390 } 1391 const canvas = getFreshForestHouseCanvas(); 1392 if (!canvas) return false; 1393 disposeForestHouse(); 1394 1395 const rect = canvas.getBoundingClientRect(); 1396 const width = Math.max(1, Math.round(rect.width || canvas.clientWidth || 320)); 1397 const height = Math.max(1, Math.round(rect.height || canvas.clientHeight || 160)); 1398 const aspect = width / height; 1399 1400 cameraFH = new THREE.PerspectiveCamera(45, aspect, 0.1, 100); 1401 cameraFH.position.set(1.5, 4, 9); 1402 1403 sceneFH = new THREE.Scene(); 1404 sceneFH.background = null; 1405 1406 const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 1.2); 1407 hemiLight.position.set(0, 20, 0); 1408 sceneFH.add(hemiLight); 1409 1410 const dirLight = new THREE.DirectionalLight(0xffffff, 1); 1411 dirLight.position.set(5, 10, 7.5); 1412 sceneFH.add(dirLight); 1413 1414 const dracoLoader = new DRACOLoader(); 1415 dracoLoader.setDecoderPath('https://threejs.org/examples/jsm/libs/draco/gltf/'); 1416 1417 const loader = new GLTFLoader(); 1418 loader.setDRACOLoader(dracoLoader); 1419 loader.setPath('https://threejs.org/examples/models/gltf/AVIFTest/'); 1420 loader.load( 1421 'forest_house.glb', 1422 function (gltf) { 1423 houseRoot = gltf.scene;
1424 sceneFH.add(houseRoot); 1425 }, 1426 undefined, 1427 function () { 1428 createFallbackHouse(); 1429 } 1430 ); 1431 1432 try { 1433 rendererFH = new THREE.WebGLRenderer({ 1434 canvas: canvas, 1435 antialias: true, 1436 alpha: true, 1437 failIfMajorPerformanceCaveat: false, 1438 }); 1439 } catch (error) { 1440 disposeForestHouse(); 1441 forestHouseDisabled = true; 1442 try { 1443 console.warn('[ProParcelLoader] Forest house WebGL init skipped:', error); 1444 } catch (_) {} 1445 return false; 1446 } 1447 rendererFH.setPixelRatio(window.devicePixelRatio); 1448 rendererFH.setSize(width, height, false); 1449 1450 controlsFH = new OrbitControls(cameraFH, canvas); 1451 controlsFH.addEventListener('change', renderForestHouse); 1452 controlsFH.target.set(0, 2, 0); 1453 controlsFH.update(); 1454 1455 window.addEventListener('resize', onForestHouseResize); 1456 return true; 1457 } 1458 1459 function createFallbackHouse() { 1460 if (!sceneFH || houseRoot) return; 1461 const group = new THREE.Group(); 1462 1463 const body = new THREE.Mesh( 1464 new THREE.BoxGeometry(2.8, 1.6, 2.2), 1465 new THREE.MeshStandardMaterial({ color: 0xe5e7eb, roughness: 0.7, metalness: 0.1 }) 1466 ); 1467 body.position.y = 1.0; 1468 group.add(body); 1469 1470 const roof = new THREE.Mesh( 1471 new THREE.ConeGeometry(2.1, 1.1, 4), 1472 new THREE.MeshStandardMaterial({ color: 0x2563eb, roughness: 0.55, metalness: 0.05 }) 1473 ); 1474 roof.rotation.y = Math.PI / 4; 1475 roof.position.y = 2.35; 1476 group.add(roof); 1477 1478 const door = new THREE.Mesh( 1479 new THREE.BoxGeometry(0.45, 0.95, 0.06), 1480 new THREE.MeshStandardMaterial({ color: 0x334155 }) 1481 ); 1482 door.position.set(0, 0.55, 1.13); 1483 group.add(door); 1484 1485 houseRoot = group; 1486 sceneFH.add(houseRoot); 1487 } 1488 1489 function onForestHouseResize() { 1490 const canvas = document.getElementById('pp-inner-canvas'); 1491 if (!canvas || !cameraFH || !rendererFH) return; 1492 1493 const rect = canvas.getBoundingClientRect(); 1494 const aspect = rect.width / (rect.height || 1); 1495 1496 cameraFH.aspect = aspect; 1497 cameraFH.updateProjectionMatrix(); 1498 1499 rendererFH.setSize(rect.width, rect.height, false); 1500 renderForestHouse(); 1501 } 1502 1503 function renderForestHouse() { 1504 if (!rendererFH || !sceneFH || !cameraFH) return; 1505 rendererFH.render(sceneFH, cameraFH); 1506 } 1507 1508 function animateForestHouse() { 1509 if (!forestHouseAnimating) return; 1510 requestAnimationFrame(animateForestHouse); 1511 if (houseRoot) { 1512 houseRoot.rotation.y += 0.005; 1513 } 1514 renderForestHouse(); 1515 } 1516</script>
1516 1517 1518 1519 1520 <!-- TKGM: Parsel Bulunamadı banner --> 1521 <div id="pp-tkgm-parcel-not-found-banner" role="status" aria-live="polite">Parsel Bulunamadı</div> 1522 1523 <!-- APP HEADER --> 1524 <header class="pp-header"> 1525 <!-- TOPBAR - Merkezi partial'dan yükleniyor --> 1526 1527 1528 1529<style> 1530 /* Merkezi dropdown radius yönetimi (index dahil tüm sayfalar). */ 1531 :root { 1532 --pp-dropdown-radius: 0px; 1533 } 1534 1535 #main-topbar .topbar-dropdown > .dropdown-menu, 1536 #main-topbar #main-menu-dropdown > .dropdown-menu, 1537 #main-topbar #user-menu-dropdown > .dropdown-menu, 1538 #main-topbar #user-menu-dropdown > .dropdown-menu.user-dropdown-menu, 1539 #main-topbar #notifications-dropdown > .dropdown-menu, 1540 #main-topbar #notifications-dropdown > .notifications-dropdown-menu, 1541 [data-role="param-menu"], 1542 [data-role="param-view-menu"], 1543 [data-role="param-roads-menu"], 1544 [data-role="param-list"], 1545 .select2-dropdown { 1546 border-radius: var(--pp-dropdown-radius) !important; 1547 } 1548 1549 #main-topbar .sidebar-toggle-btn, 1550 #main-topbar .topbar-right-actions .credit-badge, 1551 #main-topbar .topbar-right-actions .notifications-btn, 1552 #main-topbar .topbar-right-actions .user-menu-btn, 1553 #main-topbar .topbar-right-actions .right-info-toggle-topbar-btn, 1554 #main-topbar .topbar-right-actions .portal-topbar-btn, 1555 #main-topbar .topbar-vitrin-btn, 1556 #main-topbar .topbar-right-group .notifications-btn, 1557 #main-topbar .topbar-right-group .user-menu-btn, 1558 #main-topbar #main-menu-dropdown .dropdown-menu > .toggle-btn, 1559 #main-topbar #main-menu-dropdown .dropdown-menu > a.toggle-btn, 1560 #main-topbar #main-menu-dropdown .dropdown-menu > .pp-collapsible-wrap > .toggle-btn, 1561 #main-topbar #user-menu-dropdown .dropdown-menu > .toggle-btn, 1562 #main-topbar #user-menu-dropdown .dropdown-menu > a.toggle-btn, 1563 #main-topbar #user-menu-dropdown .dropdown-menu > .pp-collapsible-wrap > .toggle-btn, 1564 #main-topbar #user-menu-dropdown .dropdown-menu .user-menu-item, 1565 #main-topbar #notifications-dropdown .mark-all-read-btn, 1566 #main-topbar .topbar-dropdown #myQueriesList .query-del { 1567 border-radius: var(--pp-dropdown-radius) !important; 1568 } 1569</style> 1570 1571<!-- TOPBAR --> 1572<nav id="main-topbar" class="pp-topbar tkgm-topbar" role="banner" aria-label="Ana navigasyon"> 1573 1574 <!-- Sol: Hamburger Menü + ProParcel --> 1575 <div class="topbar-dropdown" id="main-menu-dropdown"> 1576 <button id="main-menu-toggle" class="sidebar-toggle-btn" aria-label="Ana menü" aria-expanded="false"> 1577 <svg width="22" height="22" viewBox="0 0 24 24" fill="none" aria-hidden="true"> 1578 <rect x="3" y="6" width="18" height="2" rx="1" fill="#fff" /> 1579 <rect x="3" y="11" width="18" height="2" rx="1" fill="#fff" /> 1580 <rect x="3" y="16" width="18" height="2" rx="1" fill="#fff" /> 1581 </svg> 1582 </button> 1583 <div class="dropdown-menu"> 1584 <a href="/?skip_landing_intro=1" class="toggle-btn" title="Tanıtım Sayfası" style="text-decoration:none;"> 1585 <i class="fa fa-home"></i> 1586 <span>Tanıtım Sayfası</span> 1587 </a> 1588 1589 <button id="dropdown-parsel-sorgu-btn" class="toggle-btn active" onclick="if(typeof toggleSidebar==='function')toggleSidebar();" title="Parsel Sorgu"> 1590 <i class="fa fa-search"></i> 1591 <span>Parsel Sorgu</span> 1592 </button> 1593 1594 <a href="/portal/ilan/vitrin/" id="pp-emlak-vitrini-hamburger-link" class="toggle-btn" title="Emlak Vitrini" style="text-decoration:none;"> 1595 <i class="fas fa-th-large"></i> 1596 <span>Emlak Vitrini</span> 1597 </a> 1598 <a href="/accounts/emlak-danismanlari/" class="toggle-btn" title="Emlak DanıÅmanları" style="text-decoration:none;"> 1599 <i class="fas fa-user-tie"></i> 1600 <span>Emlak DanıÅmanları</span> 1601 </a> 1602 <a href="/portal/recent-queries/?ref=recent90" class="toggle-btn" title="Son 90 Gün Pro Sorgular" style="text-decoration:none;"> 1603 <i class="fas fa-calendar-alt"></i> 1604 <span>Son 90 Gün Pro Sorgular</span> 1605 </a> 1606 1607 <div class="user-menu-divider"></div> 1608 <a href="/destek/" class="toggle-btn" id="mainMenuSupportLink" title="Destek" style="text-decoration:none;"> 1609 <i class="fas fa-life-ring"></i>
1610 <span>Destek</span> 1611 </a> 1612 <a href="/proje-olustur/" class="toggle-btn" id="mainMenuHowToLink" title="Nasıl Yapılır" style="text-decoration:none;"> 1613 <i class="fas fa-circle-play"></i> 1614 <span>Nasıl Yapılır</span> 1615 </a> 1616 </div> 1617 </div> 1618 1619 1620 1621 <!-- Marka İsmi --> 1622 <a href="/?skip_landing_intro=1" class="topbar-brand-text">ProParcel</a> 1623 1624 1625 <!-- Esnek BoÅluk --> 1626 <div style="flex: 1;"></div> 1627 1628 1629 1630 <!-- SaÄ taraf butonları - tutarlı gap ile --> 1631 <div class="topbar-right-actions"> 1632 1633 <!-- Son 90 Gün Pro Sorgular --> 1634 <a id="pp-son-30-gun-btn" href="/portal/recent-queries/?ref=recent90" class="right-info-toggle-topbar-btn" title="Son 90 Gün Pro Sorgular" style="text-decoration:none;"> 1635 <i class="fas fa-calendar-alt"></i> 1636 <span>Son 90 Gün Pro Sorgular</span> 1637 </a> 1638 <!-- Emlak Vitrini --> 1639 <a href="/portal/ilan/vitrin/" id="pp-emlak-vitrini-topbar-btn" class="right-info-toggle-topbar-btn" title="Emlak Vitrini" style="text-decoration:none;"> 1640 <i class="fas fa-store"></i> 1641 <span>Emlak Vitrini</span> 1642 </a> 1643 <a href="/mahalle-bilgileri/" class="right-info-toggle-topbar-btn" title="ProMahalle" style="text-decoration:none;"> 1644 <i class="fas fa-map-marker-alt"></i> 1645 <span>ProMahalle</span> 1646 </a> 1647 1648 1649 <!-- VIP badge (VIP kullanıcılar için) --> 1650 <span class="vip-topbar-badge" id="vipTopbarBadge" title="VIP Ãye" style="display: none;"> 1651 <i class="fas fa-crown"></i> 1652 <span>VIP</span> 1653 </span> 1654 1655 1656 1657 1658 <!-- Kredi bakiyesi badge'i (giriÅ yapmıŠkullanıcılar için) --> 1659 <a href="/accounts/pricing/" class="credit-badge" id="creditBadge" title="Tepe Kredi Bakiyeniz" style="display: none;"> 1660 <i class="fas fa-coins"></i> 1661 <span id="userCreditBalance">0</span> 1662 <span class="credit-label">TK</span> 1663 </a> 1664 1665 1666 1667 <!-- Kullanıcı Menüsü (bildirimler + avatar) --> 1668 1669 1670 1671<!-- Bildirimler (giriÅ yapılmıÅsa) --> 1672<div class="topbar-dropdown auth-only" id="notifications-dropdown" style="display: none;"> 1673 <button id="notificationsBtn" class="notifications-btn" aria-label="Bildirimler" aria-expanded="false" title="Bildirimler"> 1674 <i class="fas fa-bell"></i> 1675 <span id="notificationsBadge" class="notifications-badge" style="display: none;">0</span> 1676 </button> 1677 <div class="dropdown-menu notifications-dropdown-menu" id="notificationsMenu"> 1678 <div class="notifications-header"> 1679 <div class="notifications-header-main"> 1680 <span class="notifications-title">Bildirimler</span> 1681 <button id="markAllReadBtn" class="mark-all-read-btn" title="Tümünü okundu iÅaretle"> 1682 <i class="fas fa-check-double"></i> 1683 </button> 1684 </div> 1685 <div class="notifications-actions"> 1686 <button id="notificationsSelectAllBtn" class="notifications-action-btn" type="button">Tümünü Seç</button> 1687 <button id="notificationsDeleteSelectedBtn" class="notifications-action-btn notifications-action-btn--danger" type="button" disabled>Seçileni Sil</button> 1688 </div> 1689 </div> 1690 <div class="notifications-list" id="notificationsList"> 1691 <div class="notifications-empty"> 1692 <i class="fas fa-bell-slash"></i> 1693 <span>Bildirim bulunmuyor</span> 1694 </div> 1695 </div> 1696 <div class="notifications-footer"> 1697 <a href="/accounts/notifications/" id="viewAllNotificationsLink">Tüm Bildirimleri Gör</a> 1698 </div> 1699 </div> 1700</div> 1701 1702<!-- Kullanıcı Menüsü --> 1703<div class="topbar-dropdown" id="user-menu-dropdown"> 1704 <button id="userMenuBtn" class="user-menu-btn" aria-label="Kullanıcı menüsü" aria-expanded="false"> 1705 1706 <i class="fas fa-user-circle"></i> 1707 1708 </button> 1709 <div class="dropdown-menu"> 1710 <!-- Kullanıcı bilgisi (giriÅ yapılmıÅsa) --> 1711 <div class="user-menu-header" id="userMenuHeader" style="display: none;"> 1712 <img src="" alt="" class="user-menu-avatar" id="userMenuAvatar" width="48" height="48" decoding="async" style="display: none;"> 1713 <div class="user-menu-avatar-placeholder" id="userMenuAvatarPlaceholder" style="display: none;"> 1714 <i class="fas fa-user"></i> 1715 </div> 1716 <div class="user-menu-info">
1717 <span class="user-menu-name" id="userMenuName">Kullanıcı</span> 1718 <span class="vip-menu-badge" id="vipMenuBadge" style="display: none;"> 1719 <i class="fas fa-crown"></i> VIP 1720 </span> 1721 <span class="user-menu-email" id="userMenuEmail">[email protected]</span> 1722 </div> 1723 </div> 1724 <div class="user-menu-divider" id="userMenuDivider" style="display: none;"></div> 1725 1726 <!-- GiriÅ yapılmamıÅsa --> 1727 <a href="/accounts/login/" class="toggle-btn" id="menuLoginLink"> 1728 <i class="fas fa-sign-in-alt"></i> 1729 <span>GiriÅ Yap</span> 1730 </a> 1731 1732 <!-- 1. Profil --> 1733 <a href="/accounts/profile/" class="toggle-btn auth-only" id="menuProfileLink" style="display: none;"> 1734 <i class="fas fa-user"></i> 1735 <span>Profil</span> 1736 </a> 1737 1738 <!-- Bina Ãiz â /bina-ciz/ (parsel kontrolü yok; boÅ sayfa açılır) --> 1739 <a href="/bina-ciz/" class="toggle-btn" id="menuBinaCizLink" title="Bina Ãiz" style="text-decoration:none;"> 1740 <i class="fas fa-building"></i> 1741 <span>Bina Ãiz</span> 1742 </a> 1743 1744 <!-- Admin --> 1745 <a href="/accounts/admin/" class="toggle-btn admin-only" id="menuAdminLink" style="display: none;"> 1746 <i class="fas fa-shield-alt"></i> 1747 <span>Admin Panel</span> 1748 </a> 1749 1750 <!-- 2. Emlak Vitrini --> 1751 <a href="/portal/ilan/vitrin/" class="toggle-btn auth-only" id="menuEmlakVitriniLink" title="Emlak Vitrini" style="display: none; text-decoration:none;"> 1752 <i class="fas fa-store"></i> 1753 <span>Emlak Vitrini</span> 1754 </a> 1755 1756 <!-- 3. İlan İÅlemleri --> 1757 <div data-pp-collapsible="user-ilan-islemleri" class="pp-collapsible-wrap auth-only" id="menuIlanIslemleriWrap" style="display: none;"> 1758 <button type="button" id="menuIlanIslemleriBtn" data-pp-collapsible-toggle="user-ilan-islemleri" class="toggle-btn pp-collapsible-toggle" title="İlan İÅlemleri" aria-expanded="false" aria-controls="user-ilan-islemleri-content"> 1759 <i class="fas fa-briefcase"></i> 1760 <span>İlan İÅlemleri</span> 1761 <i class="fa fa-chevron-down pp-collapsible-chevron" aria-hidden="true"></i> 1762 </button> 1763 <div id="user-ilan-islemleri-content" data-pp-collapsible-content="user-ilan-islemleri" class="pp-collapsible-content" role="region" aria-label="İlan İÅlemleri alt menü"> 1764 <a href="/portal/ilan/olustur/" class="pp-collapsible-item" id="menuIlanOlusturLink" title="İlan ver" style="text-decoration:none;"> 1765 <i class="fas fa-plus-circle"></i> 1766 <span>İlan ver</span> 1767 </a> 1768 <a href="/portal/ilan/ilanlarim/" class="pp-collapsible-item" id="menuIlanlarimLink" title="İlanlarım" style="text-decoration:none;"> 1769 <i class="fas fa-list"></i> 1770 <span>İlanlarım</span> 1771 </a> 1772 </div> 1773 </div> 1774 1775 <!-- 4. Son 90 Gün Pro Sorguları --> 1776 <a href="/portal/recent-queries/?ref=recent90" class="toggle-btn auth-only" id="menuSon30GunProLink" title="Son 90 Gün Pro Sorguları" style="display: none; text-decoration:none;"> 1777 <i class="fas fa-calendar-alt"></i> 1778 <span>Son 90 Gün Pro Sorguları</span> 1779 </a> 1780 1781 <!-- 5. Basit --> 1782 <button type="button" class="toggle-btn auth-only" id="menuBasitSorguLink" title="Basit sorgu modu" style="display: none;"> 1783 <i class="fas fa-map"></i> 1784 <span>Basit</span> 1785 </button> 1786 1787 <!-- 6. Sorgularım --> 1788 <button type="button" class="toggle-btn auth-only" id="menuMyQueriesLink" title="Kayıtlı sorgularım" style="display: none;"> 1789 <i class="fa fa-history"></i> 1790 <span>Sorgularım</span> 1791 </button> 1792 1793 <!-- 7. ProMahalle --> 1794 <a href="/mahalle-bilgileri/" class="toggle-btn auth-only" id="menuProMahalleLink" title="ProMahalle" style="display: none; text-decoration:none;"> 1795 <i class="fas fa-comments"></i> 1796 <span>ProMahalle</span> 1797 </a> 1798 1799 <!-- 8. AI İÅlemleri --> 1800 <div data-pp-collapsible="user-ai-video" class="pp-collapsible-wrap auth-only" id="menuAiVideoWrap" style="display: none;"> 1801 <button type="button" id="menuAiVideoBtn" data-pp-collapsible-toggle="user-ai-video" class="toggle-btn pp-collapsible-toggle" title="AI İÅlemleri" aria-expanded="false" aria-controls="user-ai-vi
1801deo-content"> 1802 <i class="fas fa-magic"></i> 1803 <span>AI İÅlemleri</span> 1804 <i class="fa fa-chevron-down pp-collapsible-chevron" aria-hidden="true"></i> 1805 </button> 1806 <div id="user-ai-video-content" data-pp-collapsible-content="user-ai-video" class="pp-collapsible-content" role="region" aria-label="AI İÅlemleri alt menü" hidden> 1807 <a href="/portal/ai-video-olusturucu/" class="pp-collapsible-item" id="menuAiVideoStudioLink" title="AI Video" style="text-decoration:none;"> 1808 <i class="fas fa-film"></i> 1809 <span>AI Video</span> 1810 </a> 1811 <a href="/portal/ai-drone/" class="pp-collapsible-item" id="menuAiDroneVideoLink" title="AI Drone Video" style="text-decoration:none;" onclick="this.href='/portal/ai-drone/?v=' + Date.now();"> 1812 <i class="fas fa-helicopter"></i> 1813 <span>AI Drone Video</span> 1814 </a> 1815 </div> 1816 </div> 1817 1818 <!-- 9. Sosyal Medya Postu --> 1819 <a href="/portal/ilan/sosyal-medya-sablonu/?source=menu" class="toggle-btn auth-only" id="menuSocialMediaTemplateLink" title="Sosyal Medya Postu" style="display: none; text-decoration:none;"> 1820 <i class="fas fa-share-alt"></i> 1821 <span>Sosyal Medya Postu</span> 1822 </a> 1823 1824 <!-- 10. Emsal Bildir --> 1825 <a href="/accounts/emsal-sales-report/" class="toggle-btn auth-only emsal-only" id="menuEmsalSalesReportLink" style="display: none;"> 1826 <i class="fas fa-bullhorn"></i> 1827 <span>Emsal Bildir</span> 1828 </a> 1829 1830 <!-- 11. Aranacaklar --> 1831 <a href="/portal/aranacaklar/" class="toggle-btn auth-only" id="menuAranacaklarLink" title="Aranacaklar" style="display: none; text-decoration:none;"> 1832 <i class="fas fa-address-book"></i> 1833 <span>Aranacaklar</span> 1834 </a> 1835 1836 <!-- 12. Kredi Paketleri --> 1837 <a href="/accounts/pricing/" class="toggle-btn auth-only" id="menuPricingLink" style="display: none;"> 1838 <i class="fas fa-coins"></i> 1839 <span>Kredi Paketleri</span> 1840 </a> 1841 <a href="#" class="user-menu-item auth-only" id="menuKomisyonHesaplaLink" role="menuitem"> 1842 <i class="fas fa-calculator" aria-hidden="true"></i> 1843 <span>Komisyon Hesapla</span> 1844 </a> 1845 1846 <!-- 13. Dosyalarım --> 1847 <div data-pp-collapsible="user-dosyalarim" class="pp-collapsible-wrap auth-only" style="display: none;"> 1848 <button type="button" id="user-menu-dosyalarim-btn" data-pp-collapsible-toggle="user-dosyalarim" class="toggle-btn pp-collapsible-toggle" title="Dosyalarım" aria-expanded="false" aria-controls="user-dosyalarim-content"> 1849 <i class="fa fa-folder"></i> 1850 <span>Dosyalarım</span> 1851 <i class="fa fa-chevron-down pp-collapsible-chevron" aria-hidden="true"></i> 1852 </button> 1853 <div id="user-dosyalarim-content" data-pp-collapsible-content="user-dosyalarim" class="pp-collapsible-content" role="region" aria-label="Dosyalarım alt menü"> 1854 <a href="/hisseli-parsel/?projects=1" class="pp-collapsible-item" title="Hisseli Parsel Projelerim" style="text-decoration:none;"> 1855 <i class="fas fa-file-alt"></i> 1856 <span>Hisseli Parsel Projelerim</span> 1857 </a> 1858 <a href="/accounts/3d-designs/" class="pp-collapsible-item" title="3D Tasarımlarım" style="text-decoration:none;"> 1859 <i class="fas fa-cube"></i> 1860 <span>3D Tasarımlarım</span> 1861 </a> 1862 <div data-pp-collapsible="user-uzman" class="pp-collapsible-wrap" id="menuExpertRequestsGroup"> 1863 <button type="button" id="user-menu-uzman-btn" data-pp-collapsible-toggle="user-uzman" class="pp-collapsible-item pp-collapsible-toggle" title="Taleplerim" aria-expanded="false" aria-controls="user-uzman-content"> 1864 <i class="fas fa-user-tie"></i> 1865 <span>Taleplerim</span> 1866 <span id="expertRequestsBadge" class="pp-collapsible-badge" style="display:none;">0</span> 1867 <i class="fa fa-chevron-down pp-collapsible-chevron" aria-hidden="true"></i> 1868 </button> 1869 <div id="user-uzman-content" data-pp-collapsible-content="user-uzman" class="pp-collapsible-content" role="region" aria-label="Taleplerim alt menü"> 1870 <a href="/accounts/expert-requests/mine/" class="pp-collapsible-nested-item" title="İstekler" style="text-decoration:none;"> 1871 <i class="fas fa-paper-plane"></i>
1872 <span>İstekler</span> 1873 <span id="myRequestsBadge" class="pp-collapsible-badge" style="display:none;">0</span> 1874 </a> 1875 <a href="/accounts/expert-requests/incoming/" class="pp-collapsible-nested-item" id="menuIncomingRequestsLink" title="Gelenler" style="text-decoration:none;"> 1876 <i class="fas fa-inbox"></i> 1877 <span>Gelenler</span> 1878 <span id="incomingRequestsBadge" class="pp-collapsible-badge" style="display:none;">0</span> 1879 </a> 1880 </div> 1881 </div> 1882 </div> 1883 </div> 1884 1885 <!-- DiÄerleri --> 1886 <a href="/portal/ilan/mesajlar/" class="toggle-btn auth-only" id="menuIlanMesajlarLink" title="Mesajlarım" style="display: none; text-decoration:none;"> 1887 <i class="fas fa-comments"></i> 1888 <span>Mesajlar</span> 1889 </a> 1890 1891 <div class="user-menu-divider" id="userMenuBottomDivider"></div> 1892 <a href="/destek/" class="toggle-btn" id="menuSupportLink" style="text-decoration:none;"> 1893 <i class="fas fa-life-ring"></i> 1894 <span>Destek</span> 1895 </a> 1896 <a href="/proje-olustur/" class="toggle-btn" id="menuHowToLink" title="Nasıl Yapılır" style="text-decoration:none;"> 1897 <i class="fas fa-circle-play"></i> 1898 <span>Nasıl Yapılır</span> 1899 </a> 1900 <a href="/rehber/" class="toggle-btn" id="menuRehberLink" style="text-decoration:none;"> 1901 <i class="fas fa-book-open"></i> 1902 <span>Rehber</span> 1903 </a> 1904 <a href="/accounts/logout/" class="toggle-btn user-menu-logout auth-only" id="menuLogoutLink" style="display: none;"> 1905 <i class="fas fa-sign-out-alt"></i> 1906 <span>ÃıkıŠYap</span> 1907 </a> 1908 </div> 1909</div> 1910 1911 1912 </div> 1913</nav> 1914 1915<!-- Topbar Dropdown Script --> 1916<!-- NOT: Ana dropdown iÅlevselliÄi dropdowns.js tarafından yönetilir. 1917 Bu script sadece dropdowns.js yüklenmeyen sayfalar için fallback saÄlar. 1918 dropdowns.js yüklenecekse bu script devre dıÅı kalır. -->
1919<script> 1920(function(){ 1921 // dropdowns.js yüklenip yüklenmeyeceÄini bekle (sayfa tamamen yüklenene kadar) 1922 // dropdowns.js yüklendiyse, o zaten tüm iÅlevselliÄi saÄlar 1923 function initTopbarDropdownsFallback() { 1924 const menuToggle = document.getElementById('main-menu-toggle'); 1925 const menuDropdown = document.getElementById('main-menu-dropdown'); 1926 const userToggle = document.getElementById('userMenuBtn'); 1927 const userDropdown = document.getElementById('user-menu-dropdown'); 1928 1929 // dropdowns.js zaten bind ettiyse (flag kontrolü) - atla 1930 if(menuToggle && menuToggle.__ppDropdownBound) return; 1931 if(userToggle && userToggle.__ppDropdownBound) return; 1932 1933 // Hamburger menü 1934 if(menuToggle && menuDropdown){ 1935 menuToggle.__ppDropdownBound = true; 1936 1937 menuToggle.addEventListener('click', function(e){ 1938 e.stopPropagation(); 1939 e.preventDefault(); 1940 menuDropdown.classList.toggle('open'); 1941 // Kullanıcı menüsünü kapat 1942 if(userDropdown) userDropdown.classList.remove('open'); 1943 }); 1944 } 1945 1946 // Kullanıcı menüsü 1947 if(userToggle && userDropdown){ 1948 userToggle.__ppDropdownBound = true; 1949 1950 // Click event 1951 userToggle.addEventListener('click', function(e){ 1952 e.stopPropagation(); 1953 e.preventDefault(); 1954 userDropdown.classList.toggle('open'); 1955 // Ana menüyü kapat 1956 if(menuDropdown) menuDropdown.classList.remove('open'); 1957 }); 1958 1959 // Touch event (mobil için) 1960 userToggle.addEventListener('touchend', function(e){ 1961 e.preventDefault(); 1962 e.stopPropagation(); 1963 userDropdown.classList.toggle('open'); 1964 // Ana menüyü kapat 1965 if(menuDropdown) menuDropdown.classList.remove('open'); 1966 }, { passive: false }); 1967 } 1968 1969 // DıÅarı tıklamada kapat - sadece bir kez bind et 1970 if(!window.__ppTopbarDropdownOutsideClose){ 1971 window.__ppTopbarDropdownOutsideClose = true; 1972 1973 function closeDropdowns(e) { 1974 const menuDD = document.getElementById('main-menu-dropdown'); 1975 const userDD = document.getElementById('user-menu-dropdown'); 1976 if(menuDD && !menuDD.contains(e.target)) { 1977 menuDD.classList.remove('open'); 1978 } 1979 if(userDD && !userDD.contains(e.target)) { 1980 userDD.classList.remove('open'); 1981 } 1982 } 1983 1984 document.addEventListener('click', closeDropdowns); 1985 document.addEventListener('touchend', closeDropdowns, { passive: true }); 1986 } 1987 } 1988 1989 // Sayfa tamamen yüklendikten SONRA çalıÅtır (dropdowns.js'e öncelik ver) 1990 // dropdowns.js varsa zaten binding yapmıŠolacak, bu script atlanacak 1991 window.addEventListener('load', function(){ 1992 // Küçük bir gecikme ile çalıÅtır - dropdowns.js'in çalıÅmasını bekle 1993 setTimeout(initTopbarDropdownsFallback, 100); 1994 }); 1995})(); 1996</script>
1996 1997 1998<!-- Tepe Kredi Sistemi --> 1999
2000<script src="/static/js/credit_system.js"></script>
2000 2001 2002<!-- Kullanıcı menüsü durumu güncelleme -->
2003<script id="pp-user" type="application/json"> 2004{ 2005 "authenticated": false, 2006 "id": "", 2007 "email": "", 2008 "name": "", 2009 "avatar": "", 2010 "initial": "", 2011 "is_admin": false, 2012 "is_vip": false, 2013 "can_view_expert_price": false, 2014 "has_seen_welcome": true, 2015 "has_seen_app_tour": true, 2016 "member_type": "", 2017 "corporate_type": "", 2018 "effective_corporate_type": "", 2019 "consultant_type": "", 2020 "can_access_vault": false, 2021 "can_access_prosorgu": false, 2022 "is_company_authority": false, 2023 "role": "", 2024 "company": "", 2025 "phone": "", 2026 "customer_type": "basic", 2027 "features": {"smart_query":false,"street_view":false,"portal_share_pdf":true,"portal_share_link":true} 2028} 2029</script>
vendor: 1 bytes, line 2029
2029
2030<script> 2031 window.PP_WEB_ILAN_PORTAL_UI_ENABLED = true; 2032 window.PP_WEB_ILAN_VITRIN_UI_ENABLED = true; 2033</script>
vendor: 1 bytes, line 2033
2033
2034<script> 2035 (function() { 2036 try { 2037 const ppElement = document.getElementById('pp-user'); 2038 if (!ppElement) { 2039 console.warn('[PP-User] pp-user element not found, using defaults'); 2040 window.PP_USER_AUTHENTICATED = false; 2041 window.PP_USER_EMAIL = null; 2042 window.PP_USER_NAME = null; 2043 window.PP_USER_AVATAR = null; 2044 window.PP_USER_INITIAL = null; 2045 window.PP_USER_IS_ADMIN = false; 2046 window.PP_USER_IS_VIP = false; 2047 window.PP_USER_CAN_VIEW_EXPERT_PRICE = false; 2048 window.PP_USER_HAS_SEEN_WELCOME = true; 2049 window.PP_USER_HAS_SEEN_APP_TOUR = true; 2050 window.PP_USER_MEMBER_TYPE = null; 2051 window.PP_USER_ROLE = null; 2052 window.PP_USER_CORPORATE_TYPE = null; 2053 window.PP_USER_IS_COMPANY_AUTHORITY = false; 2054 window.PP_USER_COMPANY = null; 2055 window.PP_USER_PHONE = null; 2056 window.PP_CAN_ACCESS_VAULT = false; 2057 window.PP_CAN_ACCESS_PROSORGU = false; 2058 window.PP_WEB_ILAN_PORTAL_UI_ENABLED = false; 2059 window.PP_WEB_ILAN_VITRIN_UI_ENABLED = true; 2060 return; 2061 } 2062 const pp = JSON.parse(ppElement.textContent); 2063 window.PP_USER_AUTHENTICATED = !!pp.authenticated; 2064 window.PP_USER_ID = pp.id || null; 2065 window.PP_USER_EMAIL = pp.email || null; 2066 window.PP_USER_NAME = pp.name || null; 2067 window.PP_USER_AVATAR = pp.avatar || null; 2068 window.PP_USER_INITIAL = pp.initial || null; 2069 window.PP_USER_IS_ADMIN = !!pp.is_admin; 2070 window.PP_USER_IS_VIP = !!pp.is_vip; 2071 window.PP_USER_CAN_VIEW_EXPERT_PRICE = !!pp.can_view_expert_price; 2072 window.PP_USER_HAS_SEEN_WELCOME = !!pp.has_seen_welcome; 2073 window.PP_USER_HAS_SEEN_APP_TOUR = !!pp.has_seen_app_tour; 2074 window.PP_USER_MEMBER_TYPE = pp.member_type || null; 2075 window.PP_USER_ROLE = pp.role || null; 2076 window.PP_USER_CORPORATE_TYPE = pp.corporate_type || null; 2077 window.PP_USER_EFFECTIVE_CORPORATE_TYPE = pp.effective_corporate_type || pp.corporate_type || null; 2078 window.PP_USER_CONSULTANT_TYPE = pp.consultant_type || null; 2079 window.PP_CAN_ACCESS_VAULT = !!pp.can_access_vault; 2080 window.PP_CAN_ACCESS_PROSORGU = pp.can_access_prosorgu !== false; 2081 window.PP_USER_IS_COMPANY_AUTHORITY = !!pp.is_company_authority; 2082 window.PP_USER_COMPANY = pp.company || null; 2083 window.PP_USER_PHONE = pp.phone || null; 2084 window.PP_USER_CUSTOMER_TYPE = pp.customer_type || 'basic'; 2085 window.PP_USER_FEATURES = pp.features || { 2086 smart_query: false, 2087 street_view: false, 2088 portal_share_pdf: true, 2089 portal_share_link: true, 2090 }; 2091 } catch (e) { 2092 console.error('[PP-User] Error parsing user data:', e); 2093 window.PP_USER_AUTHENTICATED = false; 2094 window.PP_USER_ID = null; 2095 window.PP_USER_EMAIL = null; 2096 window.PP_USER_NAME = null; 2097 window.PP_USER_AVATAR = null; 2098 window.PP_USER_INITIAL = null; 2099 window.PP_USER_IS_ADMIN = false; 2100 window.PP_USER_IS_VIP = false; 2101 window.PP_USER_CAN_VIEW_EXPERT_PRICE = false; 2102 window.PP_USER_HAS_SEEN_WELCOME = true; 2103 window.PP_USER_HAS_SEEN_APP_TOUR = true; 2104 window.PP_USER_MEMBER_TYPE = null; 2105 window.PP_USER_ROLE = null; 2106 window.PP_USER_CORPORATE_TYPE = null; 2107 window.PP_USER_CONSULTANT_TYPE = null; 2108 window.PP_CAN_ACCESS_VAULT = false; 2109 window.PP_CAN_ACCESS_PROSORGU = false; 2110 window.PP_USER_IS_COMPANY_AUTHORITY = false; 2111 window.PP_USER_COMPANY = null; 2112 window.PP_USER_PHONE = null; 2113 } 2114 })(); 2115</script>
vendor: 1 bytes, line 2115
2115
2116<script src="/static/js/core/components/collapsible_menu.js"></script>
vendor: 1 bytes, line 2116
2116
2117<script src="/static/js/app/ui/dropdowns.js"></script>
vendor: 1 bytes, line 2117
2117
2118<script src="/static/js/app/ui/user_menu.js"></script>
vendor: 1 bytes, line 2118
2118
2119<script src="/static/js/app/cost/komisyon_harclar_modal.js?v=20260725i"></script>
vendor: 1 bytes, line 2119
2119
2120<script src="/static/js/app/ui/ai_drone_admin_gate.js"></script>
vendor: 1 bytes, line 2120
2120
2121<script src="/static/js/app/ui/welcome_modal.js"></script>
vendor: 1 bytes, line 2121
2121
2122<script src="/static/js/app/ui/auth_required_3d_modal.js"></script>
2122 2123<!-- Tüm sayfalarda menülerin düzgün çalıÅması için window load'da reinit -->
2124<script> 2125(function() { 2126 // Sayfa tamamen yüklendikten sonra tekrar initialize et 2127 window.addEventListener('load', function() { 2128 setTimeout(function() { 2129 // Collapsible menüleri reinit 2130 if (typeof window.ppCollapsible !== 'undefined' && window.ppCollapsible.init) { 2131 window.ppCollapsible.init(); 2132 } 2133 // Auth-only elementleri tekrar kontrol et 2134 if (window.PP_USER_AUTHENTICATED) { 2135 var authOnlyElements = document.querySelectorAll('.auth-only'); 2136 authOnlyElements.forEach(function(el) { 2137 if (el.classList.contains('pp-collapsible-wrap')) { 2138 el.style.setProperty('display', 'block', 'important'); 2139 } 2140 }); 2141 } 2142 }, 150); 2143 }, { once: true }); 2144})(); 2145</script>
2145 2146 2147 <!-- TOOLBAR - Unified Action Bar (Basit/Pro tek bar, tema CSS ile deÄiÅir) --> 2148 <nav class="pp-toolbar mode-simple" id="top-menu-bar"> 2149 <div id="top-button-container" class="mode-simple" onclick="stopMapClick(event)"> 2150 <!-- ADA PARSEL SORGU BUTONU --> 2151 <button id="proAdaParselSorguBtn" class="toggle-btn pp-ada-parsel-toolbar-btn" title="Ada/Parsel Sorgu" type="button"> 2152 <i class="fa fa-search" aria-hidden="true"></i> 2153 <span>Ada Parsel Sorgu</span> 2154 </button> 2155 <!-- AYRAà --> 2156 <span class="btn-separator"></span> 2157 <!-- MAP TIKLAMA / BASİT MOD --> 2158 <button id="toggleMapClick" class="toggle-btn target-button" data-target="toggleMapClick" 2159 type="button" title="Tıklama Modu (Cursor)" aria-label="Basit Sorgu Tıklama Modu"> 2160 <i class="fa fa-mouse-pointer"></i> 2161 </button> 2162 <!-- PRO MOD KISAYOLU --> 2163 <button id="toolbarModeProBtn" class="toggle-btn pp-toolbar-mode-pro-btn" type="button" 2164 title="Pro Analize Geç" aria-label="Pro Analize Geç"> 2165 <i class="fa fa-mouse-pointer pp-toolbar-mode-icon" aria-hidden="true"></i> 2166 </button> 2167 <!-- VIP DoÄrulama durumu toggle (vip / vip_limited / premium) --> 2168 <button id="ppDogrulamaToggle" class="toggle-btn pp-dogrulama-toggle" type="button" 2169 title="DoÄrulama" aria-label="DoÄrulama" aria-pressed="false" style="display:none;"> 2170 <i class="fas fa-shield-halved" aria-hidden="true"></i> 2171 </button> 2172 <button type="button" id="ppKomisyonHarclarBtn" class="toggle-btn" title="Komisyon & Harçlar Hesapla" 2173 onclick="event.preventDefault();event.stopPropagation();if(typeof window.openKomisyonHarclarModal==='function'){window.openKomisyonHarclarModal({});}return false;"> 2174 <i class="fas fa-calculator"></i> 2175 <span>Komisyon</span> 2176 </button> 2177 <span class="btn-separator pp-toolbar-slide-sep" aria-hidden="true"></span> 2178 <!-- DiÄer araçlar: ikonla açılıp kapanan kaydırmalı Åerit --> 2179 <div class="pp-toolbar-extras-shell"> 2180 <button type="button" id="pp-toolbar-slide-toggle" class="toggle-btn pp-toolbar-slide-toggle" 2181 title="DiÄer araçları göster / gizle" aria-expanded="false" aria-controls="pp-toolbar-extras"> 2182 <i class="fas fa-angles-left pp-toolbar-slide-icon" aria-hidden="true"></i> 2183 <span class="visually-hidden">DiÄer araçlar</span> 2184 </button> 2185 <div id="pp-toolbar-extras" class="pp-toolbar-extras" aria-hidden="true" role="region" aria-label="Ek harita araçları"> 2186 <!-- P (Parsel Sınırı + Yükselti Görünümü) --> 2187 <button id="parcel_polygon" class="parameters nodata" data-target="parcel_polygon" title="Parsel Sınırı ve Yükselti Görünümü"> 2188 <span style="font-weight: 600; font-size: 14px;">P</span> 2189 </button> 2190 <!-- KONUM --> 2191 <button id="toolbarGeoBtn" class="toggle-btn geo-btn" data-geo="toggle" title="Konumuma Git" aria-pressed="false"> 2192 <i class="fas fa-crosshairs"></i> 2193 </button> 2194 <!-- KATMAN (Vektör harita aç/kapat) --> 2195 <button id="hdBaseBtn" type="button" class="toggle-btn" data-action="toggle-hd-base" title="Vektör harita aç/kapat" aria-label="Vektör harita aç/kapat"> 2196 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="currentColor" aria-hidden="true"> 2197 <path d="M9.5 5.1l5 1.8 5-1.6c.3-.1.5.1.5.4v13.4c0 .2-.1.4-.3.4l-5.2 1.7c-.1 0-.2 0-.3 0l-5-1.8-5 1.6c-.3.1-.5-.1-.5-.4V6c0-.2.1-.4.3-.4l5.2-1.7c.1 0 .2 0 .3 0zM9 6.6L5 5.3v12.8l4-1.3V6.6zm6 1.8l-4-1.5v10.3l4 1.5V8.4zm1 9.4l3-1V4l-3 1v12.8z"></path> 2198 </svg> 2199 </button> 2200 <!-- ARAà TAKIMI (İÄne & Metin) --> 2201 <div class="pp-annotation-dropdown" id="annotationToolDropdown" onclick="event.stopPropagation();"> 2202 <button type="button" class="toggle-btn" id="annotationToolBtn" title="Araç Takımı (İÄne / Metin)"> 2203 <i class="fas fa-toolbox"></i> 2204 <span>Araçlar</span> 2205 <i class="fas fa-caret-down" style="margin-left:4px;font-size:10px;opacity:0.7;"></i> 2206 </button> 2207 <div class="pp-annotation-menu" id="annotationMenu"> 2208 <div class="pp-annotation-menu-group"> 2209 <button type="button" class="pp-annotation-submenu-trigger" id="annotTriggerDraw" aria-expanded="false" aria-controls="annotSubmenuDraw">
2210 <span class="pp-annot-submenu-label"><i class="fas fa-pencil-alt" aria-hidden="true"></i> Ãizim Araçları</span> 2211 <i class="fas fa-chevron-right pp-annot-submenu-chevron" aria-hidden="true"></i> 2212 </button> 2213 <div class="pp-annotation-submenu" id="annotSubmenuDraw" role="region" aria-labelledby="annotTriggerDraw"> 2214 <button type="button" class="pp-annotation-menu-item" data-annotation-tool="pin" title="Haritaya İÄne Ekle"> 2215 <i class="fas fa-map-pin"></i> 2216 <span>İÄne Ekle</span> 2217 </button> 2218 <button type="button" class="pp-annotation-menu-item" data-annotation-tool="arrow" title="Haritaya Ok Ekle"> 2219 <i class="fas fa-long-arrow-alt-right"></i> 2220 <span>Ok Ekle</span> 2221 </button> 2222 <button type="button" class="pp-annotation-menu-item" data-annotation-tool="pencil" title="Serbest kalem ile sürükleyerek çiz"> 2223 <i class="fas fa-pencil-alt"></i> 2224 <span>Kalem çizimi</span> 2225 </button> 2226 <button type="button" class="pp-annotation-menu-item" data-annotation-tool="freepolyline" title="Tıklayarak çizgi â Tamam veya çift tıklama ile bitir"> 2227 <i class="fas fa-project-diagram"></i> 2228 <span>Serbest çizim (tıkla)</span> 2229 </button> 2230 <hr class="pp-annotation-menu-divider"> 2231 <button type="button" class="pp-annotation-menu-item pp-annotation-menu-item--danger" data-annotation-tool="clear" title="Parsel sınırı hariç iÅaretleri ve çizimleri temizle"> 2232 <i class="fas fa-trash-alt"></i> 2233 <span>Tümünü Temizle</span> 2234 </button> 2235 </div> 2236 </div> 2237 <div class="pp-annotation-menu-group"> 2238 <button type="button" class="pp-annotation-submenu-trigger" id="annotTriggerMeasure" aria-expanded="false" aria-controls="annotSubmenuMeasure"> 2239 <span class="pp-annot-submenu-label"><i class="fas fa-ruler" aria-hidden="true"></i> Ãlçüm Araçları</span> 2240 <i class="fas fa-chevron-right pp-annot-submenu-chevron" aria-hidden="true"></i> 2241 </button> 2242 <div class="pp-annotation-submenu" id="annotSubmenuMeasure" role="region" aria-labelledby="annotTriggerMeasure"> 2243 <button type="button" class="pp-annotation-menu-item measurement-btn" data-action="toggle-ruler" title="Mesafe Ãlçümü (Cetvel)"> 2244 <i class="fas fa-ruler"></i> 2245 <span>Mesafe Ãlçümü</span> 2246 </button> 2247 <button type="button" class="pp-annotation-menu-item measurement-btn" data-action="toggle-area" title="Alan Ãlçümü"> 2248 <i class="fas fa-drafting-compass"></i> 2249 <span>Alan Ãlçümü</span> 2250 </button> 2251 </div> 2252 </div> 2253 <hr class="pp-annotation-menu-divider"> 2254 <button type="button" class="pp-annotation-menu-item" data-annotation-tool="text" title="Haritaya Metin Ekle"> 2255 <i class="fas fa-font"></i> 2256 <span>Metin Ekle</span> 2257 </button> 2258 </div> 2259 </div> 2260 <button id="action-bar-refresh-btn" class="toggle-btn" title="Ekrandaki parselleri ve çizimleri temizle" 2261 onclick="if(typeof window.ppActionBarRefreshClear==='function')window.ppActionBarRefreshClear();"> 2262 <i class="fas fa-sync-alt"></i> 2263 </button> 2264 <span class="btn-separator pp-toolbar-extras-auth-sep"></span> 2265 <div class="pp-toolbar-extras-auth-gate pp-toolbar-extras-auth-gate--locked"> 2266 <div class="pp-toolbar-extras-auth-overlay" role="status" aria-live="polite"> 2267 <p class="pp-toolbar-extras-auth-overlay-text">Ãcretsiz Kullanım İçin Ãye GiriÅi Yapın</p> 2268 </div> 2269 <!-- HARİTA GÃRÃNTÃSà AL --> 2270 <div class="pp-capture-menu-wrap" id="pp-capture-menu-wrap"> 2271 <button id="pp-screenshot-map-btn" class="toggle-btn" title="Harita görüntüsü al" onclick="if(typeof ppToggleCaptureMenu==='function')ppToggleCaptureMenu(event);" disabled aria-disabled="true" tabindex="-1"> 2272 <i class="fas fa-camera"></i>
2273 <span>Görüntü Al</span> 2274 <i class="fas fa-chevron-down pp-capture-menu-caret"></i> 2275 </button> 2276 <div class="pp-capture-menu" id="pp-capture-menu" aria-label="Görüntü formatı seç"> 2277 <button type="button" onclick="if(typeof ppCaptureAndDownloadMap==='function')ppCaptureAndDownloadMap('horizontal');"> 2278 <i class="fas fa-arrows-alt-h"></i> 2279 <span>Yatay</span> 2280 </button> 2281 <button type="button" onclick="if(typeof ppCaptureAndDownloadMap==='function')ppCaptureAndDownloadMap('vertical');"> 2282 <i class="fas fa-mobile-alt"></i> 2283 <span>Dikey Hikaye</span> 2284 </button> 2285 </div> 2286 </div> 2287 <!-- 3D GÃRÃNÃME GEà --> 2288 <button class="toggle-btn map-3d-toggle pp-webgl-compat-disabled" id="toggle3DMap" title="3D uyumluluÄu kontrol ediliyor" aria-disabled="true" data-pp-webgl-pending="1" data-pp-webgl-blocked="1" style="background:#e5e7eb!important;background-image:none!important;color:#64748b!important;border-color:#cbd5e1!important;box-shadow:none!important;text-shadow:none!important;opacity:.45!important;filter:grayscale(1)!important;cursor:not-allowed!important;" disabled tabindex="-1"> 2289 <i class="fa fa-cube"></i> 2290 <span id="toggle3DText"></span> 2291 </button> 2292 <!-- SOKAK GÃRÃNTÃSà BUTONU --> 2293 <button id="street-view-menu-btn" class="toggle-btn" title="Sokak Görüntüsü" onclick="openStreetViewModal()" disabled aria-disabled="true" tabindex="-1"> 2294 <i class="fa fa-street-view"></i> 2295 <span>Sokak Görüntüsü</span> 2296 </button> 2297 <span class="btn-separator"></span> 2298 <!-- HISSELİ PARSELLERE BÃL â ayraç saÄında, 3D Model ile yan yana --> 2299 <button id="hisseli-parsel-btn" class="toggle-btn" title="Hisseli Parsellere Böl (önce haritada parsel seçin)" onclick="openHisseliParselPage()" disabled aria-disabled="true" tabindex="-1"> 2300 <i class="fa fa-object-group"></i> 2301 <span>Hisseli Parsellere Böl</span> 2302 </button> 2303 <!-- 3D MODEL EKLE (hamburger menüden taÅındı) --> 2304 <a href="javascript:void(0)" data-pp-original-href="/3d-editor/" id="pp-3d-editor-toolbar-link" class="toggle-btn action-bar-link pp-webgl-compat-disabled" title="3D uyumluluÄu kontrol ediliyor" aria-disabled="true" data-pp-webgl-pending="1" data-pp-webgl-blocked="1" style="background:#e5e7eb!important;background-image:none!important;color:#64748b!important;border-color:#cbd5e1!important;box-shadow:none!important;text-shadow:none!important;opacity:.45!important;filter:grayscale(1)!important;cursor:not-allowed!important;" tabindex="-1"> 2305 <i class="fas fa-cube"></i> 2306 <span>3D Model</span> 2307 </a> 2308 <a href="javascript:void(0)" data-pp-original-href="/bina-ciz/" id="pp-ne-yapilir-btn" class="toggle-btn action-bar-link pp-webgl-compat-disabled" title="Proje OluÅtur â önce haritada parsel seçin" aria-disabled="true" data-pp-webgl-pending="1" data-pp-webgl-blocked="1" style="background:#e5e7eb!important;background-image:none!important;color:#64748b!important;border-color:#cbd5e1!important;box-shadow:none!important;text-shadow:none!important;opacity:.45!important;filter:grayscale(1)!important;cursor:not-allowed!important;" tabindex="-1"> 2309 <i class="fas fa-building"></i> 2310 <span>Proje OluÅtur</span> 2311 </a> 2312 <button type="button" id="pp-ai-drone-video-btn" class="toggle-btn" title="AI Drone Video â önce haritada parsel seçin veya sorgulayın" data-pp-webgl-pending="1" disabled tabindex="-1"> 2313 <i class="fas fa-video"></i> 2314 <span>AI Drone Video</span> 2315 </button> 2316 </div> 2317 </div> 2318 </div> 2319 <div class="pp-toolbar-flex-spacer" aria-hidden="true"></div> 2320 <!-- GÃSTERGE (en saÄda) --> 2321 <div id="map-zoom-indicator" class="toggle-btn" 2322 style="min-width: 80px; text-align: center; display: flex; align-items: center; justify-content: center;"> 2323 - 2324 </div> 2325 </div> 2326 </nav> 2327 </header> 2328
2328<script> 2329 (function () { 2330 'use strict'; 2331 var DEBUG = false; 2332 var applyingActionBarState = false; 2333 var featureBlocks = [ 2334 { selector: '#toggle3DMap', feature: '3d_mode' }, 2335 { selector: '#pp-3d-editor-toolbar-link', feature: 'model_editor' }, 2336 { selector: '#pp-ne-yapilir-btn', feature: 'model_editor' }, 2337 { selector: '#pp-ai-drone-video-btn', feature: 'drone_editor' } 2338 ]; 2339 var warningText = 'Bu bilgisayar/tarayıcı 3D harita, 3D model ve AI Drone özelliklerini desteklemiyor. Ekran kartı sürücünüz eski olabilir. Lütfen güncel Chrome/Edge/Firefox veya daha yeni bir bilgisayar kullanın.'; 2340 2341 function debugLog(stage, payload) { 2342 if (!DEBUG) return; 2343 try { 2344 console.warn('[PP_WEBGL_ACTIONBAR_GUARD]', stage, payload || {}); 2345 } catch (e) {} 2346 } 2347 2348 function supportsFeature(feature) { 2349 if (feature === 'drone_editor') { 2350 try { 2351 if (typeof window.ppIsDroneEditorAllowed === 'function' && !window.ppIsDroneEditorAllowed()) return false; 2352 } catch (e) {} 2353 } 2354 try { 2355 if (window.PPWebGLCompat && typeof window.PPWebGLCompat.supports === 'function') { 2356 return window.PPWebGLCompat.supports(feature); 2357 } 2358 } catch (e) {} 2359 var mode = window.__PP_GPU_MODE || 'minimal_gpu'; 2360 if (mode === 'no_gpu') return feature === 'drone_editor'; 2361 if (mode === 'full_gpu') return true; 2362 if (feature === '3d_mode' || feature === 'model_editor') return false; 2363 return true; 2364 } 2365 2366 function warningForFeature(feature) { 2367 if (feature === 'model_editor') return 'Bu cihazda geliÅmiÅ 3D düzenleme desteklenmiyor.'; 2368 if (feature === 'drone_editor') return 'AI Drone Video â Åu an kullanılamıyor'; 2369 return 'Bu cihazda 3D harita ve terrain modu desteklenmiyor. 2D uydu harita ve sorgu iÅlemleri kullanılabilir.'; 2370 } 2371 2372 function showLegacyWarning() { 2373 try { 2374 if (window.PPWebGLCompat && typeof window.PPWebGLCompat.showWarning === 'function') { 2375 window.PPWebGLCompat.showWarning(); 2376 return; 2377 } 2378 } catch (e) {} 2379 alert(warningText); 2380 } 2381 2382 function setDisabledVisual(el) { 2383 if (!el) { 2384 debugLog('set_disabled_missing_element', {}); 2385 return; 2386 } 2387 if (el.getAttribute('data-pp-index-actionbar-disabled') === '1') return; 2388 el.classList.remove('active'); 2389 el.classList.remove('pp-green'); 2390 el.classList.add('pp-webgl-compat-disabled', 'pp-webgl-3d-disabled'); 2391 el.setAttribute('aria-disabled', 'true'); 2392 el.setAttribute('data-pp-webgl-blocked', '1'); 2393 el.setAttribute('data-pp-index-actionbar-disabled', '1'); 2394 if (el.id === 'pp-ai-drone-video-btn') { 2395 el.title = 'AI Drone Video â Åu an kullanılamıyor'; 2396 } else { 2397 el.title = 'Bu cihaz bu özelliÄi desteklemiyor'; 2398 } 2399 if (el.tagName === 'A') { 2400 if (!el.getAttribute('data-pp-original-href')) el.setAttribute('data-pp-original-href', el.getAttribute('href') || ''); 2401 el.setAttribute('href', 'javascript:void(0)'); 2402 } 2403 if (el.hasAttribute && el.hasAttribute('onclick')) { 2404 if (!el.getAttribute('data-pp-original-onclick')) el.setAttribute('data-pp-original-onclick', el.getAttribute('onclick') || ''); 2405 el.removeAttribute('onclick'); 2406 } 2407 [ 2408 ['background', '#e5e7eb'], 2409 ['background-image', 'none'], 2410 ['color', '#64748b'], 2411 ['border-color', '#cbd5e1'], 2412 ['box-shadow', 'none'], 2413 ['text-shadow', 'none'], 2414 ['opacity', '0.45'], 2415 ['filter', 'grayscale(1)'], 2416 ['cursor', 'not-allowed'] 2417 ].forEach(function (pair) { 2418 try { el.style.setProperty(pair[0], pair[1], 'important'); } catch (e) {} 2419 }); 2420 try { 2421 el.querySelectorAll('i,svg,span').forEach(function (child) { 2422 child.style.setProperty('color', '#64748b', 'important'); 2423 child.style.setProperty('fill', '#64748b', 'important'); 2424 }); 2425 } catch (e) {} 2426 debugLog('set_disabled_applied', { 2427 id: el.id, 2428 tagName: el.tagName, 2429 className: el.className, 2430 href: el.getAttribute('href'), 2431 ariaDisabled: el.getAttribute('aria-disabled'), 2432 dataBlocked: el.getAttribute('data-pp-webgl-blocked'), 2433 inlineStyle: el.getAttribute('style') 2434 }); 2435 } 2436 2437 function clearDisabledVisual(el) { 2438 if (!el) return; 2439 if (el.getAttribute('data-pp-admin-blocked') === '1') return; 2440 if (el.getAttribute('data-pp-webgl-pending') !== '1') return; 2441 el.classList.remove('pp-webgl-compat-disabled'); 2442 el.classList.remove('pp-webgl-3d-disabled'); 2443 el.removeAttribute('aria-disabled'); 2444 el.removeAttribute('data-pp-webgl-blocked'); 2445 el.removeAttribute('data-pp-index-actionbar-disabled'); 2446 el.removeAttribute('data-pp-webgl-pending'); 2447 if (el.id === 'toggle3DMap') {
2448 el.title = '3D Görünüme Geç'; 2449 } else if (el.id === 'pp-3d-editor-toolbar-link') { 2450 el.title = '3D Model Ekle (seçili parsel varsa ada/parsel taÅınır)'; 2451 } else if (el.id === 'pp-ne-yapilir-btn') { 2452 el.title = 'Proje OluÅtur â seçili parsel ile bina çiz'; 2453 } else if (el.id === 'pp-ai-drone-video-btn') { 2454 el.title = 'AI Drone Video â önce haritada parsel seçin veya sorgulayın'; 2455 } 2456 if (el.tagName === 'A') { 2457 var originalHref = el.getAttribute('data-pp-original-href') || (el.id === 'pp-ne-yapilir-btn' ? '/bina-ciz/' : '/3d-editor/'); 2458 el.setAttribute('href', originalHref); 2459 } 2460 [ 2461 'background', 2462 'background-image', 2463 'color', 2464 'border-color', 2465 'box-shadow', 2466 'text-shadow', 2467 'opacity', 2468 'filter', 2469 'cursor' 2470 ].forEach(function (prop) { 2471 try { el.style.removeProperty(prop); } catch (e) {} 2472 }); 2473 try { 2474 el.querySelectorAll('i,svg,span').forEach(function (child) { 2475 child.style.removeProperty('color'); 2476 child.style.removeProperty('fill'); 2477 }); 2478 } catch (e) {} 2479 debugLog('clear_disabled_for_supported_device', { 2480 id: el.id, 2481 className: el.className, 2482 href: el.getAttribute('href'), 2483 inlineStyle: el.getAttribute('style') 2484 }); 2485 } 2486 2487 function applyActionBarDisabled() { 2488 if (applyingActionBarState) return; 2489 applyingActionBarState = true; 2490 try { 2491 var anyBlocked = false; 2492 featureBlocks.forEach(function (item) { 2493 var el = document.querySelector(item.selector); 2494 if (!el) return; 2495 if (supportsFeature(item.feature)) { 2496 if (el.getAttribute('data-pp-admin-blocked') === '1') { 2497 setDisabledVisual(el); 2498 } else { 2499 clearDisabledVisual(el); 2500 } 2501 } else { 2502 anyBlocked = true; 2503 setDisabledVisual(el); 2504 } 2505 }); 2506 try { 2507 if (anyBlocked) { 2508 document.documentElement.classList.add('pp-webgl-compat-is-disabled'); 2509 document.body && document.body.classList.add('pp-webgl-compat-is-disabled'); 2510 } else { 2511 document.documentElement.classList.remove('pp-webgl-compat-is-disabled'); 2512 document.body && document.body.classList.remove('pp-webgl-compat-is-disabled'); 2513 } 2514 } catch (e) {} 2515 try { 2516 if (window.PPWebGLCompat && typeof window.PPWebGLCompat.update3DControls === 'function') window.PPWebGLCompat.update3DControls(); 2517 } catch (e) {} 2518 } finally { 2519 applyingActionBarState = false; 2520 } 2521 } 2522 2523 document.addEventListener('click', function (event) { 2524 var target = event.target && event.target.closest ? event.target.closest(featureBlocks.map(function (i) { return i.selector; }).join(',')) : null; 2525 if (!target) return; 2526 var block = null; 2527 featureBlocks.forEach(function (item) { 2528 if (!block && target.matches && target.matches(item.selector)) block = item; 2529 if (!block && target.closest && target.closest(item.selector)) block = item; 2530 }); 2531 if (!block || supportsFeature(block.feature)) return; 2532 event.preventDefault(); 2533 event.stopPropagation(); 2534 if (typeof event.stopImmediatePropagation === 'function') event.stopImmediatePropagation(); 2535 setDisabledVisual(target); 2536 showLegacyWarning(); 2537 }, true); 2538 2539 debugLog('inline_guard_loaded', { 2540 readyState: document.readyState, 2541 currentScript: document.currentScript ? document.currentScript.src : null, 2542 hasExternalGuard: !!window.PPWebGLCompat 2543 }); 2544 try { 2545 window.__PP_WEBGL_ACTIONBAR_GUARD_LOADED = true; 2546 window.__PP_WEBGL_ACTIONBAR_GUARD_VERSION = '20260520-per-feature-blocks'; 2547 } catch (e) {} 2548 window.__ppApplyActionBarWebglState = applyActionBarDisabled; 2549 applyActionBarDisabled(); 2550 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', applyActionBarDisabled); 2551 var runs = 0; 2552 var timer = window.setInterval(function () { 2553 runs += 1; 2554 applyActionBarDisabled(); 2555 if (runs > 30) window.clearInterval(timer); 2556 }, 300); 2557 try { 2558 new MutationObserver(applyActionBarDisabled).observe(document.getElementById('top-button-container') || document.body, { 2559 childList: true, 2560 subtree: true 2561 }); 2562 } catch (e) {} 2563 })(); 2564 </script>
2564 2565
2565<script> 2566 (function () { 2567 function _pv() { 2568 var d = window.lastParcelResponse || window.data_general; 2569 return (d && d.parameters_data && d.parameters_data.parcel_values) || {}; 2570 } 2571 function _props() { 2572 var d = window.lastParcelResponse || window.data_general; 2573 return (d && d.properties) || {}; 2574 } 2575 function _selectedMahalleTkgm() { 2576 try { 2577 var mhEl = document.getElementById('mahalle-select'); 2578 if (mhEl && mhEl.selectedIndex >= 0) { 2579 var opt = mhEl.options[mhEl.selectedIndex]; 2580 if (opt) { 2581 var tv = opt.getAttribute('data-tkgmvalue'); 2582 if (tv != null && String(tv).trim() !== '' && tv !== 'null' && tv !== 'undefined') { 2583 return String(tv).trim(); 2584 } 2585 } 2586 } 2587 } catch (e) {} 2588 return ''; 2589 } 2590 function resolveMahalleTkgm() { 2591 var pv = _pv(); 2592 var props = _props(); 2593 var tkgm = window.lastTkgmData && window.lastTkgmData.properties; 2594 var m = tkgm && (tkgm.mahalleId || tkgm.mahalle_id); 2595 if (m == null || m === '') { 2596 m = _selectedMahalleTkgm(); 2597 } 2598 if (m == null || m === '') { 2599 m = pv.mahalleId || props.mahalleId || pv.mahalle_id || props.mahalle_id; 2600 } 2601 m = String(m || '').trim(); 2602 return m; 2603 } 2604 /** processParcelData ile aynı kaynaklar + snake_case + çoklu parsel + sidebar input */ 2605 function _parcelValuesBundle() { 2606 var d = window.lastParcelResponse || window.data_general; 2607 if (!d || typeof d !== 'object') return null; 2608 var pd = d.parameters_data || {}; 2609 return ( 2610 pd.parcel_values || 2611 pd.parcel_dict || 2612 pd.parcelInfo || 2613 d.parcel_values || 2614 d.parcel_dict || 2615 d.parcelInfo || 2616 null 2617 ); 2618 } 2619 /** TKGM'de ada=0 geçerlidir; 0 veya "0" dolu sayılır (yalnızca null/undefined/boÅ deÄil) */ 2620 function parcelPartFilled(v) { 2621 if (v === undefined || v === null) return false; 2622 return String(v).trim() !== ''; 2623 } 2624 function firstParcelPart(parts) { 2625 for (var i = 0; i < parts.length; i++) { 2626 var v = parts[i]; 2627 if (parcelPartFilled(v)) return String(v).trim(); 2628 } 2629 return ''; 2630 } 2631 function _pickAdaParselFromObj(o) { 2632 if (!o || typeof o !== 'object') return { ada: '', parsel: '' }; 2633 var ada = o.adaNo != null && o.adaNo !== '' ? o.adaNo : (o.Ada != null && o.Ada !== '' ? o.Ada : (o.ada != null && o.ada !== '' ? o.ada : (o.ada_no != null && o.ada_no !== '' ? o.ada_no : ''))); 2634 var parsel = o.parselNo != null && o.parselNo !== '' ? o.parselNo : (o.Parsel != null && o.Parsel !== '' ? o.Parsel : (o.parsel != null && o.parsel !== '' ? o.parsel : (o.parsel_no != null && o.parsel_no !== '' ? o.parsel_no : ''))); 2635 return { ada: String(ada == null ? '' : ada).trim(), parsel: String(parsel == null ? '' : parsel).trim() }; 2636 } 2637 /** "10290/128" veya "0 / 12" gibi etiketlerden ada/parsel (harita katmanı sadece label tutabiliyor) */ 2638 function _parseAdaParselSlashLabel(s) { 2639 if (s == null) return { ada: '', parsel: '' }; 2640 var str = String(s).trim(); 2641 if (!str) return { ada: '', parsel: '' }; 2642 var m = str.match(/^(\d+)\s*\/\s*(\d+)\s*$/); 2643 if (m) return { ada: m[1], parsel: m[2] }; 2644 return { ada: '', parsel: '' }; 2645 } 2646 /** TKGM ozet: "Fadıllı-/116" â ada 0, parsel 116; veya içinde "945/12" geçen özetler */ 2647 function _parseAdaParselFromOzet(oz) { 2648 if (oz == null) return { ada: '', parsel: '' }; 2649 var s = String(oz).trim(); 2650 if (!s) return { ada: '', parsel: '' }; 2651 var m = s.match(/(\d+)\s*\/\s*(\d+)/); 2652 if (m) return { ada: m[1], parsel: m[2] }; 2653 m = s.match(/\/\s*(\d+)\s*$/); 2654 if (m) return { ada: '0', parsel: m[1] }; 2655 return { ada: '', parsel: '' }; 2656 } 2657 function _responseRoot() { 2658 var d = window.lastParcelResponse || window.data_general; 2659 return d && typeof d === 'object' ? d : null; 2660 } 2661 function _parcelPolygonFeatureProps() { 2662 try { 2663 var d = _responseRoot(); 2664 var fc = d && d.parameters_polygons && d.parameters_polygons.parcel_polygon; 2665 var feats = fc && fc.features; 2666 if (!feats || !feats.length) return null; 2667 var p = feats[0] && feats[0].properties; 2668 return p && typeof p === 'object' ? p : null; 2669 } catch (e) { 2670 return null; 2671 } 2672 } 2673 function _globalParcelPolygonProps() {
2674 try { 2675 var gl = window.globalLayers && window.globalLayers['parcel_polygon']; 2676 return gl && gl.properties && typeof gl.properties === 'object' ? gl.properties : null; 2677 } catch (e) { 2678 return null; 2679 } 2680 } 2681 function resolveParcelAreaM2() { 2682 try { 2683 var tkgm = window.lastTkgmData && window.lastTkgmData.properties; 2684 if (tkgm && (tkgm.alan != null || tkgm.ALAN != null)) { 2685 var a = tkgm.alan != null ? tkgm.alan : tkgm.ALAN; 2686 if (a != null && String(a).trim() !== '') return String(a).trim(); 2687 } 2688 } catch (e0) {} 2689 try { 2690 var bundle = _parcelValuesBundle(); 2691 if (bundle && bundle.alan != null && String(bundle.alan).trim() !== '') return String(bundle.alan).trim(); 2692 } catch (e1) {} 2693 return ''; 2694 } 2695 function resolveAdaParsel() { 2696 var partsAda = []; 2697 var partsParsel = []; 2698 var adaEl = document.getElementById('ada-input'); 2699 var parselEl = document.getElementById('parsel-input'); 2700 if (adaEl) partsAda.push(adaEl.value); 2701 if (parselEl) partsParsel.push(parselEl.value); 2702 var tkgm = window.lastTkgmData && window.lastTkgmData.properties; 2703 if (tkgm) { 2704 var p3 = _pickAdaParselFromObj(tkgm); 2705 partsAda.push(p3.ada); 2706 partsParsel.push(p3.parsel); 2707 var ozT = _parseAdaParselFromOzet(tkgm.ozet || tkgm.Ozet); 2708 partsAda.push(ozT.ada); 2709 partsParsel.push(ozT.parsel); 2710 } 2711 var glp = _globalParcelPolygonProps(); 2712 if (glp) { 2713 var pG = _pickAdaParselFromObj(glp); 2714 partsAda.push(pG.ada); 2715 partsParsel.push(pG.parsel); 2716 var slashG = _parseAdaParselSlashLabel(glp.AdaParsel || glp.adaParsel || glp.label); 2717 partsAda.push(slashG.ada); 2718 partsParsel.push(slashG.parsel); 2719 var ozG = _parseAdaParselFromOzet(glp.ozet || glp.Ozet); 2720 partsAda.push(ozG.ada); 2721 partsParsel.push(ozG.parsel); 2722 } 2723 try { 2724 if (window.multipleParcels && window.multipleParcels.length) { 2725 var last = window.multipleParcels[window.multipleParcels.length - 1]; 2726 if (last && last.properties) { 2727 var p4 = _pickAdaParselFromObj(last.properties); 2728 partsAda.push(p4.ada); 2729 partsParsel.push(p4.parsel); 2730 var slashM = _parseAdaParselSlashLabel(last.properties.AdaParsel || last.properties.adaParsel || last.properties.label); 2731 partsAda.push(slashM.ada); 2732 partsParsel.push(slashM.parsel); 2733 } 2734 } 2735 } catch (e) {} 2736 var bundle = _parcelValuesBundle(); 2737 if (bundle) { 2738 var p0 = _pickAdaParselFromObj(bundle); 2739 partsAda.push(p0.ada); 2740 partsParsel.push(p0.parsel); 2741 } 2742 var p1 = _pickAdaParselFromObj(_pv()); 2743 partsAda.push(p1.ada); 2744 partsParsel.push(p1.parsel); 2745 partsAda.push(_pickAdaParselFromObj(_props()).ada); 2746 partsParsel.push(_pickAdaParselFromObj(_props()).parsel); 2747 var polyProps = _parcelPolygonFeatureProps(); 2748 if (polyProps) { 2749 var pPoly = _pickAdaParselFromObj(polyProps); 2750 partsAda.push(pPoly.ada); 2751 partsParsel.push(pPoly.parsel); 2752 var slashP = _parseAdaParselSlashLabel(polyProps.AdaParsel || polyProps.adaParsel || polyProps.label); 2753 partsAda.push(slashP.ada); 2754 partsParsel.push(slashP.parsel); 2755 var ozP = _parseAdaParselFromOzet(polyProps.ozet || polyProps.Ozet); 2756 partsAda.push(ozP.ada); 2757 partsParsel.push(ozP.parsel); 2758 } 2759 try { 2760 var root = _responseRoot(); 2761 var pd = root && root.parameters_data; 2762 if (pd && pd.parcel && typeof pd.parcel === 'object') { 2763 var pParcel = _pickAdaParselFromObj(pd.parcel); 2764 partsAda.push(pParcel.ada); 2765 partsParsel.push(pParcel.parsel); 2766 } 2767 if (root && root.parcel && typeof root.parcel === 'object') { 2768 var pRoot = _pickAdaParselFromObj(root.parcel); 2769 partsAda.push(pRoot.ada); 2770 partsParsel.push(pRoot.parsel); 2771 } 2772 } catch (e2) {} 2773 var adaOut = firstParcelPart(partsAda); 2774 var parselOut = firstParcelPart(partsParsel);
2775 try { 2776 var pr = _props(); 2777 var pvOz = _pv(); 2778 var ozPr = _parseAdaParselFromOzet((pr && (pr.ozet || pr.Ozet)) || (pvOz && (pvOz.ozet || pvOz.Ozet))); 2779 if (!parcelPartFilled(adaOut) && parcelPartFilled(ozPr.ada)) adaOut = ozPr.ada; 2780 if (!parcelPartFilled(parselOut) && parcelPartFilled(ozPr.parsel)) parselOut = ozPr.parsel; 2781 } catch (eOz) {} 2782 /* TKGM çoÄu kaynakta adaNo "" döner; parsel tek baÅına geçerliyse ada=0 (tapu/TKGM uyumu) */ 2783 if (!parcelPartFilled(adaOut) && parcelPartFilled(parselOut)) { 2784 adaOut = '0'; 2785 } 2786 return { ada: adaOut, parsel: parselOut }; 2787 } 2788 window.build3dEditorUrlFromParcel = function () { 2789 var m = resolveMahalleTkgm(); 2790 var ap = resolveAdaParsel(); 2791 var editorQs = []; 2792 /* mahalle TKGM yokken bile ada/parsel taÅınmalı (lisans sayfası GET ile dolar) */ 2793 if (parcelPartFilled(m)) { 2794 editorQs.push('mahalle=' + encodeURIComponent(m)); 2795 } 2796 if (parcelPartFilled(ap.ada) && parcelPartFilled(ap.parsel)) { 2797 editorQs.push('ada=' + encodeURIComponent(ap.ada)); 2798 editorQs.push('parsel=' + encodeURIComponent(ap.parsel)); 2799 } 2800 var ilEl = document.getElementById('il-select'); 2801 var ilceEl = document.getElementById('ilce-select'); 2802 var mhEl = document.getElementById('mahalle-select'); 2803 if (ilEl && ilEl.value) editorQs.push('city_id=' + encodeURIComponent(ilEl.value)); 2804 if (ilceEl && ilceEl.value) editorQs.push('town_id=' + encodeURIComponent(ilceEl.value)); 2805 if (mhEl && mhEl.value) editorQs.push('quarter_id=' + encodeURIComponent(mhEl.value)); 2806 return editorQs.length ? '/3d-editor/?' + editorQs.join('&') : '/3d-editor/'; 2807 }; 2808 function bindToolbar3dLink() { 2809 var a = document.getElementById('pp-3d-editor-toolbar-link'); 2810 if (!a) return; 2811 a.addEventListener('click', function () { 2812 a.href = window.build3dEditorUrlFromParcel(); 2813 }); 2814 } 2815 /** Ekranda çizili / seçili parsel var mı (çoklu veya tek parsel poligonu). */ 2816 window.ppHasParcelDrawableOnMap = function ppHasParcelDrawableOnMap() { 2817 try { 2818 if (window.multipleParcels && window.multipleParcels.length > 0) return true; 2819 } catch (e0) {} 2820 try { 2821 var d = window.lastParcelResponse || window.data_general; 2822 var fc = d && d.parameters_polygons && d.parameters_polygons.parcel_polygon; 2823 if (fc && fc.features && fc.features.length > 0) return true; 2824 } catch (e1) {} 2825 try { 2826 var m = resolveMahalleTkgm(); 2827 var ap = resolveAdaParsel(); 2828 if (parcelPartFilled(m) && parcelPartFilled(ap.ada) && parcelPartFilled(ap.parsel)) return true; 2829 } catch (e2) {} 2830 return false; 2831 } 2832 window.buildAiDroneVideoPurchaseUrlFromParcel = function () { 2833 var ilEl = document.getElementById('il-select'); 2834 var ilceEl = document.getElementById('ilce-select'); 2835 var mhEl = document.getElementById('mahalle-select'); 2836 var adaEl = document.getElementById('ada-input'); 2837 var parselEl = document.getElementById('parsel-input'); 2838 // ÃNCELİK: Son baÅarılı sorgu yanıtındaki gerçek mahalleId (parsel bilgi kartında görünen). 2839 // Kaynak sırası: lastTkgmData.properties â lastParcelResponse.properties â 2840 // lastParcelResponse.parameters_data.parcel_values â globalLayers parcel feature â 2841 // dropdown data-tkgmvalue. 2842 function pickStr(o, keys) { 2843 if (!o || typeof o !== 'object') return ''; 2844 for (var i = 0; i < keys.length; i++) { 2845 var v = o[keys[i]]; 2846 if (v != null && String(v).trim() !== '' && String(v).trim() !== 'null' && String(v).trim() !== 'undefined') { 2847 return String(v).trim(); 2848 } 2849 } 2850 return ''; 2851 } 2852 var diag = { sources: [] }; 2853 var m = ''; 2854 var ap = { ada: '', parsel: '' }; 2855 var tkgmKeys = ['mahalleId', 'mahalle_id', 'mahalle_tkgm_value', 'tkgm_value', 'MahalleId']; 2856 var adaKeys = ['adaNo', 'Ada', 'ada', 'ada_no']; 2857 var parselKeys = ['parselNo', 'Parsel', 'parsel', 'parsel_no']; 2858 function tryFill(label, obj) { 2859 if (!obj || typeof obj !== 'object') return; 2860 diag.sources.push(label); 2861 if (!m) m = pickStr(obj, tkgmKeys); 2862 if (!ap.ada) ap.ada = pickStr(obj, adaKeys); 2863 if (!ap.parsel) ap.parsel = pickStr(obj, parselKeys); 2864 }
2865 try { tryFill('lastTkgmData.properties', window.lastTkgmData && window.lastTkgmData.properties); } catch (e) {} 2866 try { tryFill('lastParcelResponse.properties', window.lastParcelResponse && window.lastParcelResponse.properties); } catch (e) {} 2867 try { tryFill('lastParcelResponse.parameters_data.parcel_values', window.lastParcelResponse && window.lastParcelResponse.parameters_data && window.lastParcelResponse.parameters_data.parcel_values); } catch (e) {} 2868 try { tryFill('data_general.properties', window.data_general && window.data_general.properties); } catch (e) {} 2869 try { tryFill('data_general.parameters_data.parcel_values', window.data_general && window.data_general.parameters_data && window.data_general.parameters_data.parcel_values); } catch (e) {} 2870 try { 2871 var glProps = window.globalLayers && window.globalLayers['parcel_polygon'] && window.globalLayers['parcel_polygon'].properties; 2872 tryFill('globalLayers.parcel_polygon.properties', glProps); 2873 } catch (e) {} 2874 try { 2875 var ppFc = window.lastParcelResponse && window.lastParcelResponse.parameters_polygons && window.lastParcelResponse.parameters_polygons.parcel_polygon; 2876 var firstFeat = ppFc && ppFc.features && ppFc.features[0] && ppFc.features[0].properties; 2877 tryFill('lastParcelResponse.parameters_polygons.parcel_polygon[0].properties', firstFeat); 2878 } catch (e) {} 2879 var dropdownTkgm = ''; 2880 try { 2881 if (mhEl && mhEl.selectedOptions && mhEl.selectedOptions.length) { 2882 dropdownTkgm = mhEl.selectedOptions[0].getAttribute('data-tkgmvalue') || ''; 2883 } 2884 } catch (eDd) {} 2885 if (!m && dropdownTkgm) m = String(dropdownTkgm).trim(); 2886 if (!ap.ada && adaEl) ap.ada = String(adaEl.value || '').trim(); 2887 if (!ap.parsel && parselEl) ap.parsel = String(parselEl.value || '').trim(); 2888 diag.resolved = { mahalleTkgm: m, ada: ap.ada, parsel: ap.parsel, dropdownTkgm: dropdownTkgm }; 2889 try { console.info('[buildAiDroneVideoPurchaseUrl] resolved', diag); } catch (e) {} 2890 // Admin ID'ler (city_id/town_id/quarter_id) kullanıcının dropdown'dan seçtiÄi 2891 // proparcel admin DB ID'leri; bunlar TKGM mahalleId'den baÄımsız ve hep doÄru. 2892 // Resolver canonical mahalleId'yi dropdown'dakinden farklı belirleyebilir 2893 // (örn. "Ãksülü Mh." â dropdown 156936, canonical 156978) â bu durum admin 2894 // ID'lerin doÄruluÄunu etkilemez. ÃNCE GÃNDERMEMEK satın alma sayfasını 2895 // O(NÃMÃK) prefill loop'una düÅürüp yüzlerce gereksiz quarters/?TownId= 2896 // isteÄi yapmasına neden oluyordu. Bu yüzden adminIdsTrusted koÅulunu 2897 // kaldırıyoruz â admin ID'ler ne olursa olsun gönderilmeli. 2898 var editorQs = []; 2899 if (parcelPartFilled(m)) { 2900 editorQs.push('mahalle=' + encodeURIComponent(m)); 2901 } 2902 if (parcelPartFilled(ap.ada) && parcelPartFilled(ap.parsel)) { 2903 editorQs.push('ada=' + encodeURIComponent(ap.ada)); 2904 editorQs.push('parsel=' + encodeURIComponent(ap.parsel)); 2905 } 2906 // Görünen mahalle / il / ilçe adları (TKGM id yerine isim) 2907 var mahalleName = ''; 2908 try { 2909 var propsName = 2910 (window.lastTkgmData && window.lastTkgmData.properties) || 2911 (window.lastParcelResponse && window.lastParcelResponse.properties) || 2912 {}; 2913 mahalleName = String(propsName.mahalleAd || propsName.mahalle || '').trim(); 2914 var cityName = String(propsName.ilAd || propsName.il_ad || '').trim(); 2915 var districtName = String(propsName.ilceAd || propsName.ilce_ad || '').trim(); 2916 if (!mahalleName && mhEl && mhEl.selectedOptions && mhEl.selectedOptions.length) { 2917 mahalleName = String(mhEl.selectedOptions[0].textContent || '').trim(); 2918 } 2919 if (!cityName && ilEl && ilEl.selectedOptions && ilEl.selectedOptions.length) { 2920 cityName = String(ilEl.selectedOptions[0].textContent || '').trim(); 2921 } 2922 if (!districtName && ilceEl && ilceEl.selectedOptions && ilceEl.selectedOptions.length) { 2923 districtName = String(ilceEl.selectedOptions[0].textContent || '').trim(); 2924 } 2925 if (mahalleName) editorQs.push('mahalle_name=' + encodeURIComponent(mahalleName)); 2926 if (cityName) editorQs.push('city=' + encodeURIComponent(cityName)); 2927 if (districtName) editorQs.push('district=' + encodeURIComponent(districtName)); 2928 } catch (eName) {} 2929 if (ilEl && ilEl.value) editorQs.push('city_id=' + encodeURIComponent(ilEl.value)); 2930 if (ilceEl && ilceEl.value) editorQs.push('town_id=' + encodeURIComponent(ilceEl.value)); 2931 if (mhEl && mhEl.value) editorQs.push('quarter_id=' + encodeURIComponent(mhEl.value));
2932 try { 2933 var pv = 2934 (mhEl && mhEl.selectedOptions && mhEl.selectedOptions[0] && mhEl.selectedOptions[0].getAttribute('data-proparcel')) || 2935 (mhEl && mhEl.value) || 2936 ''; 2937 if (pv) editorQs.push('proparcel_value=' + encodeURIComponent(String(pv).trim())); 2938 } catch (ePv) {} 2939 var areaM2 = resolveParcelAreaM2(); 2940 if (areaM2) editorQs.push('parcel_area=' + encodeURIComponent(areaM2)); 2941 editorQs.push('fresh_map_start=1'); 2942 editorQs.push('v=' + encodeURIComponent(String(Date.now()))); 2943 var dronePath = editorQs.length ? '/portal/ai-drone/?' + editorQs.join('&') : '/portal/ai-drone/'; 2944 var purchaseQs = ['next=' + encodeURIComponent(dronePath), 'target=drone_video']; 2945 if (parcelPartFilled(m)) { 2946 purchaseQs.push('mahalle=' + encodeURIComponent(m)); 2947 } 2948 if (parcelPartFilled(ap.ada) && parcelPartFilled(ap.parsel)) { 2949 purchaseQs.push('ada=' + encodeURIComponent(ap.ada)); 2950 purchaseQs.push('parsel=' + encodeURIComponent(ap.parsel)); 2951 } 2952 if (mahalleName) purchaseQs.push('mahalle_name=' + encodeURIComponent(mahalleName)); 2953 try { 2954 if (cityName) purchaseQs.push('city=' + encodeURIComponent(cityName)); 2955 if (districtName) purchaseQs.push('district=' + encodeURIComponent(districtName)); 2956 } catch (eBuy) {} 2957 if (ilEl && ilEl.value) purchaseQs.push('city_id=' + encodeURIComponent(ilEl.value)); 2958 if (ilceEl && ilceEl.value) purchaseQs.push('town_id=' + encodeURIComponent(ilceEl.value)); 2959 if (mhEl && mhEl.value) purchaseQs.push('quarter_id=' + encodeURIComponent(mhEl.value)); 2960 if (areaM2) purchaseQs.push('parcel_area=' + encodeURIComponent(areaM2)); 2961 return '/accounts/3d-editor-purchase/?' + purchaseQs.join('&'); 2962 }; 2963 function bindAiDroneVideoToolbarBtn() { 2964 var btn = document.getElementById('pp-ai-drone-video-btn'); 2965 if (!btn) return; 2966 btn.addEventListener('click', function () { 2967 if (btn.getAttribute('data-pp-webgl-blocked') === '1' || btn.getAttribute('aria-disabled') === 'true') { 2968 return; 2969 } 2970 if (!ppHasParcelDrawableOnMap()) { 2971 alert('Ãnce haritada parsel seçin veya parsel sorgusu yapın.'); 2972 return; 2973 } 2974 window.location.href = window.buildAiDroneVideoPurchaseUrlFromParcel(); 2975 }); 2976 } 2977 if (document.readyState === 'loading') { 2978 document.addEventListener('DOMContentLoaded', bindToolbar3dLink); 2979 document.addEventListener('DOMContentLoaded', bindAiDroneVideoToolbarBtn); 2980 } else { 2981 bindToolbar3dLink(); 2982 bindAiDroneVideoToolbarBtn(); 2983 } 2984 })(); 2985 </script>
2985 2986 2987 <!-- MAIN CONTENT --> 2988 <main class="pp-main" id="main-content"> 2989 <!-- HARİTA ALANI --> 2990 <div class="pp-map-container" id="mapArea"> 2991 <!-- Map container (Mapbox GL JS used for both 2D(flat) and 3D) --> 2992 <div class="pp-map" id="map3D"> 2993 <div id="pp-static-map-backdrop" aria-hidden="true" style="position:absolute;inset:0;z-index:1;background:#93c5fd;background-image:radial-gradient(circle at 18% 24%, rgba(34,197,94,.58) 0 9%, transparent 10%),radial-gradient(circle at 78% 34%, rgba(34,197,94,.52) 0 13%, transparent 14%),radial-gradient(circle at 42% 72%, rgba(34,197,94,.45) 0 16%, transparent 17%),linear-gradient(135deg,#bfdbfe 0%,#93c5fd 46%,#60a5fa 100%);"> 2994 <div style="position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);padding:10px 14px;border-radius:999px;background:rgba(15,23,42,.78);color:#fff;font:600 14px Arial,sans-serif;white-space:nowrap;">2D uydu harita yükleniyor...</div> 2995 </div> 2996 <iframe 2997 id="pp-static-leaflet-fallback" 2998 title="Uydu 2D Harita" 2999 srcdoc="<!doctype html><html><head><meta charset='utf-8'><meta name='viewport' content='width=device-width,initial-scale=1'><link rel='stylesheet' href='https://unpkg.com/[email protected]/dist/leaflet.css'><style>html,body,#map{margin:0;width:100%;height:100%;background:#e5e7eb}body:before{content:'Uydu harita yükleniyor...';position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);font:14px Arial,sans-serif;color:#475569;z-index:0}#map{position:relative;z-index:1}</style></head><body><div id='map'></div>
2999<script src='https://unpkg.com/[email protected]/dist/leaflet.js'><\/script>
2999<script>(function(){try{var map=L.map('map',{zoomControl:true,attributionControl:true,preferCanvas:true}).setView([39,35],6);L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',{maxZoom:19,attribution:'Tiles © Esri'}).addTo(map);map.on('click',function(e){try{parent.postMessage({type:'PP_STATIC_LEAFLET_FALLBACK_CLICK',lat:e.latlng.lat,lng:e.latlng.lng},'*')}catch(_){}});setTimeout(function(){try{map.invalidateSize()}catch(_){}} ,100)}catch(e){document.body.innerHTML='<div style="padding:24px;font:14px Arial,sans-serif;color:#334155;background:#e5e7eb;height:100%;box-sizing:border-box;">2D uydu harita baÅlatılamadı.</div>'}})();<\/script></body></html>" 3000 style="position:absolute;inset:0;width:100%;height:100%;border:0;background:#e5e7eb;z-index:2;" 3001 loading="eager" 3002 referrerpolicy="no-referrer-when-downgrade" 3003 ></iframe> 3004 <div id="pp-static-satellite-tiles" aria-hidden="true" style="position:absolute;inset:0;z-index:3;pointer-events:none;background:#1f2937;overflow:hidden;"> 3005 <img alt="" src="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/6/23/37" style="position:absolute;left:0;top:0;width:50%;height:50%;object-fit:cover;"> 3006 <img alt="" src="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/6/23/38" style="position:absolute;left:50%;top:0;width:50%;height:50%;object-fit:cover;"> 3007 <img alt="" src="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/6/24/37" style="position:absolute;left:0;top:50%;width:50%;height:50%;object-fit:cover;"> 3008 <img alt="" src="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/6/24/38" style="position:absolute;left:50%;top:50%;width:50%;height:50%;object-fit:cover;"> 3009 <div style="position:absolute;right:12px;bottom:10px;padding:5px 8px;border-radius:6px;background:rgba(15,23,42,.72);color:#fff;
3009font:12px Arial,sans-serif;">2D uydu harita</div> 3010 </div> 3011 </div> 3012
3012<script> 3013 (function () { 3014 try { 3015 if (window.__PP_HIDE_STATIC_MAP_FALLBACK) { 3016 var fallbackIds = ['pp-static-map-backdrop', 'pp-static-leaflet-fallback', 'pp-static-satellite-tiles']; 3017 for (var f = 0; f < fallbackIds.length; f += 1) { 3018 var fallbackEl = document.getElementById(fallbackIds[f]); 3019 if (fallbackEl && fallbackEl.parentNode) fallbackEl.parentNode.removeChild(fallbackEl); 3020 } 3021 } 3022 if (!window.__PP_STATIC_LEAFLET_HIDE_BOUND) { 3023 window.__PP_STATIC_LEAFLET_HIDE_BOUND = true; 3024 window.addEventListener('message', function (event) { 3025 try { 3026 var data = event && event.data; 3027 if (!data || data.type !== 'PP_STATIC_LEAFLET_READY') return; 3028 var staticTiles = document.getElementById('pp-static-satellite-tiles'); 3029 if (staticTiles) staticTiles.style.display = 'none'; 3030 } catch (e) {} 3031 }); 3032 } 3033 var loadingContainer = document.getElementById('loading-container'); 3034 if (loadingContainer) loadingContainer.style.display = 'none'; 3035 var loadingOverlay = document.getElementById('loading-overlay'); 3036 if (loadingOverlay) loadingOverlay.style.display = 'none'; 3037 var proLoader = document.getElementById('pp-loader-overlay'); 3038 if (proLoader) proLoader.style.display = 'none'; 3039 var proLoaderBg = document.getElementById('pp-loader-bg3d'); 3040 if (proLoaderBg) proLoaderBg.style.display = 'none'; 3041 var map3d = document.getElementById('map3D'); 3042 if (map3d) { 3043 map3d.style.background = '#e5e7eb'; 3044 } 3045 if (typeof window.__PP_INIT_LEGACY_LEAFLET_MAP === 'function') { 3046 window.__PP_INIT_LEGACY_LEAFLET_MAP(); 3047 } 3048 } catch (e) {} 3049 })(); 3050 </script>
3050 3051 3052
3052<script> 3053 window.__ppLoaderAutoShow = false; 3054 window.__PP_DISABLE_LOADER_WEBGL = false; 3055 window.__PP_FORCE_DISABLE_LOADER_WEBGL = false; 3056 window.__ppUseAnimatedLoader = false; 3057 </script>
3057 3058 3059 <!-- City3D Statik Overlay (body sonuna taÅındı) --> 3060 <!-- 3D Kamera Kontrol Paneli --> 3061 <div class="pp-camera-controls" id="cameraControlPanel"> 3062 <div class="cam-dpad"> 3063 <button id="turnerBtnLeft" class="cam-btn cam-turn-left 2dDisabled" title="Ters Döndür"><i 3064 class="fa fa-refresh"></i></button> 3065 <button class="cam-btn cam-up 2dDisabled" data-action="pitch-up" title="Yukarı"><i 3066 class="fa fa-chevron-up"></i></button> 3067 <button id="turnerBtnRight" class="cam-btn cam-turn-right 2dDisabled" title="Döndür"><i 3068 class="fa fa-refresh"></i></button> 3069 3070 <button class="cam-btn cam-left 2dDisabled" data-action="bearing-left" title="Sola"><i 3071 class="fa fa-chevron-left"></i></button> 3072 <div class="center-col"> 3073 <button class="cam-btn cam-zoom-in 2dDisabled" data-action="zoom-in" 3074 title="YakınlaÅtır"><span>+</span></button> 3075 <button class="cam-btn cam-zoom-out 2dDisabled" data-action="zoom-out" 3076 title="UzaklaÅtır"><span>-</span></button> 3077 </div> 3078 <button class="cam-btn cam-right 2dDisabled" data-action="bearing-right" title="SaÄa"><i 3079 class="fa fa-chevron-right"></i></button> 3080 3081 <button class="cam-btn cam-down 2dDisabled" data-action="pitch-down" title="AÅaÄı"><i 3082 class="fa fa-chevron-down"></i></button> 3083 <!-- Alt köÅe butonları: Konum ve Tam Ekran (simetrik yerleÅim) --> 3084 <button id="camGeolocateBtn" class="cam-btn cam-bottom-left" title="Konumuma Git" aria-label="Konumuma Git"><i 3085 class="fas fa-crosshairs" style="font-size:12px;"></i></button> 3086 <button id="camFullscreenBtn" class="cam-btn cam-bottom-right" title="Tam Ekran" aria-label="Tam Ekran"><i 3087 class="fa fa-expand" style="font-size:12px;"></i></button> 3088 </div> 3089 </div> 3090 </div> 3091 3092 <!-- Görüntü Al overlay (mobildeki gibi onay + fiyat) --> 3093 <div id="pp-capture-overlay" class="pp-capture-overlay" aria-hidden="true"> 3094 <div class="pp-capture-overlay__mask" id="pp-capture-mask"></div> 3095 <div class="pp-capture-overlay__frame" id="pp-capture-frame"></div> 3096 <button type="button" class="pp-capture-overlay__cancel" id="pp-capture-cancel" aria-label="İptal"> 3097 <i class="fas fa-times"></i> 3098 <span>İptal</span> 3099 </button> 3100 <div class="pp-capture-overlay__panel"> 3101 <div class="pp-capture-overlay__price-title">Gönderide görünecek fiyat bilgisini giriniz.</div> 3102 <input type="text" class="pp-capture-overlay__price-input" id="pp-capture-price-input" 3103 placeholder="örn: 1.250.000" inputmode="numeric" autocomplete="off"> 3104 <div class="pp-capture-overlay__meta"> 3105 <div class="pp-capture-overlay__meta-item"> 3106 <div class="pp-capture-overlay__meta-label">Birim Fiyat</div> 3107 <div class="pp-capture-overlay__meta-value" id="pp-capture-unit">-</div> 3108 </div> 3109 <div class="pp-capture-overlay__meta-item"> 3110 <div class="pp-capture-overlay__meta-label">Alan</div> 3111 <div class="pp-capture-overlay__meta-value" id="pp-capture-area">-</div> 3112 </div> 3113 <div class="pp-capture-overlay__meta-item"> 3114 <div class="pp-capture-overlay__meta-label">Toplam</div> 3115 <div class="pp-capture-overlay__meta-value" id="pp-capture-total">-</div> 3116 </div> 3117 </div> 3118 <div id="pp-capture-login-hint" class="pp-capture-overlay__login-hint" style="display:none;"> 3119 GiriÅ yaparak coin kazanabilirsiniz. 3120 </div> 3121 <div class="pp-capture-overlay__buttons"> 3122 <button type="button" class="pp-capture-overlay__btn pp-capture-overlay__btn--cancel" id="pp-capture-btn-cancel">İptal</button> 3123 <button type="button" class="pp-capture-overlay__btn pp-capture-overlay__btn--confirm" id="pp-capture-btn-confirm"> 3124 <i class="fas fa-check"></i> 3125 Onayla 3126 </button> 3127 </div> 3128 </div> 3129 <div class="pp-capture-overlay__loading" id="pp-capture-loading"> 3130 <div class="pp-capture-overlay__loading-inner"> 3131 <div class="spinner-border text-light" role="status" aria-label="Yükleniyor"></div> 3132 <div>Ekran Görüntüsü Hazırlanıyor</div> 3133 </div> 3134 </div> 3135 </div> 3136 </main> 3137 3138 3139 3140 <!-- HARITA ALTI İÃERİK KONTEYNER -->
3141 <div id="below-map-content" class="below-map-container"> 3142 <!-- Harita ve alt content arası boÅluk --> 3143 <div style="height: 20px;"></div> 3144 3145 <!-- Küçük mini yükleniyor kutusu --> 3146 <div id="map-loading-toast"> 3147 <div class="map-toast-inner"> 3148 <div class="spinner-border spinner-border-sm text-light" role="status"></div> 3149 <span class="ms-2">Parsel sorgulanıyor...</span> 3150 </div> 3151 </div> 3152 3153 3154 3155 <!-- Gizli info paneli --> 3156 <div id="info" style="display:none;"> 3157 <h2>Parsel Bilgileri</h2> 3158 <p id="parcel_info">Parsel bilgileri burada görünecek...</p> 3159 3160 3161 </div> 3162 3163 <style> 3164 .info-card { 3165 transition: box-shadow 0.2s; 3166 } 3167 3168 .info-card:hover { 3169 box-shadow: 0 4px 16px rgba(0, 0, 0, 0.13); 3170 z-index: 2; 3171 } 3172 3173 /* Index: bilgi kartında radius kaldır */ 3174 #info { 3175 border-radius: 0 !important; 3176 display: none !important; 3177 } 3178 3179 /* Dikey baÅlık stilleri */ 3180 .vertical-title { 3181 display: flex; 3182 flex-direction: column; 3183 align-items: center; 3184 justify-content: center; 3185 min-width: 80px; 3186 height: 120px; 3187 writing-mode: vertical-rl; 3188 text-orientation: mixed; 3189 transform: rotate(180deg); 3190 border-right: 2px solid #e0e0e0; 3191 padding-right: 15px; 3192 } 3193 3194 .vertical-title .title-text { 3195 font-weight: 600; 3196 font-size: 14px; 3197 color: #333; 3198 margin-bottom: 8px; 3199 } 3200 3201 .vertical-title .title-value { 3202 font-weight: bold; 3203 font-size: 16px; 3204 color: #1e3a8a; 3205 background: rgba(30, 58, 138, 0.1); 3206 padding: 4px 8px; 3207 border-radius: 6px; 3208 min-width: 50px; 3209 text-align: center; 3210 } 3211 3212 /* Yatay içerik stilleri */ 3213 .horizontal-content { 3214 display: flex; 3215 flex-direction: column; 3216 justify-content: center; 3217 min-height: 120px; 3218 } 3219 3220 /* Kamera Paneli Stilleri */ 3221 #cameraControlPanel .camera-grid { 3222 display: grid; 3223 grid-template-columns: 1fr auto 1fr; 3224 gap: 8px; 3225 justify-items: center; 3226 margin-bottom: 6px; 3227 background: rgba(20, 20, 20, 0.38); 3228 border: 1px solid rgba(255, 255, 255, 0.22); 3229 padding: 6px 8px; 3230 border-radius: 10px; 3231 backdrop-filter: blur(4px); 3232 } 3233 3234 /* D-Pad yerleÅimi */ 3235 #cameraControlPanel .cam-dpad { 3236 position: relative; 3237 width: 170px; 3238 height: 170px; 3239 background: rgba(20, 20, 20, 0.38); 3240 border: 1px solid rgba(255, 255, 255, 0.22); 3241 border-radius: 16px; 3242 backdrop-filter: blur(4px); 3243 display: grid; 3244 grid-template-rows: 1fr 1fr 1fr; 3245 grid-template-columns: 1fr 1fr 1fr; 3246 align-items: center; 3247 justify-items: center; 3248 gap: 6px; 3249 padding: 10px; 3250 } 3251 3252 #cameraControlPanel .center-col { 3253 grid-row: 2; 3254 grid-column: 2; 3255 display: grid; 3256 gap: 6px; 3257 } 3258 3259 #cameraControlPanel .cam-up { 3260 grid-row: 1; 3261 grid-column: 2; 3262 } 3263 3264 #cameraControlPanel .cam-down { 3265 grid-row: 3; 3266 grid-column: 2; 3267 } 3268 3269 #cameraControlPanel .cam-left { 3270 grid-row: 2; 3271 grid-column: 1; 3272 } 3273 3274 #cameraControlPanel .cam-right { 3275 grid-row: 2; 3276 grid-column: 3; 3277 } 3278 3279 #cameraControlPanel .cam-turn-left { 3280 grid-row: 1; 3281 grid-column: 1; 3282 } 3283 3284 #cameraControlPanel .cam-turn-right { 3285 grid-row: 1; 3286 grid-column: 3; 3287 } 3288 3289 #cameraControlPanel .cam-btn { 3290 width: 32px; 3291 height: 32px; 3292 border-radius: 8px; 3293 border: 1px solid rgba(255, 255, 255, 0.35); 3294 background: rgba(255, 255, 255, 0.22); 3295 color: #fff; 3296 display: flex; 3297 align-items: center; 3298 justify-content: center; 3299 cursor: pointer; 3300 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18); 3301 transition: transform 0.08s ease, background 0.2s ease; 3302 user-select: none; 3303 } 3304 3305 #cameraControlPanel .cam-btn:hover { 3306 background: rgba(255, 255, 255, 0.32); 3307 } 3308 3309 #cameraControlPanel .cam-btn:active { 3310 transform: scale(0.96); 3311 } 3312 3313 #cameraControlPanel .cam-bottom-left { 3314 grid-row: 3; 3315 grid-column: 1; 3316 } 3317 3318 #cameraControlPanel .cam-bottom-right { 3319 grid-row: 3; 3320 grid-column: 3; 3321 } 3322 3323 /* Tools toggle buttons equal width */ 3324 .tools-toggle { 3325 width: 100%; 3326 display: inline-flex; 3327 align-items: center; 3328 gap: 8px; 3329 justify-content: flex-start; 3330 } 3331 3332 /* Smooth collapse containers */ 3333 .collapse-container { 3334 display: none; 3335 overflow: hidden; 3336 max-height: 0; 3337 transition: max-height 260ms ease; 3338 } 3339 </style> 3340 3341 </div> <!-- below-map-content container end --> 3342 </div> 3343 3344 <!-- Sidebar Overlay kaldırıldı - haritaya tıklanabilmeli --> 3345 3346 <!-- Sol Sidebar Paneli --> 3347 <aside id="sidebar" class="pp-sidebar sidebar"> 3348 <!-- Sekme seçici â sidebar form alanlarıyla uyumlu dropdown --> 3349 <div class="pp-sidebar-tab-dropdown" id="pp-sidebar-tab-dropdown"> 3350 <button type="button" class="pp-sidebar-tab-trigger" id="pp-sidebar-tab-trigger" 3351 aria-haspopup="listbox" aria-expanded="false" aria-controls="pp-sidebar-tab-menu">
3352 <span class="pp-sidebar-tab-trigger__icon" aria-hidden="true"> 3353 <i class="fa fa-search"></i> 3354 </span> 3355 <span class="pp-sidebar-tab-trigger__text" data-role="label-text">Parsel Sorgula</span> 3356 <span class="pp-sidebar-tab-trigger__chevron" aria-hidden="true"> 3357 <i class="fa fa-chevron-down"></i> 3358 </span> 3359 </button> 3360 <ul class="pp-sidebar-tab-menu" id="pp-sidebar-tab-menu" role="listbox" 3361 aria-label="Sorgu sekmeleri" hidden> 3362 <li class="active" data-tab="parsel-sorgu-tab" data-label="Parsel Sorgula" data-icon="fa-search" 3363 role="option" aria-selected="true"> 3364 <span class="pp-sidebar-tab-item__icon"><i class="fa fa-search" aria-hidden="true"></i></span> 3365 <span class="pp-sidebar-tab-item__label">Parsel Sorgula</span> 3366 <span class="pp-sidebar-tab-item__check" aria-hidden="true"><i class="fa fa-check"></i></span> 3367 </li> 3368 <li data-tab="sorgularim-tab" data-label="Sorgularım" data-icon="fa-history" 3369 role="option" aria-selected="false"> 3370 <span class="pp-sidebar-tab-item__icon"><i class="fa fa-history" aria-hidden="true"></i></span> 3371 <span class="pp-sidebar-tab-item__label">Sorgularım</span> 3372 <span class="pp-sidebar-tab-item__check" aria-hidden="true"><i class="fa fa-check"></i></span> 3373 </li> 3374 <li data-tab="akilli-sorgu-tab" data-label="Akıllı Sorgu" data-icon="fa-magic" 3375 role="option" aria-selected="false"> 3376 <span class="pp-sidebar-tab-item__icon"><i class="fa fa-magic" aria-hidden="true"></i></span> 3377 <span class="pp-sidebar-tab-item__label">Akıllı Sorgu</span> 3378 <span class="pp-sidebar-tab-item__check" aria-hidden="true"><i class="fa fa-check"></i></span> 3379 </li> 3380 </ul> 3381 </div> 3382
3382<script> 3383 (function () { 3384 var menu = document.getElementById('pp-sidebar-tab-menu'); 3385 var wrap = document.getElementById('pp-sidebar-tab-dropdown'); 3386 if (menu) { menu.setAttribute('hidden', ''); menu.style.display = 'none'; } 3387 if (wrap) wrap.classList.remove('is-open'); 3388 })(); 3389 </script>
3389 3390 3391 <!-- Parsel Sorgu Sekmesi --> 3392 <div class="sidebar-tab-content active" id="parsel-sorgu-tab"> 3393 <label for="il-select" class="visually-hidden">İl</label> 3394 <select class="form-select sidebar-select" id="il-select" aria-label="İl seçimi"> 3395 <option>İl Seçiniz</option> 3396 </select> 3397 3398 <label for="ilce-select" class="visually-hidden">İlçe</label> 3399 <select class="form-select sidebar-select" id="ilce-select" aria-label="İlçe seçimi"> 3400 <option>İlçe Seçiniz</option> 3401 </select> 3402 3403 <label for="mahalle-select" class="visually-hidden">Mahalle</label> 3404 <select class="form-select sidebar-select" id="mahalle-select" aria-label="Mahalle seçimi"> 3405 <option>Mahalle Seçiniz</option> 3406 </select> 3407 3408 <label for="ada-input" class="visually-hidden">Ada</label> 3409 <input class="form-control sidebar-input" type="text" placeholder="Ada" id="ada-input" 3410 aria-label="Ada numarası"> 3411 3412 <label for="parsel-input" class="visually-hidden">Parsel</label> 3413 <input class="form-control sidebar-input" type="text" placeholder="Parsel" id="parsel-input" 3414 aria-label="Parsel numarası"> 3415 3416 <div id="mahalle-proparcel-hint" 3417 style="min-height:16px; font-size:12px; color:#9ca3af;"> 3418 <!-- Mahalle Proparcel deÄeri burada gri ve silik gösterilecek --> 3419 </div> 3420 3421 <button id="parsel-sorgula-btn" class="btn btn-success w-100 sidebar-btn" 3422 onclick="simpleParselSorgula()">Sorgula</button> 3423 <button id="pro-parsel-sorgula-btn" class="btn btn-primary w-100 sidebar-btn" 3424 onclick="proParselSorgula()">ProSorgu</button> 3425 <button id="daire-sorgula-btn" class="btn btn-primary w-100 sidebar-btn" 3426 onclick="daireSorgula()">Daire Sorgula</button> 3427 </div> 3428 3429 <!-- Sorgularım Sekmesi --> 3430 <div class="sidebar-tab-content" id="sorgularim-tab"> 3431 <div class="pp-sidebar-saved-queries"> 3432 <div class="pp-sidebar-saved-queries__header"> 3433 <strong>Sorgularım</strong> 3434 <span>Tarayıcıda saklanan son sorgular</span> 3435 </div> 3436 <div id="pp-sidebar-saved-query-list" class="pp-sidebar-saved-query-list" aria-live="polite"> 3437 <div class="pp-sidebar-saved-query-empty">Henüz kayıtlı sorgu yok.</div> 3438 </div> 3439 </div> 3440 </div> 3441 3442 <!-- Akıllı Sorgu sekmesi modal olarak açılır --> 3443 3444 <!-- Geri Bildirim Modalı --> 3445 <div class="modal fade" id="feedbackModal" tabindex="-1" aria-labelledby="feedbackModalLabel" aria-hidden="true"> 3446 <div class="modal-dialog modal-dialog-centered"> 3447 <div class="modal-content"> 3448 <div class="modal-header"> 3449 <h5 class="modal-title" id="feedbackModalLabel"><i class="fa fa-comment-dots me-2"></i>Geri Bildirim</h5> 3450 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Kapat"></button> 3451 </div> 3452 <div class="modal-body"> 3453 <textarea class="form-control" id="feedbackText" rows="4" 3454 placeholder="YanlıŠveya eksik gördüÄünüz bilgiyi buraya yazın..." 3455 aria-label="Geri bildirim metni"></textarea> 3456 </div> 3457 <div class="modal-footer"> 3458 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Vazgeç</button> 3459 <button type="button" class="btn btn-primary" id="sendFeedbackBtn">Gönder</button> 3460 </div> 3461 </div> 3462 </div> 3463 </div> 3464 </aside> 3465 3466 3467 3468 3469 3470 <!-- Auth Guard - GiriÅ yapmamıŠkullanıcı koruması (tüm JS'lerden ÃNCE yüklenmeli) --> 3471
3471<script src="/static/js/app/ui/auth_guard.js?v=20260710-daire-sorgula"></script>
3471 3472
3472<script src="/static/js/app/ui/feature_gate.js?v=20260708-sidebar-dropdown-v3"></script>
3472 3473
3473<script src="/static/js/app/ui/dogrulama_toggle.js"></script>
3473 3474 3475
3475<script src="/static/js/initialization/loading.js"></script>
3475 3476 3477 <!-- Parsel Kamera Yönetimi (Map Click Handler'dan önce yüklenmeli) --> 3478
3478<script src="/static/js/app/camera/parcel_camera_manager.js?v=20260703-no-map-stop"></script>
3478 3479 3480 <!-- Map Click Handler --> 3481
3481<script src="/static/js/core/utils/locale_number_tr.js?v=20260826-modal-area"></script>
3481 3482
3482<script src="/static/js/features/query/map_click.js?v=20260826-parcel-click"></script>
3482 3483 3484 <!-- Border Proximity Alert - CSS zaten head'de yüklü --> 3485 3486
3486<script> 3487 window.ENABLE_SIM_TOGGLE_INIT = true; 3488 window.ENABLE_SIDEBAR_CLICK_DELEGATES = true; 3489 window.ENABLE_SEARCHABLE_SELECT = true; 3490 </script>
3490 3491 <!-- TKGM API direkt çaÄrı yardımcı fonksiyonları --> 3492
3492<script src="/static/js/utils/tkgm_passive_parcel.js?v=20260523-passive-banner"></script>
3492 3493
3493<script src="/static/js/utils/tkgm_api.js"></script>
3493 3494
3494<script> 3495 // Basit/TKGM sorgu sonucunu sunucuya kaydet (kök: tkgm_click_results.json) 3496 window.persistTkgmClickResult = async function(payload) { 3497 try { 3498 const resp = await fetch('/api/save_tkgm_click_result/', { 3499 method: 'POST', 3500 headers: { 'Content-Type': 'application/json' }, 3501 body: JSON.stringify(payload || {}), 3502 keepalive: true 3503 }); 3504 if (!resp.ok) { 3505 let body = ''; 3506 try { body = await resp.text(); } catch (_) {} 3507 console.warn('[persistTkgmClickResult] failed', resp.status, body); 3508 } 3509 } catch (_) { 3510 // Kullanıcı akıÅını bozmadan konsola bilgi ver 3511 console.warn('[persistTkgmClickResult] request error'); 3512 } 3513 }; 3514 </script>
3514 3515 <!-- Pro sorgu: ekran görüntüsü modülleri buton tıklanınca yüklenir. --> 3516
3516<script> 3517 window.__ppLoadScriptOnce = window.__ppLoadScriptOnce || function(src, timeoutMs) { 3518 var limit = Math.max(2000, Number(timeoutMs) || 10000); 3519 return Promise.race([ 3520 new Promise(function(resolve, reject) { 3521 try { 3522 var existing = document.querySelector('script[data-pp-src="' + src + '"]'); 3523 if (existing) { 3524 if (existing.getAttribute('data-loaded') === '1') return resolve(); 3525 existing.addEventListener('load', function() { resolve(); }, { once: true }); 3526 existing.addEventListener('error', reject, { once: true }); 3527 return; 3528 } 3529 var script = document.createElement('script'); 3530 script.src = src; 3531 script.async = false; 3532 script.setAttribute('data-pp-src', src); 3533 script.onload = function() { script.setAttribute('data-loaded', '1'); resolve(); }; 3534 script.onerror = reject; 3535 document.head.appendChild(script); 3536 } catch (e) { 3537 reject(e); 3538 } 3539 }), 3540 new Promise(function(_, reject) { 3541 setTimeout(function() { reject(new Error('SCRIPT_LOAD_TIMEOUT')); }, limit); 3542 }) 3543 ]); 3544 }; 3545 window.__ppShouldSkipProMapCanvasCapture = window.__ppShouldSkipProMapCanvasCapture || function() { 3546 try { 3547 if (window.__PP_SKIP_PRO_MAP_CAPTURE === true) return true; 3548 if (window.PPWebGLCompat && typeof window.PPWebGLCompat.supports === 'function') { 3549 return !window.PPWebGLCompat.supports('heavy_animation'); 3550 } 3551 } catch (e) {} 3552 return window.__PP_GPU_MODE === 'minimal_gpu' || window.__PP_GPU_MODE === 'no_gpu'; 3553 }; 3554 window.__ppShouldSkipProMapCapture = window.__ppShouldSkipProMapCanvasCapture; 3555 async function __ppStaticMapCaptureDataUrl(parcelGeometry) { 3556 if (!parcelGeometry) return null; 3557 try { 3558 if (!window.PPStaticMapCapture) { 3559 await window.__ppLoadScriptOnce('/static/js/reports/static_map_capture.js?v=20260601-red-parcel', 8000); 3560 } 3561 if (window.PPStaticMapCapture && typeof window.PPStaticMapCapture.fetchDataUrl === 'function') { 3562 return await window.PPStaticMapCapture.fetchDataUrl(parcelGeometry); 3563 } 3564 } catch (e) { 3565 console.warn('[ProParcel] Static map capture hatası:', e); 3566 } 3567 return null; 3568 } 3569 window.__ppCaptureIndexMapForProQuery = window.__ppCaptureIndexMapForProQuery || async function(options) { 3570 options = options || {}; 3571 var timeoutMs = Math.max(1200, Number(options.timeoutMs) || 4500); 3572 var skipCanvas = window.__ppShouldSkipProMapCanvasCapture && window.__ppShouldSkipProMapCanvasCapture(); 3573 var captured = null; 3574 try { 3575 if (!skipCanvas) { 3576 if (!window.PPIndexMapCapture && typeof window.__ppEnsureCaptureModules === 'function') { 3577 await Promise.race([ 3578 window.__ppEnsureCaptureModules(), 3579 new Promise(function(_, reject) { setTimeout(function() { reject(new Error('capture_modules_timeout')); }, 4000); }) 3580 ]); 3581 } 3582 if (window.PPIndexMapCapture && typeof window.PPIndexMapCapture.captureIndexMap === 'function') { 3583 captured = await Promise.race([ 3584 window.PPIndexMapCapture.captureIndexMap({ 3585 cleanCapture: true, 3586 fastCapture: true, 3587 parcelGeometry: options.parcelGeometry || null, 3588 parcelLabel: options.parcelLabel || '' 3589 }), 3590 new Promise(function(resolve) { setTimeout(function() { resolve(null); }, timeoutMs); }) 3591 ]); 3592 } 3593 } 3594 if (!captured && options.parcelGeometry) { 3595 captured = await __ppStaticMapCaptureDataUrl(options.parcelGeometry); 3596 } 3597 return captured; 3598 } catch (e) { 3599 console.warn('[ProParcel] Pro sorgu harita capture hatası:', e); 3600 if (!captured && options.parcelGeometry) { 3601 try { return await __ppStaticMapCaptureDataUrl(options.parcelGeometry); } catch (_) {} 3602 } 3603 return null; 3604 } 3605 }; 3606 window.__ppEnsureCaptureModules = window.__ppEnsureCaptureModules || async function() { 3607 if (typeof window.ppCaptureOverlayOpen === 'function' && window.PPIndexMapCapture) return; 3608 var skipHeavy = window.__ppShouldSkipProMapCanvasCapture && window.__ppShouldSkipProMapCanvasCapture(); 3609 if (!skipHeavy && typeof window.html2canvas !== 'function') { 3610 await window.__ppLoadScriptOnce('https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js', 8000); 3611 } 3612 await window.__ppLoadScriptOnce('/static/js/reports/static_map_capture.js?v=20260601-red-parcel', 8000); 3613 await window.__ppLoadScriptOnce('/static/js/reports/index_map_capture.js?v=20260808-area-parse', 8000); 3614 await window.__ppLoadScriptOnce('/static/js/components/capture_overlay_modal.js?v=20260808-area-parse', 8000); 3615 }; 3616 window.ppPositionCaptureMenu = function() {
3617 try { 3618 var wrap = document.getElementById('pp-capture-menu-wrap'); 3619 var btn = document.getElementById('pp-screenshot-map-btn'); 3620 var menu = document.getElementById('pp-capture-menu'); 3621 if (!menu || !menu.classList.contains('open')) return; 3622 var anchor = btn || wrap; 3623 if (!anchor) return; 3624 var rect = anchor.getBoundingClientRect(); 3625 var menuWidth = menu.offsetWidth || 170; 3626 var vpW = window.innerWidth || document.documentElement.clientWidth || 0; 3627 var edgePad = 12; 3628 var left = rect.right - menuWidth; 3629 left = Math.max(edgePad, Math.min(left, vpW - menuWidth - edgePad)); 3630 menu.style.top = Math.round(rect.bottom + 8) + 'px'; 3631 menu.style.left = Math.round(left) + 'px'; 3632 } catch (e) { console.warn('[ppPositionCaptureMenu]', e); } 3633 }; 3634 window.ppToggleCaptureMenu = function(event) { 3635 try { 3636 if (event) { 3637 event.preventDefault(); 3638 event.stopPropagation(); 3639 } 3640 var menu = document.getElementById('pp-capture-menu'); 3641 if (!menu) return; 3642 menu.classList.toggle('open'); 3643 if (menu.classList.contains('open')) { 3644 window.ppPositionCaptureMenu(); 3645 } 3646 } catch (e) { console.warn('[ppToggleCaptureMenu]', e); } 3647 }; 3648 if (!window.__ppCaptureMenuPositionBound) { 3649 window.__ppCaptureMenuPositionBound = true; 3650 var ppRepositionCaptureMenu = function() { 3651 if (typeof window.ppPositionCaptureMenu === 'function') window.ppPositionCaptureMenu(); 3652 }; 3653 window.addEventListener('resize', ppRepositionCaptureMenu); 3654 window.addEventListener('scroll', ppRepositionCaptureMenu, true); 3655 document.addEventListener('DOMContentLoaded', function() { 3656 var extras = document.getElementById('pp-toolbar-extras'); 3657 if (extras) extras.addEventListener('scroll', ppRepositionCaptureMenu, { passive: true }); 3658 }); 3659 } 3660 document.addEventListener('click', function(e) { 3661 try { 3662 var wrap = document.getElementById('pp-capture-menu-wrap'); 3663 var menu = document.getElementById('pp-capture-menu'); 3664 if (wrap && menu && !wrap.contains(e.target) && !menu.contains(e.target)) { 3665 menu.classList.remove('open'); 3666 } 3667 } catch (_) {} 3668 }); 3669 window.ppCaptureAndDownloadMap = async function(orientation) { 3670 try { 3671 var menu = document.getElementById('pp-capture-menu'); 3672 if (menu) menu.classList.remove('open'); 3673 if (typeof window.__ppEnsureCaptureModules === 'function') { 3674 await window.__ppEnsureCaptureModules(); 3675 } 3676 if (typeof window.ppCaptureOverlayOpen === 'function') { 3677 window.ppCaptureOverlayOpen(orientation || 'horizontal'); 3678 } else { 3679 console.warn('[ppCaptureAndDownloadMap] ppCaptureOverlayOpen yüklenmedi'); 3680 } 3681 } catch (e) { console.warn('[ppCaptureAndDownloadMap]', e); } 3682 }; 3683 </script>
3683 3684
3684<script src="/static/js/initialization/alerts_and_copy.js?v=20260604-toast-fix"></script>
3684 3685
3685<script src="/static/js/app/pp_clear_pro_query_globals.js?v=20260605-query-isolation"></script>
3685 3686
3686<script src="/static/js/initialization/sidebar_and_forms.js?v=20260815-tkgm-alan"></script>
3686 3687
3687<script src="/static/js/initialization/parcel_query_buttons_sync.js?v=20260531-ada-parsel-btn"></script>
3687 3688
3688<script src="/static/js/initialization/menu_bar.js?v=20260815-kentsel"></script>
3688 3689
3689<script src="/static/js/initialization/toolbar_extras_toggle.js"></script>
3689 3690
3690<script src="/static/js/initialization/toolbar_extras_auth_gate.js?v=20260518-2"></script>
3690 3691
3691<script src="/static/js/initialization/bina_ciz_toolbar.js?v=20260819-lonlat"></script>
3691 3692
3692<script src="/static/js/initialization/geolocation.js?v=20260703-no-map-stop"></script>
3692 3693 3694 <!-- BaÅlangıç koruması --> 3695
3695<script src="/static/js/initialization/boot_guard.js"></script>
3695 3696 3697 <!-- Modern Layout Manager (YENİ) --> 3698
3698<script src="/static/js/layout/layout_manager.js"></script>
3698 3699 3700 <!-- Bootstrap JS --> 3701
3701<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
3701 3702 3703 3704 <!-- Plotly - Lazy Load (sadece ihtiyaç duyulduÄunda yüklenir) --> 3705
3705<script src="/static/js/core/utils/plotly_loader.js"></script>
3705 3706 3707 <!-- Core Modules (kademeli yeniden etkinleÅtirme) --> 3708
3708<script src="/static/js/initialization/mapbox_gl_init.js"></script>
3708 3709
3709<script> 3710 (function () { 3711 if (window.__PP_SKIP_MAPBOX_GL || window.__PP_EARLY_WEBGL_DISABLED || window.__PP_ALLOW_MAPBOX_GL === false) return; 3712 document.write('
3712<script src="https://api.mapbox.com/mapbox-gl-js/v3.2.0/mapbox-gl.js"><\/script>'); 3713 })(); 3714 </script>
3714 3715
3715<script> 3716 (function () { 3717 var shouldLoadLeaflet = window.__PP_GPU_MODE === 'no_gpu' || 3718 !!(window.__PP_SKIP_MAPBOX_GL || window.__PP_EARLY_WEBGL_DISABLED || window.__PP_ALLOW_MAPBOX_GL === false); 3719 try { 3720 shouldLoadLeaflet = shouldLoadLeaflet || /(?:\?|&)(pp_force_legacy_map|pp_leaflet_only|pp_skip_mapbox)=1(?:&|$)/.test(window.location.search || ''); 3721 } catch (e) {} 3722 if (shouldLoadLeaflet) { 3723 document.write('
3723<script src="https://unpkg.com/[email protected]/dist/leaflet.js"><\/script>'); 3724 } 3725 })(); 3726 </script>
3726 3727
3727<script src="/static/js/core/map/webgl_compat_guard.js?v=20260711-loader-webgl-guard"></script>
3727 3728
3728<script src="/static/js/core/map/map_runtime.js?v=20260706-parcel-style"></script>
3728 3729
3729<script> 3730 (function () { 3731 var shouldInit = window.__PP_GPU_MODE === 'no_gpu' || 3732 !!(window.__PP_SKIP_MAPBOX_GL || window.__PP_EARLY_WEBGL_DISABLED || window.__PP_ALLOW_MAPBOX_GL === false); 3733 try { 3734 shouldInit = shouldInit || /(?:\?|&)(pp_force_legacy_map|pp_leaflet_only|pp_skip_mapbox)=1(?:&|$)/.test(window.location.search || ''); 3735 } catch (e) {} 3736 if (!shouldInit) return; 3737 if (!window.L || typeof window.L.map !== 'function') return; 3738 3739 function initLegacyLeafletMap() { 3740 var container = document.getElementById('map3D'); 3741 if (!container || container.getAttribute('data-pp-legacy-leaflet-ready') === '1') { 3742 return window.__PP_LEGACY_LEAFLET_MAP || null; 3743 } 3744 try { 3745 container.innerHTML = ''; 3746 container.style.display = 'block'; 3747 container.style.position = 'relative'; 3748 container.style.width = '100%'; 3749 container.style.height = '100%'; 3750 container.style.background = '#e5e7eb'; 3751 container.className += ' pp-leaflet-2d-fallback'; 3752 3753 var map = window.L.map(container, { 3754 zoomControl: true, 3755 attributionControl: true, 3756 preferCanvas: true, 3757 worldCopyJump: true 3758 }).setView([39.0, 35.0], 6); 3759 3760 window.L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', { 3761 maxZoom: 19, 3762 attribution: 'Tiles © Esri, Maxar, Earthstar Geographics, and the GIS User Community' 3763 }).addTo(map); 3764 3765 map.on('click', function (event) { 3766 try { 3767 if (!window.enableMapClick || !window.proParcelApp || typeof window.proParcelApp.handleMapClick !== 'function') return; 3768 if (!event || !event.latlng) return; 3769 window.proParcelApp.handleMapClick.call(window.proParcelApp, { 3770 lngLat: { lng: event.latlng.lng, lat: event.latlng.lat }, 3771 originalEvent: event.originalEvent 3772 }); 3773 } catch (e) {} 3774 }); 3775 3776 window.__PP_LEGACY_LEAFLET_MAP = map; 3777 container.setAttribute('data-pp-legacy-leaflet-ready', '1'); 3778 window.mapManager = window.mapManager || { 3779 maps: { leaflet2d: map }, 3780 isInitialized: { leaflet2d: true }, 3781 initialize3DMap: function () { return map; }, 3782 getCurrentMap: function () { return map; }, 3783 getMap: function () { return map; }, 3784 isMapInitialized: function () { return true; }, 3785 resizeAllMaps: function () { try { map.invalidateSize(); } catch (e) {} }, 3786 drawParcelOn2DFallback: function (geometry, properties) { 3787 try { 3788 if (!geometry) return false; 3789 if (this._fallbackParcelLayer) map.removeLayer(this._fallbackParcelLayer); 3790 this._fallbackParcelLayer = window.L.geoJSON({ type: 'Feature', geometry: geometry, properties: properties || {} }, { 3791 style: { color: '#D32F2F', weight: 3, fillColor: '#D32F2F', fillOpacity: 0.14 } 3792 }).addTo(map); 3793 map.fitBounds(this._fallbackParcelLayer.getBounds(), { padding: [40, 40] }); 3794 return true; 3795 } catch (e) { 3796 return false; 3797 } 3798 } 3799 }; 3800 try { setTimeout(function () { map.invalidateSize(); }, 100); } catch (e) {} 3801 try { if (typeof window.hideLoading === 'function') window.hideLoading(); } catch (e) {} 3802 return map; 3803 } catch (e) { 3804 return null; 3805 } 3806 } 3807 3808 initLegacyLeafletMap(); 3809 if (document.readyState === 'loading') { 3810 document.addEventListener('DOMContentLoaded', initLegacyLeafletMap); 3811 } 3812 })(); 3813 </script>
3813 3814 <!-- MapManager modüler çekirdek ve yardımcıları (MapManager.js'ten önce yüklenmeli) --> 3815
3815<script src="/static/js/core/map/map_manager_core_v3.js?v=20260810-mode-overlay"></script>
3815 3816
3816<script src="/static/js/core/map/map_manager_ui_v2.js?v=20260810-mode-overlay"></script>
3816 3817
3817<script src="/static/js/core/map/map_manager_events_v2.js"></script>
3817 3818 <!-- DiÄer core yardımcılar --> 3819
3819<script src="/static/js/core/utils/coordinate_utils.js"></script>
3819 3820
3820<script src="/static/js/core/utils/cursor_manager.js?v=20260704-tile-proxy-cursor"></script>
3820 3821
3821<script src="/static/js/features/query/map_click_forwarder.js"></script>
3821 3822
3822<script src="/static/js/features/query/parcel_info_modal.js?v=20260826-modal-area"></script>
3822 3823
3823<script src="/static/js/core/layer/layer_manager.js"></script>
3823 3824 <!-- MapManager ana sınıf (global window.mapManager instance'ını oluÅturur) --> 3825
3825<script src="/static/js/core/map/map_manager_v2.js?v=20260810-mode-overlay"></script>
3825 3826 <!-- mapbox-renderer.js dosyası bulunamadı, render.js kullanılıyor --> 3827 <!-- map_config.js (Leaflet setup) removed --> 3828 3829 3830 3831
3831<script src="/static/js/core/utils/city_town_quarter_box_manager.js?v=20260510-town-encoding"></script>
3831 3832 3833 3834 <!-- Grid SatıŠModal (Ctrl+Click) --> 3835
3835<script src="/static/js/components/grid_sales_modal.js"></script>
3835 3836 3837 3838 3839 <!-- Kamera kontrolleri --> 3840
3840<script src="/static/js/graphics/3d/map_3d/camera_controls.js"></script>
3840 3841 3842 <!-- 3D Yapı Ãizim Sistemi ve Mapbox 3D Binalar kaldırıldı (performans için) --> 3843 3844
3844<script src="/static/js/drawing/tools/add_graphics/multi_road_select.js"></script>
3844 3845 <!-- ThreePOC (baÄımsız oyun motoru POC) --> 3846 3847 <!-- POC / Demo: default kapalı (3D model sistemi tek noktada yönetiliyor) --> 3848 <!--
3848<script src="/static/js/car_demo/car-demo.js"></script>
3848 --> 3849 <!--
3849<script src="/static/js/vehicles/car-model.js"></script>
3849 --> 3850 3851 <!-- Graphics Modules --> 3852
3852<script src="/static/js/graphics/elevation/elevation_view.js"></script>
3852 3853 3854 <!-- Info Updates --> 3855
3855<script src="/static/js/features/parameters/update_parameters_info.js?v=20260815-tkgm-alan"></script>
3855 3856
3856<script> 3857 window.__ppEnsureParameterInfoModals = window.__ppEnsureParameterInfoModals || function() { 3858 if (window.viewInfoModalManager && window.roadInfoModalManager) return Promise.resolve(); 3859 return window.__ppLoadScriptOnce('/static/js/features/parameters/parameters_info_modals.js?v=lazy-20260508'); 3860 }; 3861 </script>
3861 3862 <!-- Google Maps API key init (Street View için) --> 3863
3863<script src="/static/js/initialization/google_maps_init.js"></script>
3863 3864 <!-- Street View Helper (V2 rapordaki mantıÄı pro/basit modlarda kullanmak için) --> 3865
3865<script src="/static/js/graphics/street_view/street_view_helper.js"></script>
3865 3866
3866<script src="/static/js/features/parameters/render_parcel_info.js?v=20260815-tkgm-alan"></script>
3866 3867 <!-- 3D Model Editörü /3d-editor/ sayfasına taÅındı --> 3868 <!-- Raporlama --> 3869 <!-- V1 Report Generator REMOVED - Replaced with lightweight My Queries Manager --> 3870
3870<script src="/static/js/reports/my_queries_manager.js"></script>
3870 3871
3871<script src="/static/js/reports/analysis_report_v2_loader.js"></script>
3871 3872
3872<script src="/static/js/reports/price_report_client.js?v=2025-11-10-01"></script>
3872 3873 3874 <!-- Drawing Process Modules --> 3875
3875<script src="/static/js/drawing/layers/map_layer_config.js"></script>
3875 3876
3876<script src="/static/js/drawing/render/render.js?v=20260704-parcel-style"></script>
3876 3877
3877<script src="/static/js/drawing/fixes/roads_self_heal.js"></script>
3877 3878
3878<script src="/static/js/drawing/fixes/electric_self_heal.js"></script>
3878 3879 3880 <!-- New Layer Drawing Functions --> 3881
3881<script src="/static/js/drawing/tools/draw_clipped_railway.js"></script>
3881 3882
3882<script src="/static/js/drawing/tools/draw_clipped_sit.js"></script>
3882 3883 <!-- Eski mahalle bazlı sulak koruma kaldırıldı --> 3884 <!--
3884<script src="/static/js/drawing/tools/draw_clipped_sulak_koruma.js"></script>
3884 --> 3885 <!-- Åehir bazlı sulak koruma (RAMSAR) --> 3886
3886<script src="/static/js/drawing/tools/draw_city_sulak_koruma.js"></script>
3886 3887
3887<script src="/static/js/drawing/tools/draw_clipped_mill_park.js"></script>
3887 3888 3889 <!-- Tab Handlers --> 3890
3890<script src="/static/js/components/tab_handlers.js?v=20260708-sidebar-dropdown-v3"></script>
3890 3891 <!-- Akıllı Sorgu Modal --> 3892
3892<script src="/static/js/features/query/smart_query_modal.js?v=20260716-paste"></script>
3892 3893 <!-- Resim'den Sorgu (OpenAI Vision) â modal açıldıÄında/tıklamada yüklenir. --> 3894
3894<script> 3895 window.__ppEnsureOcrImageQuery = window.__ppEnsureOcrImageQuery || function() { 3896 if (window.__ppOcrImageQueryLoaded) return Promise.resolve(); 3897 return window.__ppLoadScriptOnce('/static/js/features/ocr/ocr_image_query.js?v=smart-query-20260716-ada-clean').then(function() { 3898 window.__ppOcrImageQueryLoaded = true; 3899 }); 3900 }; 3901 document.addEventListener('click', function(event) { 3902 try { 3903 var target = event.target && event.target.closest && event.target.closest('label[for="ocr-image-input"],#ocr-image-upload,#ocr-image-input,[data-tab="image_query"],[data-tab="image-query"],[data-target="image_query"],[data-target="image-query"]'); 3904 if (target && typeof window.__ppEnsureOcrImageQuery === 'function') window.__ppEnsureOcrImageQuery(); 3905 } catch (e) {} 3906 }, true); 3907 </script>
3907 3908 3909 <!-- WebGL Cleanup Utility (haritaları temizlemek için) --> 3910
3910<script src="/static/js/core/map/webgl_cleanup.js"></script>
3910 3911 3912 <!-- Core App Bootstrap --> 3913
3913<script src="/static/js/app/pro_query_background.js?v=20260601-detail-redirect"></script>
3913 3914
3914<script type="module" src="/static/js/initialization/app.js?v=20260815-tkgm-alan"></script>
3914 3915 3916 <!-- Parcel Rotate --> 3917
3917<script src="/static/js/graphics/turner.js"></script>
3917 3918 3919 <!-- Tools --> 3920
3920<script src="/static/js/features/parameters/buttons.js?v=20260728-simple-default"></script>
3920 3921 3922
3922<script src="/static/js/drawing/buttons/toggle_button_manager.js?v=2026-01-03-04"></script>
3922 3923
3923<script src="/static/js/drawing/buttons/parameters_css_handlers.js"></script>
3923 3924
3924<script src="/static/js/drawing/buttons/parameters_drawing_handler.js"></script>
3924 3925
3925<script src="/static/js/drawing/buttons/parameters_buttons_check.js"></script>
3925 3926 <!-- collapsible_menu.js ve dropdowns.js artık topbar.html'den yükleniyor --> 3927 3928 <!-- Measurement Tools (Cetvel ve Alan Ãlçümü) --> 3929
3929<script src="/static/js/drawing/measurement/measurement_manager.js"></script>
3929 3930 3931 <!-- Annotation: harita + 3D editör ortak metin/ok yardımcıları --> 3932
3932<script src="/static/js/drawing/tools/annotation_drawing_helpers.js"></script>
3932 3933 <!-- Annotation Tools (İÄne & Metin harita iÅaretleme) --> 3934
3934<script src="/static/js/drawing/tools/map_annotation_tools.js?v=20260703-no-map-stop"></script>
3934 3935 3936 3937 <!-- User Adding / Road toggle --> 3938
3938<script src="/static/js/drawing/tools/add_graphics/user_adding.js"></script>
3938 3939
3939<script src="/static/js/drawing/tools/add_graphics/add_road_to_gpkg.js"></script>
3939 3940
3940<script src="/static/js/drawing/tools/add_graphics/add_electric_to_gpkg.js"></script>
3940 3941
3941<script src="/static/js/drawing/tools/add_graphics/select_electric.js"></script>
3941 3942
3942<script src="/static/js/drawing/tools/add_graphics/user_adding_electric.js"></script>
3942 3943 3944 <!-- Fullscreen helpers --> 3945 <div id="fs-mask" aria-hidden="true"></div> 3946 <div id="fs-snapshot" aria-hidden="true"></div> 3947 3948 <!-- Tepe Kredi Sistemi --> 3949
3949<script src="/static/js/credit_system.js"></script>
3949 3950 <!-- İlk GiriŠTour Overlay (ekran görüntüsü + Pro Sorgu) --> 3951
3951<script src="/static/js/app/ui/app_tour_overlay.js?v=20260727-basit-mapclick-no-pro"></script>
3951 3952
3952<script src="/static/js/app/cost/komisyon_harclar_modal.js?v=20260725i"></script>
3952 3953 <!-- user_menu.js ve auth_required_3d_modal.js artık topbar.html'den yükleniyor --> 3954 3955 <!-- Grid SatıŠİstatistikleri Modalı - Harita Ãzerinde --> 3956 <div class="modal fade" id="gridSalesModal" tabindex="-1" aria-labelledby="gridSalesModalLabel" aria-hidden="true" 3957 style="z-index: 9999;"> 3958 <div class="modal-dialog modal-lg" id="gridSalesModalDialog" 3959 style="position: fixed; top: 80px; right: 30px; margin: 0; max-width: 600px;"> 3960 <div class="modal-content" style="box-shadow: 0 5px 15px rgba(0,0,0,0.5);"> 3961 <div class="modal-header" id="gridSalesModalHeader" style="cursor: move;"> 3962 <h5 class="modal-title" id="gridSalesModalLabel"><i class="fas fa-th me-2"></i>Grid SatıŠİstatistikleri 3963 </h5> 3964 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Kapat"></button> 3965 </div> 3966 <div class="modal-body"> 3967 <div id="gridSalesContent"> 3968 <!-- İçerik JavaScript ile doldurulacak --> 3969 <p class="text-muted">Veri yükleniyor...</p> 3970 </div> 3971 </div> 3972 <div class="modal-footer"> 3973 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Kapat</button> 3974 </div> 3975 </div> 3976 </div> 3977 </div> 3978 3979 3980</body> 3981 3982</html>
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.