PageSourceSearch

https://cfm.kt.com/js/v2/common/kt_common.js

js kt.com collected 2026-09-24 08:26:48 UTC 60,610 bytes, 2,065 lines download raw bytes

1/* 
2   KT.com version 1.0
3  
4   Copyright ⓒ 2017 kt corp. All rights reserved.
5   
6   This is a proprietary software of kt corp, and you may not use this file except in 
7   compliance with license agreement with kt corp. Any redistribution or use of this 
8   software, with or without modification shall be strictly prohibited without prior written 
9   approval of kt corp, and the copyright notice above does not evidence any actual or 
10   intended publication of such software. 
11*/ 
12
13$j = jQuery.noConflict(), $=$j;
14
15var kt_common = {
16	// Mobile Link URL
17	goMobileLink : function(){
18		KT_trackClicks('KT-개인_공통', '^KT-개인_공통^푸터^모바일 버전');
19
20		var rtValue = '';
21		try {
22			if (kt_common.isNull(ktSmartGWURL) != ''){
23				rtValue = ktSmartGWURL;
24			}
25		} catch (e){
26			rtValue = '';
27		}
28
29		if(kt_common.isNull(rtValue) == ''){
30			var code = ktMenuCd;				
31			if(kt_common.isNull(code) === ''){			
32				top.location.href = cl_mobile_domain;
33			}else{
34				kt_api.mobileLink(code);
35			}
36		}else{
37			top.location.href = rtValue;
38		}		
39	},
40
41	// Mobile Link URL callback
42	callbackMobileLinks : function(type, result){
43		try {
44			if(type === 'success'){
45				var resultData = result.data.mblLinkInfo;
46				top.location.href = resultData.svcUrl;
47			} else {
48				top.location.href = cl_mobile_domain;
49			}
50			
51			//모바일 버전으로 이동 시 PC 버전 쿠키 삭제
52			kt_common.rtdTodayClose('mobileverview', 'kt_rd', -1);
53		} catch(exception){
54			top.location.href = cl_mobile_domain;
55		}		
56	},
57
58	/*
59		MenuLink
60			linkUrl : 링크 정보
61			objStat : ga통계명 statcode
62			linktarget : 
63			_blank : 새창
64			빈값 or _self : 현재창
65			code : 메뉴코드
66			... 메뉴(페이지) 통합 로그 호출됨.			
67			lastStat : adobe통계명 statcode
68	*/ 
69	ktMenuLinkStat : function(linkUrl, objStat, linktarget, code, lastStat){
70		var titleName = 'KT-개인_공통';
71		let objStatGa = objStat || '';
72		let adobeStat = lastStat || '';
73		//GA
74		if (typeof(objStatGa) === 'object') {
75			if ("CLICK_INFO" in objStatGa) {
76				let eventObj = KT_GACallClickName(objStatGa.CLICK_INFO);
77				Object.assign(objStatGa, eventObj);
78				if (adobeStat !== '') {
79					objStatGa.ADOBE_GATEGORY = titleName;
80					objStatGa.ADOBE_CLICKNM = adobeStat;
81					objStatGa.LINK_NAME = adobeStat;
82				}
83				KT_GAtrackClicks(objStatGa);
84			}
85		} else if (typeof objStatGa === 'string') {
86			adobeStat = objStatGa;
87			//Adobe launch
88			KT_trackClicks(titleName, adobeStat);
89		}
90
91		klog.menu(titleName, adobeStat, code); //kLogcode.js
92
93		var oLinkUrl = linkUrl;
94		if (oLinkUrl !== ''){
95			setTimeout(function(){
96				if(linktarget === '' || linktarget === '_self'){
97					top.location.href=linkUrl;
98				} else if (linktarget.substring(0, 4) === '_pop'){
99					try {
100						var pw = linktarget.split('|')[1];
101						var ph = linktarget.split('|')[2];
102						kt_common.popLink(linkUrl, code, pw,  ph);
103					} catch(e){
104						common_log.log('kt_common.js ktMenuLinkStat() [팝업사이즈 오류]');
105					}
106				} else {
107					window.open(oLinkUrl,linktarget);
108				}
109			}, 100);
110		}
111	},
112
113	/*
114		메인 AOT 화면에서 배너 영역의 클릭 시 사용되는 함수. ( ktMenuLinkStat 함수와 동일.. 통합로그 호출 부분만 차이남. )
115
116		Link
117			linkUrl : 링크 정보
118			objStat : ga통계명 statcode
119			linktarget : 
120				_blank : 새창
121				빈값 or _self : 현재창
122			code : 메뉴코드
123			areaCode : 영역코드
124			type : bann...(Banner 통합log) 
125				   그 외에는 메뉴 통합로그 호출됨.
126			lastStat : adobe통계명 statcode			
127	*/ 
128	ktLinkStat : function(linkUrl, objStat, linktarget, code, areaCode, type, lastStat){
129		var titleName = 'KT-개인_메인';
130		let objStatGa = objStat || '';
131		let adobeStat = lastStat || '';
132
133		//GA
134		if (typeof(objStatGa) === 'object') {
135			if ("CLICK_INFO" in objStatGa) {
136				let eventObj = KT_GACallClickName(objStatGa.CLICK_INFO);
137				Object.assign(objStatGa, eventObj);
138				if (adobeStat !== '') {
139					objStatGa.ADOBE_GATEGORY = titleName;
140					objStatGa.ADOBE_CLICKNM = adobeStat;
141					objStatGa.LINK_NAME = adobeStat;
142				}
143				KT_GAtrackClicks(objStatGa);
144			} 
145		} else if (typeof objStatGa === 'string') {
146			adobeStat = objStatGa;
147			//Adobe launch
148			KT_trackClicks(titleName, adobeStat);
149		}
150
151		//빅배너 
152		if (type === 'omsbann'){	
153			// 온라인마케팅시스템 oms		
154			try {
155				omsf.bannerClickLog(areaCode, adobeStat, 'CL', adobeStat);
156			} catch(e){
157				common_log.log('kt_common.js omsf.bannerClickLog() [' + e.message + ']');
158			}
159
160			klog.banner(titleName, adobeStat, areaCode);
161		}
162
163		var oLinkUrl = linkUrl;
164		if (oLinkUrl !== ''){
165			setTimeout(function(){
166				if(linktarget === '' || linktarget === '_self'){
167					top.location.href=linkUrl;
168				} else if (linktarget.substring(0, 4) === '_pop'){
169					try {
170						var pw = linktarget.split('|')[1];
171						var ph = linktarget.split('|')[2];
172						kt_common.popLink(linkUrl, code, pw,  ph);
173					} catch(e){
174						common_log.log('kt_common.js ktLinkStat() [팝업사이즈 오류]');
175					}
176				} else {
177					window.open(oLinkUrl,linktarget);
178				}
179			}, 100);
180		}
181	},
182
183	/*
184		MenuLink : 마케팅 수집 연동 신규 생성
185			linkUrl : 링크 정보
186			traget : 링크 target
187			titleStat : 통계 title (구형)
188			objStat : ga통계명 statcode
189			linktarget : 
190			_blank : 새창
191			빈값 or _self : 현재창
192			code : 메뉴코드
193			... 메뉴(페이지) 통합 로그 호출됨.
194	*/ 
195	ktLinkStat2 : function(linkUrl, traget, titleStat, objStat, linktarget, code){
196		var titleName = titleStat || 'KT-개인_공통';
197		let objStatGa = objStat || '';
198		var oLinkUrl = linkUrl;
199
200		if (oLinkUrl !== ''){
201			setTimeout(function(){
202				traget.attr('href', oLinkUrl).attr('target', linktarget); //일반 링크
203				if (linktarget.substring(0, 4) === '_pop'){ // 팝업
204					try {
205						traget.attr('target', '_blank');
206						var pw = linktarget.split('|')[1];
207						var ph = linktarget.split('|')[2];
208						traget.on('click', function(e){
209							e.preventDefault();
210							kt_common.popLink(oLinkUrl, code, pw,  ph);
211						});
212					} catch(e){
213						common_log.log('kt_common.js ktMenuLinkStat() [팝업사이즈 오류]');
214					}
215				}
216
217				//GA 통계
218				traget.on('click', function(e){
219					if (typeof(objStatGa) === 'object') { // object형
220						if ("CLICK_INFO" in objStatGa) {
221							let eventObj = KT_GACallClickName(objStatGa.CLICK_INFO);
222							Object.assign(objStatGa, eventObj);
223							KT_GAtrackClicks(objStatGa);
224						}
225					} else if (typeof objStatGa === 'string') { //string형
226						KT_trackClicks(titleName, objStatGa);
227					}			
228					klog.menu(titleName, '', code); //kLogcode.js
229				});
230			}, 100);
231		}
232	},
233
234	ktLinkStatWithOMS : function(titleName, adobeStat){
235		//omsf.clickLog('CL', adobeStat);
236		KT_trackClicks(titleName, adobeStat);
237	},
238
239	/**
240	 * 링크
241	 * 	url : url주소
242	 * 	linkTarget : 링크타겟
243	 * 		_blank : 새창
244	 * 		_pop : 팝업(구분자 : |)
245	 * 			_pop|팝업명|가로길이|세로길이
246	 * 		빈값 or _self : 현재창
247	 * 	objStat : ga통계명 statcode
248	 *	lastStat : adobe통계명 statcode
249	 */
250	link : function(url, linkTarget, lastTitle, objStat, lastStat){
251		let objStatGa = objStat || '';
252		let titleName = lastTitle || '';
253		let adobeStat = lastStat || '';
254		if(kt_common.isNull(url) !== ''){
255			if(kt_common.isNull(linkTarget) === ''){
256				location.href = url;
257			} else if (linkTarget.indexOf('_pop') !== -1){
258				try {
259					var popInfo = linkTarget.split('|');
260					var pn = popInfo.length > 1 ? linkTarget.split('|')[1] : 'newWindow';
261					var pw = popInfo.length > 2 ? parseInt(linkTarget.split('|')[2]) : 820;
262					var ph = popInfo.length > 3 ? parseInt(linkTarget.split('|')[3]) : 700;
263
264					kt_common.popLink(url, pn, pw, ph);
265				} catch(e){
266					common_log.log('kt_common.js link() [팝업사이즈 오류]');
267				}
268			} else {
269				window.open(url, linkTarget);
270			}
271		}
272
273		//GA
274		if (typeof(objStatGa) === 'object') {
275			if ("CLICK_INFO" in objStatGa) {
276				let eventObj = KT_GACallClickName(objStatGa.CLICK_INFO);
277				Object.assign(objStatGa, eventObj);
278				if (adobeStat !== '') {
279					objStatGa.ADOBE_GATEGORY = titleName;
280					objStatGa.ADOBE_CLICKNM = adobeStat;
281					objStatGa.LINK_NAME = adobeStat;
282				}
283				KT_GAtrackClicks(objStatGa);
284			}
285		} else if (typeof objStatGa === 'string') {
286			adobeStat = objStatGa;
287			//Adobe launch
288			KT_trackClicks(titleName, adobeStat);
289		}
290	},
291
292	menuChk : function (code){
293		var rtCode = '';
294		try
295		{
296			if (kt_common.isNull(code) === ''){
297				rtCode = 'XXXXXX';
298			} 
299			else {
300				if (code.length > 6){
301					var strCnt = 6;
302					if (code.length === 7){
303						strCnt = 7;
304					} 
305					rtCode = code.substring(0, strCnt);
306				} else {
307					rtCode = code;
308				}
309			}
310		}catch(e)
311		{
312			rtCode = 'XXXXXX';
313		}
314		
315		return rtCode.substring(0, 1);
316	},
317
318	// 숫자 콤마 삽입
319	setComma : function(input){
320		input = String(input);
321		return input.replace(/(\d)(?=(?:\d{3})+(?!\d))/g, '$1,');
322	},
323
324	// 숫자 콤마 제거
325	removeComma : function(input){
326		input = String(input);
327		input.value.replace(/,/gi,'');
328	},
329
330	// 창닫기
331	close : function(){
332		window.open('', '_self');
333		window.close();
334	},
335
336	// api호출
337	api : function(args){
338		if(args.url.indexOf('http') === -1 && args.url.indexOf(api_domain) === -1){
339			if(args.url.indexOf('/') > 0){
340				args.url = '/' + args.url;
341			}
342
343			args.url = api_domain + args.url;
344		}
345
346		this.callAjax(args);
347	},
348	
349	/**
350	 * ajax 호출
351	 * 	args
352	 * 		- url : URL
353	 * 		- type : 전송방식(default : post)
354	 * 		- data : 전송값
355	 * 		- callback : 콜백함수
356	 * 		- cookie : true 일경우 cookie정보 보냄(생략가능)
357	 * 		- beforeSend : 전송전 실행함수(생략가능)
358	 * 		- complete : 전송완료후 실행함수(생략가능)
359	 * 		- enctype : 전송인코딩타입(생략가능)
360	 */
361	callAjax : function(args){
362		var ajaxArgs = {
363			url : args.url,
364			type : args.type !== undefined ? args.type : 'post',
365			data : args.data !== undefined ? args.data : '',
366			dataType : 'json',
367			cache : false,
368			crossDomain : true,
369			success : function(data){
370				common_log.log('kt_common.js callAjax('+ args.url +') [success]');
371				process();
372
373				function process(){
374					if(document.readyState === 'interactive' || document.readyState === 'complete'){
375						var returnCode = data.returnCode || data.responseCode;
376						if(returnCode !== undefined){
377							// returnCode : OK(성공), NG(실패)
378							if(returnCode.toLowerCase() === 'ok'){
379								if(args.callback){
380									args.callback('success', data);
381								}
382							} else {
383								common_log.log('kt_common.js callAjax('+ args.url +') [returnCode : '+ returnCode +']');
384
385								if(args.callback){
386									args.callback('fail', data);
387								}
388							}
389						} else {
390							if(args.callback){
391								args.callback('success', data);
392							}
393						}
394					} else {
395						setTimeout(function(){
396							process();
397						}, 100);
398					}
399				}
400
401				return data;
402			},
403			error : function(request, status, error){
404				common_log.log('kt_common.js callAjax('+ args.url +') ['+ error +']');
405
406				if(args.callback){
407					args.callback('error', error);
408				}
409			}
410		};
411
412		// 컨텍트타입
413		if(args.type === 'get'){
414			//ajaxArgs.contentType = 'text/plain; charset=utf-8';
415		}
416
417		// 동기/비동기
418		if(args.async !== undefined){
419			ajaxArgs.async = args.async;
420		}
421		
422		// 타임아웃
423		if(args.timeout !== undefined){
424			ajaxArgs.timeout = args.timeout;
425		}
426
427		// 쿠키
428		if(args.cookie === true){
429			ajaxArgs.xhrFields = { withCredentials:true };
430		}
431
432		// ajax 시작전 콜함수
433		if(args.beforeSend !== undefined){
434			ajaxArgs.beforeSend = args.beforeSend;
435		}
436
437		// ajax 성공후 콜함수
438		if(args.complete !== undefined){
439			ajaxArgs.complete = args.complete;
440		}
441
442		// 파일업로드
443		if(args.enctype === 'multipart/form-data'){
444			ajaxArgs.processData = false;
445			ajaxArgs.contentType = false;
446		}
447
448		$j.ajax(ajaxArgs);
449	},
450
451	/**
452	 * 쿼리스트링을 오브젝트로 변환
453	 * 	key1=value1&key2=value2 -> {key1 : value1, key2 : value2}
454	 */
455	queryToObject : function(){
456		var obj = {};
457		window.location.search.substring(1).replace(/([^=&]+)=?([^&]*)/g, function(m, key, value){
458			obj[key] = decodeURIComponent(value);
459		});
460		return obj;
461	},
462
463	/**
464	 * 오브젝트를 쿼리스트링으로 변환
465	 * 	{key1 : value1, key2 : value2} -> key1=value1&key2=value2
466	 */
467	objectToQuery : function(obj){
468		return $j.param(obj).replace(/\+/g, '%20');
469	},
470
471	/*
472	** 입력값이 특정 문자만으로 되어 있는지 체크하며
473	** 특정 문자만을 허용하려 할때 사용한다.
474	*/
475	containsCharsOnly : function(input, chars){
476		var val = input;
477		if(typeof input === 'object') {
478			val = input.value;
479		}
480
481		for (var i=0; i<val.length; i++)
482		{
483			if (chars.indexOf(val.charAt(i)) === -1)
484			{
485				return false;
486			}
487		}
488		return true;
489	},
490
491	// 입력값이 알파벳인지 체크
492	isAlphabet : function(input){
493		var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
494		return this.containsCharsOnly(input, chars);
495	},
496
497	// 입력값이 알파벳 대문자인지 체크한다
498	isUpperCase : function(input){
499		var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
500		return this.containsCharsOnly(input, chars);
501	},
502
503	// 입력값이 알파벳 소문자인지 체크한다
504	isLowerCase : function(input){
505		var chars = 'abcdefghijklmnopqrstuvwxyz';
506		return this.containsCharsOnly(input, chars);
507	},
508
509	// 입력값이 숫자만 있는지 체크한다
510	isNumber : function(input){
511		var chars = '0123456789';
512		return this.containsCharsOnly(input, chars);
513	},
514
515	// 입력값이 알파벳, 숫자로 되어 있는지 체크한다.
516	isAlphaNum : function(input){
517		var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
518		return this.containsCharsOnly(input, chars);
519	},
520
521	// 입력값이 숫자, 대시'-' 로 되어 있는지 체크한다.
522	// 전화번호나 우편번호, 계좌번호에 - 체크할때 유용하다.
523	isNumDash : function(input){
524		var chars = '-0123456789';
525		return this.containsCharsOnly(input, chars);
526	},
527
528	// 입력값이 숫자, 콤마',' 로 되어있는지 체크한다.
529	isNumComma : function(input){
530		var chars = ',0123456789';
531		return this.containsCharsOnly(input, chars);
532	},
533
534	// 입력값이 사용자가 정의한 포맷 형식인지 체크
535	isValidFormat : function(input, format){
536		var val = input;
537		if(typeof input === 'object'){
538			val = input.value;
539		}
540
541		if (val.search(format) !== -1)
542		{
543			return true;//올바른 포멧형식
544		}
545
546		return false;
547	},
548
549	// 입력값이 이메일 형식인지 체크한다.
550	isValidEmail : function(input){
551		var format = /^((\w|[\-\.])+)@((\w|[\-\.])+)\.([A-Za-z]+)$/;
552
553		return this.isValidFormat(input, format);
554	},
555
556	// 입력값이 전화번호 형식(숫자-숫자-숫자) 인지 체크한다.
557	isValidPhone : function(input){
558		var format = /^(\d+)-(\d+)-(\d+)$/;
559
560		return this.isValidFormat(input, format);
561	},
562
563	//입력값의 바이트 길이를 리턴한다.
564	//getByteLength : function(input)
565	getByteLength : function(source){
566		var byteLength = 0;
567
568		for (var i=0; i<source.length; i++)
569		{
570			var input = source.substr(i, i+1);
571			var oneChar = escape(input.charAt(0));
572
573			if (oneChar.length === 1)
574			{
575				byteLength++;
576			}else if (oneChar.indexOf('%u') !== -1)
577			{
578				byteLength += 2;
579			}else if (oneChar.indexOf('%') !== -1)
580			{
581				byteLength += oneChar.length / 3;
582			}
583		}
584
585		return byteLength;
586	},
587
588	/**
589	 * 팝업 링크
590	 * 	linkUrl : 팝업URL
591	 * 	popName : 팝업명
592	 * 	pw : 너비
593	 * 	ph : 높이
594	 * 	pt : top(생략시 가운데)
595	 * 	pl : left(생략시 가운데)
596	 */
597	popLink : function(linkUrl, popName, pw, ph, pt, pl){
598		var dualScreenLeft = window.screenLeft != undefined ? window.screenLeft : screen.left;
599		var dualScreenTop = window.screenTop != undefined ? window.screenTop : screen.top;
600
601		var width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
602		var height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;
603
604		if(kt_common.isNull(pt) === ''){
605			pt = ((height / 2) - (ph / 2)) + dualScreenTop;
606		}
607
608		if(kt_common.isNull(pl) === ''){
609			pl = ((width / 2) - (pw / 2)) + dualScreenLeft;
610		}
611
612		var newWindow = window.open(linkUrl, popName, 'width=' + pw + ', height=' + ph + ', top=' 
612+ pt + ', left=' + pl + ', status=no, scrollbars=yes');
613		if (window.focus){
614			newWindow.focus();
615		}
616	},
617
618	/**
619	 * 레이어팝업
620	 * 	$target : 레이어타겟
621	 * 	pw : 너비
622	 * 	ph : 높이
623	 * 	pt : top(생략시 가운데)
624	 * 	pl : left(생략시 가운데)
625	 */
626	showLayer : function($target, lw, lh, lt, ll){
627		var $p = $target.closest('.layers');
628		if($p.length === 0){
629			var width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
630			var height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;
631
632			if(kt_common.isNull(lt) === ''){
633				lt = (height / 2) - (lh / 2);
634			}
635
636			if(kt_common.isNull(ll) === ''){
637				ll = (width / 2) - (lw / 2);
638			}
639		} else {
640			if(kt_common.isNull(lt) === ''){
641				lt = (($p.height() - $target.outerHeight()) / 2 + $p.scrollTop()) + 'px';
642			}
643
644			if(kt_common.isNull(ll) === ''){
645				ll = (($p.width() - $target.outerWidth()) / 2 + $p.scrollLeft()) + 'px';
646			}
647		}
648
649		$target.css('position', 'absolute');
650		$target.css('width', lw);
651		$target.css('height', lh);
652		$target.css('top', lt);
653		$target.css('left', ll);
654		$target.css('z-index', 100);
655	},
656
657	// Object check
658	isNull : function(obj){
659		var rtValue = '';
660
661		try 
662		{
663			if (obj === undefined || obj === null || obj === ''){
664				rtValue = '';
665			} else {
666				rtValue = obj;
667			}
668		}catch(e){
669			rtValue = '';
670		}
671
672		return rtValue;
673	},
674
675	/**
676	 * 페이징
677	 * 	$pagination : 페이징 Jquery Obejct
678	 * 	callback : 콜백함수
679	 * 	total : 전체글수
680	 * 	currentPage : 현재페이지번호
681	 * 	recordByPage : 페이지당 글수
682	 * 	pageByBlock : 블럭당 페이지수
683	 */
684	setPagination : function($pagination, callback, total, currentPage, recordByPage, pageByBlock){
685		var textFirstPage = '첫 페이지로 이동';
686		var textPrevPage = '이전 페이지로 이동';
687		var textCurrPage = '현재위치';
688		var textNextPage = '다음 페이지로 이동';
689		var textLastPage = '마지막 페이지로 이동';
690		var language = $j('html').attr('lang');
691		if(language.indexOf('en') >= 0){
692			textFirstPage = 'Go to the first Page';
693			textPrevPage = 'Go to the previous Page';
694			textCurrPage = 'Current page';
695			textNextPage = 'Go to the next Page';
696			textLastPage = 'Go to the last Page';
697		}
698		
699		if(total !== 0){
700			var pageHtml = '<div class="scope">';
701
702			// 기본값세팅
703			if(currentPage === undefined){
704				currentPage = 1;
705			}
706
707			if(recordByPage === undefined){
708				recordByPage = 10;
709			}
710
711			if(pageByBlock === undefined){
712				pageByBlock = 10;
713			}
714
715			// 전체페이지수
716			var numOfPage = Math.ceil(total / recordByPage);
717
718			if(numOfPage > 1){
719				var disabled = '';
720				if(currentPage === 1){	// 첫페이지
721					disabled = 'disabled';
722				}
723				pageHtml += '<a href="javascript:;" class="dir first ' + disabled + '">' + textFirstPage + '</a><a href="javascript:;" class="dir prev ' + disabled + '">' + textPrevPage + '</a>';
724			}
725
726			var firstPage = Math.floor((currentPage - 1) / pageByBlock) * pageByBlock + 1;	// 현재블럭의 첫페이지
727			var lastPage = numOfPage > firstPage + pageByBlock - 1 ? firstPage + pageByBlock - 1 : numOfPage;	// 현재블럭의 마지막페이지
728			for(var page = firstPage; page <= lastPage; page++){
729				if(page === currentPage){
730					pageHtml += '<span title="' + textCurrPage + '">' + page + '</span>';
731				} else {
732					pageHtml += '<a href="javascript:;" data-page="' + page + '">' + page + '</a>';
733				}
734			}
735
736			if(numOfPage > 1){
737				var disabled = '';
738				if(currentPage === numOfPage){	// 마지막페이지
739					disabled = 'disabled';
740				}
741				pageHtml += '<a href="javascript:;" class="dir next ' + disabled + '">' + textNextPage + '</a><a href="javascript:;" class="dir last ' + disabled + '">' + textLastPage + '</a>';
742			}
743
744			pageHtml += '</div>';
745
746			$pagination.html(pageHtml);
747
748			$pagination.find('a').on('click', function (event){
749				event.preventDefault();
750
751				if($j(this).hasClass('disabled') === false){
752					if(callback){
753						if($j(this).hasClass('first')){	// 첫페이지
754							callback(1);
755				            setTimeout(function(){ $pagination.find('a.first').focus();}, 400);//vos 결함아이디 1073742 : 초점유지
756						} else if($j(this).hasClass('prev')){	// 이전페이지
757							callback(currentPage - 1);
758				            setTimeout(function(){ $pagination.find('a.prev').focus();}, 400);//vos 결함아이디 1073742 : 초점유지
759						} else if($j(this).hasClass('next')){	// 다음페이지
760							callback(currentPage + 1);
761				            setTimeout(function(){ $pagination.find('a.next').focus();}, 400);//vos 결함아이디 1073742 : 초점유지
762						} else if($j(this).hasClass('last')){	// 마지막페이지
763							callback(numOfPage);
764				            setTimeout(function(){ $pagination.find('a.last').focus();}, 400);//vos 결함아이디 1073742 : 초점유지
765						} else {
766							callback(parseInt($j(this).data('page')));	// 페이지
767				            setTimeout(function(){ $pagination.find('span').attr('tabindex', '0').focus();}, 400);//vos 결함아이디 1073742 : 초점유지
768						}
769					}
770				}
771			});
772		}
773	},
774
775	// 로컬스토리지에 데이터 저장
776	setLocalStorage : function(key, data){
777		var value = {};
778
779		value.timestamp = new Date().getTime();	// 데이터생성날짜
780		value.data = data;
781
782		localStorage.setItem(key, JSON.stringify(value));
783	},
784	
785	// 로컬스토리지에서 데이터 조회
786	getLocalStorage : function(key){
787		this.removeLocalStorage(key);	// 데이터 삭제
788
789		var value = JSON.parse(localStorage.getItem(key));
790		if(value !== null){
791			return value.data;
792		}
793
794		return null;
795	},
796	
797	// 로컬스토리지에서 데이터 조회 (데이터 삭제 안함)
798	getLocalStorageNotDel : function(key){
799		var value = JSON.parse(localStorage.getItem(key));
800		if(value !== null){
801			return value.data;
802		}
803
804		return null;
805	},
806
807	// 로컬스토리지에서 데이터 삭제
808	removeLocalStorage : function(key){
809		var value = JSON.parse(localStorage.getItem(key));
810		if(value !== null){
811			var saveTime = value.timestamp;
812			var nowTime = new Date().getTime().toString();
813
814			// 5초가 지났으면 데이터삭제
815			var timePeriod = this.compareTime(saveTime, nowTime, 'S');
816			if(timePeriod > 5){
817				localStorage.removeItem(key);
818			}
819		}
820	},
821
822	// 현재시간 yyyy-mm-dd hh:mi:ss
823	dateToStr : function(t){
824		var now = new Date();
825		var year = now.getFullYear();
826		var month = now.getMonth() + 1;
827		var day = now.getDate();
828		var hour = now.getHours();
829		var minute = now.getMinutes();
830		var second = now.getSeconds();
831		if(month < 10){
832			month = '0' + month;
833		}
834		if(day < 10){
835			day = '0' + day;
836		}
837		if(hour < 10){
838			hour = '0' + hour;
839		}
840		if(minute < 10){
841			minute = '0' + minute;
842		}
843		if(second < 10){
844			second = '0' + second;
845		}
846		if (t=='N'){
847			return year + '' + month + '' + day + '' + hour + '' + minute + '' + second;
848		}else{
849			return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second;
850		}
851	},
852
853	// 시간비교
854	compareTime : function(source, target, type){
855		var t = 1;
856		switch(type){
857			case 'S' :
858				t = 1000;
859				break;
860			case 'M' :
861				t = 1000 * 60;
862				break;
863			case 'H' :
864				t = 1000 * 60 * 60;
865				break;
866			case 'D' :
867				t = 1000 * 60 * 60 * 24;
868				break;
869			default :
870				break;
871		}
872		return Math.floor((target - source) / t);
873	},
874
875	// 시간계산
876	addDays : function(date, days){
877		if(kt_common.isNull(date) !== ''){
878			if(kt_common.isNull(days) === ''){
879				days = 1;
880			}
881			var today = new Date();
882			if(typeof date === 'string'){
883				date = date.replace(/[^(0-9)]/gi, '');
884
885				today.setFullYear(date.substring(0, 4));
886				today.setMonth(parseInt(date.substring(4, 6)) - 1);
887				today.setDate(date.substring(6, 8));
888			} else if(typeof date === 'object'){
889				today = date;
890			}
891			today.setDate(today.getDate() + days);
892			return today;
893		}
894	},
895
896	// 시간계산
897	addMonths : function(date, months){
898		if(kt_common.isNull(date) !== ''){
899			if(kt_common.isNull(months) === ''){
900				months = 1;
901			}
902			var today = new Date();
903			if(typeof date === 'string'){
904				date = date.replace(/[^(0-9)]/gi, '');
905
906				today.setFullYear(date.substring(0, 4));
907				today.setMonth(parseInt(date.substring(4, 6)) - 1);
908				today.setDate(date.substring(6, 8));
909			} else if(typeof date === 'object'){
910				today = date;
911			}
912			let originalDay = today.getDate();
913			today.setDate(1);
914			
915			today.setMonth(today.getMonth() + months);
916			let lastDay = new Date(today.getFullYear(), today.getMonth()+1, 0).getDate();
917			today.setDate(Math.min(originalDay, lastDay));
918			return today;
919		}
920	},
921
922	// 접근페이지확인
923	checkedReferrer : function(url){
924		var isPossibled  = false;
925
926		if(/MSIE (\d+\.\d+);/.test(navigator.userAgent) || getIEVersion() !== 'N/A'){	// IE
927			isPossibled = true;
928		} else {
929			var referrerUrl = document.referrer;
930			var indexQueryStr = referrerUrl.indexOf('?');
931			if(indexQueryStr !== -1){
932				referrerUrl = referrerUrl.substring(0, indexQueryStr);
933			}
934
935			if(referrerUrl === url){
936				isPossibled = true;
937			}
938		}
939		
940		return isPossibled;
941	},
942
943	/* 
944		통합kt.com에서 개발되는 page. 에서는 배너 클릭시 호출되는 함수
945		adobe 통계 + GA 통계 + 통합Log
946	*/ 
947	KT_trackClicksNkLog : function (ClickCatName, ClickName, code){
948  		KT_trackClicks(ClickCatName, ClickName);
949  		klog.banner(ClickCatName, ClickName, code);
950	},
951
952	/*
953		검색어 
954			... 검색어 통합 로그 호출됨.
955	*/	
956	KT_trackClicksSearchkLog : function (existSch, notExistSch){
957  		klog.search(existSch, notExistSch);
958	},
959
960	/*
961		See&Click Banner Click
962			... 캠페인(See&Click) 통합 로그 호출됨.
963	*/	
964	KT_trackClicksSNCkLog : function (ClickCatName, ClickName, code, exeType, sgnlType, rtdEvtId, evSorcId){
965        KT_trackClicks(ClickCatName, ClickName);
966        switch(ktChannel){
967            case 'Cl' :
968                klog.snc(ClickCatName, ClickName, code, exeType, sgnlType, rtdEvtId, evSorcId);
969                break;
970            case 'Bz' :
971                klog.snc(ClickCatName, ClickName, code);
972                break;
973        }
974    },
975
976	/*
977		See&Click Banner View
978			... 노출 통합 로그 호출됨.
979	*/	
980	KT_trackClicksViewkLog : function (ClickCatName, ClickName, code, exeType, sgnlType, rtdEvtId, evSorcId){
981        KT_trackClicks(ClickCatName, ClickName);
982        switch(ktChannel){
983            case 'Cl' :
984                klog.sncview(ClickCatName, ClickName, code, exeType, sgnlType, rtdEvtId, evSorcId);
985                break;
986            case 'Bz' :
987                klog.sncview(ClickCatName, ClickName, code);
988                break;
989        }
990    },
991
992	/*
993		See&Click Banner Close
994			... 노출 통합 로그 호출됨.
995	*/	
996	KT_trackClicksClosekLog : function (ClickCatName, ClickName, code, exeType, sgnlType, rtdEvtId, evSorcId){
997        KT_trackClicks(ClickCatName, ClickName);
998        switch(ktChannel){
999            case 'Cl' :
1000                klog.sncclose(ClickCatName, ClickName, code, exeType, sgnlType, rtdEvtId, evSorcId);
1001                break;
1002            case 'Bz' :
1003                klog.sncclose(ClickCatName, ClickName, code);
1004                break;
1005        }
1006        
1007    },
1008
1009	/*
1010		See&Click Banner Close
1011			... 노출 통합 로그 호출됨.
1012	*/	
1013	KT_trackClicksNeverClosekLog : function (ClickCatName, ClickName, code, exeType, sgnlType, rtdEvtId, evSorcId){
1014        KT_trackClicks(ClickCatName, ClickName);
1015        switch(ktChannel){
1016            case 'Cl' :
1017                klog.sncneverclose(ClickCatName, ClickName, code, exeType, sgnlType, rtdEvtId, evSorcId);
1018                break;
1019            case 'Bz' :
1020                klog.sncneverclose(ClickCatName, ClickName, code);
1021                break;
1022        }
1023    },
1024
1025	callRtdTodayClose : function(cookieType, cookieName, period){
1026		$j("#checkbox-"+cookieName).prop('checked', true);
1027		kt_common.rtdTodayClose(cookieType, cookieName, period);
1028	},
1029
1030	/*
1031		오늘 닫기 기능 ( 일정기간 보지않기 체크시에는 쿠키 관리 필요 )
1032		cookieName : 쿠키명
1033	*/
1034	rtdTodayClose : function(cookieType, cookieName, period){
1035		if(typeof period === 'string'){
1036			period = parseInt(period);
1037		}
1038
1039		// 0기간동안 열지않기 check box 확인
1040		if(cookieType === 'snc'){
1041			if($j('#checkbox_snc').is(':checked') === true || $j('#checkbox_snc_fold').is(':checked') === true){
1042				kt_common.setArrayCookie('snc_menu', ktMenuCd, period);
1043				kt_common.setArrayCookie('snc_camp', cookieName, period);
1044			}
1045		} else {
1046			var isCookie = false;
1047			if($j('#checkbox-' + cookieName).length){
1048				if($j('#checkbox-' + cookieName).is(':checked') === true){
1049					isCookie = true;
1050				}
1051			} else {
1052				isCookie = true;
1053			}
1054
1055			if(isCookie){
1056				kt.setComCookie(cookieName, new Date().toString(), period);
1057			}
1058		}
1059	},
1060
1061	/*
1062		쿠키세팅 - 배열
1063	*/
1064	setArrayCookie : function(cookieName, code, period){
1065		var val = kt.getComCookie(cookieName);
1066		var obj = [];
1067		if(val !== ''){
1068			obj = JSON.parse(val);
1069		}
1070
1071		var key = 'code';
1072		if(cookieName === 'snc_menu'){
1073			key = 'menuCd';
1074		} else if(cookieName === 'snc_camp'){
1075			key = 'campId';
1076		}
1077
1078		if(obj.length > 0){
1079			for(var i = 0; i < obj.length; i++){
1080				if(obj[i][key] === code){
1081					obj.splice(i, 1);
1082					break;
1083				}
1084			}
1085		}
1086
1087		var expire = new Date();
1088		expire.setSeconds(0);
1089		expire.setMinutes(0)
1090		expire.setHours(0);
1091
1092		var value = {};
1093		value[key] = code;
1094		value['expire'] = kt_common.addDays(expire, period).getTime();
1095		obj.push(value);
1096
1097		kt.setComCookie(cookieName, JSON.stringify(obj), 365);	// 365일 저장
1098	},
1099
1100	/*
1101		쿠키조회 - 배열
1102	*/
1103	getArrayCookie : function(cookieName, code){
1104		var returnValue = '';
1105		var val = kt.getComCookie(cookieName);
1106		var obj = [];
1107		if(val !== ''){
1108			obj = JSON.parse(val);
1109		}
1110		var key = 'code';
1111		if(cookieName === 'snc_menu'){
1112			key = 'menuCd';
1113		} else if(cookieName === 'snc_camp'){
1114			key = 'campId';
1115		}
1116
1117		if(obj.length > 0){
1118			var nowTime = new Date().getTime().toString();
1119
1120			for(var i = 0; i < obj.length; i++){
1121				if(obj[i][key] === code){
1122					if(kt_common.compareTime(nowTime, obj[i]['expire'], 'S') > 0){
1123						returnValue = obj[i];
1124					} else {
1125						kt_common.removeArrayCookie(cookieName, code);
1126					}
1127
1128					break;
1129				}
1130			}
1131		}
1132
1133		return returnValue;
1134	},
1135
1136	/*
1137		쿠키삭제 - 배열
1138	*/
1139	removeArrayCookie : function(cookieName, code){
1140		var val = kt.getComCookie(cookieName);
1141		var obj = [];
1142		if(val !== ''){
1143			obj = JSON.parse(val);
1144		}
1145
1146		var key = 'code';
1147		if(cookieName === 'snc_menu'){
1148			key = 'menuCd';
1149		} else if(cookieName === 'snc_camp'){
1150			key = 'campId';
1151		}
1152
1153		if(obj.length > 0){
1154			for(var i = 0; i < obj.length; i++){
1155				if(obj[i][key] === code){
1156					obj.splice(i, 1);
1157					break;
1158				}
1159			}
1160		}
1161
1162		kt.setComCookie(cookieName, JSON.stringify(obj), 365);	// 365일 저장
1163	},
1164
1165	// 태그제거
1166	removeTag : function(str){
1167		return kt_common.isNull(str).replace(/(<([^>]+)>)/gi, '');
1168	},
1169
1170	tagReplaceAll : function(str){
1171		return kt_common.isNull(str).replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&#39;/g, '\'').replace(/&#34;/g, '"').replace(/inside\/01\//g, 'inside/');
1172	},
1173
1174	txtReplaceAll : function(str){
1175		return kt_common.isNull(str).replace(/\r\n/g, '<br />').replace(/\n/g,'<br />').replace(/inside\/01\//g, 'inside/');
1176	},
1177
1178	// Path 끝 '/' 붙히기
1179	addLastSlash : function(path){
1180		var path = kt_common.isNull(path);
1181		if(path.lastIndexOf('/')  !== path.length - 1){
1182			path = path + '/';
1183		}
1184		return path;
1185	},
1186
1187	// 말줄임
1188	ellipsis : function(str, limit, letter){
1189		if(kt_common.isNull(letter) === ''){
1190			letter = '...';
1191		}
1192
1193		var cutStr = kt_common.cutStr(str, limit);
1194		if(str !== cutStr){
1195			cutStr += letter;
1196		}
1197		
1198		return cutStr;
1199	},
1200
1201	// Byte수 만큼 글자 자르기
1202	cutStr : function(str, limit){
1203		var str = kt_common.isNull(str);
1204		if(str === ''){
1205			return 0;
1206		}
1207
1208		var len = str.length;
1209		var size = 0;
1210		var cutIndex = len;
1211		for(var i = 0; i < len; i++){
1212			size += kt_common.charByteSize(str.charAt(i));
1213			if(size === limit){
1214				cutIndex = i + 1;
1215				break;
1216			} else if(size > limit){
1217				cutIndex = i;
1218				break;
1219			}
1220		}
1221
1222		return str.substring(0, cutIndex);
1223	},
1224
1225	// Byte 크기 구하기
1226	charByteSize : function(ch){
1227		if(kt_common.isNull(ch) === ''){
1228			return 0;
1229		}
1230
1231		var charCode = ch.charCodeAt(0);
1232		if(charCode <= 0x00007F){
1233			return 1;
1234		} else if(charCode <= 0x0007FF){
1235			return 2;
1236		} else if(charCode <= 0x00FFFF){
1237			return 3;
1238		} else {
1239			return 4;
1240		}
1241	},
1242
1243	ranDateNum : function(s){
1244		var d1 = new Date().getTime().toString();
1245		var d2 = parseInt(d1) % s;
1246
1247		return d2;
1248	},
1249
1250	//통계
1251	sendPageStatis : function(data, pageName){
1252		var result = data;
1253		var gaPageName = '';
1254		let loginStatusType = 'N';
1255	
1256		if(pageName !== undefined && pageName !== '' && pageName !== null){
1257			if(ktChannel === 'Cl'){
1258				gaPageName = pageName;
1259			}else{
1260				if(result.returnCode === 'ok' && result.data.scrnStatInfo !== '' && result.data.scrnStatInfo !== null){
1261					gaPageName = result.data.scrnStatInfo;
1262				}else{
1263					gaPageName = document.location.href;
1264				}
1265			}
1266		}else{
1267			if(result.returnCode === 'ok' && result.data.scrnStatInfo !== '' && result.data.scrnStatInfo !== null){
1268				gaPageName = result.data.scrnStatInfo;
1269			}else{
1270				gaPageName = document.location.href;
1271			}
1272		}
1273
1274		if(kt.isLogin() === 'Y'){
1275			loginStatusType = 'Y';
1276		}
1277
1278		//GA4
1279		let commonGapageView = {
1280			ADOBE_TITLE:gaPageName,
1281			PAGE_CLASS: document.location.href,
1282			PAGE_ID: ktMenuCd,
1283			DAY: this.getWeek(),
1284			CHANNEL: this.ktGaChannelName(),
1285			PLATFORM: cfmGainfo.PLATFORM,
1286			DEVICE: cfmGainfo.DEVICE,
1287			DEVICE_CATEGORY: cfmGainfo.DEVICE_CATEGORY,
1288			OS: cfmGainfo.OS,
1289			BROWSER: cfmGainfo.BROWSER,
1290			RESOLUTION: cfmGainfo.RESOLUTION,
1291			LOGIN_YN: loginStatusType
1292		}
1293
1294		let arrCommondepthName = this.ktGaDepthSplitName(gaPageName);
1295        commonGapageView.PAGE_TITLE = arrCommondepthName.PAGE_FULLNM;
1296        commonGapageView.PAGE_0DEPTH = arrCommondepthName.PAGE_0DEPTH;
1297        commonGapageView.PAGE_1DEPTH = arrCommondepthName.PAGE_1DEPTH;
1298        commonGapageView.PAGE_2DEPTH = arrCommondepthName.PAGE_2DEPTH;
1299		commonGapageView.PAGE_3DEPTH = arrCommondepthName.PAGE_3DEPTH;
1300
1301		sendGAPage(commonGapageView);
1302
1303		cfmFooterAreaHtml.statPageOms();  //온마시 통계
1304	},	
1305
1306	//통계
1307	sendStatis : function(data, pageName){
1308		var result = data;
1309		var apiPageName = '';
1310	
1311		if(pageName !== undefined && pageName !== '' && pageName !== null){
1312			if(ktChannel === 'Cl'){
1313				apiPageName = pageName;
1314			}else{
1315				if(result.returnCode === 'ok' && result.data.scrnStatInfo !== '' && result.data.scrnStatInfo !== null){	
1316					apiPageName = result.data.scrnStatInfo;
1317				}else{
1318					apiPageName = '통계용 페이지명 없음';
1319				}
1320			}
1321		}else{
1322			if(result.returnCode === 'ok' && result.data.scrnStatInfo !== '' && result.data.scrnStatInfo !== null){	
1323				apiPageName = result.data.scrnStatInfo;
1324			}else{
1325				apiPageName = '통계용 페이지명 없음';
1326			}
1327		}
1328		// GA용 통계 스크립트 호출
1329		ga('set', 'title', apiPageName); //GA용, adobe 통계 pageName을 그대로 호출
1330		ga('rollup.set', 'title', apiPageName); //Adobe s.pageName
1331		if(kt.isLogin() === 'Y'){
1332			s.eVar11='Y';
1333			ga('set','dimension1','Y');
1334			ga('rollup.set','dimension1','Y');
1335		}else{
1336			s.eVar11='N';
1337			ga('set','dimension1','N');
1338			ga('rollup.set','dimension1','N');
1339		}
1340		
1341		try{
1342			var GAcid = GAgetCookie('_ga').split('.');
1343			ga('set', 'dimension20', GAcid[2]+'.'+GAcid[3]); 
1344			ga('rollup.set', 'dimension20', GAcid[2]+'.'+GAcid[3]);
1345		} catch(e){
1346			common_log.log('kt_common.js sendStatis() [' + e.message + ']');
1347		}
1348	
1349		ga('send', 'pageview'); // GA용, 통계 전송
1350		ga('rollup.send', 'pageview');
1351		s.pageName = apiPageName;
1352		
1353		loadAdobeChk();
1354	},
1355	
1356	//통계 Launch
1357	sendStatisLaunch : function(data, pageName){
1358		var result = data;
1359		var apiPageName = '';
1360		var logPageName = ''
1361		var gaPageName = '';
1362		var rtUrl = document.location;
1363		let loginStatusType = 'N';
1364	
1365		if(pageName !== undefined && pageName !== '' && pageName !== null){
1366			if(ktChannel === 'Cl'){
1367				apiPageName = pageName;
1368				logPageName = pageName;
1369				gaPageName = pageName;
1370			}else{
1371				if(result.returnCode === 'ok' && result.data.scrnStatInfo !== '' && result.data.scrnStatInfo !== null){	
1372					apiPageName = result.data.scrnStatInfo;
1373					logPageName = result.data.scrnStatInfo;
1374					gaPageName = result.data.scrnStatInfo;
1375				}else{
1376					apiPageName = rtUrl;
1377					gaPageName = document.location.href;
1378				}
1379			}
1380		}else{
1381			if(result.returnCode === 'ok' && result.data.scrnStatInfo !== '' && result.data.scrnStatInfo !== null){	
1382				apiPageName = result.data.scrnStatInfo;
1383				logPageName = result.data.scrnStatInfo;
1384				gaPageName = result.data.scrnStatInfo;
1385			}else{
1386				apiPageName = rtUrl;
1387				gaPageName = document.location.href;
1388			}
1389		}
1390
1391		// GA용 통계 스크립트 호출
1392		ga('set', 'title', apiPageName); //GA용, adobe 통계 pageName을 그대로 호출
1393		ga('rollup.set', 'title', apiPageName); //Adobe s.pageName
1394		
1395		//Adobe launch
1396		_commonDL = {
1397			pageInfo :{
1398				page_name : apiPageName, //각 페이지명, 페이지명은 별도의 엑셀파일 참조, 페이지 depth 구분은 "^"로 구분
1399				page_url : rtUrl,
1400				channel : "PC", //예시) pc web : PC, mobile web : Mobile, App : App
1401				login_status : "N", // 예시) "Y"(로그인),  "N"(비로그인)
1402				login_type : "", // 예시) ID 로그인 : normal, 소셜로그인 : facelook, kakaotalk, 자동로그인 : auto
1403			}
1404		};
1405
1406		if(kt.isLogin() === 'Y'){
1407			_commonDL.pageInfo.login_status = 'Y';
1408			loginStatusType = 'Y';
1409			ga('set','dimension1','Y');
1410			ga('rollup.set','dimension1','Y');
1411		}else{
1412			_commonDL.pageInfo.login_status = 'N';
1413			ga('set','dimension1','N');
1414			ga('rollup.set','dimension1','N');
1415		}
1416		
1417		try{
1418			var GAcid = GAgetCookie('_ga').split('.');
1419			ga('set', 'dimension20', GAcid[2]+'.'+GAcid[3]); 
1420			ga('rollup.set', 'dimension20', GAcid[2]+'.'+GAcid[3]);
1421		} catch(e){
1422			common_log.log('kt_common.js sendStatis() [' + e.message + ']');
1423		}
1424	
1425		ga('send', 'pageview'); // GA용, 통계 전송
1426		ga('rollup.send', 'pageview');
1427
1428		//GA4
1429		let commonGapageView = {
1430			ADOBE_TITLE:gaPageName,
1431			PAGE_CLASS: document.location.href,
1432			PAGE_ID: ktMenuCd,
1433			DAY: this.getWeek(),
1434			CHANNEL: this.ktGaChannelName(),
1435			PLATFORM: cfmGainfo.PLATFORM,
1436			DEVICE: cfmGainfo.DEVICE,
1437			DEVICE_CATEGORY: cfmGainfo.DEVICE_CATEGORY,
1438			OS: cfmGainfo.OS,
1439			BROWSER: cfmGainfo.BROWSER,
1440			RESOLUTION: cfmGainfo.RESOLUTION,
1441			LOGIN_YN: loginStatusType
1442		}
1443
1444		let arrCommondepthName = this.ktGaDepthSplitName(gaPageName);
1445        commonGapageView.PAGE_TITLE = arrCommondepthName.PAGE_FULLNM;
1446        commonGapageView.PAGE_0DEPTH = arrCommondepthName.PAGE_0DEPTH;
1447        commonGapageView.PAGE_1DEPTH = arrCommondepthName.PAGE_1DEPTH;
1448        commonGapageView.PAGE_2DEPTH = arrCommondepthName.PAGE_2DEPTH;
1449		commonGapageView.PAGE_3DEPTH = arrCommondepthName.PAGE_3DEPTH;
1450
1451		sendGAPage(commonGapageView);
1452
1453		cfmFooterAreaHtml.statPageLaunch(logPageName);  //페이지통계
1454	},
1455
1456	//날짜포멧
1457	dateFormat: function(type, date){
1458		var format = '';
1459		if(kt_common.isNull(date) != ''){
1460			date = new Date(date);
1461		}else{
1462			date = new Date();
1463		}
1464
1465		var year = date.getFullYear();
1466		var month = date.getMonth() + 1;
1467		var day = date.getDate();
1468		var hour = date.getHours();
1469		var minute = date.getMinutes();
1470		var second = date.getSeconds();
1471
1472		month = month > 9 ? month : '0'+ month;
1473		day = day > 9 ? day : '0'+ day;
1474		hour = hour > 9 ? hour : '0'+ hour;
1475		minute = minute > 9 ? minute : '0'+ minute;
1476		second = second > 9 ? second : '0'+ second;
1477
1478		format = type;
1479		format = format.replace('YYYY', year);
1480		format = format.replace('MM', month);
1481		format = format.replace('DD', day);
1482		format = format.replace('HH', hour);
1483		format = format.replace('mm', minute);
1484		format = format.replace('ss', second);
1485
1486		common_log.log('kt_common.js dateFormat() [loadServerTime:'+ loadServerTime +', date:'+ format +']');
1487
1488		return format;
1489	},
1490	
1491	//컨텐츠 타입
1492    contsViewType: function(mode, target, areaData, conts){
1493        var html;
1494        if(conts.areaContsType == "01"){ //html
1495            html = $j(conts.htmlInfo);
1496            target.append(html);
1497        }else if(conts.areaContsType == "02"){ //이미지
1498            html = $j('<a href="#"><img src="#"/></a>');
1499            html.find('img').attr('alt', kt_common.removeTag(conts.altText));
1500
1501			if(mode == 'common'){
1502				html.find('img').attr('src', cfm_domain + conts.saveImgPath + conts.saveImgNm);
1503			}else{
1504				html.find('img').attr('src', cl_domain + conts.saveImgPath + conts.saveImgNm);
1505			}
1506
1507            conts.statInfo = areaData.statInfo + conts.statInfo;			
1508			conts.omsBannerName = conts.statInfo;
1509            kt_common.linkInfo(mode, 'img', html, conts, conts.floatTrgtType, conts.popupWdth, conts.popupVrtc);
1510
1511			target.append(html);
1512        }else if(conts.areaContsType == "03"){ //이미지맵
1513            html = $j('<img src="#">');
1514			html.attr('alt', kt_common.removeTag(conts.altText));
1515            html.attr('usemap', '#'+ conts.areaContsId);
1516
1517			if(mode == 'common'){
1518				html.attr('src', cfm_domain + conts.saveImgPath + conts.saveImgNm);
1519			}else{
1520				html.attr('src', cl_domain + conts.saveImgPath + conts.saveImgNm);
1521			}
1522
1523            target.append(html);
1524            target.append('<map name="'+ conts.areaContsId +'"></map>');
1525            
1526            $j.each(conts.areaContsImgMapList, function(i, map){
1527                var area = $j('<area>');
1528                var imgMapType = "";
1529                if (map.imgmapType == "01"){ //사각형
1530                    imgMapType = "rect";
1531                }else if (map.imgmapType == "02"){ //원형
1532                    imgMapType = "circle";
1533                }else if (map.imgmapType == "03"){ //다각형
1534                    imgMapType = "poly";
1535                }
1536
1537                map.statInfo = areaData.statInfo + map.imgmapStatInfo;
1538                map.areaId = map.areaContsId;
1539                map.omsBannerType = conts.omsBannerType;
1540                map.omsBannerName = areaData.statInfo + map.imgmapStatInfo;
1541
1542                area.attr('alt', kt_common.removeTag(map.altText));
1543                area.attr('coords', map.imgmapCrd);
1544                area.attr('shape', imgMapType);                
1545                target.find('map').append(area);
1546				kt_common.linkInfo(mode, 'imgMap', area, map, map.popupTrgtType, map.popupWdth, map.popupVrtc);
1547            });
1548        }
1549
1550        return html;
1551    },
1552
1553	//링크정보
1554	linkInfo: function(mode, type, traget, item, linkType, linkPopW, linkPopH){
1555		var linkTarget = '', titleName = '';
1556
1557        linkType = parseInt(linkType);
1558        if(linkType == '3'){
1559            linkTarget = '_pop|'+ linkPopW +'|'+ linkPopH;
1560            traget.attr('title', '새창열림');
1561        }else if(linkType == '2'){
1562            linkTarget = '_blank';
1563            traget.attr('title', '새창열림');
1564        }else{			
1565            linkTarget = '_self';
1566        }
1567		
1568		if(kt_common.isNull(item.menuCd) == '') item.menuCd = '';
1569        if(kt_common.isNull(item.areaId) == '') item.areaId = '';
1570        if(kt_common.isNull(item.omsBannerType) == '') item.omsBannerType = '';
1571        if(kt_common.isNull(item.omsBannerName) == '') item.omsBannerName = '';
1572
1573		if(mode == 'common'){ //공통
1574			titleName = 'KT-개인_공통';
1575
1576			if(type == 'click'){
1577				traget.on('click', function(e){
1578					if(item.svcUrl == 'login'){ //로그인
1579						KT_trackClicks(titleName, item.statInfo);
1580						kt.popupLogin(location.href);
1581						return false;
1582					}else if(item.svcUrl == 'logout'){ //로그아웃
1583						KT_trackClicks(titleName, item.statInfo);
1584						kt.goLogout();
1585						return false;
1586					}else if(item.svcUrl == 'stsfcSurvey'){ //만족도 조사
1587						KT_trackClicks(titleName, item.statInfo);
1588						kt_common.standAlone();
1589                		return false;
1590					}else if(item.svcUrl == 'cfmSmartTalkLink'){ //케이톡
1591						if($j(this).attr('id') == 'cfmSmartTalkLink'){
1592							KT_trackClicks(titleName, item.statInfo);
1593							cfmFooterAreaHtml.smartTalkPopup(0); //아이콘
1594						}else{
1595							cfmFooterAreaHtml.smartTalkPopup(1);
1596						}
1597						
1598                		return false;
1599					}else{
1600						if($j(this).attr('id') == 'cfmFloatingInfoBtn'){ //소개
1601							item.svcUrl = item.urlInfo;
1602						}
1603
1604						kt_common.ktMenuLinkStat(item.svcUrl, item.statInfo, linkTarget, item.menuCd);
1605						if(item.svcUrl != '') return false;
1606					}
1607				});
1608			}else{ //메인						
1609				if(type == 'all'){
1610					if(item.statInfo != undefined) item.statInfo = item.statInfo.replace('^GNB', '^전체메뉴'); //통계정보 변경
1611				}else if(type == 'channel' || type == 'recommend' || type == 'direct' || type == 'img'){
1612					item.svcUrl = item.urlInfo;
1613				}else if(type == 'targetMenu'){
1614					if(item.statInfo != undefined) item.statInfo = item.statInfo.replace('GNB^', '퀵메뉴^최근본메뉴^'); //통계정보 변경
1615				}
1616	
1617				traget.attr('href', 'javascript:kt_common.ktMenuLinkStat(\''+ item.svcUrl +'\',\''+ item.statInfo +'\',\''+ linkTarget +'\',\''+ item.menuCd +'\');');
1618			}
1619		}else if(mode == 'main'){ //메인
1620			titleName = 'KT-개인_메인';
1621
1622			if(type == 'click'){
1623				//중복제거
1624				if(item.statInfo.indexOf('^KT-개인_메인^') > -1){
1625                    KT_trackClicks(titleName, item.statInfo);
1626                }else{
1627					KT_trackClicks(titleName, '^KT-개인_메인^'+ item.statInfo);
1628				}				
1629			}else{
1630				traget.attr('href', 'javascript:kt_common.ktLinkStat(\''+ item.urlInfo +'\',\''+ item.statInfo +'\',\''+ linkTarget +'\',\''+ item.menuCd +'\',\''+ item.areaId +'\',\''+ item.omsBannerType +'\',\''+ item.omsBannerName +'\');');
1631			}
1632		}	
1633	},
1634
1635	//링크정보 : 마케팅 수집 연동 신규 생성
1636	linkInfo2: function(mode, type, traget, item, linkType, linkPopW, linkPopH){
1637		var linkTarget = '', titleName = '';
1638
1639		linkType = parseInt(linkType);
1640		if(linkType == '3'){
1641			linkTarget = '_pop|'+ linkPopW +'|'+ linkPopH;
1642			traget.attr('title', '새창열림');
1643		}else if(linkType == '2'){
1644			linkTarget = '_blank';
1645			traget.attr('title', '새창열림');
1646		}else{			
1647			linkTarget = '_self';
1648		}
1649		
1650		if(kt_common.isNull(item.menuCd) == '') item.menuCd = '';
1651		if(kt_common.isNull(item.areaId) == '') item.areaId = '';
1652		if(kt_common.isNull(item.omsBannerType) == '') item.omsBannerType = '';
1653		if(kt_common.isNull(item.omsBannerName) == '') item.omsBannerName = '';
1654
1655		if(mode == 'common'){ //공통
1656			titleName = 'KT-개인_공통';
1657
1658			if(type == 'click'){
1659				traget.on('click', function(e){
1660					if(item.svcUrl == 'login'){ //로그인
1661						KT_trackClicks(titleName, item.statInfo);
1662						kt.popupLogin(location.href);
1663						return false;
1664					}else if(item.svcUrl == 'logout'){ //로그아웃
1665						KT_trackClicks(titleName, item.statInfo);
1666						kt.goLogout();
1667						return false;
1668					}else if(item.svcUrl == 'stsfcSurvey'){ //만족도 조사
1669						KT_trackClicks(titleName, item.statInfo);
1670						kt_common.standAlone();
1671						return false;
1672					}else if(item.svcUrl == 'cfmSmartTalkLink'){ //케이톡
1673						if($j(this).attr('id') == 'cfmSmartTalkLink'){
1674							KT_trackClicks(titleName, item.statInfo);
1675							cfmFooterAreaHtml.smartTalkPopup(0); //아이콘
1676						}else{
1677							cfmFooterAreaHtml.smartTalkPopup(1);
1678						}
1679						
1680						return false;
1681					}else{
1682						if($j(this).attr('id') == 'cfmFloatingInfoBtn'){ //소개
1683							item.svcUrl = item.urlInfo;
1684						}
1685						kt_common.ktMenuLinkStat(item.svcUrl, item.statInfo, linkTarget, item.menuCd);
1686						if(item.svcUrl != '') return false;
1687					}
1688				});
1689			}else{ //메인						
1690				if(type == 'all'){
1691					if(item.statInfo != undefined) item.statInfo = item.statInfo.replace('^GNB', '^전체메뉴'); //통계정보 변경(전체메뉴)
1692				}else if(type == 'channel' || type == 'recommend' || type == 'direct' || type == 'img'){ //recommend:간편서비스
1693					item.svcUrl = item.urlInfo;
1694				}else if(type == 'targetMenu'){ //최근 본 메뉴
1695					if(item.statInfo != undefined) item.statInfo = item.statInfo.replace('GNB^', '퀵메뉴^최근본메뉴^'); //통계정보 변경
1696				}				
1697				this.ktLinkStat2(item.svcUrl, traget, titleName, item.statInfo, linkTarget, item.menuCd);
1698			}
1699		}else if(mode == 'main'){ //메인
1700			titleName = 'KT-개인_메인';
1701
1702			if(type == 'click'){
1703				//중복제거
1704				if(item.statInfo.indexOf('^KT-개인_메인^') > -1){
1705					KT_trackClicks(titleName, item.statInfo);
1706				}else{
1707					KT_trackClicks(titleName, '^KT-개인_메인^'+ item.statInfo);
1708				}				
1709			}else{
1710				this.ktLinkStat2(item.urlInfo, traget, titleName, item.statInfo, linkTarget, item.menuCd);
1711			}
1712		}	
1713	},
1714
1715	//만족도조사 정보
1716	standAloneInfo: function() {
1717		if(properties == 'prd'){ //상용
1718			sdegWidgetId = 'KT_MAIN_NEW'; //메인
1719			sdegKey = '88a21276-a85b-4f96-9b8e-41bce6bad571';
1720
1721			if($j('#ktMainYn').length == 0 && kt_common.isNull(ktMenuCd) != ''){
1722				if(ktMenuCd.substring(0,1) == 'A'){ //마이
1723					sdegWidgetId = 'KT_MY_PAGE_NEW';
1724					sdegKey = '9c27088c-16b7-4644-937a-10af620d4950';
1725				}else if(ktMenuCd.substring(0,1) == 'B'){ //상품
1726					sdegWidgetId = 'KT_PRODUCT_NEW';
1727					sdegKey = '20a41da2-ec18-44ea-bae0-1d08c8ac4cf3';
1728				}else if(ktMenuCd.substring(0,1) == 'C'){ //혜택
1729					sdegWidgetId = 'KT_MSHIP_BNFIT_NEW';
1730					sdegKey = '5a64ddae-a80c-4e77-ae0d-1c306e37c8c9';
1731				}
1731else if(ktMenuCd.substring(0,1) == 'E'){ //고객지원
1732					sdegWidgetId = 'KT_CUST_SUPRT_NEW';
1733					sdegKey = '423af5ce-075a-4610-add7-5825c1637821';
1734				}
1735			}
1736		}else{ //기타
1737			sdegWidgetId = 'KT_MAIN_NEW'; //메인
1738			sdegKey = '8fa1d67d-1d43-4952-bcb6-62c6062ae8b0';
1739
1740			if($j('#ktMainYn').length == 0 && kt_common.isNull(ktMenuCd) != ''){		
1741				if(ktMenuCd.substring(0,1) == 'A'){ //마이
1742					sdegWidgetId = 'KT_MY_PAGE_NEW';
1743					sdegKey = 'ef390078-1528-4e01-93cf-b0ba2663dad2';
1744				}else if(ktMenuCd.substring(0,1) == 'B'){ //상품
1745					sdegWidgetId = 'KT_PRODUCT_NEW';
1746					sdegKey = '5ccab8b1-e6ff-4c76-992b-3681f3c718aa';
1747				}else if(ktMenuCd.substring(0,1) == 'C'){ //혜택
1748					sdegWidgetId = 'KT_MSHIP_BNFIT_NEW';
1749					sdegKey = '693d2100-3360-49c6-ab77-cd76d9aaecd3';
1750				}else if(ktMenuCd.substring(0,1) == 'E'){ //고객지원
1751					sdegWidgetId = 'KT_CUST_SUPRT_NEW';
1752					sdegKey = '32da9696-53b7-4682-bce6-4439c0e130e3';
1753				}
1754			}
1755		}
1756	},
1757
1758	//만족도조사 링크
1759	standAlone: function() {
1760		kt_common.setArrayCookie('stsfcSurvey', sdegWidgetId, 30); //30일(고정)
1761		var url = sdeg_domain + '/web/widget/sdeg.html?k='+ sdegKey +'&w='+ sdegWidgetId;
1762        window.open(url,'SdegPopup','width=460, height=720, toolbar=no, location=no, status=no, menubar=no');
1763    },
1764
1765	//페이지구분-2차(배포 DATA url 및 예외처리)
1766	pageType: function() {
1767		var str = 'cl';
1768		try {
1769			switch (chkMenu.substring(0, 1)) {
1770				case 'F' :
1771					str = 'shop';
1772					break;				
1773				default :
1774					str = 'cl';
1775					break;
1776			}
1777		} catch (error) {
1778			str = 'cl';
1779		}
1780
1781		return str;
1782	},
1783
1784	//페이지구분-2차(배포 DATA url 및 예외처리)
1785	pageUrlType: function() {
1786		var str = '';
1787		try {
1788			switch (chkMenu.substring(0, 1)) {
1789				case 'F' :
1790					str = 'shop-';
1791					break;				
1792				default :
1793					str = '';
1794					break;
1795			}
1796		} catch (error) {
1797			str = '';
1798		}
1799
1800		return str;
1801	},
1802
1803
1804	/* GA 페이지 통계 */
1805	escapeRegExp : (string) =>  {
1806		return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1807	},
1808
1809	// 요일가져오기
1810	getWeek : function(dateStr) {
1811		let chkDate = dateStr || '';
1812		let weekArray = ['일', '월', '화', '수', '목', '금', '토'];
1813		let date = new Date();
1814
1815		if(chkDate !== '') {
1816			chkDate = chkDate.replace(/[^(0-9)]/gi, '');
1817
1818			date.setFullYear(chkDate.substring(0, 4));
1819			date.setMonth(parseInt(chkDate.substring(4, 6)) - 1);
1820			date.setDate(chkDate.substring(6, 8));
1821		}
1822
1823		return weekArray[date.getDay()];
1824	},
1825
1826	/*
1827		페이지 통계 명칭 변경
1828		1. ktGaPageNameChange : 고정 명칭 변경 및 구분자 변경
1829		2. ktGaDepthSplitName : depth 구조 생성
1830    */
1831    
1832	ktGaPageNameChange : function(depth_name) {
1833		let replaceTagMap = {
1834            "^www^KT-About KT^" : "회사소개_PC_E^",
1835            "^www^KT-IRE^" : "회사소개_PC_E^",
1836            "^www^KT-IR^" : "회사소개_PC^",            
1837			"^www^kt-회사소개^" : "회사소개_PC^",
1838			"^www^KT-회사소개^" : "회사소개_PC^",
1839            "^www^KT^기업^상품/서비스^" : "KT닷컴_PC_기업^",
1840            "^www^KT-기업^" : "KT닷컴_PC_기업^",
1841            "^www^KT^개인^상품/서비스^" : "KT닷컴_PC^",
1842            "^www^인터넷/TV/결합^" : "KT닷컴_PC^",
1843            "^www^Shop집전화^" : "KT닷컴_PC^",
1844            "^www^Shop인터넷^" : "KT닷컴_PC^",
1845            "^www^Shop모바일^" : "KT닷컴_PC^",
1846            "^www^ShopUSIM/e^" : "KT닷컴_PC^",
1847            "^www^Shoptv^" : "KT닷컴_PC^",
1848            "^www^ShopMIT^" : "KT닷컴_PC^",
1849            "^www^KT-KIOSK^" : "KT닷컴_PC^",
1850            "^www^EXT-Bizmek^" : "KT닷컴_PC^",
1851            "^www^Shop^" : "KT닷컴_PC^",
1852            "^www^비즈멤버십^" : "KT닷컴_PC^",
1853            "^www^고객지원^" : "KT닷컴_PC^",
1854            "^www^서비스^" : "KT닷컴_PC^",
1855            "^www^5G^" : "KT닷컴_PC^",
1856            "^www^KT-개인^" : "KT닷컴_PC^",
1857            "^www^KT^" : "KT닷컴_PC^"
1858		}		
1859		let replaceYn = false;
1860		let pattern = new RegExp(Object.keys(replaceTagMap).map(this.escapeRegExp).join("|"), "g");
1861		if (depth_name.startsWith('^www^Shop^')) { //Shop일때만 예외처리 추가
1862			depth_name = depth_name.replace('^www^Shop^', '^www^KT^Shop^');
1863		}
1864		let result_name = depth_name.replace(pattern, match => {
1865			replaceYn = true;
1866			return replaceTagMap[match];
1867		});
1868	
1869		if (!replaceYn) {
1870			let arrSplitList;
1871			if (result_name.indexOf('^') > -1) {
1872				arrSplitList = result_name.split('^');
1873			} else {
1874				arrSplitList = result_name.split('>');
1875			}
1876			if (arrSplitList.length > 1) {
1877				if (arrSplitList.length >= 2) {
1878					result_name = "";
1879					for (let i = 0; i < arrSplitList.length; i++) {
1880						if (arrSplitList[i] !== '') {
1881							result_name += `${arrSplitList[i]}>`;
1882						}
1883					}
1884					result_name = result_name.substring(0, result_name.length-1);
1885	
1886				} else {            
1887					result_name = result_name.substring(1, result_name.length);
1888				}
1889			}
1890		}
1891	
1892		result_name = result_name.replaceAll('^', '>');
1893	
1894		return result_name; 
1895
1896	},
1897
1898	ktGaDepthSplitName : function(depth_name) {
1899		let PAGE_FULLNM = '';
1900		let PAGE_0DEPTH = '';
1901		let PAGE_1DEPTH = '';
1902		let PAGE_2DEPTH = '';
1903		let PAGE_3DEPTH = '';
1904
1905		PAGE_FULLNM = this.ktGaPageNameChange(depth_name);
1906		PAGE_0DEPTH = PAGE_1DEPTH = PAGE_2DEPTH = PAGE_3DEPTH = PAGE_FULLNM
1907
1908		let arrSplitList = PAGE_FULLNM.split('>');
1909		if (arrSplitList.length >= 1) {
1910			PAGE_0DEPTH = arrSplitList[0];
1911		}
1912
1913		if (arrSplitList.length >= 2) {
1914			PAGE_1DEPTH = arrSplitList.slice(0, 2).join(">");
1915		}
1916
1917		if (arrSplitList.length >= 3) {
1918			PAGE_2DEPTH = arrSplitList.slice(0, 3).join(">");
1919		}
1920
1921		if (arrSplitList.length >= 4) {
1922			PAGE_3DEPTH = arrSplitList.slice(0).join(">");
1923		}
1924
1925		return {"PAGE_FULLNM":PAGE_FULLNM, "PAGE_0DEPTH":PAGE_0DEPTH, "PAGE_1DEPTH":PAGE_1DEPTH, "PAGE_2DEPTH":PAGE_2DEPTH, "PAGE_3DEPTH":PAGE_3DEPTH};
1926	},
1927
1928	ktGaChannelName : function() {
1929		let channelNm = 'KT닷컴';
1930	
1931		if (ktChannel === 'Cl') {
1932			channelNm = 'KT닷컴';
1933		}
1934
1935		return channelNm;
1936	}
1937}
1938
1939var banner = {
1940	//간편조회배너
1941	simple: function(){
1942		if($j('.simple-banner').length){
1943			kt_api.simpleBanner();
1944		}
1945	},
1946
1947	//간편조회배너 callback 
1948    callbackSimple: function(type, result){
1949		try {
1950			if(type === 'success') {
1951				if(kt_common.isNull(result.data) !== '' && result.data.length > 0) {
1952					var resultList = result.data[0].areaSetList[0].areaContsList;
1953					if(kt_common.isNull(resultList) !== '' && resultList.length > 0) {
1954						var resultData = resultList[0];
1955						var targetType = '_self';	// 기본값 : 본창
1956						var targetTitle = '';	// 기본값 : 
1957						if(resultData.trgtType === '02') {	// 새창
1958							targetType = '_blank';
1959							targetTitle = ' title="새창열림"';
1960						}
1961	
1962						html = '<a href="' + resultData.urlInfo + '" target="' + targetType + '" '+ targetTitle +'><img src="' + cl_domain + kt_common.addLastSlash(resultData.saveImgPath) + kt_c
1962ommon.isNull(resultData.saveImgNm) + '" alt="' + resultData.altText + '"></a>';
1963						$j('.simple-banner').html(html);
1964					}
1965				}
1966			}
1967		} catch (e) {
1968			common_log.log('kt_common.js callbackSimple() [' + e.message + ']');
1969		}
1970	}
1971}
1972
1973let gaBasicInfo = {
1974	parseUAFallback : function(ua) {
1975		ua = (ua || '').toLowerCase();
1976	
1977		// DEVICE CATEGORY
1978		const isMobile = /mobile|iphone|ipod|android/.test(ua);
1979		const isTablet = /ipad|tablet/.test(ua) ||
1980			(navigator.maxTouchPoints > 1 && screen.width >= 768 && screen.width <= 1366);
1981		const deviceCategory = isTablet ? 'tablet' : (isMobile ? 'mobile' : 'desktop');
1982	
1983		// OS
1984		let os = 'Unknown';
1985		if (/windows nt/.test(ua)) os = 'Windows';
1986		else if (/mac os x|macintosh/.test(ua)) os = 'macOS';   // <-- macOS 로 수정
1987		else if (/android/.test(ua)) os = 'Android';
1988		else if (/iphone|ipad|ipod/.test(ua)) os = 'iOS';
1989		else if (/linux/.test(ua)) os = 'Linux';
1990	
1991		// BROWSER
1992		let browser = 'Unknown';
1993		if (/edg\//.test(ua)) browser = 'Edge';
1994		else if (/chrome\//.test(ua)) browser = 'Chrome';
1995		else if (/safari\//.test(ua) && !/chrome\//.test(ua)) browser = 'Safari';
1996		else if (/firefox\//.test(ua)) browser = 'Firefox';
1997	
1998		return { deviceCategory, os, browser };
1999	},
2000
2001	brandFromAndroidModel : function(modelRaw = '') {
2002		const m = (modelRaw || '').toUpperCase();
2003		if (!m) return '';
2004		if (m.startsWith('SM-') || m.startsWith('SM') || m.includes('SAMSUNG')) return 'samsung';
2005		if (m.startsWith('PIXEL') || m.includes('GOOGLE')) return 'Google';
2006		if (m.startsWith('ONEPLUS') || m.startsWith('CPH')) return 'OnePlus / OPPO';
2007		if (m.startsWith('MI') || m.startsWith('MIX') || m.includes('XIAOMI') || m.startsWith('REDMI')) return 'Xiaomi';
2008		if (m.startsWith('MOTO') || m.includes('MOTOROLA')) return 'Motorola';
2009		if (m.startsWith('VOG') || m.includes('HUAWEI')) return 'Huawei';
2010		if (m.startsWith('LM-') || m.includes('LG')) return 'LG';
2011		if (m.includes('SONY') || m.startsWith('XQ-')) return 'Sony';
2012		return 'Android Device';
2013	},
2014
2015	getClientInfoSync : function(){
2016		const ua = navigator.userAgent || '';
2017		const { deviceCategory: dc, os: osFallback, browser: brFallback } = this.parseUAFallback(ua);
2018	
2019		// DEVICE_CATEGORY
2020		const isTouch = navigator.maxTouchPoints > 0;
2021		const shortSide = Math.min(screen.width, screen.height);
2022		let DEVICE_CATEGORY = dc;
2023		if (isTouch && shortSide < 768) DEVICE_CATEGORY = 'mobile';
2024		else if (isTouch && shortSide >= 768 && shortSide <= 1366) DEVICE_CATEGORY = 'tablet';
2025		else if (!isTouch) DEVICE_CATEGORY = 'desktop';
2026	
2027		const PLATFORM = (DEVICE_CATEGORY === 'desktop') ? 'Web' : 'Mobile Web';
2028	
2029		// DEVICE 
2030		let DEVICE = '';
2031		if (/iphone/i.test(ua)) DEVICE = 'iPhone';
2032		else if (/ipad/i.test(ua)) DEVICE = 'iPad';
2033		else if (/ipod/i.test(ua)) DEVICE = 'iPod';
2034		else if (/android/i.test(ua)) {
2035			DEVICE = 'Android Device';
2036			try {
2037				const match = ua.match(/android[^;]*;([^)]+)/i);			
2038				if (match && match[1]) {
2039					const parts = match[1].split(';');
2040					let rawModel = parts[parts.length - 1].trim();
2041
2042					rawModel = rawModel.split(/\s+build/i)[0].trim();
2043
2044					if (rawModel.length > 2 && rawModel.toLowerCase() !== 'android') {
2045						DEVICE = this.brandFromAndroidModel(rawModel) + '_' + rawModel;
2046					}
2047				}
2048			} catch (e) {
2049				DEVICE = 'Android Device';
2050			}
2051		}
2052		else if (/windows/i.test(ua)) DEVICE = 'Windows PC';
2053		else if (/macintosh|mac os x/i.test(ua)) DEVICE = 'Mac';
2054		else if (/linux/i.test(ua)) DEVICE = 'Linux PC';
2055		else DEVICE = (DEVICE_CATEGORY === 'desktop') ? 'PC' : 'Device';
2056	
2057		const OS = osFallback;
2057        // Windows / macOS / Android / iOS / Linux
2058		const BROWSER = brFallback;   // Edge / Chrome / Safari / Firefox / Unknown
2059		const RESOLUTION = `${screen.width}x${screen.height}`;
2060	
2061		return { PLATFORM, DEVICE, DEVICE_CATEGORY, OS, BROWSER, RESOLUTION };
2062	}
2063}
2064
2065const cfmGainfo = gaBasicInfo.getClientInfoSync();

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.