1document.addEventListener("DOMContentLoaded", function () { 2 const popup = document.getElementById("noticePopup"); 3 const track = document.getElementById("noticeTrack"); 4 5 if (!popup || !track) return; 6 7 const popupSheet = popup.querySelector(".popup-sheet"); 8 const dotsContainer = document.getElementById("slideDots"); 9 const currentSlideElement = document.getElementById("currentSlide"); 10 const totalSlideElement = document.getElementById("totalSlide"); 11 const detailButton = document.getElementById("detailButton"); 12 const closeButton = document.getElementById("closePopupButton"); 13 const hideDayButton = document.getElementById("hideDayButton"); 14 15 let slides = Array.from(track.querySelectorAll(".notice-slide")); 16 const initialSlideSet = new Set(slides); 17 const initialTrackChildren = new Set(Array.from(track.children)); 18 19 let dots = []; 20 let activeIndex = -1; 21 let scrollTimer = null; 22 let viewTimer = null; 23 let initializeTimer = null; 24 let popupInitialized = false; 25 26 let isDragging = false; 27 let isHorizontalDrag = false; 28 let dragStartX = 0; 29 let dragStartY = 0; 30 let dragCurrentX = 0; 31 let dragStartScrollLeft = 0; 32 let dragStartIndex = 0; 33 let ignoreNextClick = false; 34 35 const DRAG_THRESHOLD = 40; 36 const ONE_DAY = 24 * 60 * 60 * 1000; 37 const ADROP_NOTICE_ID = "adrop_main_popup"; 38 const ADROP_UNIT_ID = "01J8M2R6NS7D248TH24MFGTMEN"; 39 40 function getStorageValue(storage, key) { 41 try { 42 return storage.getItem(key); 43 } catch (error) { 44 return null; 45 } 46 } 47 48 function setStorageValue(storage, key, value) { 49 try { 50 storage.setItem(key, value); 51 return true; 52 } catch (error) { 53 return false; 54 } 55 } 56 57 function removeStorageValue(storage, key) { 58 try { 59 storage.removeItem(key); 60 } catch (error) { 61 // Storage ì¬ì©ì´ ë¶ê°ë¥í íê²½ììë 무ìí©ëë¤. 62 } 63 } 64 65 function refreshSlides() { 66 slides = Array.from(track.querySelectorAll(".notice-slide")); 67 } 68 69 function isAdropSlide(slide) { 70 if (!slide) return false; 71 72 const popGb = String(slide.dataset.popGb || "").trim().toLowerCase(); 73 const noticeId = String(slide.dataset.noticeId || "").trim().toLowerCase(); 74 75 return ( 76 slide.classList.contains("notice-slide--adrop") || 77 popGb === "adrop" || 78 noticeId.startsWith("adrop_") 79 ); 80 } 81 82 function isImageDetailAction(action) { 83 return ( 84 action === "bn_link" || 85 action === "bn_pop" || 86 action === "bn_outopen" 87 ); 88 } 89 90 function getNoticeHideKey(slide) { 91 if (!slide) return ""; 92 93 const noticeId = String(slide.dataset.noticeId || "").trim(); 94 const version = String(slide.dataset.version || "1").trim(); 95 96 if (!noticeId) return ""; 97 98 return "notice-hidden:" + noticeId + ":" + version; 99 } 100 101 function hideNoticeForOneDay(slide) { 102 const storageKey = getNoticeHideKey(slide); 103 if (!storageKey) return false; 104 105 return setStorageValue( 106 localStorage, 107 storageKey, 108 String(Date.now() + ONE_DAY) 109 ); 110 } 111 112 function removeHiddenNotices() { 113 const now = Date.now(); 114 115 slides.forEach(function (slide) { 116 const storageKey = getNoticeHideKey(slide); 117 if (!storageKey) return; 118 119 const hiddenUntil = Number( 120 getStorageValue(localStorage, storageKey) || 0 121 ); 122 123 if (hiddenUntil > now) { 124 slide.remove(); 125 return; 126 } 127 128 if (hiddenUntil > 0) { 129 removeStorageValue(localStorage, storageKey); 130 } 131 }); 132 133 refreshSlides(); 134 } 135 136 function renderDots() { 137 const showNavigation = slides.length > 1; 138 const slideCountElement = currentSlideElement 139 ? currentSlideElement.closest(".slide-count") 140 : null; 141 142 if (slideCountElement) { 143 slideCountElement.hidden = !showNavigation; 144 } 145 146 if (totalSlideElement) { 147 totalSlideElement.textContent = String(slides.length); 148 } 149 150 if (!dotsContainer) { 151 dots = []; 152 return; 153 } 154 155 dotsContainer.hidden = !showNavigation; 156 dotsContainer.innerHTML = ""; 157 158 if (!showNavigation) { 159 dots = []; 160 return; 161 } 162
163 slides.forEach(function (_, index) { 164 const dot = document.createElement("button"); 165 dot.type = "button"; 166 dot.className = "slide-dot"; 167 dot.setAttribute("aria-label", String(index + 1) + "ë²ì§¸ ê³µì§ ë³´ê¸°"); 168 169 dot.addEventListener("click", function () { 170 moveToSlide(index, true); 171 }); 172 173 dotsContainer.appendChild(dot); 174 }); 175 176 dots = Array.from(dotsContainer.children); 177 } 178 179 function getNearestSlideIndex() { 180 if (slides.length === 0) return 0; 181 182 const trackRect = track.getBoundingClientRect(); 183 const trackCenter = trackRect.left + trackRect.width / 2; 184 let nearestIndex = 0; 185 let nearestDistance = Infinity; 186 187 slides.forEach(function (slide, index) { 188 const slideRect = slide.getBoundingClientRect(); 189 const slideCenter = slideRect.left + slideRect.width / 2; 190 const distance = Math.abs(trackCenter - slideCenter); 191 192 if (distance < nearestDistance) { 193 nearestDistance = distance; 194 nearestIndex = index; 195 } 196 }); 197 198 return nearestIndex; 199 } 200 201 function moveToSlide(index, useAnimation) { 202 if (index < 0 || index >= slides.length) return; 203 204 track.scrollTo({ 205 left: index * track.clientWidth, 206 behavior: useAnimation ? "smooth" : "auto" 207 }); 208 209 changeActiveSlide(index); 210 } 211 212 function updateDetailButton(slide) { 213 const action = String(slide ? slide.dataset.detailAction || "" : "").trim(); 214 const seq = String(slide ? slide.dataset.detailSeq || "" : "").trim(); 215 const showDetailButton = 216 !isAdropSlide(slide) && 217 action === "notice_view" && 218 seq !== ""; 219 const useImageLink = 220 !isAdropSlide(slide) && 221 isImageDetailAction(action) && 222 seq !== ""; 223 const actionArea = detailButton 224 ? detailButton.closest(".popup-action") 225 : null; 226 227 if (detailButton) { 228 detailButton.disabled = !showDetailButton; 229 detailButton.hidden = !showDetailButton; 230 } 231 232 if (slide) { 233 const noticeBody = slide.querySelector(".notice-body"); 234 slide.classList.toggle("notice-slide--layer-link", useImageLink); 235 236 if (noticeBody && useImageLink) { 237 noticeBody.setAttribute("role", "link"); 238 noticeBody.setAttribute("tabindex", "0"); 239 noticeBody.setAttribute("aria-label", "ë°°ë ìì¸ë³´ê¸°"); 240 noticeBody.dataset.popupLayerLink = "true"; 241 } else if (noticeBody && noticeBody.dataset.popupLayerLink === "true") { 242 noticeBody.removeAttribute("role"); 243 noticeBody.removeAttribute("tabindex"); 244 noticeBody.removeAttribute("aria-label"); 245 delete noticeBody.dataset.popupLayerLink; 246 } 247 } 248 249 if (actionArea) { 250 actionArea.classList.toggle("is-hidden", !showDetailButton); 251 } 252 } 253 254 function updatePopupLayout(slide) { 255 if (!popupSheet || !slide) return; 256 257 const adrop = isAdropSlide(slide); 258 popupSheet.classList.toggle("is-adrop-active", adrop); 259 260 // ì¼ë° ê³µì§ì Adrop 모ë ëì¼í íì ê°ë¡íì ì¬ì©í©ëë¤. 261 popupSheet.style.width = ""; 262 popupSheet.style.maxWidth = ""; 263 } 264 265 function changeActiveSlide(index) { 266 if (index < 0 || index >= slides.length) return; 267 if (activeIndex === index) return; 268 269 activeIndex = index; 270 271 slides.forEach(function (slide, slideIndex) { 272 slide.setAttribute( 273 "aria-hidden", 274 slideIndex === index ? "false" : "true" 275 ); 276 }); 277 278 dots.forEach(function (dot, dotIndex) { 279 const active = dotIndex === index; 280 dot.classList.toggle("active", active); 281 282 if (active) { 283 dot.setAttribute("aria-current", "true"); 284 } else { 285 dot.removeAttribute("aria-current"); 286 } 287 }); 288 289 if (currentSlideElement) { 290 currentSlideElement.textContent = String(index + 1); 291 } 292 293 const currentSlide = slides[index]; 294 updatePopupLayout(currentSlide); 295 updateDetailButton(currentSlide); 296 scheduleViewCount(currentSlide); 297 } 298 299 function scheduleViewCount(slide) { 300 window.clearTimeout(viewTimer); 301 302 if (!slide || isAdropSlide(slide)) return; 303 304 viewTimer = window.setTimeout(function () { 305 increaseViewCount(slide); 306 }, 500); 307 } 308 309 async function increaseViewCount(slide) { 310 if (!slide) return; 311 312 const noticeId = String(slide.dataset.noticeId || "").trim(); 313 const version = String(slide.dataset.version || "1").trim();
314 const seq = String(slide.dataset.detailSeq || "").trim(); 315 const popGb = String(slide.dataset.popGb || "").trim(); 316 317 if (!noticeId) return; 318 319 const storageKey = "notice-view:" + noticeId + ":" + version; 320 if (getStorageValue(sessionStorage, storageKey)) return; 321 322 setStorageValue(sessionStorage, storageKey, "1"); 323 324 try { 325 const response = await fetch("/inc/axPopBnLog.hbb", { 326 method: "POST", 327 credentials: "same-origin", 328 keepalive: true, 329 headers: { 330 "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" 331 }, 332 body: new URLSearchParams({ 333 noticeId: noticeId, 334 seq: seq, 335 popGb: popGb 336 }).toString() 337 }); 338 339 if (!response.ok) { 340 throw new Error("ì¡°íì ì ì¥ ì¤í¨: " + response.status); 341 } 342 } catch (error) { 343 removeStorageValue(sessionStorage, storageKey); 344 console.error(error); 345 } 346 } 347 348 track.addEventListener("scroll", function () { 349 if (isDragging || slides.length === 0) return; 350 351 window.clearTimeout(scrollTimer); 352 scrollTimer = window.setTimeout(function () { 353 if (track.clientWidth <= 0) return; 354 355 const index = Math.round(track.scrollLeft / track.clientWidth); 356 const safeIndex = Math.max(0, Math.min(index, slides.length - 1)); 357 changeActiveSlide(safeIndex); 358 }, 150); 359 }, { passive: true }); 360 361 track.addEventListener("pointerdown", function (event) { 362 if (event.pointerType === "mouse" && event.button !== 0) return; 363 if (slides.length === 0) return; 364 365 isDragging = true; 366 isHorizontalDrag = false; 367 ignoreNextClick = false; 368 dragStartX = event.clientX; 369 dragStartY = event.clientY; 370 dragCurrentX = event.clientX; 371 dragStartScrollLeft = track.scrollLeft; 372 dragStartIndex = activeIndex >= 0 ? activeIndex : getNearestSlideIndex(); 373 374 }); 375 376 track.addEventListener("pointermove", function (event) { 377 if (!isDragging) return; 378 379 const moveX = event.clientX - dragStartX; 380 const moveY = event.clientY - dragStartY; 381 dragCurrentX = event.clientX; 382 383 if (!isHorizontalDrag) { 384 if (Math.abs(moveX) < 6) return; 385 if (Math.abs(moveY) > Math.abs(moveX)) return; 386 387 isHorizontalDrag = true; 388 track.classList.add("is-dragging"); 389 390 // ë¨ì í´ë¦ì ë°°ë ë´ë¶ ë§í¬ê° ê·¸ëë¡ ì²ë¦¬íëë¡ ëê³ , 391 // ì¤ì ê°ë¡ ì¤ìì´íê° ììë ê²½ì°ìë§ í¬ì¸í°ë¥¼ 캡ì²í©ëë¤. 392 try { 393 track.setPointerCapture(event.pointerId); 394 } catch (error) { 395 // ì¼ë¶ ë¸ë¼ì°ì ììë pointer capture를 ì§ìíì§ ìì ì ììµëë¤. 396 } 397 } 398 399 track.scrollLeft = dragStartScrollLeft - moveX; 400 event.preventDefault(); 401 }); 402 403 function finishDrag(event) { 404 if (!isDragging) return; 405 406 const moveX = dragCurrentX - dragStartX; 407 isDragging = false; 408 track.classList.remove("is-dragging"); 409 410 try { 411 if ( 412 track.hasPointerCapture && 413 track.hasPointerCapture(event.pointerId) 414 ) { 415 track.releasePointerCapture(event.pointerId); 416 } 417 } catch (error) { 418 // ì¼ë¶ ë¸ë¼ì°ì ìì¸ë¥¼ 무ìí©ëë¤. 419 } 420 421 if (!isHorizontalDrag) { 422 isHorizontalDrag = false; 423 return; 424 } 425 426 isHorizontalDrag = false; 427 ignoreNextClick = Math.abs(moveX) > 5; 428 429 let targetIndex = dragStartIndex; 430 if (Math.abs(moveX) >= DRAG_THRESHOLD) { 431 targetIndex = moveX < 0 ? dragStartIndex + 1 : dragStartIndex - 1; 432 } 433 434 targetIndex = Math.max(0, Math.min(targetIndex, slides.length - 1)); 435 moveToSlide(targetIndex, true); 436 } 437 438 track.addEventListener("pointerup", finishDrag); 439 track.addEventListener("pointercancel", finishDrag); 440 441 track.addEventListener("click", function (event) { 442 if (!ignoreNextClick) return; 443 444 event.preventDefault(); 445 event.stopPropagation(); 446 ignoreNextClick = false; 447 }, true); 448 449 track.addEventListener("dragstart", function (event) { 450 event.preventDefault(); 451 }); 452 453 function executeDetailAction(slide) { 454 if (!slide) return; 455 456 const action = String(slide.dataset.detailAction || "").trim();
457 const seq = String(slide.dataset.detailSeq || "").trim(); 458 const popGb = String(slide.dataset.popGb || "").trim().toLowerCase(); 459 460 if (!action) return; 461 462 if (!/^\d+$/.test(seq)) { 463 console.error("ì못ë ìì¸ë³´ê¸° ë²í¸ì ëë¤.", seq); 464 return; 465 } 466 467 const encodedSeq = encodeURIComponent(seq); 468 469 if (popGb === "brd" && action === "notice_view") { 470 closePopup(); 471 window.location.href = "/cs/notice_view.hbb?brd_id=" + encodedSeq; 472 return; 473 } 474 475 if (popGb === "brd" && action === "bn_link") { 476 if (typeof window.actBnLink !== "function") { 477 console.error("actBnLink í¨ìê° ììµëë¤."); 478 return; 479 } 480 481 closePopup(); 482 window.actBnLink(seq); 483 return; 484 } 485 486 if (popGb === "banner" && action === "bn_link") { 487 closePopup(); 488 window.location.href = "/inc/bn_link.hbb?seq=" + encodedSeq; 489 return; 490 } 491 492 if (popGb === "banner" && action === "bn_pop") { 493 if (typeof window.goUrl !== "function") { 494 console.error("goUrl í¨ìê° ììµëë¤."); 495 return; 496 } 497 498 closePopup(); 499 window.goUrl("/inc/bn_link.hbb?seq=" + encodedSeq, "Y", ""); 500 return; 501 } 502 503 if (popGb === "banner" && action === "bn_outopen") { 504 const externalUrl = "/inc/bn_link.hbb?seq=" + encodedSeq; 505 closePopup(); 506 507 if (typeof window.outOpen === "function") { 508 window.outOpen(externalUrl); 509 } else { 510 window.open(externalUrl, "_blank", "noopener,noreferrer"); 511 } 512 return; 513 } 514 515 console.warn("ë±ë¡ëì§ ìì ìì¸ë³´ê¸° ì¡°í©:", { 516 popGb: popGb, 517 action: action, 518 seq: seq 519 }); 520 } 521 522 function executeLayerDetailAction(event) { 523 const noticeBody = event.target.closest( 524 ".notice-slide--layer-link .notice-body" 525 ); 526 if (!noticeBody || !track.contains(noticeBody)) return; 527 528 const slide = noticeBody.closest(".notice-slide"); 529 if (!slide || isAdropSlide(slide)) return; 530 531 event.preventDefault(); 532 executeDetailAction(slide); 533 } 534 535 track.addEventListener("click", executeLayerDetailAction); 536 537 track.addEventListener("keydown", function (event) { 538 if (event.key !== "Enter" && event.key !== " ") return; 539 540 const noticeBody = event.target.closest( 541 ".notice-slide--layer-link .notice-body" 542 ); 543 if (!noticeBody || !track.contains(noticeBody)) return; 544 545 event.preventDefault(); 546 executeDetailAction(noticeBody.closest(".notice-slide")); 547 }); 548 549 if (detailButton) { 550 detailButton.addEventListener("click", function (event) { 551 event.preventDefault(); 552 553 if ( 554 detailButton.disabled || 555 detailButton.hidden || 556 activeIndex < 0 || 557 activeIndex >= slides.length 558 ) { 559 return; 560 } 561 562 executeDetailAction(slides[activeIndex]); 563 }); 564 } 565 566 function hideActiveNoticeForOneDay() { 567 if (activeIndex < 0 || activeIndex >= slides.length) return; 568 569 window.clearTimeout(viewTimer); 570 window.clearTimeout(scrollTimer); 571 572 const currentSlide = slides[activeIndex]; 573 if (!hideNoticeForOneDay(currentSlide)) { 574 console.error("í루 ì¨ê¹ ì 보를 ì ì¥íì§ ëª»íìµëë¤."); 575 return; 576 } 577 578 const removedIndex = activeIndex; 579 currentSlide.remove(); 580 refreshSlides(); 581 582 if (slides.length === 0) { 583 closePopup(); 584 return; 585 } 586 587 renderDots(); 588 589 const nextIndex = Math.min(removedIndex, slides.length - 1); 590 activeIndex = -1; 591 track.scrollLeft = 0; 592 593 window.requestAnimationFrame(function () { 594 moveToSlide(nextIndex, false); 595 }); 596 } 597 598 function setPopupVisible(visible) { 599 popup.hidden = !visible; 600 popup.setAttribute("aria-hidden", visible ? "false" : "true"); 601 document.body.classList.toggle("popup-open", visible); 602 } 603 604 function openPopup() { 605 refreshSlides(); 606 607 if (slides.length === 0) { 608 setPopupVisible(false); 609 return; 610 } 611 612 activeIndex = -1; 613 setPopupVisible(true); 614 615 window.requestAnimationFrame(function () { 616 track.scrollLeft = 0; 617 changeActiveSlide(0);
618 }); 619 } 620 621 function closePopup() { 622 window.clearTimeout(scrollTimer); 623 window.clearTimeout(viewTimer); 624 isDragging = false; 625 isHorizontalDrag = false; 626 track.classList.remove("is-dragging"); 627 setPopupVisible(false); 628 } 629 630 if (closeButton) { 631 closeButton.addEventListener("click", closePopup); 632 } 633 634 if (hideDayButton) { 635 hideDayButton.addEventListener("click", hideActiveNoticeForOneDay); 636 } 637 638 popup.addEventListener("click", function (event) { 639 if (event.target === popup) closePopup(); 640 }); 641 642 document.addEventListener("keydown", function (event) { 643 if (event.key === "Escape" && !popup.hidden) closePopup(); 644 }); 645 646 window.addEventListener("resize", function () { 647 if (popup.hidden || activeIndex < 0 || activeIndex >= slides.length) return; 648 649 window.clearTimeout(scrollTimer); 650 scrollTimer = window.setTimeout(function () { 651 updatePopupLayout(slides[activeIndex]); 652 moveToSlide(activeIndex, false); 653 }, 100); 654 }); 655 656 function prepareAdropSlides() { 657 const currentSlides = Array.from(track.querySelectorAll(".notice-slide")); 658 let adropSlides = currentSlides.filter(function (slide) { 659 const popGb = String(slide.dataset.popGb || "").trim().toLowerCase(); 660 return popGb === "adrop" || !initialSlideSet.has(slide); 661 }); 662 663 // SDKê° article.notice-slide ìì´ ì¼ë° ììë§ ì¶ê°í ê²½ì° íëì ì¬ë¼ì´ëë¡ ê°ìëë¤. 664 if (adropSlides.length === 0) { 665 const newChildren = Array.from(track.children).filter(function (child) { 666 return !initialTrackChildren.has(child); 667 }); 668 669 if (newChildren.length > 0) { 670 const article = document.createElement("article"); 671 const body = document.createElement("div"); 672 article.className = "notice-slide notice-slide--adrop"; 673 body.className = "notice-body"; 674 675 track.insertBefore(article, newChildren[0]); 676 article.appendChild(body); 677 newChildren.forEach(function (child) { 678 body.appendChild(child); 679 }); 680 681 adropSlides = [article]; 682 } 683 } 684 685 adropSlides.forEach(function (slide, index) { 686 slide.classList.add("notice-slide--adrop"); 687 slide.dataset.noticeId = index === 0 688 ? ADROP_NOTICE_ID 689 : ADROP_NOTICE_ID + "_" + String(index + 1); 690 slide.dataset.version = "1"; 691 slide.dataset.popGb = "adrop"; 692 slide.dataset.detailAction = ""; 693 slide.dataset.detailSeq = ""; 694 slide.setAttribute("aria-hidden", "true"); 695 track.prepend(slide); 696 }); 697 } 698 699 function initializeNoticePopup() { 700 if (popupInitialized) return; 701 popupInitialized = true; 702 window.clearTimeout(initializeTimer); 703 setPopupVisible(false); 704 705 refreshSlides(); 706 prepareAdropSlides(); 707 refreshSlides(); 708 removeHiddenNotices(); 709 refreshSlides(); 710 711 if (slides.length === 0) { 712 setPopupVisible(false); 713 return; 714 } 715 716 renderDots(); 717 openPopup(); 718 } 719 720 function finishAdropInitialization() { 721 initializeNoticePopup(); 722 } 723 724 // SDKê° ì½ë°±ì í¸ì¶íì§ ìë ê²½ì°ìë ì¼ë° ê³µì§ë íìí©ëë¤. 725 initializeTimer = window.setTimeout(finishAdropInitialization, 4000); 726 727 if ( 728 window.jQuery && 729 window.jQuery.adropAd && 730 typeof window.jQuery.adropAd.getAdropBanner === "function" 731 ) { 732 const adropSessionId = 733 typeof sessionId !== "undefined" ? sessionId : ""; 734 735 window.jQuery.adropAd.getAdropBanner( 736 ADROP_UNIT_ID, 737 "noticeTrack", 738 adropSessionId, 739 finishAdropInitialization, 740 finishAdropInitialization 741 ); 742 } else { 743 finishAdropInitialization(); 744 } 745});
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.