PageSourceSearch

https://www.cathaysec.com.tw/cathaysec/scripts/js/common.js?20220622_01

js cathaysec.com.tw collected 2026-09-24 10:47:12 UTC 54,938 bytes, 1,515 lines download raw bytes

1const elems = {
2    $window: window,
3    $document: document,
4    $html: 'html',
5    $body: 'body',
6    $wrap: '.jWrap',
7    $hd: '.jHd',
8    $nav: '.jNav',
9    $navCtrl: '.jNavCtrl',
10    $navMain: '.jNavMain',
11    $navItem: '.jNavItem',
12    $navBtn: '.jNavBtn',
13    $navSub: '.jNavSub',
14    $sitemap: '.jSitemap',
15    $sitemapBtn: '.jSitemapBtn',
16    $sitemapCnt: '.jSitemapCnt',
17    $top: '.jTop',
18    $online: '.jOnline',
19    $topBtn: '.jTopBtn',
20    $popup: '.jPopup',
21    $popupClose: '.jPopupClose',
22    $alertClose: '.jAlertClose',
23    $targetLink: '.jTargetLink',
24    $alertMsg: '.jAlertMsg',
25    $anim: '.jAnim',
26    $linkText: '.jLinkText',
27    $tabScroll: '.jTabScroll',
28    $tabScrollBtn: '.jTabScrollBtn',
29    $section: '.jSection',
30    $sectionHd: '.jSectionHd',
31    $selectURL: '.jSelectURL',
32    $fade: '.jFade',
33    $fadeItem: '.jFadeItem',
34    $switch: '.jSwitch',
35    $switchItem: '.jSwitchItem',
36    $switchBtn: '.jSwitchBtn',
37    $select: '.jSelect',
38    $linkScroll: '.jLinkScroll',
39    $linkScrollBtn: '.jLinkScrollBtn',
40    $form: '.jForm',
41    $formElem: '.jFormElem',
42    $formItem: '.jFormItem',
43    $formError: '.jFormError',
44    $point: '.jPoint',
45    $pointFigure: '.jPointFigure',
46    $pointAnim: '.jPointAnim',
47    $pointImg: '.jPointImg',
48    $loading: '.jLoading',
49    $loadingCnt: '.jLoadingCnt',
50    $post: '.jPost',
51    $postBtn: '.jPostBtn',
52    $store: '.jStore',
53    $projectFixed: '.jProjectFixed',
54    $projectFixedBtn: '.jProjectFixedBtn',
55    $projectFixedMain: '.jProjectFixedMain',
56    $copy: '.jCopy',
57    $copyTooltop: '.jCopyTooltip',
58    $checkbox: '.jCheckbox',
59    $notePopup: '.jNotePopup',
60    $stoPopup: '.jStoPopup'
61};
62const activeClass = 'active';
63const disabledClass = 'disabled';
64const showClass = '--show';
65const lockClass = '--lock';
66const overflowHiddenClass = '--overflow-hidden';
67const hideClass = 'hidden';
68const hiddenClass = '--hidden';
69const errorClass = '--error';
70const scrollClass = '--scroll';
71const successClass = '--success';
72const topClass = '--top';
73const moveClass = '--move';
74const stickyClass = '--sticky';
75const animClass = 'anim';
76let animIndex = null;
77let tabScrollIndex = null;
78let navScrollTop = null;
79let tabOffsetTop = null;
80let tabScrollPosition = [];
81const SST = {
82    POST: '6A1625DF0BCECEFA8DE9493A500E9D97'
83}
84
85const device = () => {
86    const angle = window.screen.orientation ? window.screen.orientation.angle : 0
87
88    if (window.innerWidth <= 740 || /Android|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
89        return 'm'
90    }
91
92    if ((angle === 0 && window.innerWidth > 740 && window.innerWidth < 1024) || /Android|webOS|iPad|BlackBerry/i.test(navigator.userAgent)) {
93        return 't'
94    }
95
96    if ((angle !== 0 && window.innerWidth > 730 && window.innerWidth < 815) || /iPhone/i.test(navigator.userAgent)) {
97        return 'm'
98    }
99
100    return 'p'
101};
102
103const documentOff = (evt, elem, fn) => {
104    // let isOff = true;
105    $(elems.$document).off(evt).on(evt, (e) => {
106        e.stopPropagation();
107
108        if (!$(e.target).is(elem)) {
109            if (typeof (fn) === 'function') {
110                fn();
111            }
112
113            // $(elems.$document).off(evt);
114        }
115    });
116};
117
118const navSubPosition = () => {
119    const angle = window.screen.orientation ? window.screen.orientation.angle : 0
120    const $nav = $(elems.$nav);
121    const $navMain = $(elems.$navMain);
122    const $navItem = $(elems.$navItem);
123
124    if ($nav.length) {
125        const navMainPosition = ($navMain.outerWidth(true) + $navMain.offset().left);
126
127        $(elems.$navSub).removeAttr('style');
128
129        $(elems.$navSub).each(function (index, element) {
130            const $navSub = $(element);
131            const $navSubChild = $(element).children();
132
133            $navSub.removeClass('--right --left');
134
135            const navSubPosition = ($navSub.outerWidth(true) + $navSub.offset().left);
136
137            if (device() === 'p' || (window.innerWidth > 1024 && angle !== 0)) {
138                $navSub.css({
139                    'max-height': $navSubChild.outerHeight(true)
140                });
141
142                if (navSubPosition > navMainPosition) {
143                    $navSub.addClass('--right')
144                } else {
145                    $navSub.addClass('--left')
146                }
147            }
148        })
149
150        if (device() === 'p') {
151            documentOff('click.nav', `${elems.$navItem}, ${elems.$navItem} *`, () => {
152                $navItem.removeClass(activeClass);
153            })
154
155
156            // $navItem.hover(function() {
157            //   const $this = $(this);
158
159            //   $this.addClass('active');
160            // }, function() {
161            //   const $this = $(this);
162
163            //   $this.removeClass('active');
164            // })
165        }
166    }
167};
168
169const sitemapInit = () => {
170    const $sitemapCnt = $(elems.$sitemapCnt);
171    const $sitemapData = $sitemapCnt.children();
172
173    $sitemapCnt.css({
174        'max-height': $sitemapData.outerHeight(true)
175    })
176};
177
178// tinySlider
179const tinySlider = () => {
180    const $tneElem = $('.jTns');
181
182    if ($tneElem.length !== 0) {
183        $tneElem.each((idx, elem) => {
184            let tnsSlide = null;
185            const $tnsElemEq = $(elem);
186            const $tenItem = $tnsElemEq.find('.jTnsItem');
187            const tneSet = $tnsElemEq.attr(':set') ? JSON.parse($tnsElemEq.attr(':set').replace(/'/g, '"')) : {};
188            let startIndex = 0;
189            let newSet = {};
190            const resizeFuns = () => {
191                if (tneSet.destroy) {
192                    const notEqual = /^!/.test(tneSet.destroy);
193                    const destroyDevice = notEqual ? /(?!^!).*/.exec(tneSet.destroy)[0] : tneSet.destroy;
194
195                    if (notEqual) {
196                        if (device() !== destroyDevice) {
197                            if (tnsSlide.destroy) {
198                                tnsSlide.destroy();
199                            }
200                        } else if (!tnsSlide.destroy) {
201                            tnsSlide = tnsSlide.rebuild();
202                        }
203                    } else if (device() !== destroyDevice) {
204                        if (!tnsSlide.destroy) {
205                            tnsSlide = tnsSlide.rebuild();
206                        }
207                    } else if (tnsSlide.destroy) {
208                        tnsSlide.destroy();
209                    }
210                }
211            };
212
213            Object.keys(tneSet).forEach(key => {
214                if (tneSet[key] instanceof Object) {
215                    if (!newSet.responsive) {
216                        newSet.responsive = {
217                            1: {},
218                            768: {},
219                            1000: {}
220                        };
221                    }
222
223                    newSet.responsive['1'][key] = tneSet[key].m;
224                    newSet.responsive['768'][key] = tneSet[key].t;
225                    newSet.responsive['1000'][key] = tneSet[key].p;
226                } else {
227                    newSet[key] = tneSet[key];
228                }
229            });
230
231            for (let j = 0; j < $tenItem.length; j += 1) {
232                const $tenItemElem = $tenItem.eq(j);
233
234                if ($tenItemElem.hasClass('active')) {
235                    startIndex = $tenItemElem.index();
236                }
237            }
238
239            tnsSlide = tns({
240                ...{
241                    container: elem,
242                    startIndex: startIndex,
243                    autoplayButtonOutput: false,
244                    navPosition: tneSet.navPosition ? tneSet.navPosition : 'bottom',
245                    useLocalStorage: false,
246                    onInit: (info) => {
247                        if (newSet.init) {
248                            const fn = window[newSet.init];
249
250                            fn(info);
251                        }
252                    }
253                },
254                ...newSet
255            });
256
257            if (tneSet.prevElem && tneSet.nextElem) {
258                let $prev = $(tneSet.prevElem);
259                let $next = $(tneSet.nextElem);
260
261                if (!tneSet.autoplay && !tneSet.loop) {
262                    $prev.prop('disabled', (startIndex === 0));
263                    $next.prop('disabled', (startIndex === ($tenItem[0].length - 1)));
264
265                    tnsSlide.events.on('indexChanged', info => {
266                        // $prev = $(tneSet.prevElem);
267                        // $next = $(tneSet.nextElem);
268
269                        console.log(info);
270                        console.log(info.index);
271
272                        if (info.index === 1) {
273                            console.log($prev[0]);
274                            $prev.prop('disabled', true);
275                        } else {
276                            $prev.prop('disabled', false);
277                        }
278
279                        if (info.slideCount - info.items - info.indexCached <= 0) {
280                            $next.prop('disabled', true);
281                        } else {
282                            $next.prop('disabled', false);
283                        }
284                    });
285                }
286
287                $prev.on('click', e => {
288                    const $this = $(e.$this);
289                    if (!$this.prop('disabled')) {
290                        tnsSlide.goTo('prev');
291                    }
292                });
293
294                $next.on('click', e => {
295                    const $this = $(e.$this);
296
297                    if (!$this.prop('disabled')) {
298                        tnsSlide.goTo('next');
299                    }
300                });
301            }
302
303            if (newSet.changed) {
304                tnsSlide.events.on('indexChanged', info => {
305                    const fn = window[newSet.changed];
306
307                    fn(info);
308                })
309            }
310
311            resizeFuns();
312
313            $(elems.$window).on('resize', () => {
314                resizeFuns();
315            });
316        });
317    }
318};
319
320// tabSlider
321const tabSlider = () => {
322    const $tabElem = '.jTab';
323    const $tabBtn = '.jTabBtn';
324    const $tabBd = '.jTabBd';
325    const $tabSlider = '.jTabSlider';
326    const $tabItem = '.jTabItem';
327    const $tabFt = '.jTabFt';
328    const activedClass = `${activeClass}d`;
329    const tabSet = $($tabElem).attr(':set') ? JSON.parse($($tabElem).attr(':set').replace(/'/g, '"')) : {};
330    const newSet = {
331        ...{
332            sliderAnim: true,
333            ftAnim: true
334        },
335        ...tabSet
336    }
337
338    if ($($tabElem).length !== 0) {
339        $(elems.$body).on('click', $tabBtn, (e) => {
340            const $this = $(e.currentTarget);
341            const $bd = $this.parents($tabElem).find($tabBd)
342            const $slider = $bd.find($tabSlider);
343            const $sliderItem = $slider.find($tabItem);
344            const $ft = $this.parents($tabElem).find($tabFt);
345            const $ftItem = $ft.find($tabItem);
346            const $itemActive = $slider.children(`${$tabItem}.${activeClass}`);
347            const index = $this.parent().index();
348            const itemShow = [$itemActive.index(), index];
349            const startDate = +new Date()
350            const easeInOutQuad = (t, b, c, d) => {
351                t /= d / 2
352                if (t < 1) return (c / 2) * t * t + b
353                t -= 1
354                return (-c / 2) * (t * (t - 2) - 1) + b
355            };
356            const animateScroll = () => {
357                const currentDate = +new Date();
358                const currentTime = currentDate - startDate;
359                const sliderStart = itemShow[0] > itemShow[1]
360                    ? ($sliderItem.width() * -1)
361                    : itemShow[0] < itemShow[1]
362                        ? 0
363                        : null;
364                const sliderChange = itemShow[0] > itemShow[1]
365                    ? (sliderStart * -1)
366                    : itemShow[0] < itemShow[1]
367                        ? (sliderStart - $sliderItem.width())
368                        : null;
369                const ftStart = itemShow[0] > itemShow[1]
370                    ? ($ftItem.width() * -1)
371                    : itemShow[0] < itemShow[1]
372                        ? 0
373                        : null;
374                const ftChange = itemShow[0] > itemShow[1]
375                    ? (ftStart * -1)
376                    : itemShow[0] < itemShow[1]
377                        ? (ftStart - $ftItem.width())
378                        : null;
379
380                $slider.css({
381                    transform: newSet.sliderAnim ? `translate3d(${parseInt(easeInOutQuad(currentTime, sliderStart, sliderChange, 300), 10)}px, 0, 0)` : 'translate3d(0, 0, 0)'
382                });
383
384                $ft.css({
385                    transform: newSet.ftAnim ? `translate3d(${parseInt(easeInOutQuad(currentTime, ftStart, ftChange, 300), 10)}px, 0, 0)` : 'translate3d(0, 0, 0)'
386                });
387
388                if (currentTime < 300) {
389                    requestAnimationFrame(animateScroll)
390                } else {
391                    $slider.removeAttr('style');
392                    $ft.removeAttr('style');
393                    $sliderItem.eq(itemShow[0]).removeClass(activedClass);
394                    $ftItem.eq(itemShow[0]).removeClass(activedClass);
395                }
396            }
397
398            $this.addClass(activeClass).parent().siblings().find($tabBtn).removeClass(activeClass);
399            $sliderItem.eq(itemShow[0]).removeClass(activeClass).addClass(activedClass);
400            $sliderItem.eq(itemShow[1]).addClass(activeClass);
401            $ftItem.eq(itemShow[0]).removeClass(activeClass).addClass(activedClass);
402            $ftItem.eq(itemShow[1]).addClass(activeClass);
403            if (itemShow[1] !== 0) {
404                $bd.addClass('--radius');
405            } else {
406                $bd.removeClass('--radius');
407            }
408            animateScroll();
409        })
410    }
411};
412
413// top show
414const topScroll = () => {
415    const $top = $(elems.$top);
416    const $online = $(elems.$online);
417    const scrollTop = $(elems.$window).scrollTop();
418
419    if (scrollTop !== 0) {
420        $top.addClass(showClass);
421        $online.addClass(topClass);
422        $('.smart_all').addClass(moveClass);
423    } else {
424        $top.removeClass(showClass);
425        $online.removeClass(topClass);
426        $('.smart_all').removeClass(moveClass);
427    }
428};
429
430// afa
431const afaInit = (opts) => {
432    if (window.afa_init) {
433        const $online = $(elems.$online);
434        const smartSayNone = () => {
435            const interval = setInterval(() => {
436                if ($('.smart_say').css('display') === 'none') {
437                    window.clearInterval(interval);
438                    $online.removeClass(moveClass);
439                } else {
440                    if (!$online.hasClass(moveClass)) {
441                        $online.addClass(moveClass);
442                    }
443                }
444            }, 50);
445        }
446        afa_init(opts);
447
448        // $('.smart_alpha').attr('data-ga-code', 'ga-01-11');
449
450        smartSayNone();
451    }
452};
453
454const anim = (callback) => {
455    const $window = $(elems.$window);
456    const $document = $(elems.$document);
457    const $animElem = $(elems.$anim);
458    const spac = 3;
459    const windowHeight = ($window.height() % spac !== 0) ? ($window.height() - Math.floor(($window.height() / spac))) : ($window.height() - ($window.height() / spac));
460
461    if ($animElem.length !== 0) {
462        for (var i = 0; i < $animElem.length; i++) {
463            const $animItem = $animElem.eq(i);
464
465            if (($window.scrollTop() > ($animItem.offset().top - windowHeight) && $window.scrollTop() < ($animItem.offset().top + $animItem.outerHeight(true))) || $window.scrollTop() + $window.height() === $document.height()) {
466                animIndex = i;
467            } else if ($window.scrollTop() > ($animItem.offset().top + $animItem.outerHeight(true))) {
468                animIndex = null;
469            }
470
471            if (animIndex !== null) {
472                if (!$animElem.eq(animIndex).hasClass(animClass)) {
473                    // if ( common._classSet._animOvRme ) {
474                    //   $animElem.removeClass(animClass).eq(animIndex).addClass(animClass);
475                    // } else {
476                    $animElem.eq(animIndex).addClass(animClass);
477                    // }
478                }
479            }
480            // else {
481            //   if ( common._classSet._animOvRme ) {
482            //     $animElem.removeClass(animClass);
483            //   }
484            // }
485        }
486    }
487};
488
489const fade = () => {
490    const $fade = $(elems.$fade);
491
492    if ($fade.length) {
493        const $fadeItem = $(elems.$fadeItem);
494        const fadeSet = $fade.attr(':set') ? JSON.parse($fade.attr(':set').replace(/'/g, '"')) : {};
495        let show = fadeSet.start ? fadeSet.start : 1;
496        const autoplayTime = fadeSet.autoplayTime ? fadeSet.autoplayTime : 3000;
497        const showClass = '--show-';
498        const fadeAnim = (() => {
499            const fadeTimeout = setTimeout(() => {
500                window.clearInterval(fadeTimeout);
501
502                fadeAnim();
503
504                $fade.removeClass(`${showClass}${show}`);
505
506                show += 1;
507
508                if (show > $fadeItem.length) {
509                    show = 1;
510                }
511
512                $fade.addClass(`${showClass}${show}`);
513            }, autoplayTime)
514        });
515
516        fadeAnim();
517    }
518}
519
520const selectInit = (select) => {
521    const $select = select ? $(select) : $(elems.$select);
522
523    if ($.fn.selectmenu && $select.length) {
524        for (let i = 0; i < $select.length; i += 1) {
525            const $selectItem = $select.eq(i);
526            const selectSet = $selectItem.attr(':set') ? JSON.parse($selectItem.attr(':set').replace(/'/g, '"')) : {};
527
528            $selectItem.selectmenu({
529                classes: {
530                    'ui-selectmenu-button': $selectItem[0].className.replace(new RegExp(`m-form-item|${elems.$select.replace(/^\./, '')}`, 'g'), '')
531                },
532                change: (event, data) => {
533                    if (selectSet.change) {
534                        const fn = window[selectSet.change];
535                        fn(data.item.value)
536                    }
537                }
538            });
539
540            if (selectSet.destroy) {
541                for (let j = 0, destroy = selectSet.destroy.split(''); j < destroy.length; j += 1) {
542                    const destroyItem = destroy[j];
543
544                    if (destroyItem === device()) {
545                        $selectItem.selectmenu('destroy')
546                    }
547                }
548            }
549        }
550    } else if (!$.fn.selectmenu && $select.length) {
551        alert('please load jquery-ui plugin!');
552    }
553}
554
555const linkScroll = () => {
556    const $link = $(elems.$linkScroll);
557
558    if ($link.length && device() === 'm') {
559        const $linkBtn = $link.find(elems.$linkScrollBtn);
560
561        if (!$link.hasClass(scrollClass)) {
562            $link.addClass(scrollClass);
563
564            for (let i = 0; i < $linkBtn.length; i += 1) {
565                const $linkBtnItme = $linkBtn.eq(i);
566                const $linkBtnParent = $linkBtnItme.parent();
567
568                if (new RegExp(activeClass).test($linkBtnItme[0].className)) {
569                    const paddingLeft = parseInt($linkBtnParent.css('padding-left'), 10);
570
571                    $link.find('> ul').animate({
572                        scrollLeft: ($linkBtnParent.offset().left + paddingLeft - (($($link).outerWidth(true) - $($linkBtnItme).outerWidth(true)) / 2))
573                    }, 300, 'swing');
574                }
575            }
576        }
577    }
578}
579
580const pointScroll = () => {
581    const $window = $(elems.$window);
582    const $document = $(elems.$document);
583    const $pointAnim = $(elems.$pointAnim);
584    const spac = 3;
585    const windowHeight = ($window.height() % spac !== 0) ? ($window.height() - Math.floor(($window.height() / spac))) : ($window.height() - ($window.height() / spac));
586
587    if ($pointAnim.length && device() === 'm') {
588        if (($window.scrollTop() > ($pointAnim.offset().top - windowHeight) && $window.scrollTop() < ($pointAnim.offset().top + $pointAnim.outerHeight(true))) || $window.scrollTop() + $window.height() === $document.height()) {
589            if (!$pointAnim.hasClass(animClass)) {
590                $pointAnim.addClass(animClass).stop().delay(0).queue(() => {
591                    const animDuration = (parseFloat($pointAnim.find('> *').css('animation-duration'), 10) * 1000);
592
593                    $pointAnim.dequeue().stop().delay(animDuration).queue(() => {
594                        $pointAnim.addClass(hiddenClass).dequeue();
595                    });
596                });
597            }
598        }
599    }
600}
601
602const pointInit = () => {
603    const $pointFigure = $(elems.$pointFigure);
604
605    if ($pointFigure.length && !$pointFigure.hasClass(scrollClass)) {
606        $pointFigure.addClass(scrollClass);
607
608        if (device() === 'm') {
609            const centerPosition = (($(elems.$pointFigure).find('> *').outerWidth(true) - $(elems.$pointFigure).outerWidth(true)) / 2);
610
611            $pointFigure.scrollLeft(centerPosition);
612            pointScroll();
613        }
614    }
615}
616
617const loadingTigger = (event) => {
618    const $loading = $(elems.$loading);
619
620    if (event === 'close') {
621        $loading.addClass(hiddenClass);
622    } else if (event === 'open') {
623        $loading.removeClass(hiddenClass);
624    }
625}
626
627const loadingInit = () => {
628    const $loading = $(elems.$loading);
629    const loadSet = $loading.attr(':set') ? JSON.parse($loading.attr(':set').replace(/'/g, '"')) : {};
630
631    if (loadSet.onLoadClose) {
632        loadingTigger('close');
633    }
634}
635
636const postTigger = (event) => {
637    const $body = $(elems.$body);
638    const $loading = $(elems.$loading);
639    const $loadingCnt = $(elems.$loadingCnt);
640    const $post = $(elems.$post);
641    const loadingDuration = $loading.hasClass(hiddenClass) ? ((parseFloat($loadingCnt.css('transition-duration'), 10) * 1000) + 100) : 300;
642
643    if (event === 'close') {
644        $post.addClass(hiddenClass);
645        $body.removeClass(lockClass);
646
647        if (device() !== 'p') {
648            $('html, body').stop().animate({
649                scrollTop: navScrollTop
650            }, 0, () => {
651                navScrollTop = null;
652            });
653        }
654
655    } else if (event === 'open') {
656        navScrollTop = navScrollTop || $(window).scrollTop();
657
658        $body.addClass(lockClass);
659
660        if (device() !== 'p') {
661            $body.css({
662                top: (navScrollTop * -1)
663            });
664        }
665
666        $loadingCnt.stop().delay(loadingDuration).queue(() => {
667            $post.removeClass(hiddenClass);
668            $loadingCnt.dequeue();
669        })
670    }
671}
672
673const postInit = () => {
674    const $post = $(elems.$post);
675
676    if ($post.length) {
677        const postSet = $post.attr(':set') ? JSON.parse($post.attr(':set').replace(/'/g, '"')) : {};
678
679        if (postSet.open) {
680            const year = new Date().getFullYear();
681            const month = (new Date().getMonth() + 1);
682            const day = new Date().getDate();
683            const open = () => {
684                sessionStorage.setItem(SST.POST, +new Date());
685                postTigger('open');
686            }
687
688            if (!sessionStorage.getItem(SST.POST)) {
689                open();
690            } else {
691                const storageDate = new Date(Number(sessionStorage.getItem(SST.POST)));
692                const storageYear = storageDate.getFullYear();
693                const storageMonth = (storageDate.getMonth() + 1);
694                const storageDay = storageDate.getDate();
695
696                if (year !== storageYear || month !== storageMonth || day !== storageDay) {
697                    open();
698                }
699
700                // console.log(storageYear)
701                // console.log(storageMonth)
702                // console.log(storageDay)
703                // console.log(year)
704                // console.log(month)
705                // console.log(day)
706            }
707        }
708    }
709}
710
711const projectFixedInit = () => {
712    const $projectFixedMain = $(elems.$projectFixedMain);
713
714    if ($projectFixedMain.length) {
715        const mainHeight = $projectFixedMain.find('> *').outerHeight();
716
717        $projectFixedMain.removeAttr('style').css({
718            'max-height': mainHeight
719        });
720    }
721}
722
723const copyInit = () => {
724    const $copy = $(elems.$copy);
725
726    if ($copy.length) {
727        const copySet = $copy.attr(':set') ? JSON.parse($copy.attr(':set').replace(/'/g, '"')) : {};
728        const $tooltip = copySet.success ? `<div class="m-copy-tooltip ${elems.$copyTooltop.replace(/^\./, '')}"><p>${copySet.success}</p></div>` : null;
729
730        if ($tooltip) {
731            $copy.addClass('m-copy relative');
732            $copy.append($tooltip);
733
734            $(elems.$body).on('click', elems.$copy, (e) => {
735                const $this = $(e.currentTarget);
736                const copySet = $this.attr(':set') ? JSON.parse($this.attr(':set').replace(/'/g, '"')) : {};
737                const copyText = copySet.text
738                    ? copySet.text === 'location.href'
739                        ? window.location.href
740                        : copySet.text
741                    : $this[0].nodeName === 'A'
742                        ? $this.attr('href')
743                        : null;
744
745                if (copyText && copyToClipboard(copyText)) {
746                    const duration = ((parseFloat($(elems.$copyTooltop).css('transition-duration'), 10) * 1000) + (copySet.timeout ? copySet.timeout : 1500));
747
748                    $(elems.$copyTooltop).addClass(successClass).stop().delay(duration).queue(() => {
749                        $(elems.$copyTooltop).removeClass(successClass);
750                    });
751                }
752            });
753        }
754    }
755};
756
757const copyToClipboard = (copyText) => {
758    const textToClipboard = copyText;
759    let success = true;
760    const SelectContent = element => {
761        // first create a range
762        var rangeToSelect = document.createRange();
763        rangeToSelect.selectNodeContents(element);
764
765        // select the contents
766        const selection = window.getSelection();
767        selection.removeAllRanges();
768        selection.addRange(rangeToSelect);
769    };
770    const CreateElementForExecCommand = text => {
771        const forExecElement = document.createElement('div');
772        // place outside the visible area
773        forExecElement.style.position = 'absolute';
774        forExecElement.style.left = '-99999px';
775        forExecElement.style.top = '-99999px';
776        // write the necessary text into the element and append to the document
777        forExecElement.textContent = text;
778        document.body.appendChild(forExecElement);
779        // the contentEditable mode is necessary for the  execCommand method in Firefox
780        forExecElement.contentEditable = true;
781
782        return forExecElement;
783    };
784
785    if (window.clipboardData) {
786        window.clipboardData.setData('Text', textToClipboard);
787    } else {
788        const forExecElement = CreateElementForExecCommand(textToClipboard);
789
790        SelectContent(forExecElement);
791        // var supported = true;
792        try {
793            if (window.netscape && window.netscape.security) {
794                window.netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
795            }
796            success = document.execCommand('copy', false, null);
797        } catch (e) {
798            success = false;
799        }
800
801        document.body.removeChild(forExecElement);
802    }
803
804    return success;
805};
806
807const formReset = (input) => {
808    const $elem = input ? $(input) : $('form');
809
810    if ($elem.length) {
811        const $formElem = input ? $elem.parents('form') : $elem;
812        const $formItem = $(elems.$formItem);
813
814
815        $formElem[0].reset();
816
817        for (let i = 0; i < $formItem.length; i += 1) {
818            const $formItemEq = $formItem.eq(i);
819            const $form = $formItemEq.parents(elems.$form);
820            const $formError = $form.find(elems.$formError);
821            const isRadio = $formItemEq.attr('type') === 'radio';
822            const isCheckbox = $formItemEq.eq(i).attr('type') === 'checkbox';
823
824            if (!isRadio) {
825                if (!isCheckbox) {
826                    $formItemEq.removeClass(errorClass);
827                    $formError.removeClass(errorClass).empty();
828                }
829            }
830        }
831    }
832}
833
834const tabScrollReset = (reset) => {
835    const $tabScroll = $(elems.$tabScroll);
836
837    if ($tabScroll.length) {
838        if (reset) {
839            tabScrollPosition = [];
840            tabOffsetTop = null;
841            $tabScroll.find('> ul').scrollLeft(0);
842            $tabScroll.removeClass(stickyClass);
843        }
844
845        if (!tabOffsetTop) {
846            tabOffsetTop = $tabScroll.offset().top
847        }
848    }
849}
850
851const tabScroll = () => {
852    const $window = $(elems.$window);
853    const $header = $(elems.$hd);
854    const $tabScroll = $(elems.$tabScroll);
855    const headerHeight = $header.outerHeight(true);
856    const spac = device() !== 'm' ? 2 : 3;
857    const windowHeight = ($window.height() % spac !== 0) ? ($window.height() - Math.floor(($window.height() / spac))) : ($window.height() - ($window.height() / spac));
858
859    if ($tabScroll.length) {
860        const $tabScrollBtn = $(elems.$tabScrollBtn);
861        const $section = $(elems.$section);
862
863        tabScrollReset();
864
865        if (($window.scrollTop() + headerHeight) >= tabOffsetTop) {
866            $tabScroll.addClass(stickyClass);
867        } else {
868            $tabScroll.removeClass(stickyClass);
869        }
870
871        if (!tabScrollPosition.length) {
872            for (let i = 0; i < $tabScrollBtn.length; i += 1) {
873                const $tabScrollBtnItem = $tabScrollBtn.eq(i);
874                const tabScrollBtnPosition = $tabScrollBtnItem.parent().offset().left;
875
876                tabScrollPosition.push(tabScrollBtnPosition);
877            }
878        }
879
880        for (let i = 0; i < $section.length; i += 1) {
881            const $sectionItem = $section.eq(i);
882
883            if (($window.scrollTop() > ($sectionItem.offset().top - windowHeight) && $window.scrollTop() < ($sectionItem.offset().top + $sectionItem.outerHeight(true)))) {
884                tabScrollIndex = i;
885            } else if ($window.scrollTop() > ($sectionItem.offset().top + $sectionItem.outerHeight(true))) {
886                tabScrollIndex = null;
887            }
888
889            if (tabScrollIndex !== null) {
890                if (!$tabScrollBtn.eq(tabScrollIndex).hasClass(activeClass)) {
891                    const scrollLeft = (tabScrollPosition[tabScrollIndex] - (($tabScroll.find('> ul').outerWidth(true) - $tabScrollBtn.parent().eq(tabScrollIndex).outerWidth(true)) / 2));
892
893                    $tabScrollBtn.eq(tabScrollIndex).parent().find(elems.$tabScrollBtn).addClass(activeClass).parent().siblings().find(elems.$tabScrollBtn).removeClass(activeClass);
894                    $tabScroll.find('> ul').scrollLeft(scrollLeft);
895                }
896            } else {
897                $tabScrollBtn.removeClass(activeClass);
898            }
899        }
900    }
901}
902
903const formDisabled = (elem) => {
904    const $checkbox = elem ? $(elem) : $(elems.$checkbox);
905    const checkboxSet = $checkbox.attr(':set') ? JSON.parse($checkbox.attr(':set').replace(/'/g, '"')) : null;
906    const $formCheck = $(checkboxSet.ctrlElem);
907    const $select = $(elems.$select);
908    const isCheck = $checkbox.prop('checked');
909
910    $select.selectmenu({
911        disabled: !isCheck
912    });
913
914    for (let i = 0; i < $formCheck.length; i += 1) {
915        const $formCheckItem = $formCheck.eq(i);
916
917        // console.log($formCheckItem[0].nodeName)
918
919        $formCheckItem.prop(disabledClass, !isCheck);
920
921        if (isCheck) {
922            if ($formCheckItem[0].nodeName !== 'INPUT'
923                || $formCheckItem[0].nodeName !== 'SELECT'
924                || $formCheckItem[0].nodeName !== 'TEXTAREA'
925                || $formCheckItem[0].nodeName !== 'BUTTON'
926            ) {
927                $formCheckItem.removeClass(disabledClass)
928            }
929        } else {
930            $formCheckItem.addClass(disabledClass)
931        }
932    }
933}
934
935function postTinyInit(info) {
936    const { slideCount, displayIndex } = info;
937
938    $('.jPostTotal').text((slideCount >= 9 ? slideCount : `0${slideCount}`));
939    $('.jPostNow').text((displayIndex >= 9 ? displayIndex : `0${displayIndex}`));
940}
941
942function postTinyChange(info) {
943    const { displayIndex } = info;
944
945    $('.jPostNow').text((displayIndex >= 9 ? displayIndex : `0${displayIndex}`));
946}
947
948function branches(keyword) {
949    const $mapDateItem = $('.jMapDateItem');
950
951    if ($mapDateItem.length) {
952        $('.jBranchesItem:gt(0)').remove();
953        $('.jMapItem:gt(0)').remove();
954
955        const $branchesItem = $('.jBranchesItem');
956        const $mapItem = $('.jMapItem');
957        const saveMapDate = [];
958        let mapDate = [];
959
960
961        for (let i = 0; i < $mapDateItem.length; i += 1) {
962            const $mapDateItemEq = $mapDateItem.eq(i);
963            const mapDateTitle = $mapDateItemEq.find('.jMapDateTitle').text();
964            const mapDatePhone = $mapDateItemEq.find('.jMapDatePhone').text();
965            const mapDateTime = $mapDateItemEq.find('.jMapDateTime').text();
966            const mapDateAddress = $mapDateItemEq.find('.jMapDateAddress').text();
967            const mapDateGMapIframe = $mapDateItemEq.find('.jMapDateGMap').text();
968            const mapDateGMapLink = $mapDateItemEq.find('.jMapDateGMap').attr('href');
969            const getClassName = (className) => {
970                return $.trim(new RegExp(`^.*(?=\\s?${className})`).exec($mapDateItemEq.find(`.${className}`)[0].className)[0])
971            }
972
973            saveMapDate.push({
974                title: {
975                    text: mapDateTitle,
976                    className: getClassName('jMapDateTitle')
977                },
978                phone: {
979                    text: mapDatePhone,
980                    className: getClassName('jMapDatePhone')
981                },
982                time: {
983                    text: mapDateTime,
984                    className: getClassName('jMapDateTime')
985                },
986                address: {
987                    text: mapDateAddress,
988                    className: getClassName('jMapDateAddress')
989                },
990                mapIframe: mapDateGMapIframe,
991                mapLink: mapDateGMapLink
992            })
993        }
994
995        if (keyword != '全部') {
996            for (let i = 0; i < saveMapDate.length; i += 1) {
997                const saveMapDateItem = saveMapDate[i];
998
999                if (new RegExp(keyword).test(saveMapDateItem.address.text)) {
1000                    mapDate.push({
1001                        title: saveMapDateItem.title,
1002                        phone: saveMapDateItem.phone,
1003                        time: saveMapDateItem.time,
1004                        address: saveMapDateItem.address,
1005                        mapIframe: saveMapDateItem.mapIframe,
1006                        mapLink: saveMapDateItem.mapLink
1007                    })
1008                }
1009            }
1010        } else {
1011            mapDate = saveMapDate
1012        }
1013
1014        if (mapDate.length > 0) {
1015            $('.jMapIframe').attr('src', mapDate[0].mapIframe);
1016        }
1017
1018        for (let i = 0; i < mapDate.length; i += 1) {
1019            const mapDateItem = mapDate[i];
1020            const $branchesItemClone = $branchesItem.clone();
1021            const $mapItemClone = $mapItem.clone();
1022
1023            if (i !== 0) {
1024                $branchesItem.parent().append($branchesItemClone);
1025                $mapItem.parent().append($mapItemClone);
1026                $('.jMapItem').eq(i).removeClass(activeClass);
1027            } else {
1028                $('.jMapItem').eq(i).addClass(activeClass);
1029            }
1030
1031            $('.jBranchesItem').eq(i).find('.jBranchesTitle').text(mapDateItem.title.text).parents('td').addClass(mapDateItem.title.className);
1032            $('.jBranchesItem').eq(i).find('.jBranchesPhone').attr('href', `tel:${mapDateItem.phone.text}`).find('em').text(mapDateItem.phone.text).parents('td').addClass(mapDateItem.phone.className);
1033            $('.jBranchesItem').eq(i).find('.jBranchesTime').text(mapDateItem.time.text).parents('td').addClass(mapDateItem.time.className);
1034            $('.jBranchesItem').eq(i).find('.jBranchesAddress').text(mapDateItem.address.text).parents('td').addClass(mapDateItem.address.className);
1035            $('.jMapItem').eq(i).find('.jMapTitle').text(mapDateItem.title.text);
1036            $('.jMapItem').eq(i).find('.jMapPhone').text(mapDateItem.phone.text);
1037            $('.jMapItem').eq(i).find('.jMapTime').text(mapDateItem.time.text);
1038            $('.jMapItem').eq(i).find('.jMapAddress').text(mapDateItem.address.text);
1039            $('.jMapItem').eq(i).find('.jMapMobilePhone').attr('href', `tel:${mapDateItem.phone.text}`);
1040            $('.jMapItem').eq(i).find('.jMapMobileLink').attr('href', mapDateItem.mapLink);
1041        }
1042
1043        if (device() === 'p') {
1044            $(elems.$body).on('click', '.jMapItem', (e) => {
1045                const $this = $(e.currentTarget);
1046                const index = $this.index();
1047
1048                $('.jMapIframe').attr('src', mapDate[index].mapIframe);
1049                $('.jMapItem').removeClass(activeClass).eq(index).addClass(activeClass);
1050            });
1051        }
1052    }
1053}
1054
1055function formSend() {
1056    formReset();
1057    formDisabled();
1058}
1059
1060function alertMsg(obj) {
1061    if (obj && obj.content) {
1062        const $popup = $(elems.$popup);
1063
1064        for (let i = 0; i < $popup.length; i += 1) {
1065            const $popupElem = $popup.eq(i);
1066            const popSet = $($popupElem).attr(':set') ? JSON.parse($($popupElem).attr(':set').replace(/'/g, '"')) : null;
1067
1068            var closeText = obj.closeText || "OK";
1069
1070            if (popSet && popSet.name === 'alertMsg') {
1071                const $alertMsg = $popupElem.find(elems.$alertMsg);
1072                const $closeBtn = $popupElem.find(elems.$popupClose);
1073                const $alertCloseText = $popupElem.find(elems.$alertClose);
1074
1075                $alertMsg.html(obj.content);
1076
1077                if (obj.href) {
1078                    $closeBtn.attr('href', obj.href)
1079
1080                    if (obj.target) {
1081                        $closeBtn.attr('target', obj.target)
1082
1083                        if (obj.target === '_blank') {
1084                            $closeBtn.attr('rel', 'noopener')
1085                        }
1086                    }
1087                }
1088
1089                const $bObject = $alertCloseText.find('b');
1090
1091                $bObject.text(closeText)
1092
1093
1094                if (obj.hideCloseButton) {
1095                    $alertCloseText.hide();
1096                }
1097                else {
1098                    $alertCloseText.show();
1099                }
1100
1101                $(elems.$body).addClass(lockClass);
1102                $popupElem.addClass(showClass);
1103            }
1104        }
1105    } else {
1106        alert('使用 alertMsg Function 請帶入必要參數!')
1107    }
1108}
1109
1110$(elems.$body).on('click', elems.$sitemapBtn, (e) => {
1111    // const $this = $(e.currentTarget);
1112    const $sitemap = $(elems.$sitemap);
1113
1114    $sitemap.toggleClass(activeClass);
1115}).on('click', elems.$navCtrl, (e) => {
1116    const $this = $(e.currentTarget);
1117    const $body = $(elems.$body);
1118    const $nav = $(elems.$nav);
1119    const $navItem = $(elems.$navItem);
1120
1121    navScrollTop = navScrollTop || $(window).scrollTop();
1122
1123    $this.toggleClass(activeClass);
1124    $nav.toggleClass(activeClass);
1125    $body.toggleClass(lockClass);
1126    $navItem.removeClass(activeClass)
1127
1128
1129    if ($this.hasClass(activeClass)) {
1130        $body.css({
1131            top: (navScrollTop * -1)
1132        });
1133    } else {
1134        $body.removeAttr('style');
1135
1136        $('html, body').stop().animate({
1137            scrollTop: navScrollTop
1138        }, 0, () => {
1139            navScrollTop = null;
1140        });
1141    }
1142    // $(elems.$nav).css('height', ($(elems.$window)[0].innerHeight - 60));
1143    // $(elems.$navSub).css('height', ($(elems.$window)[0].innerHeight - 60));
1144
1145}).on('click', elems.$navBtn, (e) => {
1146    const $this = $(e.currentTarget);
1147
1148    $(elems.$navBtn).parent().removeClass(activeClass);
1149    $this.parent().addClass(activeClass);
1150
1151    // documentOff('click', `${elems.$navMain}, ${elems.$navMain} *`, () => {
1152    //   $(elems.$navBtn).parent().removeClass(activeClass);
1153    // })
1154}).on('blur', elems.$navBtn, (e) => {
1155    // 延遲檢查,避免立即關閉導航
1156    setTimeout(() => {
1157            $(elems.$navBtn).parent().removeClass(activeClass)
1158    }, 100)
1159}).on('click', elems.$topBtn, (e) => {
1160
1161    $('body, html').stop().animate({
1162        scrollTop: 0
1163    }, 300, 'swing');
1164}).on('click', 'a', (e) => {
1165    const $this = $(e.currentTarget);
1166    const $popup = $(elems.$popup);
1167    const target = $this.attr('target');
1168    const href = $this.attr('href');
1169    const linkText = $this.hasClass(elems.$linkText.replace(/^\./, ''))
1170        ? $this.text()
1171        : $this.find(elems.$linkText).text() || null;
1172
1173    if (target && linkText) {
1174        e.preventDefault();
1175
1176        for (let i = 0; i < $popup.length; i += 1) {
1177            const $popupElem = $popup.eq(i);
1178            const popSet = $($popupElem).attr(':set') ? JSON.parse($($popupElem).attr(':set').replace(/'/g, '"')) : null;
1179
1180            if (popSet && popSet.name === 'targetBlank') {
1181                const $targetLink = $popupElem.find(elems.$targetLink);
1182                const $closeBtn = $popupElem.find(elems.$popupClose);
1183
1184                $(elems.$body).addClass(overflowHiddenClass);
1185                $popupElem.addClass(showClass);
1186                $targetLink.text(linkText);
1187
1188                for (let j = 0; j < $closeBtn.length; j += 1) {
1189                    const $closeBtnElem = $($closeBtn[j]);
1190
1191                    if ($closeBtnElem[0].nodeName === 'A') {
1192                        $closeBtnElem.attr('href', href);
1193                    }
1194                }
1195            }
1196        }
1197    }
1198}).on('click', elems.$notePopup, (e) => {
1199    const $this = $(e.currentTarget);
1200    const $popup = $(elems.$popup);
1201
1202    for (let i = 0; i < $popup.length; i += 1) {
1203        const $popupElem = $popup.eq(i);
1204        const popSet = $($popupElem).attr(':set') ? JSON.parse($($popupElem).attr(':set').replace(/'/g, '"')) : null;
1205
1206        if (popSet && popSet.name === 'notePopup') {
1207
1208
1209            $(elems.$body).addClass(overflowHiddenClass);
1210            $popupElem.addClass(showClass);
1211
1212        }
1213    }
1214}).on('click', elems.$popupClose, (e) => {
1215    const $this = $(e.currentTarget);
1216    const $popup = $this.parents(elems.$popup);
1217    const $alertClose = $(elems.$alertClose);
1218
1219    $popup.toggleClass(showClass);
1220    $(elems.$body).removeClass(`${lockClass} ${overflowHiddenClass}`);
1221
1222    $popup.stop().delay(100).queue(() => {
1223        $alertClose.removeAttr('target').removeAttr('rel');
1224        $popup.dequeue();
1225    })
1226
1227}).on('click', elems.$tabScrollBtn, (e) => {
1228    const $this = $(e.currentTarget);
1229    const $tabScroll = $(elems.$tabScroll);
1230    const $section = $(elems.$section);
1231
1232    if ($this[0].nodeName === 'BUTTON') {
1233        const text = $.trim($this.text());
1234
1235        for (let i = 0; i < $section.length; i += 1) {
1236            const $sectionEelm = $section.eq(i);
1237            const $sectionHd = $sectionEelm.find(elems.$sectionHd);
1238
1239            if ($.trim($sectionHd.text()) === text) {
1240                const sectionOffsetTop = $sectionEelm.offset().top;
1241
1242                $('html, body').stop().animate({
1243                    scrollTop: (sectionOffsetTop - $(elems.$hd).outerHeight(true) - 10 - $tabScroll.outerHeight(true))
1244                }, 300, 'swing');
1245            }
1246        }
1247    }
1248}).on('click', elems.$switchBtn, (e) => {
1249    const $this = $(e.currentTarget);
1250    const $switch = $this.parents(elems.$switch);
1251    const $switchItem = $this.parents(elems.$switchItem);
1252    const switchSet = $switch.attr(':set') ? JSON.parse($switch.attr(':set').replace(/'/g, '"')) : {};
1253    const index = ($switchItem.index() + 1)
1254    const $switchCtelEelm = $(switchSet.ctrlElem);
1255    const switchCtelClass = switchSet.ctrlClass;
1256
1257    $switch[0].className = $switch[0].className.replace(/(?!--switch-)\d/, index);
1258    $switchCtelEelm[0].className = $switchCtelEelm[0].className.replace(new RegExp(`(?!${switchCtelClass}-)\\d`), index);
1259
1260}).on('click', elems.$postBtn, (e) => {
1261    // const $this = $(e.currentTarget);
1262
1263    postTigger('close');
1264}).on('click', '[type="submit"]', (e) => {
1265    // const $this = $(e.currentTarget);
1266    // const $formElem = $this.parents('form');
1267    const $formItem = $(elems.$formItem);
1268    let isError = false;
1269    let errorOffsetTop = null;
1270
1271    for (let i = 0; i < $formItem.length; i += 1) {
1272        const $formItemEq = $formItem.eq(i);
1273        const $form = $formItemEq.parents(elems.$form);
1274        const $formError = $form.find(elems.$formError);
1275        const formValidate = $($formItemEq).attr(':validate') ? JSON.parse($($formItemEq).attr(':validate').replace(/'/g, '"')) : {};
1276        const isRadio = $formItemEq.attr('type') === 'radio';
1277        const isCheckbox = $formItemEq.eq(i).attr('type') === 'checkbox';
1278        let value = null;
1279        const { required, phone, email, checkRequired, chinese, name, choice, number, symbols, eNumber, max } = formValidate;
1280
1281        if (!isRadio) {
1282            if (!isCheckbox) {
1283                $formItemEq.removeClass(errorClass);
1284                $formError.removeClass(errorClass).empty();
1285                value = $formItemEq.val();
1286            } else {
1287                value = $formItemEq.prop('checked');
1288            }
1289        } else {
1290            value = $(`[name="${$formItemEq.attr('name')}"]:checked`).val();
1291        }
1292
1293        if (required && !value) {
1294            isError = true;
1295            $formItemEq.addClass(errorClass);
1296            $formError.addClass(errorClass).text(required);
1297        } else if (value) {
1298            if (phone && !/^09\d{8}$/.test(value)) {
1299                isError = true;
1300                $formError.stop().delay(0).queue(() => {
1301                    $formItemEq.addClass(errorClass);
1302                    $formError.addClass(errorClass).text(phone).dequeue();
1303                });
1304            } else if (email && !/^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z]+$/.test(value)) {
1305                isError = true;
1306                $formError.stop().delay(0).queue(() => {
1307                    $formItemEq.addClass(errorClass);
1308                    $formError.addClass(errorClass).text(email).dequeue();
1309                });
1310            } else if (number && !/^\d+$/.test(value)) {
1311                console.log($formError)
1312                isError = true;
1313                $formError.stop().delay(0).queue(() => {
1314                    $formItemEq.addClass(errorClass);
1315                    $formError.addClass(errorClass).text(number).dequeue();
1316                });
1317            } else if (chinese && !/[\u4e00-\u9fa5]/.test(value)) {
1318                isError = true;
1319                $formError.stop().delay(0).queue(() => {
1320                    $formItemEq.addClass(errorClass);
1321                    $formError.addClass(errorClass).text(chinese).dequeue();
1322                });
1323            } else if (name && !/^[\u4e00-\u9fa5a-zA-Z\s-]+$/.test(value)) {
1324                isError = true;
1325                $formError.stop().delay(0).queue(() => {
1326                    $formItemEq.addClass(errorClass);
1327                    $formError.addClass(errorClass).text(name).dequeue();
1328                });
1329            } else if (checkRequired) {
1330                if (isRadio && value && value === $formItemEq.val() && !$(checkRequired.elem).val()) {
1331                    isError = true;
1332
1333                    $(checkRequired.elem).stop().delay(0).queue(() => {
1334                        $formError.addClass(errorClass).text(checkRequired.error);
1335                        $(checkRequired.elem).addClass(errorClass).dequeue();
1336                    });
1337                } else if (!isRadio && value && !$(checkRequired.elem).val()) {
1338                    isError = true;
1339
1340                    $(checkRequired.elem).stop().delay(0).queue(() => {
1341                        $formError.addClass(errorClass).text(checkRequired.error);
1342                        $(checkRequired.elem).addClass(errorClass).dequeue();
1343                    });
1344                }
1345            } else if (symbols && /[<>\[\]{}'"]/.test(value)) {
1346                isError = true;
1347                $formError.stop().delay(0).queue(() => {
1348                    $formItemEq.addClass(errorClass);
1349                    $formError.addClass(errorClass).text(symbols).dequeue();
1350                });
1351            } else if (eNumber && !/^[a-zA-Z0-9]+$/.test(value)) {
1352                isError = true;
1353                $formError.stop().delay(0).queue(() => {
1354                    $formItemEq.addClass(errorClass);
1355                    $formError.addClass(errorClass).text(eNumber).dequeue();
1356                });
1357            } else if (max) {
1358                if (max.textLength < value.length) {
1359                    const error = max.error.replace(/{\s?maxlength\s?}/, max.textLength);
1360
1361                    isError = true;
1362                    $formError.stop().delay(0).queue(() => {
1363                        $formItemEq.addClass(errorClass);
1364                        $formError.addClass(errorClass).text(error).dequeue();
1365                    });
1366                }
1367            }
1368        } else if (choice) {
1369            const $choice = $(choice.elem);
1370            let isChoice = false;
1371
1372            for (let i = 0; i < $choice.length; i += 1) {
1373                const $choiceItem = $choice.eq(i);
1374                const $choiceItemValue = $choiceItem.val();
1375
1376                if ($choiceItemValue) {
1377                    isChoice = true;
1378                }
1379            }
1380
1381            if (!isChoice) {
1382                isError = true;
1383                $formItemEq.addClass(errorClass);
1384                $formError.addClass(errorClass).text(choice.error);
1385            }
1386        }
1387    }
1388
1389    if (isError) {
1390        e.preventDefault();
1391
1392        $('html, body').stop().delay(0).queue(() => {
1393            errorOffsetTop = $(`${elems.$formItem}.${errorClass}`).eq(0).offset().top;
1394
1395            $('html, body').stop().animate({
1396                scrollTop: (errorOffsetTop - $(elems.$hd).outerHeight(true) - 10)
1397            }, 300, 'swing');
1398        });
1399    }
1400}).on('click', '[type="reset"]', (e) => {
1401    const $agree = $('.jAgree');
1402    let errorOffsetTop = $(elems.$formItem).eq(0).offset().top;
1403    const agree = $agree.prop('checked');
1404
1405    formReset(e.currentTarget);
1406    $agree.stop().delay(0).queue(() => {
1407        $agree.prop('checked', agree);
1408
1409        $('html, body').stop().animate({
1410            scrollTop: (errorOffsetTop - $(elems.$hd).outerHeight(true) - 10)
1411        }, 300, 'swing');
1412
1413        $agree.dequeue();
1414    });
1415
1416}).on('click', elems.$projectFixedBtn, (e) => {
1417    const $this = $(e.currentTarget);
1418    const $projectFixed = $this.parents(elems.$projectFixed);
1419
1420    $projectFixed.toggleClass(`p:${hiddenClass} t:${hiddenClass} m:${hiddenClass}`);
1421
1422}).on('click', '.jAfaClick', () => {
1423    $('.smart_alpha').click();
1424}).on('change', elems.$selectURL, (e) => {
1425    const $this = $(e.currentTarget);
1426
1427    window.location = $this.val();
1428}).on('change', elems.$checkbox, (e) => {
1429    formDisabled(e.currentTarget)
1430}).on('keydown', elems.$formItem, (e) => {
1431    const $this = $(e.currentTarget);
1432    const typeIsTel = $this.attr('type') === 'tel';
1433    const ASCIICode = e.keyCode || e.which;
1434    let isShift = !!e.shiftKey;
1435
1436    if (typeIsTel) {
1437        if (isShift) {
1438            return false;
1439        } else {
1440            return (
1441                (ASCIICode === 8 ||
1442                    ASCIICode === 9 ||
1443                    ASCIICode === 13 ||
1444                    ASCIICode === 46 ||
1445                    ASCIICode === 190 ||
1446                    (ASCIICode >= 35 && ASCIICode <= 40) ||
1447                    (ASCIICode >= 48 && ASCIICode <= 57) ||
1448                    (ASCIICode >= 96 && ASCIICode <= 105)) &&
1449                ASCIICode !== 229
1450            );
1451        }
1452    }
1453}).on('focus', elems.$formItem, (e) => {
1454    const $this = $(e.currentTarget);
1455    const $formElem = $this.parents(elems.$formElem);
1456    const $radio = $formElem.find('[type="radio"]');
1457    const $checkbox = $formElem.find('[type="checkbox"]');
1458
1459    if ($radio.length) {
1460        $radio.prop('checked', true);
1461    } else if ($checkbox.length) {
1462        $checkbox.prop('checked', true);
1463    }
1464}).on("click", elems.$stoPopup, (e) => {
1465    const $this = $(e.currentTarget);
1466    const $popup = $(elems.$popup);
1467
1468    for (let i = 0; i < $popup.length; i += 1) {
1469        const $popupElem = $popup.eq(i);
1470        const popSet = $($popupElem).attr(":set")
1471            ? JSON.parse($($popupElem).attr(":set").replace(/'/g, '"'))
1472            : null;
1473
1474        if (popSet && popSet.name === "stoPopup") {
1475            $(elems.$body).addClass(overflowHiddenClass);
1476            $popupElem.addClass(showClass);
1477        }
1478    }
1479});
1480
1481$(elems.$window).ready(() => {
1482    sitemapInit();
1483    tinySlider();
1484    tabSlider();
1485    //afaInit();
1486    topScroll();
1487    anim();
1488    fade();
1489    branches();
1490    selectInit();
1491    linkScroll();
1492    pointInit();
1493    copyInit();
1494    formReset('[type="reset"]');
1495    tabScroll();
1496}).on('load', () => {
1497    navSubPosition();
1498    loadingInit();
1499    postInit();
1500    projectFixedInit();
1501}).on('resize', () => {
1502    navSubPosition();
1503    sitemapInit();
1504    selectInit();
1505    linkScroll();
1506    pointInit();
1507    projectFixedInit();
1508    tabScrollReset(true);
1509    tabScroll();
1510}).on('scroll', () => {
1511    topScroll();
1512    anim();
1513    pointScroll();
1514    tabScroll();
1515})

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.