PageSourceSearch

https://bluetire.co.kr/js/pages/index.js

js bluetire.co.kr collected 2026-10-09 01:55:42 UTC 26,809 bytes, 708 lines download raw bytes

1/*
2 * © NHN Commerce Corp. All rights reserved.
3 * NHN Corp. PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 *
5 * @author Eunbi Kim
6 * @since 2021-6-23
7 */
8
9(() => {
10  shopby.home = {
11    initiate() {
12      shopby.setGlobalVariableBy('MAIN');
13      this.banner.initiate();
14      this.sectionProduct.initiate();
15      this.instagram.initiate();
16      this.ProductsReviewsWidget.initiate();
17      this.boardNotice.initiate(); //24.05.08 seet3 추가
18      this.csCenter.initiate(); //24.07.25 seet3
19
20      //카드혜택 탭 클릭이벤트 추가
21      $('.tab_btn button').click(function(){
22          $('.tab_btn button').removeClass('on');
23          $(this).addClass('on');
24          $('.tab_con div').removeClass('on');
25          $('.tab_con div').eq($(this).index()).addClass('on');
26      });
27
28    },
29    banner: {
30      DEFAULT_COLOR: '#ffffff',
31      data: {
32        totalBanners: {},
33      },
34      initiate() {
35        this.setTotalBanners();
36        this.render();
37        this.iterateSkin(bannerInfo => this.setBannerSize(bannerInfo));
38        this.setMainSlider();
39      },
40      render() {
41        $('#promotionBanner').render(this.data.totalBanners);
42        this.$sliderBanner = $('.slider-banner');
43      },
44      setTotalBanners() {
45        this.iterateSkin(({ bannerName, banners }) => {
46          this.data.totalBanners[bannerName] = this.findLatestBanner(banners);
47        });
48      },
49      findLatestBanner(banners = []) {
50        if (banners.length === 0) return;
51        if (banners.length === 1) return banners[0];
52        return banners.reduce((prev, curr) => {
53          return new Date(prev.updateDateTime).getTime() <= new Date(curr.updateDateTime).getTime() ? curr : prev;
54        });
55      },
56      iterateSkin(func) {
57        const skin = shopby.cache.getSkin();
58        if (!Array.isArray(skin)) return;
59
60        skin.forEach(({ bannerGroupCode, banners }) => {
61          const bannerName = this.findBannerName(bannerGroupCode);
62          func({ banners, currentBanner: this.data.totalBanners[bannerName], bannerName });
63        });
64      },
65      findBannerName(bannerGroupCode) {
66        // eslint-disable-next-line no-unused-vars
67        return shopby.config.skin.bannerGroupCodes.find(value => value === bannerGroupCode);
68      },
69      setBannerSize({ bannerName, currentBanner }) {
70        const exclusionBanners = ['LOGO0001', 'BANNER08', 'BANNER09'];
71        if (exclusionBanners.includes(bannerName)) return;
72
73        const { sizeUnitType, height, width } = currentBanner;
74        if (!width && !height) return;
75
76        const $img = $(`#banner-${bannerName}`).find('img');
77        if (sizeUnitType === 'PIXEL') {
78          $img.css({ width: `${width}px`, height: `${height}px` });
79        } else {
80          $img.css({ width: `${width}%` });
81        }
82      },
83      setMainSlider() {
84        if (!this.data.totalBanners || !this.data.totalBanners.BANNER01) return;
85        const banner = this.data.totalBanners.BANNER01;
86        this.setSlick(banner);
87        this.setNavigationBtn(banner);
88        this.setNavigationBtnColor(banner);
89        this.setPrevAndNextBtn(banner);
90      },
91      setSlick(banner) {
92        const SPEED_TYPE = {
93          FAST: 300,
94          NORMAL: 1300,
95          SLOW: 2300,
96        };
97        const defaultSlideBannerConfig = {
98          slideNavigationType: null,
99          usableSlideButton: null,
100          slideTime: 0,
101          slideSpeedType: null,
102          slideEffectType: null,
103        };
104        const slideBannerConfig = (({
105          slideNavigationType,
106          usableSlideButton,
107          slideTime,
108          slideSpeedType,
109          slideEffectType,
110        }) => {
111          if (usableSlideButton === false) {
112           
113            $('.main_visual .swiper-button-next,.main_visual .swiper-button-prev').addClass('dn');
114          }
115
116          return {
117            autoplay:!slideTime ? false : { delay: slideTime * 1000 } ,
118            navigation:
119              usableSlideButton === 'false'
120                ? false
121                : {
122                    nextEl: '.main_visual .swiper-button-next',
123                    prevEl: '.main_visual .swiper-button-prev',
124                  },
125            pagination:
126              slideNavigationType === 'visible'
127                ? false
128                : {
129                    el: '.main_visual .swiper-pagination',
130                    clickable: true,
131                  },
132            speed: SPEED_TYPE[slideSpeedType] || 1300,
133            slidesPerView: 1,
134            effect: slideEffectType === 'FADE' ? 'fade' : 'slide',
135            fadeEffect: {
136              crossFade: slideEffectType === 'FADE',
137            },
138            spaceBetween: 0,
139            loop: true,
140            autoHeight: false,
141            on: {
142              init: function () {
143                const swiper = this;
144                // if (!usableSlideButton) {
145                //   //const sliderBannerEl = swiper.$el[0].closest('.slider-banner');
146                //   if (sliderBannerEl) {
147                //     sliderBannerEl.classList.add('hideBtn');
148                //   }
149                // }
150              },
151            },
152          };
153        })(banner && banner.slideBannerConfig ? banner.slideBannerConfig : defaultSlideBannerConfig);
154
155        this.swiper = new Swiper('.swiper-container', slideBannerConfig);
156      },
157      setNavigationBtn(banner) {
158        if (
159          !banner.slideBannerConfig ||
160          !banner.slideBannerConfig.slideNavigationInfo ||
161          !banner.slideBannerConfig.slideNavigationInfo.buttonSizeType
162        )
163          return;
164
165        const classList = [];
166        const prefix = 'indicator-';
167        const { buttonSizeType, buttonBorderType } = banner.slideBannerConfig.slideNavigationInfo;
168        if (buttonSizeType) {
169          classList.push(prefix + 'btn-' + buttonSizeType.toLowerCase());
170        }
171        if (buttonBorderType) {
172          classList.push(prefix + 'border-' + buttonBorderType.toLowerCase());
173        }
174        this.$sliderBanner.addClass(classList.join(' '));
175      },
176      setNavigationBtnColor(banner) {
177        const defaultSlideBannerConfig = {
178          slideNavigationInfo: null,
179          slideNavigationType: null,
180        };
181        const defaultSlideNavigationInfo = {
182          inactiveButtonColor: null,
183          activeButtonColor: null,
184        };
185        const { slideNavigationInfo, slideNavigationType } =
186          (banner && banner.slideBannerConfig) || defaultSlideBannerConfig;
187        if (slideNavigationType !== 'VISIBLE') return;
188        const { inactiveButtonColor, activeButtonColor } = slideNavigationInfo || defaultSlideNavigationInfo;
189        const color = inactiveButtonColor ? inactiveButtonColor : this.DEFAULT_COLOR;
190        const activeColor = activeButtonColor ? activeButtonColor : this.DEFAULT_COLOR;
191        $('.main_visual .swiper-pagination span.swiper-pagination-bullet').css({ background: color });
192
193        const style = document.createElement('style');
194        document.head.appendChild(style);
195        style.sheet.insertRule(
196          `.main_visual .swiper-pagination span.swiper-pagination-bullet-active{ background: ${activeColor}!important; }`,
197          0,
198        );
199      },
200      setPrevAndNextBtn(banner) {
201        const defaultSlideBannerConfig = {
202          slideButtonColor: null,
203          usableSlideButton: null,
204        };
205        const { slideButtonColor, usableSlideButton } =
206          (banner && banner.slideBannerConfig) || defaultSlideBannerConfig;
207        if (!usableSlideButton) return;
208        const $prevBtn = this.$sliderBanner.find('.slick-prev');
209        const $nextBtn = this.$sliderBanner.find('.slick-next');
210        const color = slideButtonColor ? escape(slideButtonColor) : this.DEFAULT_COLOR;
211
212        const prevUrl = `"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'${color}'%2F%3E%3C%2Fsvg%3E"`;
213        const nextUrl = `"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'${color}'%2F%3E%3C%2Fsvg%3E"`;
214        $prevBtn.css({ 'background-image': `url(${prevUrl})` });
215        $nextBtn.css({ 'background-image': `url(${nextUrl})` });
216      },
217    },
218    sectionProduct: {
219      newSectionProduct: null,
220      async initiate() {
221        const sectionIds = shopby.config.skin.sections.pc;
222        const responses = await Promise.all(sectionIds.map(id => this._fetchSectionProducts(id)));
223
224        responses
225          .map(({ data }) => data)
226          .filter(Boolean)
227          .map(({ productTotalCount, products, displayConfig, label, sectionId }) => ({
228            sectionId: sectionId,
229            pagination: null,
230            totalCount: productTotalCount,
231            productList: products,
232            page: 0,
233            pageSize: 0,
234            listType: 'LIST',
235            displayConfig: displayConfig,
236            title: label,
237          }))
238          .forEach(section => {
239            this.setSectionProduct(section);
240          });
241      },
242
243      async _fetchSectionProducts(sectionsId, pageNumber = '0', pageSize = '0') {
244        const request = {
245          pathVariable: {
246            sectionsId,
247          },
248          queryString: {
249            pageNumber,
250            pageSize,
251            sectionsId,
252            soldout: true,
253            hasTotalCount: true,
254          },
255        };
256
257        return await shopby.api.display.getDisplaySectionsIdsSectionId(request);
258      },
259
260      setSectionProduct(section) {
261        this.setDisplayConfig(section);
262        this.render(section);
263        this.setPagination(section);
264        this.bindEvents(section);
265      },
266
267      setDisplayConfig(sectionProduct) {
268        const LIST_TYPE_CONVERTOR = {
269          GALLERY: 'gallery',
270          LIST: 'list',
271          CART: 'basket',
272          SIMPLE_IMAGE: 'simple',
273          PRODUCT_MOVE: 'slide',
274        };
275        const { displayHeight, displayWidth, displayType } = sectionProduct.displayConfig;
276        sectionProduct.pageSize = displayHeight * displayWidth;
277        sectionProduct.listType = LIST_TYPE_CONVERTOR[displayType];
278      },
279      render(sectionProduct) {
280        const sectionProductTemplate = this.getMainSectionProductTemplate(sectionProduct);
281        $(`#goodsList-${sectionProduct.sectionId}`).html(sectionProductTemplate).show();
282
283        const { listType, productList } = sectionProduct;
284        productList.forEach(product => {
285          product.calculatedSalePrice = shopby.utils.getDisplayProductPrice(product);
286          product.isSoldOut = this.isSoldOut(product && product.reservationData, product.stockCnt);
287          product.isUnablePurchasing = this.checkUnablePurchasing(product);
288          return product;
289        });
290        const handlebarTemplate = $(`#product-list-type-${listType}`).html();
291        const template = Handlebars.compile(handlebarTemplate);
292        const html = template({ productList });
293        $(`#productList-${sectionProduct.sectionId}`).html(html);
294      },
295      bindEvents(sectionProduct) {
296        const { sectionId } = sectionProduct;
297        $(`#productListPaging-${sectionId}`).on('click', '.moreBtn', this.onClickMoreBtn.bind(this, sectionProduct));
298        $(`#productList-${sectionId}`)
299          .on('click', '#wishBtn', event => this.onClickWishBtn(sectionProduct, event))
300          .on('click', '#cartBtn', this.onClickCartBtn.bind(this));
301      },
302      async onClickMoreBtn(sectionProduct) {
303        const { sectionId, pageSize, page } = sectionProduct;
304        const pageNumber = page === 0 ? page + 2 : page + 1;
305        try {
306          const { data } = await this._fetchSectionProducts(sectionId, pageNumber, pageSize);
307          const newSectionProduct = { ...sectionProduct };
308          newSectionProduct.productList = newSectionProduct.productList.concat(data.products);
309          newSectionProduct.page = pageNumber;
310          this.setSectionProduct(newSectionProduct);
311        } catch (e) {
312          console.error(e);
313        }
314      },
315      async onClickWishBtn(sectionProduct, event) {
316        event.preventDefault();
317
318        if (!shopby.logined()) {
319          return shopby.confirmLogin();
320        }
321        try {
322          const $button = $(event.currentTarget);
323          const liked = $button.hasClass('on');
324          const productNo = $button.closest('li').data('product-no');
325          const requestBody = { productNos: [productNo] };
326          await shopby.api.product.postProfileLikeProducts({ requestBody });
327          liked ? $button.removeClass('on') : $button.addClass('on');
328
329          const sectionId = $button.closest('.goods_list_cont').data('sectionId');
330          if (sectionProduct.listType === 'swipe') return;
331          this.updateSectionProduct(sectionId, sectionProduct);
332        } catch (e) {
333          console.error(e);
334        }
335      },
336      onClickCartBtn({ target }) {
337        shopby.popup('cart-product-option', { productNo: $(target).closest('li').data('product-no') });
338      },
339      async updateSectionProduct(sectionId, sectionProduct) {
340        this.newSectionProduct = { ...sectionProduct };
341        const { data } = await this._fetchSectionProducts(
342          sectionId,
343          this.newSectionProduct.page === 0 ? 0 : 1,
344          this.newSectionProduct.page * this.newSectionProduct.pageSize,
345        );
346
347        this.newSectionProduct.productList = data.products;
348        this.setSectionProduct(this.newSectionProduct);
349      },
350      setPagination(sectionProduct) {
351        const { listType, totalCount, pageSize, sectionId } = sectionProduct;
352        if (listType !== 'slide') {
353          sectionProduct.totalPage = Math.ceil(totalCount / pageSize);
354          this.drawMoreButton(sectionProduct);
355          return;
356        }
357        const SLICK_OPTION = {
358          draggable: true,
359          autoplay: true,
360          infinite: true,
361          slidesToShow: pageSize,
362          slidesToScroll: 1,
363        };
364        $(`#productList-${sectionId}`).find('.item_slide_horizontal .slide_horizontal_1').slick(SLICK_OPTION);
365      },
366      drawMoreButton(sectionProduct) {
367        const { totalPage, page, sectionId } = sectionProduct;
368        if (page >= totalPage) return;
369        const moreBtn = `<div class="btn_goods_down_more">
370                            <button class="btn_goods_view_down_more moreBtn">더보기</button>
371                         </div>`.trim();
372
373        $(`#productListPaging-${sectionId}`).html(moreBtn);
374      },
375      getMainSectionProductTemplate(sectionProduct) {
376        const { title, sectionId } = sectionProduct;
377
378                    return `<div class="goods_list_tit">
379            <h3>${title}</h3>
380            <div class="btn_goods_more">
381                <a href="/pages/product/list.html?sectionId=${sectionId}" class="btn_goods_view_more">더보기</a>
382            </div>
383            </div>
384            <div class="goods_list_cont" id="productList-${sectionId}" data-section-id="${sectionId}"></div>
385            <div class="paging" id="productListPaging-${sectionId}"></div>`.trim();
386                },
387      isSoldOut(reservationData, stockCnt) {
388        if (shopby.utils.isPreSalePeriod(reservationData)) {
389          if (reservationData && reservationData.reservationStockCnt === 0) return true;
390        } else {
391          if (stockCnt === 0) return true;
392        }
393      },
394      checkUnablePurchasing({ stockCnt, saleStatusType, reservationData }) {
395        // 판매종료, 판매정지, 판매금지
396        if (['FINISHED', 'STOP', 'PROHIBITION', 'READY'].includes(saleStatusType)) {
397          return true;
398        }
399
400        // 판매중 : 품절 (예약판매 재고, 일반 판매재고)
401        return this.isSoldOut(reservationData, stockCnt);
402      },
403    },
404    instagram: {
405      initiate() {
406        this.fetchInstagramContents().then(data => data && data.length && this.render(data));
407      },
408      fetchInstagramContents() {
409        const request = {
410          queryString: {
411            platform: 'PC',
412          },
413        };
414
415        return shopby.api.manage.getShopbyInstagramMedia(request).then(res => res.data.data);
416      },
417      render(data) {
418        const target = document.getElementById('instagram-widget');
419        target.innerHTML = this.getHTMLTemplate(data, 12);
420        target.style.display = 'block';
421      },
422      getHTMLTemplate(contents, maxLength) {
423        const getUsernameTemplate = contents => {
424          const { username } = contents.find(({ username }) => Boolean(username));
425          return username
426            ? `
427            <p>@${username}</p>
428          `
429            : '';
430        };
431
432        return `
433         <div class="main_goods_cont instagram_widget">
434          <header class="instagram_widget_head">
435            <img style="width:84px" src="/assets/img/banner/instagram-logo.png" alt="Instagram" />
436            ${getUsernameTemplate(contents)}
437          </header>
438          <ul class="instagram_widget_contents">
439            ${contents
440              .slice(0, maxLength)
441              .filter(({ thumbnail_url, media_url }) => !!thumbnail_url || !!media_url)
442              .map(
443                content => `
444                <li>
445                  <a href="${content.permalink}" target="_blank">
446                    <img src="${
447                      content.thumbnail_url ? content.thumbnail_url : content.media_url
448                    }" alt="instagram image" />
449                  </a>
450                </li>
451              `,
452              )
453              .join('')}
454          </ul>
455        </div>
456        `;
457      },
458    },
459    ProductsReviewsWidget: {
460      isAllUse: true,
461      allReviewWidgets: [],
462      isPhotoUse: true,
463      photoWidgets: [],
464      isReviewProducts: true,
465      reviewWidgets: [],
466      async initiate() {
467        await this.getProductReviewsConfigurations();
468        await this.render();
469        this.bindEvents();
470      },
471      async render() {
472        if (this.isAllUse) {
473          const widgetList = await this.getReviewBoards('ALL');
474          this.allReviewWidgets = widgetList.map(item => ({ ...item, type: 'ALL' }));
475          this.renderWidgetList(this.allReviewWidgets, 'ALL');
476        }
477
478        if (this.isPhotoUse) {
479          this.photoWidgets = await this.getReviewBoards('PHOTO');
480          this.renderWidgetList(this.photoWidgets, 'PHOTO');
481        }
482
483        if (this.isReviewProducts) {
484          this.reviewWidgets = await this.getReviewsBoardsReviewedProducts();
485          this.renderWidgetList(this.reviewWidgets, 'REVIEW');
486        }
487      },
488      bindEvents() {
489        $('.photo-display-popup-open').on('click', this.onClickLayerPopup.bind(this));
490      },
491      renderWidgetList(widgetList, type) {
492        const domId = type === 'ALL' ? 'all-review' : type === 'PHOTO' ? 'photo-review' : 'product-review';
493        const handlebarTemplate = $(
494          `${type === 'REVIEW' ? '#widget-list-reviewedProducts-template' : '#widget-list-allPhoto-template'}`,
495        ).html();
496        const template = Handlebars.compile(handlebarTemplate);
497        const html = template({ widgetList, type });
498        document.getElementById(domId).insertAdjacentHTML('beforeend', html);
499      },
500      async getReviewBoards(type) {
501        const {
502          data: { items },
503        } = await shopby.api.display.getReviewBoards({
504          queryString: {
505            'sorting.sortCriterion': 'BEST_REVIEW',
506            'sorting.ordering': 'DESC',
507            depth1DisplayCategoryNo: 0,
508            keyword: '',
509            pageNumber: 1,
510            boardType: type,
511            isWidget: true,
512          },
513        });
514        return items;
515      },
516      async getReviewsBoardsReviewedProducts() {
517        const {
518          data: { items },
519        } = await shopby.api.display.getReviewBoardsReviewedProducts({
520          queryString: {
521            'sorting.sortCriterion': 'REVIEW_COUNT',
522            'sorting.ordering': 'DESC',
523            depth1DisplayCategoryNo: 0,
524            keyword: '',
525            pageNumber: 1,
526            isWidget: true,
527          },
528        });
529
530        return items.map(item => {
531          return {
532            ...item,
533            mainImage: item.mainImage.includes('no_img') ? '' : item.mainImage,
534            salePrice: item.salePrice,
535            appliedImmediateDiscountPrice: item.appliedImmediateDiscountPrice,
536          };
537        });
538      },
539      async getProductReviewsConfigurations() {
540        const { data } = await shopby.api.display.getProductReviewsConfigurations();
541        this.setProductReviewsConfigurations(data);
542      },
543      setProductReviewsConfigurations(data) {
544        const widgetConfig = data.expandedReviewConfig.widgetConfig;
545        this.isAllUse = widgetConfig.allReviewWidgetUsable;
546        this.isPhotoUse = widgetConfig.photoReviewWidgetUsable;
547        this.isReviewProducts = widgetConfig.productReviewWidgetUsable;
548      },
549      getProductReviewsRequest(productNo) {
550        return {
551          pathVariable: { productNo },
552          queryString: {
553            'order.by': 'BEST_REVIEW',
554            pageNumber: 1,
555            pageSize: 9999,
556            hasTotalCount: true,
557          },
558        };
559      },
560      getBoardsRequest(boardType) {
561        return {
562          queryString: {
563            'sorting.sortCriterion': 'BEST_REVIEW',
564            'sorting.ordering': 'DESC',
565            depth1DisplayCategoryNo: 0,
566            keyword: '',
567            pageNumber: 1,
568            isWidget: true,
569            boardType,
570          },
571        };
572      },
573      onClickLayerPopup(event) {
574        event.stopPropagation();
575        const reviewNo = Number(event.currentTarget.dataset.reviewNo);
576        const productNo = Number(event.currentTarget.dataset.productNo);
577        const { type }
577 = event.currentTarget.dataset;
578        const isReviewedProducts = type === 'REVIEWED_PRODUCTS';
579        const popupType = isReviewedProducts ? 'productReviews' : 'boards';
580        const parameter = isReviewedProducts ? this.getProductReviewsRequest(productNo) : this.getBoardsRequest(type);
581        let totalPage = '';
582
583        if (type === 'ALL') totalPage = this.allReviewWidgets.length;
584        if (type === 'PHOTO') totalPage = this.photoWidgets.length;
585        if (type === 'REVIEWED_PRODUCTS') totalPage = this.reviewWidgets.length;
586
587        shopby.popup('photo-review-detail', {
588          reviewNo,
589          productNo,
590          hasCloseBtn: true,
591          type: popupType,
592          isMain: true,
593          parameter,
594          totalPage,
595        });
596      },
597    },
598    boardNotice: { //24.05.08 seet3 추가
599      $boardNotice: null,
600      data: {
601        boardNotice: [],
602      },
603      page: shopby.pagination,
604      backPageNumber: null,
605      mallInfo: null,
606      boardId: 'notice',
607      async initiate() {
608        this.$boardNotice = $('#boardNotice'); 
609        this.page = new shopby.pagination(this.onPagination.bind(this), '#pagination', 10);
610        await this._getBoardList(this.getCurrentPageNumber()),
611        this.render();
612      },
613      render() {
614        const { boardNotice } = this.data;
615        if (this.$boardNotice && boardNotice.length > 0) {
616          const noticeListHtml = boardNotice.map(item => `
617            <li>
618              <a href="/pages/board/view.html?boardId=notice&amp;articleNo=${item.articleNo}&amp;secreted=false">
619                <span class="notice_tit">${item.title}</span>
620                <span class="notice_date">${item.registerYmdt.substr(0, 10)}</span>
621              </a>
622            </li>
623          `).join('');
624          
625          this.$boardNotice.find('.notice_list').html(noticeListHtml);
626        }
627      },
628      onPagination() {
629        this.backPageNumber = null;
630        this._getBoardList();
631      },
632      getCurrentPageNumber() {
633        const localstoragePageNumber = localStorage.getItem('pageNumber');
634        localStorage.removeItem('pageNumber');
635        return localstoragePageNumber ? Number(localstoragePageNumber) : this.page.pageNumber;
636      },
637      async _getBoardList(pageNumber) {
638        const request = {
639          pathVariable: { boardNo: this.boardId },
640          queryString: {
641            hasTotalCount: true,
642            withReplied: false,
643            pageNumber: this.backPageNumber ? this.backPageNumber : pageNumber || this.page.pageNumber,
644            pageSize: this.page.pageSize,
645          },
646        };
647        const { data: boardList } = await shopby.api.manage.getBoardsBoardNoArticles(request);
648        
649        if(boardList){          
650          this.data.boardNotice = boardList.items.slice(0,3);
651        }    
652      },      
653    },
654    csCenter: { //24.07.26 seet3 추가
655      mallInfo: null,
656      renderData: {
657        bottom: null,
658      },
659      async initiate() {
660        await this._getCache();
661        this.setData();
662        this.render();
663      },
664      setData() {
665        this.renderData = {
666          bottom: this._getBottomData(),
667        };
668      },
669      render() {      
670        const target = document.getElementById('csTel');
671        target.innerText = this.renderData.bottom.serviceBasicInfo.representPhoneNo.replace('02-', '');
672        target.href='tel:'+this.renderData.bottom.serviceBasicInfo.representPhoneNo;
673        
674      },
675      _getBottomData() {
676        const {serviceBasicInfo } = this.mallInfo;
677        return {
678          serviceBasicInfo,
679        };
680      },
681      async _getCache() {
682        this.mallInfo = shopby.cache.getMall();
683        this.boardsConfig = shopby.cache.getBoardsConfig();
684        this.articles = shopby.cache.getFooterArticles().items;
685        this.aboutConfig = shopby.cache.getFooterAbout();
686        this.mallSSLSeal = this._mapSSLSeal(shopby.cache.getMallsSSLSeal());
687        const data = await shopby.cache.getOrderConfigs();
688        this.orderConfig = {
689          ...data,
690          pgType: data.escrow.exposeLogo ? data.pgType : '',
691        };
692        //console.log(this.mallSSLSeal); // TODO: debug. seal 적용된 도메인만 실제 노출여부 확인가능하기땜에 일단 찍어둠
693      },
694      _mapSSLSeal(mallsSSLSeal) {
695        const mallSSLSeal = mallsSSLSeal.find(({ domain }) => domain === location.hostname);
696        return mallSSLSeal && mallSSLSeal.trustSeal ? mallSSLSeal.trustSeal : null;
697      },
698      get about() {
699        return [
700          { page: 'company', label: '회사소개', used: this.aboutConfig.mall_introduction.used },
701          { page: 'guide', label: '이용안내', used: this.aboutConfig.access_guide.used },
702        ];
703      },
704    },
705  };
706
707  shopby.start.initiate(shopby.home.initiate.bind(shopby.home));
708})();

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.