import { ensureBaronSsoAuth } from "../baron-sso-auth.js?v=20260721-worker2"; import "../header-login.js?v=20261030-1"; const pathSegments = location.pathname.split('/').filter(Boolean); const rootMarkerSegments = ['ko', 'en', 'callback', 'assets', 'protected', 'public', 'recruit']; const rootPrefix = pathSegments.length && !rootMarkerSegments.includes(pathSegments[0]) ? `/${pathSegments[0]}` : ''; const normalizePath = (path) => { const normalizedPath = (path || '/').replace(/\/index\.html$/i, '/'); if (normalizedPath.length > 1 && normalizedPath.endsWith('/')) { return normalizedPath.slice(0, -1); } return normalizedPath; }; const currentPath = normalizePath(location.pathname); const matchesPublicPath = (path, entry) => { const normalizedEntry = normalizePath(entry); if (normalizedEntry.endsWith('_')) { return path.startsWith(normalizedEntry); } return path === normalizedEntry || path.startsWith(`${normalizedEntry}/`); }; const landingPagePaths = [ `${rootPrefix}/ko`, `${rootPrefix}/ko/`, `${rootPrefix}/ko/index.html`, `${rootPrefix}/en`, `${rootPrefix}/en/`, `${rootPrefix}/en/index.html`, ]; const publicPagePaths = [ ...landingPagePaths, `${rootPrefix}/ko/br_`, `${rootPrefix}/en/br_`, `${rootPrefix}/ko/dt_`, `${rootPrefix}/en/dt_`, `${rootPrefix}/recruit/`, `${rootPrefix}/ko/sv_sw.html`, `${rootPrefix}/en/sv_sw.html`, `${rootPrefix}/ko/sv_sw_`, `${rootPrefix}/en/sv_sw_`, `${rootPrefix}/ko/egbim`, `${rootPrefix}/en/egbim`, `${rootPrefix}/ko/tova`, `${rootPrefix}/en/tova`, `${rootPrefix}/ko/pr_`, `${rootPrefix}/en/pr_`, `${rootPrefix}/ko/gaia`, `${rootPrefix}/en/gaia`, `${rootPrefix}/ko/kngil`, `${rootPrefix}/en/kngil`, `${rootPrefix}/ko/sv_bigroom.html`, `${rootPrefix}/en/sv_bigroom.html`, ]; const normalizedLandingPagePaths = landingPagePaths.map(normalizePath); const isLandingPage = normalizedLandingPagePaths.includes(currentPath); const isPublicInfoPage = publicPagePaths.some((entry) => matchesPublicPath(currentPath, entry)); const loginRequested = isPublicInfoPage && new URL(window.location.href).searchParams.get('login') === '1'; if (isLandingPage) { document.documentElement.dataset.baronPageMode = 'landing'; } else if (isPublicInfoPage) { document.documentElement.dataset.baronPageMode = 'public-info'; } const authResult = await ensureBaronSsoAuth( isPublicInfoPage ? { publicPaths: publicPagePaths, forceAuth: loginRequested, } : {} ); const isAuthenticated = Boolean(authResult?.session); document.documentElement.dataset.baronAuthState = isAuthenticated ? 'authenticated' : 'anonymous'; // Disabled links in anonymous navigation must not navigate, including keyboard/programmatic clicks. document.addEventListener('click', (event) => { const target = event.target instanceof Element ? event.target : null; const disabledLink = target?.closest('a[data-auth-disabled="true"]'); if (!disabledLink) return; event.preventDefault(); event.stopImmediatePropagation(); }, true); function followLoginTooltip(event) { const target = event.target instanceof Element ? event.target : null; const menuItem = target?.closest('li.nav-login-required[data-login-tooltip]'); if (!menuItem) return; const rect = menuItem.getBoundingClientRect(); const margin = 8; const offset = 16; const tooltipWidth = Math.min(320, Math.max(0, window.innerWidth - margin * 2)); const tooltipHeight = 84; let left = event.clientX + offset; if (left + tooltipWidth > window.innerWidth - margin) { left = event.clientX - tooltipWidth - offset; } left = Math.max(margin, left); let top = event.clientY + offset; if (top + tooltipHeight > window.innerHeight - margin) { top = event.clientY - tooltipHeight - offset; } top = Math.max(margin, top); menuItem.style.setProperty('--login-tooltip-left', `${left - rect.left}px`); menuItem.style.setProperty('--login-tooltip-top', `${top - rect.top}px`); } document.addEventListener('pointermove', followLoginTooltip, { passive: true }); // ?�� AJAX 관??SCRIPT $(function () { const includeVersion = '20261030-1'; // 비로그인 요청은 Worker가 nav-public.html만 허용하므로 로그인 상태에 맞는 메뉴 파일을 선택한다. const navIncludeFile = isAuthenticated ? 'nav.html' : 'nav-public.html'; const includeBase = `${rootPrefix}/_include/eng`; $.ajaxSetup({ cache: false }); // Share both in-flight and completed static includes within this page. const htmlRequests = new Map(); function loadHTML(url, target, callback) { let request = htmlRequests.get(url); if (!request) { request = $.ajax({ url, cache: true, dataType: "html", timeout: 5000 }); htmlRequests.set(url, request); request.fail(function () { htmlRequests.delete(url); }); } request.done(function (data) { $(target).html(data); if (typeof callback === "function") callback(); }).fail(function (xhr, status, error) { console.error(`Failed to load ${url}:`, error || status); if (typeof callback === "function") callback(); }); } function normalizeSiteLinks(root) { if (!root) { return; } root.querySelectorAll('a[href], img[src], source[src]').forEach((node) => { const attributeName = node.hasAttribute('href') ? 'href' : 'src'; const rawValue = node.getAttribute(attributeName); if (!rawValue || /^(?:https?:|mailto:|tel:|javascript:|#)/i.test(rawValue)) { return; } const normalizedValue = rawValue .replace(/^\.\.\/(ko|en|recruit)\//, `${rootPrefix}/$1/`) .replace(/^\/(ko|en|recruit)\//, `${rootPrefix}/$1/`) .replace(/^\.\.\/callback\.html$/, `${rootPrefix}/callback.html`) .replace(/^\/callback\.html$/, `${rootPrefix}/callback.html`); if (normalizedValue !== rawValue) { node.setAttribute(attributeName, normalizedValue); } }); } // nav 연결 (depth3 지원) function connectNavToMapList() { const currentPathname = location.pathname; // 전체 경로로 비교 const navLinks = document.querySelectorAll( "header .corp nav ol li.depth1 ul.depth2 li a" ); let matchedLink = null; navLinks.forEach((link) => { const href = link.getAttribute("href"); // 절대경로 그대로 if (href === currentPathname || currentPathname.endsWith(href)) { if (matchedLink && matchedLink.closest('.depth3')) { return; } if (!matchedLink || link.closest('.depth3')) { matchedLink = link; } } }); if (matchedLink) { const mapList = document.querySelector(".map_list"); if (mapList) { mapList.innerHTML = ""; matchedLink.closest(".depth1").classList.add("active"); const hasDepth3 = matchedLink.closest("li.has_depth3"); if (hasDepth3) { matchedLink.closest(".depth1").querySelectorAll("li.has_depth3").forEach(el => { el.classList.remove("active"); }); hasDepth3.classList.add("active"); } const liHome = document.createElement("li"); liHome.innerHTML = ''; mapList.appendChild(liHome); const categoryTitle = matchedLink .closest(".depth1") ?.querySelector("span") ?.textContent.trim(); const subTitle = matchedLink .closest(".depth1") ?.querySelector("em") ?.textContent.trim(); const mainTitle = categoryTitle.replace(subTitle, "").trim(); const liCategory = document.createElement("li"); liCategory.textContent = mainTitle || ""; mapList.appendChild(liCategory); const depth3El = matchedLink.closest('.depth3'); if (depth3El) { const depth2Link = matchedLink.closest('.has_depth3')?.querySelector('a'); const depth2Title = depth2Link ? depth2Link.textContent.trim() : ""; const liDepth2 = document.createElement("li"); liDepth2.textContent = depth2Title; mapList.appendChild(liDepth2); const targetTitle = matchedLink.textContent.trim(); const liOn = document.createElement("li"); liOn.classList.add("on"); liOn.textContent = targetTitle || ""; mapList.appendChild(liOn); } else { const targetTitle = matchedLink.textContent.trim(); const liOn = document.createElement("li"); liOn.classList.add("on"); liOn.textContent = targetTitle || ""; mapList.appendChild(liOn); } } } } // PC GNB 패키지 S/W 3depth 탭 전환 기능 function initPackageSWTab() { const $dropdown = $('.package_sw_dropdown'); if (!$dropdown.length) return; const $menuItems = $dropdown.find('> li.has_depth3'); // 패키지 S/W 1depth 메뉴 호버 시 드롭다운이 열리면 첫 번째 항목 기본 활성화 $dropdown.closest('.depth1').on('mouseenter', function () { if (!$menuItems.filter('.active').length) { $menuItems.removeClass('active'); $menuItems.first().addClass('active'); } }); // 2depth 메뉴 호버 시 active 클래스 전환 $menuItems.on('mouseenter', function () { $menuItems.removeClass('active'); $(this).addClass('active'); }); } function trimPopupDepth3Nav() { const popupNav = document.querySelector(".popup_wrap.sitemap .popup_contents_wrap nav"); if (!popupNav) { return; } popupNav.querySelectorAll("li.has_depth3 > .depth3").forEach((depth3) => { depth3.remove(); }); } function configureHeaderActions(root) { if (!root) { return; } const loginWrap = root.querySelector('.header_login'); const loginLink = root.querySelector('.header_login_link'); if (!loginWrap || !loginLink) { return; } if (isAuthenticated) { loginWrap.hidden = false; loginLink.textContent = 'LOGOUT'; loginLink.href = '#'; loginLink.onclick = (event) => { event.preventDefault(); window.baronSsoLogout?.(); }; return; } if (!isPublicInfoPage) { loginWrap.hidden = true; return; } loginWrap.hidden = false; loginLink.textContent = 'LOGIN'; loginLink.href = `${location.pathname}?login=1`; loginLink.onclick = null; } function loadSitemapNav() { if (!$('.container').hasClass('recruit')) { loadHTML(`${includeBase}/${navIncludeFile}?v=${includeVersion}`, '.popup_wrap.sitemap .popup_contents_wrap nav', function () { normalizeSiteLinks(document.querySelector('.popup_wrap.sitemap .popup_contents_wrap nav')); mobileMenu(); }); } else { loadHTML(`${includeBase}/nav_recruit.html?v=${includeVersion}`, '.popup_wrap.sitemap .popup_contents_wrap nav', function () { mobileMenu(); }); } } if (!$('.container').hasClass('recruit')) { loadHTML(`${includeBase}/header.html?v=${includeVersion}`, '#header', function () { normalizeSiteLinks(document.querySelector('#header')); loadHTML(`${includeBase}/${navIncludeFile}?v=${includeVersion}`, '#header .corp .nav', function () { normalizeSiteLinks(document.querySelector('#header .corp .nav')); connectNavToMapList(); initPackageSWTab(); }); configureHeaderActions(document.querySelector('#header')); loadSitemapNav(); }); } else { loadHTML(`${includeBase}/header_recruit.html?v=${includeVersion}`, '#header_recruit', function () { loadSitemapNav(); if (!$(".container").hasClass("recruit")) { } else { const currentPath = location.pathname.split("/").pop(); const navLinks = document.querySelectorAll( "header .recruit nav ol li.depth1 a" ); navLinks.forEach((link) => { const href = link.getAttribute("href").split("/").pop(); if (href === currentPath) { link.closest(".depth1").classList.add("active"); } }); } }); } loadHTML(`${includeBase}/footer.html?v=${includeVersion}`, '#footer', function () { normalizeSiteLinks(document.querySelector('#footer')); loadHTML(`${includeBase}/${navIncludeFile}?v=${includeVersion}`, '#footer .nav', function () { normalizeSiteLinks(document.querySelector('#footer .nav')); }); }); }); // ?�� TITLE 관??SCRIPT // ?�� S: title ?�일?�기 $(function () { const currentPath = location.pathname; if (currentPath.indexOf("/recruit/") > 0) { document.querySelector("head title").textContent = "?�재채용 | (�?바론컨설?�트"; } else { document.querySelector("head title").textContent = "BaronConsultant"; } }); // E : title ?�일?�기 // ?�� S : header ?�기�? $(function () { const showNav = gsap .from("#header, #header_recruit", { yPercent: -200, paused: true, duration: 0.2, onStart: () => { const stHeader = document.querySelector("header"); if (window.scrollY > 100) { stHeader.classList.add("open"); } }, onReverseComplete: () => { const stHeader = document.querySelector("header"); stHeader.classList.remove("open"); }, }) .progress(1); let showMapList = null; const headerNavMM = gsap.matchMedia(); headerNavMM.add("(max-width: 1400px)", () => { showMapList = gsap .from(".map_list", { y: -40, autoAlpha: 0, paused: true, duration: 0.2, }) .progress(1); return () => { showMapList = null; }; }); ScrollTrigger.create({ start: "top top", end: 99999, onUpdate: (self) => { if (lenis.isStopped) return; if (self.direction === -1) { showNav.play(); showMapList && showMapList.play(); } else { showNav.reverse(); showMapList && showMapList.reverse(); } }, }); }); // E : header ?�기�? // ?�� POPUP SCRIPT // ?��S : ?�업 ?�기 // ?��S : ?�업 ?�기 $(function () { $(document).on("click", "button", function () { const button = this; const value = button.getAttribute("data-value"); const popup = document.querySelector(`.popup_wrap.${value}`); if (popup) { // ?�재 ?�크�??�치 ?�?? const scrollY = window.scrollY; document.body.setAttribute('data-scroll-lock', scrollY); // body 고정 document.body.style.position = 'fixed'; document.body.style.top = `-${scrollY}px`; document.body.style.left = '0'; document.body.style.right = '0'; // Lenis ?�전 중�? if (lenis) { lenis.destroy(); } // ?�업 ?�시 popup.style.display = 'block'; // ?�업 ?��? ?�치 ?�크�?강제 ?�성?? const popupContents = popup.querySelector('.popup_contents_wrap'); if (popupContents) { popupContents.removeAttribute('data-lenis-prevent-wheel'); popupContents.removeAttribute('data-lenis-prevent'); popupContents.style.cssText = ` overflow-y: auto !important; -webkit-overflow-scrolling: touch !important; overscroll-behavior: contain !important; height: 100vh !important; touch-action: pan-y !important; `; // ?�치 ?�벤??강제 ?�용 popupContents.addEventListener('touchstart', function(e) { e.stopPropagation(); }, { passive: true }); popupContents.addEventListener('touchmove', function(e) { e.stopPropagation(); }, { passive: true }); } } }); }); // E : ?�업 ?�기 // ?��S : ?�업 ?�기 $(function () { $(document).on("click", function (e) { const $target = $(e.target); // ?��?�기 버튼 ?�릭 ?? if ($target.closest(".btn_close").length) { const $popupWrap = $target.closest(".popup_wrap"); if ($popupWrap.length) { $popupWrap.hide(); enableBodyScroll(); } return; } // ?��popup_contents_wrap ?�릭 ?�도 ?�함?�서 ?�기 const $popupContents = $target.closest(".popup_contents_wrap"); if ($popupContents.length && $target.is(".popup_contents_wrap")) { const $popupWrap = $target.closest(".popup_wrap"); if ($popupWrap.length) { $popupWrap.hide(); enableBodyScroll(); } } }); // ?��?�업 ?�힐 ??body ?�크�??�성?? function enableBodyScroll() { // body ?�크�??�치 복원 const scrollY = document.body.style.top; document.body.style.position = ''; document.body.style.top = ''; document.body.style.width = ''; window.scrollTo(0, parseInt(scrollY || '0') * -1); // Lenis ?�시?? lenis.start(); } }); // E : ?�업 ?�기 // ?��S : map list ?�직이�? /* 250604추�??�� */ let lastScrollY = window.scrollY; const stickyBox = document.querySelector(".map_list"); window.addEventListener("scroll", () => { const currentScrollY = window.scrollY; const width = window.innerWidth; if (width > 1440) { //250604 추�? if (stickyBox != null) { if (currentScrollY > lastScrollY) { // ?�래�??�크롤할 ?? stickyBox.style.top = "24px"; } else { // ?�로 ?�크롤할 ?? stickyBox.style.top = "124px"; } } } else { if (stickyBox != null) { if (currentScrollY > lastScrollY) { // ?�래�??�크롤할 ?? stickyBox.style.top = "24px"; } else { // ?�로 ?�크롤할 ?? stickyBox.style.top = "74px"; } } } lastScrollY = currentScrollY; }); // E : map list ?�직이�? // ?�� SCROLL SCRIPT // ?��AOS AOS.init(); // ?��Lenis let lenis; function handleStartLenis() { lenis = new Lenis({ lerp: 0.1, // ?�크롤의 부?�러???�도 smoothWheel: true, smoothTouch: false, }); gsap.ticker.add((time) => { lenis.raf(time * 1000); }); gsap.ticker.lagSmoothing(0); } handleStartLenis(); export default lenis; function mobileMenu() { const mNav = document.querySelectorAll(".sitemap ol > li.depth1"); mNav.forEach((item) => { const trigger = item.querySelector(":scope > span"); const depth2 = item.querySelector(":scope > .depth2"); if (!trigger || !depth2 || trigger.dataset.mobileMenuBound === "true") { return; } trigger.dataset.mobileMenuBound = "true"; trigger.addEventListener("click", function () { if (window.innerWidth > 1440) { return; } const isActive = item.classList.contains("active"); // 다른 모든 활성화된 메뉴 닫기 (아코디언 동작) mNav.forEach((otherItem) => { if (otherItem !== item) { otherItem.classList.remove("active"); const otherDepth2 = otherItem.querySelector(":scope > .depth2"); if (otherDepth2) { otherDepth2.style.maxHeight = null; } } }); if (!isActive) { item.classList.add("active"); depth2.style.maxHeight = depth2.scrollHeight + "px"; } else { item.classList.remove("active"); depth2.style.maxHeight = null; } }); }); }