PageSourceSearch

http://ehbook.co.kr/home/wp-content/themes/bcp/library/js/bcp.js?ver=0108

js ehbook.co.kr collected 2026-09-25 00:31:39 UTC 58,379 bytes, 2,349 lines download raw bytes

1var $ = jQuery;
2
3is_IE = $.browser.msie;
4browser_version = parseInt($.browser.version);
5bcp = {};
6
7$.fn.bcp = function(){
8	$.extend(this, bcp);
9	return this;
10}
11
12/* ######################################################################
13
14PLUGINS
15
16###################################################################### */
17
18/**
19 * WP전용. 갤러리에 Fancybox 구현
20 */
21bcp.wp_gallery = function(){
22	if( !$.fn.fancybox ) return this;
23	return this.each(function(i){
24		var t = $(this);
25		$('a > img', t).each(function(){
26			var a = $(this).parent();
27			a.attr('title', $(this).attr('alt'));
28			$(this).removeAttr('alt');
29		});
30	});
31}
32
33/**
34 * WP전용. 멀티페이지(페이지 브레이크가 들어간 싱글러)의 네비게이션 마크업이 
35 * paginate_links()로 생성되는 네비게이션과 마크업 구조가 달라서 마크업 강화.
36 */
37bcp.wp_multipage_markup_enhance = function(){
38	return this.each(function(i){
39		var t = $(this);
40		$('> span', t).addClass('current');
41		$('> span, a', t).addClass('page-numbers');
42	});
43}
44
45/**
46 * WP전용. 캡션 패딩 없앰.
47 */
48bcp.wp_caption_resize = function(_max_w){
49	return this.each(function(i){
50		var t = $(this);
51		var w = parseInt(t.css('width'));
52		if( w ){
53			t.width(w-10);
54		}
55		if( t.find('a').length )
56			t.find('a').addClass('inner-border');
57		else
58			t.find('img').wrap('<span/>').parent().addClass('inner-border');
59	});
60}
61
62/**
63 * IE hack
64 */
65bcp.ie_hack = function(){
66	if( !is_IE ) return;
67	
68	if( browser_version<=6 ){
69		$('input[type=text], input[type=password]').addClass('type-text');
70		$('input[type=checkbox]').addClass('type-checkbox');
71		$('input[type=radio]').addClass('type-radio');
72		$('input[type=button]').addClass('type-button');
73		$('input[type=submit]').addClass('type-submit');
74	}
75	if( browser_version<=8 ){
76		$('p:last-child, li:last-child').addClass('last-child');
77	}
78}
79
80/**
81 * IE 본문 영역보다 큰 이미지 크기 조정
82 * 
83 * max-width 속성이 없는 IE6에서만 해도 되지만, IE8 세로속성이 조정되지않는 문제때문에 IE8이하에 적용.
84 */
85bcp.ie_image_resize = function(_max_w){
86	if( !is_IE || (is_IE && browser_version>8) ) return this;
87	return this.each(function(i){
88		var t = $(this);
89		t.find('img').each(function(){ 
90			if( $(this).css('display')!='none' )
91				$(this).hide().data('tmp-hide', true);
92		});
93		var max_w = _max_w || parseInt(t.css('width'));
94		$(window).load( function(){
95			t.find('img').each(function(){
96				if( this.width >= max_w && $(this).css('max-width')!='none' ){ 
97					this.height = this.height*(max_w/this.width); 
98					this.width = max_w;
99				}
100				if( $(this).data('tmp-hide') )
101					$(this).show().data('tmp-hide', null);
102			});
103		});
104	});
105}
106
107/**
108 * 외부 링크의 target속성과 external 클래스 추가
109 */
110bcp.external_link_class = function(){
111	return this.each(function() {
112		$('a', this).each(function(){
113			var this_hostname = this.hostname.replace(/www./,'');
114			var loc_hostname = location.hostname.replace(/www./,'');
115			if(this_hostname!='' && this_hostname!=loc_hostname ){
116				$(this).attr('target', '_blank');
117				if( $(this).find('img').length==0 ) 
118					$(this).addClass('external');
119			}
120		});
121	});
122}
123
124/**
125 * 주기적으로 클래스 토글
126 */
127bcp.blink_class = function(opts){
128	var opts = $.extend({delay:1000, class_name:'invisible', repeat:''}, opts);
129	var t = this;
130	var repeat_count = 0;
131	var repeat_id;
132	var blink = function(){
133		if( typeof opts.repeat == 'number' && t.hasClass(opts.class_name) ){
134			repeat_count++;
135			if( repeat_count==opts.repeat ){
136				clearInterval(repeat_id);
137			}
138		}
139		t.toggleClass(opts.class_name);
140	}
141	if( opts.class_name )
142		repeat_id = setInterval(blink, opts.delay);
143}
144
145/**
146 * 요소 외부를 클릭했을 때 반응
147 */
148bcp.onclick_outside = function(handler){
149	return this.each(function(i){
150		var t = $(this);
151		
152		if( handler )
153			t.bind('onclick_outside', handler);
154		
155		$(window).mousedown(function(e){
156			var offset = t.offset();
157			var w = t.outerWidth();
158			var h = t.outerHeight();
159			if(offset.left>e.pageX || offset.top>e.pageY || offset.left+w<e.pageX || offset.top+h<e.pageY ){
160				t.trigger('onclick_outside');
161			}
162		});
163	});
164}
165
166
167
168/**
169 * AJAX 페이징
170 */
171bcp.ajax_paginate = function(){
172	return this.each(function(){
173		var t = $(this);
174		var args = t.data('ajax_args');
175		var nav = t.find('nav');
176		if(nav.length==0) return;
177		
178		$('a', nav).live('click', function(e){
179			e.preventDefault();
180			
181			$(this).addClass('loading');
182			
183			var data = {
184				action: 'paginate',
185				args: args
186			}
187			data[args.paged_key] = this.href.get_value_from_querystring(args.paged_key);
188			
189			$.post(bcp_vars.ajaxurl, data, function(rs){
190				var html = $(rs).html();
191				t.html(html).trigger('ajax_paginate_load_complete');
192			});
193			
194			if( window.history.replaceState ){
195				var url = this.href;
196				if( location.hash )
197					url += location.hash;
198				window.history.replaceState(null, '', url);
199			}
200			t.trigger('ajax_paginate_load_start');
201		});
202		
203		t.bind('ajax_paginate_load_complete', function(){
204			var top = t.offset().top - 20;
205			if( top < $('body').scrollTop() )
206				$('body').animate({scrollTop:top}, 200);
207		});
208	});
209}
210
211/**
212  * 폼 유효성 검사
213  */ 
214bcp.validate_form = function(_opts){
215	return this.each(function(){
216		var t = $(this);
217		
218		var valid;
219		
220		var opts = $.extend({lang:'kr'}, _opts);
221		
222		var error_msg = {
223			required_input: '필수 입력 항목입니다.',
224			required_select: '필수 선택 항목입니다.',
225			format: '형식이 올바르지 않습니다.'
226		};
227		
228		if( opts.lang=='en' ){
229			error_msg = {
230				required_input: 'Required field.',
231				required_select: 'Required option.',
232				format: 'Invalid format.'
233			};
234		}
235		
236		var show_error = function(parent, error){
237			$('span.error', parent).remove();
238			if( error_msg[error] ) 
239				error = error_msg[error];
240			var err = $(' <span class="error"> '+error+' </span> ').appendTo(parent);
241			if( bcp.blink_class )
242				err.bcp().blink_class({class_name:'invisible', repeat:5});
243			valid = false;
244		}
245		
246		var submit_handler = function(e){
247			if( t.hasClass('processing') )
248				return false;
249			
250			t.addClass('processing');
251			
252			valid = true;
253			$('span.error', t).remove();
254			
255			$('input, textarea', t).each(function(i){
256				if( this.type!='file' )
257					this.value = $.trim( this.value );
258			});
259			
260			// format fix
261			$('input.fix:not(.skip)', t).each(function(i){
262				if( $(this).hasClass('url') )
263					if( /^https?:\/\//.test(this.value) == false )
264						this.value = 'http://'+this.value;
265				
266				if( $(this).hasClass('number') )
267					this.value = this.value.replace(/[^0-9]/g, '');
268						
269				if( $(this).hasClass('alpha') )
270					this.value = this.value.replace(/[^a-zA-Z]/g, '');
271					
272				if( $(this).hasClass('alphalower') )
273					this.value = this.value.replace(/[^a-z]/g, '');
274					
275				if( $(this).hasClass('alphanumber') )
276					this.value = this.value.replace(/[^a-zA-Z0-9]/g, '');
277				
278				if( $(this).hasClass('alphalowernumber') )
279					this.value = this.value.replace(/[^a-z0-9]/g, '');
280			});
281			
282			// required
283			$('.required:not(.skip)', t).each(function(i){
284				var parent = $(this).parent();
285				if( parent[0].tagName=='LABEL' || parent.hasClass('bcp-select'))
286					parent = parent.parent();
287				
288				var type;
289				switch( this.tagName.toLowerCase() ){
290					case 'textarea':
291					case 'select':
292						type = this.tagName.toLowerCase();
293						break;
294						
295					default:""
296						type = this.type;
297						break;
298				}
299				
300				switch( type ){
301					case 'text':
302					case 'password':
303					case 'textarea':
304						if( this.value=='' )
305							show_error(parent, 'required_input');
306						break;
307					
308					case 'select':
309						if( this.value=='' )
310							show_error(parent, 'required_select');
311						break;
312						
313					case 'radio':
314					case 'checkbox':
315						if( $('input[type='+type+']:checked', parent).length==0 && $('.error', parent).length==0 )
316							show_error(parent, 'required_select');
317						break;
318				}
319			});
320			
321			// format
322			$('input:not(.skip)', t).each(function(i){
323				var parent = $(this).parent();
324				var patt = [];
325				
326				if( $('.error', parent).length || (this.value=='' && !$(this).hasClass('required')) )
327					return;
328				
329				if( $(this).hasClass('email') ){
330					patt.push( /[\w\.-]+@[\w\.-]+\.\w{2,4}/i );
331				}
332				
333				if( $(this).hasClass('url') ){
334					patt.push( /^https?:\/\/[a-z0-9-\.]+\.[a-z]{2,4}\/?\S*?$/i );
335				}
336				
337				if( $(this).hasClass('phone') ){
338					this.value = this.value.replace(/[^0-9-\s]/g, '').replace(/\s+/g, '-', this.value).replace(/-+/g, '-', this.value);
339					patt.push( /(\d{2}-)?\d{1,3}-\d{3,4}-\d{4}/ );
340				}
341				
342				if( $(this).hasClass('number') ){
343					patt.push( /[0-9]/g );
344				}
345				
346				if( $(this).hasClass('alpha') ){
347					patt.push( /[a-zA-Z]/g );
348				}
349				
350				if( $(this).hasClass('alphalower') ){
351					patt.push( /[a-z]/g );
352				}
353				
354				if( $(this).hasClass('alphanumber') ){
355					patt.push( /[a-zA-Z0-9]/g );
356				}
357				
358				if( $(this).hasClass('alphalowernumber') ){
359					patt.push( /[a-z0-9]/g );
360				}
361				
362				if( $(this).data('regex') ){
363					var regex = $(this).data('regex').match(/^\/(.+)\/(.*)?$/);
364					if( regex ){
365						patt.push( new RegExp(regex[1], (regex[2] || '')) );
366					}
367				}
368				
369				if( patt.length ){
370					for(var i=0; i<patt.length; i++){
371						var matches = this.value.match(patt[i]);
372						if( matches == null )
373							matches = [];
374						if( matches.join('') != this.value ){
375							show_error(parent, 'format');
376						}
377					}
378				}
379				
380				var length_match = this.className.match(/\blength-(\d*)\b/);
381				if( length_match ){
382					if( this.value.length != Number(length_match[1]) ){
383						show_error(parent, 'format');
384					}
385				}
386				
387				var min_length_match = this.className.match(/\bmin_length-(\d*)\b/);
388				if( min_length_match ){
389					if( this.value.length < Number(min_length_match[1]) ){
390						show_error(parent, 'format');
391					}
392				}
393			});
394			
395			this.form_valid = valid;
396			
397			if( !valid ){
398				t.removeClass('processing').trigger('error_occured');
399				return false;
400			}
401		}
402		
403		this.submit_handler = submit_handler;
404		this.show_error = show_error;
405		this.form_valid = valid;
406		
407		t.submit(submit_handler);
408	});
409}
410
411// 폼 요소 리턴키 사용 금지
412bcp.disable_form_return = function(){
413	return this.each(function(){
414		var t = $(this);
415		$('input', t).keydown(function(e){
416			if( e.keyCode==13 )
417				return false;
418		});
419	});
420}
421
422bcp.tabs = function(){
423	return this.each(function(){
424		var t = $(this);
425		
426		if( t.hasClass('ready') )
427			return;
428			
429		t.addClass('ready').addClass('bcp-tabs');
430		
431		var body = $('<div class="tabs-content"/>').prependTo(t);
432		var nav = $('<div class="tabs-nav clearfix"/>').prependTo(t);
433		var hds = $('> .tabs-hd', t);
434		var bds = $('> .tabs-bd', t);
435		
436		if( hds.length<2 ){
437			nav.remove();
438			hds.remove();
439			return;
440		}
441			
442		hds.each(function(i){
443			var hd = $(this).addClass('button').wrapInner('<span class="inner"/>');
444			var bd = bds.eq(i);
445			
446			hd.appendTo(nav);
447			bd.appendTo(body);
448			
449			hd.click(function(e){
450				hds.removeClass('selected');
451				hd.addClass('selected');
452				bds.hide();
453				bd.show();
454				t.trigger('tab_change', [hd, bd, i]);
455			});
456		});
457		
458		if( t.hasClass('full-size') ){
459			var w = 100/hds.length;
460			hds.css('width', w+'%');
461		}
462		
463		$('.tabs-hd:first-child', nav).addClass('first');
464		$('.tabs-hd:last-child', nav).addClass('last');
465		
466		var open_index = 0;
467		var hash = location.hash.replace(/#/, '');
468		if( hash ){
469			var index_match = location.hash.match(/tab-(\d*)/);
470			if( index_match ){
471				open_index = Math.max(0, Number(index_match[1])-1);
472			}else{
473				bds.each(function(i){
474					if( this.id==hash )
475						open_index = i;
476				});
477			}
478		}else{
479			bds.each(function(i){
480				if( $(this).hasClass('selected') )
481					open_index = i;
482			});
483		}
484		hds.eq(open_index).trigger('click');
485	});
486}
487
488bcp.accordion = function(_opts){
489	return this.each(function(){
490		var t = $(this);
491		
492		if( t.hasClass('ready') )
493			return;
494			
495		t.addClass('ready').addClass('bcp-accordion');
496		
497		var defaults = {
498			auto_open: 1,
499			selected: 0,
500			speed: 200,
501			show_toggle_button: true
502		};
503		
504		var opts = $.extend(defaults, _opts);
505		
506		for(var prop in opts)
507			if( t.data(prop)!=undefined )
508				opts[prop] = t.data(prop);
509		
510		var hds = $('> .accordion-hd', t);
511		var bds = $('> .accordion-bd', t).addClass('clearfix');
512		
513		hds.each(function(i){
514			var hd = $(this).addClass('button').wrapInner('<span class="inner"/>').append('<em/>');
515			var bd = bds.eq(i);
516			
517			hd.click(function(e, first_click){
518				if( hd.hasClass('selected') ){
519					hd.removeClass('selected');
520					bd.removeClass('opened').slideUp(opts.speed);
521				}else{
522					hds.removeClass('selected');
523					bds.removeClass('opened').slideUp(opts.speed);
524					hd.addClass('selected');
525					bd.addClass('opened');
526					if( first_click )
527						bd.show();
528					else
529						bd.slideDown(opts.speed);
530					t.trigger('accordion_change', [hd, bd, i]);
531				}
532			});
533		});
534		
535		if( opts.show_toggle_button ){
536			t.addClass('has-toggle-button');
537			var open_all = false;
538			$('<a href="#" class="toggle-button">모두열기</a>').click(function(){
539				if( open_all ){
540					$(this).text('모두열기');
541					hds.removeClass('selected');
542					bds.removeClass('selected').slideUp(opts.speed);
543					t.trigger('all_open');
544				}else{
545					$(this).text('모두접기');
546					hds.addClass('selected');
547					bds.addClass('selected').slideDown(opts.speed);
548					t.trigger('all_close');
549				}
550				open_all = !open_all;
551				return false;
552			}).appendTo(t);
553		}
554		
555		if( opts.auto_open )
556			hds.eq(opts.selected).trigger('click', true);
557	});
558}
559
560
561bcp.button_group = function(){ 
562	return this.each(function(){
563		var t = $(this);
564		
565		if( t.hasClass('ready') )
566			return;
567			
568		t.addClass('ready').addClass('bcp-button-group');
569		
570		var btns = $('> a', t).addClass('button').wrapInner('<span class="inner"/>');
571		
572		if( t.hasClass('full-size') ){
573			var w = 100/btns.length;
574			btns.css('width', w+'%');
575		}
576		$('a:first-child', t).addClass('first');
577		$('a:last-child', t).addClass('last');
578	});
579}
580
581
582
583bcp.slider = function(_opts){
584	return this.each(function(){
585		var t = $(this);
586		
587		if( t.hasClass('ready') )
588			return;
589			
590		t.addClass('ready').addClass('bcp-slider');
591		
592		var list = $('ul', t);
593		var items = $('li', list);
594		var list_wrap = list.wrap('<div/>').parent().addClass('list-wrap');
595		var nav = $('<div/>').addClass('nav').appendTo(t);
596		var np_nav = $('<div/>').addClass('np-nav').appendTo(t);
597		
598		var defaults = {
599			type: 'slider', // or 'fader'
600			auto: 1,
601			delay: 5,
602			speed: .5,
603			page: 0,
604			touchable: true
605		};
606		
607		var opts = $.extend(defaults, _opts);
608		
609		for(var prop in opts)
610			if( t.data(prop)!=undefined )
611				opts[prop] = t.data(prop);
612		
613		opts.delay = Math.max(1000, opts.delay*1000);
614		opts.speed = opts.speed*1000;
615		
616		var is_playing = opts.auto;
617		var page = opts.page;
618		var total_page = $('li', list).length;
619		var prev_page, z_index = 0, first_change = true, pause=false, change_id, item_width, item_height;
620		
621		t.addClass(opts.type);
622		
623		var change_page = function(_page, _speed){
624			page = (_page || 0) % total_page;
625				
626			var item = items.eq(page);
627			var item_index = item.data('index');
628			var speed = first_change ? 0 : (_speed || opts.speed);
629			
630			first_change = false;
631			
632			if( opts.type=='slider' ){
633				list.animate({marginLeft: -(item_index*item_width)+'px'}, speed);
634				
635			}else if( opts.type=='fader' ){
636				if( page != prev_page){
637					items.each(function(i){
638						$(this).css({'z-index': $(this).css('z-index')-1});
639					});
640					item.css({opacity:0, 'z-index':total_page}).animate({opacity:1}, speed);
641				}
642			}
643			
644			if( is_playing ) {
645				timeout_change_page();
646			}else{
647				stop_change();
648			}
649			
650			if( nav ) {
651				nav.find('span').removeClass('selected').eq(page).addClass('selected');
652			}
653			
654			if( np_nav ){
655				np_nav_visibility();
656			}
657			prev_page = page;
658		}
659		
660		var stop_change = function(){
661			is_playing = false;
662			clearTimeout(change_id);
663		}
664		
665		var timeout_change_page = function(){
666			if( opts.auto && pause==false ){
667				is_playing = true;
668				change_id = setTimeout(function(){ change_page(page+1); }, opts.delay);
669			}
670		}
671		
672		var create_nav = function(){
673			if( total_page > 1 ){
674				for(var i=0; i<total_page; i++){
675					$('<span data-page="'+i+'">'+(i+1)+'</span>').click(function(){
676						pause = true;
677						stop_change();
678						change_page( $(this).data('page') );
679					}).appendTo(nav);
680				}
681				
682				$('<span/>').addClass('prev').appendTo(np_nav);
683				$('<span/>').addClass('next').appendTo(np_nav);
684				$('span', np_nav).click(function(){
685					if( $(this).hasClass('prev') && page > 0 ){
686						pause = true;
687						stop_change();
688						change_page(page-1);
689					}else if( $(this).hasClass('next') && page < total_page-1 ){
690						pause = true;
691						stop_change();
692						change_page(page+1);
693					}
694				});
695				
696			}else{
697				nav.remove();
698				np_nav.remove();
699			}
700		}
701		
702		var np_nav_visibility = function(){
703			$('span', np_nav).removeClass('disabled');
704			if( page == 0 ){
705				$('.prev', np_nav).addClass('disabled');
706			}
707			if( page == total_page-1 ){
708				$('.next', np_nav).addClass('disabled');
709			}
710		}
711		
712		var touchbable = function(){
713			var touch_start = 0, touch_end = 0, touch_diff = 0, swipped = false, list_touch_start, list_touch_end;
714			
715			if( opts.type=='slider' ){
716				list.bind('touchstart', function(e){
717					e = e.originalEvent;
718					stop_change();
719					touch_start = e.pageX;
720					list_touch_start = parseInt(list.css('margin-left'));
721				});
722			}else if( opts.type=='fader' ){
723				list.bind('touchstart', function(e){
724					stop_change();
725					touch_start = e.pageX;
726				});
727			}
728			
729			list.bind('touchstart', function(e){
730				$('body').bind('touchmove', prevent_default);
731			})
732			.click(function(e){
733				if( swipped )
734					e.preventDefault();
735					swipped = false;
736			})
737			.bind('touchmove', function(e){
738				e = e.originalEvent;
739				touch_end = e.pageX;
740				touch_diff = touch_end - touch_start;
741				swipped = Math.abs(touch_diff) > 10;
742					
743				if( opts.type=='slider' ){
744					list.css({'margin-left': list_touch_start + touch_diff + 'px'});
745				}
746			})
747			.bind('touchend', function(e){
748				e = e.originalEvent;
749				$('body').unbind('touchmove', prevent_default);
750				if( opts.type=='slider' ){
751					list_touch_end = parseInt(list.css('margin-left'));
752					var new_page = -Math.round(list_touch_end/item_width);
753					new_page = Math.max(0, Math.min(total_page-1, new_page));
754					
755					var new_pos = items.eq(new_page).data('index')*item_width;
756					var diff = Math.min(Math.abs(new_pos+list_touch_end), item_width);
757					var speed = diff*opts.speed/item_width;
758				
759				}else if( opts.type=='fader' ){
760					if( touch_diff < 0 ){
761						new_page = page+1;
762					}else{
763						new_page = page-1;
764					}
765				}
766				pause = true;
767				change_page(new_page, speed);
768			});
769		}
770		
771		var prevent_default = function(e){
772			e.preventDefault(); 
773		}
774		
775		var init = function(){
776			item_width = t.width();
777			items.width(item_width);
778			list_wrap.width(item_width);
779			items.each(function(i){
780				$(this).data('index', i);
781				$('a', this).hover(
782					function(){
783						stop_change();
784					},
785					function(){
786						timeout_change_page();
787					}
788				);
789			});
790			
791			if( opts.type=='slider' ){
792				items.each(function(i){
793					$(this).css({left: item_width*i});
794				});
795				list.width(item_width*total_page);
796				
797			}else if( opts.type=='fader' ){
798				items.each(function(i){
799					$(this).css({'z-index': total_page-i});
800				});
801			}
802			
803			create_nav();
804			change_page();
805			
806			if( opts.touchable ){
807				try {  
808					document.createEvent("TouchEvent");
809					touchbable();
810				} catch(e) {}
811			}
812		}
813		
814		init();
815	});
816}
817
818
819// bxslider 편의설정
820bcp.bxslider = function(_opts){
821	if( ! $.fn.bxSlider ) 
822		return;
823	
824	return this.each(function(i){
825		var t = $(this).addClass('bcp-bxslider');
826		
827		if( t.hasClass('ready') )
828			return;
829			
830		t.addClass('ready');
831		
832		var slider = $('.slider', t);
833		
834		var opts = $.extend({ 
835			preloadImages: 'all',
836			auto: true,
837			controls: false
838		}, $.extend(_opts, t.data('option')));
839		
840		slider.bxSlider(opts);
841		
842		this.slider = slider;
843		
844		var group_id = new Date();
845		group_id = 'gallery-' + i + '-' + group_id.getTime();
846		
847		$('a', slider).each(function(i){
848			if( this.href.match(/.(jpg|jpeg|gif|png)$/) )
849				$(this).attr('rel', group_id).addClass('fancybox-group');
850		});
851		$('.fancybox-group', t).fancybox({
852		   nextEffect: 'none', 
853			prevEffect: 'none',
854			openEffect: 'none', 
855			closeEffect: 'none',
856			closeBtn: true,
857			padding: 0,
858			margin: 15
859		});
860	});
861}
862
863/**
864 * 툴팁
865 * 
866 * title 속성을 툴팁으로 띄울수도 있고, 
867 * rel 속성에 다른 앨리먼트의 아이디를 입력해서 띄울 수도 있음
868 */
869bcp.tooltip = function(_opts){
870	return this.each(function(){
871		var t = $(this);
872		
873		var defaults = {max_width: 300, direction: 'auto', classname: ''};
874		var opts = $.extend(defaults, _opts);
875		for(var prop in opts)
876			if( t.data(prop)!=undefined )
877				opts[prop] = t.data(prop);
878			
879		var balloon, balloon_text, prong, text = '';
880		
881		var create_balloon = function(){
882			if( balloon )
883				return;
884			if( $('#bcp-tooltip-balloon').length ) {
885				balloon = $('#bcp-tooltip-balloon');
886			}else{
887				balloon = $('<div id="bcp-tooltip-balloon"> <div class="text"></div> <div class="prong"><em></em></div> </div>').appendTo('body');
888			}
889			if( opts.classname )
890				balloon.addClass(opts.classname);
891			balloon_text = $('.text', balloon);
892			prong = $('.prong em', balloon);
893			balloon.hover(
894				function(){ 
895					$(this).addClass('hover').show(); 
896				},
897				function(){ 
898					$(this).removeClass('hover').hide();
899				}
900			);
901		}
902		
903		var show_balloon = function(){
904			clearTimeout(window.bcp_tooltip_timeout);
905			
906			create_balloon();
907			
908			balloon.css({width: 'auto', top:0, left:0, right: 'auto'});
909			balloon_text.html(text);
910			
911			if( balloon.width()> opts.max_width ){
912				balloon.width(opts.max_width);
913				balloon.addClass('multiline');
914			}else{
915				balloon.removeClass('multiline');
916			}
917			
918			var pos = bcp.get_balloon_position(t, balloon, prong, {direction: opts.direction});
919			
920			balloon.css({top:pos.top, left:pos.left, right:pos.right}).show();
921			
922			prong.css({left:pos.prong_left});
923		}
924		
925		var hide_balloon = function(){
926			window.bcp_tooltip_timeout = setTimeout(function(){
927				if( ! balloon.hasClass('hover') ){
928					balloon.hide();
929				}
930			}, 200);
931		}
932		
933		if( opts.text ){
934			text = opts.text;
935		}else if( t.attr('rel') && $('#'+t.attr('rel')).length ){
936			text = $('#'+t.attr('rel')).html();
937			$('#'+t.attr('rel')).remove();
938		}else{
939			text = t.attr('title');
940			t.removeAttr('title');
941		}
942		if( text ){
943			t.hover( show_balloon, hide_balloon ).click(function(e){
944				if( $(this).attr('href')=='#' ){
945					e.preventDefault();
946					balloon.toggle();
947				}
948			});
949		}
950	});
951}
952
953bcp.balloon = function(button_id){
954	return this.each(function(){
955		if( $(this).hasClass('ready') )
956			return;
957		
958		var balloon = $(this).addClass('bcp-balloon').addClass('ready').removeClass('hidden').appendTo('body');
959		balloon.append('<div class="prong"><em></em></div>');
960		
961		var prong = $('.prong em', balloon);
962		var button = $('#'+button_id).click(function(){
963			if( balloon.css('display')=='none' ){
964				set_pos();
965				balloon.show();
966			}else{
967				balloon.hide();
968			}
969		});
970		
971		var set_pos = function(){
972			var pos = bcp.get_balloon_position(button, balloon, prong);
973			balloon.css({top:pos.top, left:pos.left, right:pos.right});
974			prong.css({left:pos.prong_left});
975		}
976		
977		$(window).resize(function(){
978			if( window.balloon_timeout )
979				clearTimeout(window.balloon_timeout);
980				
981			window.balloon_timeout = setTimeout(set_pos, 100);
982		});
983		
984	});
985}
986
987bcp.fontsizer = function(){
988	return this.each(function(){
989	
990		var t = $(this).addClass('bcp-fontsizer');
991		var target = t.data('target');
992		if( !target )
993			target = '.entry-content';
994		var cookie_name = target.replace(/[^a-z0-9]/gi, '') + '-fontsize';
995		var saved_font_size = bcp.get_cookie(cookie_name);
996		var font_size = 1;
997		
998		var html = '';
999		html += '<a class="button minus" title="글자작게">가</a>';
1000		html += '<a class="button plus" title="글자크게">가</a>';
1001		t.html(html);
1002				
1003		var set_font = function(){
1004			if(font_size < 1 )
1005				font_size = 1;
1006			if(font_size > 1.4 )
1007				font_size = 1.4;
1008			font_size = Math.round( font_size*10 ) / 10;
1009			$(target).css({'font-size': font_size+'em'});
1010			bcp.set_cookie(cookie_name, font_size, {path:'/'});
1011		}
1012		
1013		$('a', t).click(function(e){
1014			e.preventDefault();
1015			if( $(this).hasClass('plus') ){ 
1016				font_size += 0.2; 
1017			}else if( $(this).hasClass('minus') ){ 
1018				font_size -= 0.2; 
1019			}else{ 
1020				font_size = 1;
1021			}
1022			set_font();
1023		})
1024		.bcp().tooltip();	
1025		
1026		if( Number(saved_font_size) ){
1027			font_size = Number(saved_font_size);
1028			set_font();
1029		}
1030	
1031	});
1032}
1033
1034bcp.treeview = function(){
1035	return this.each(function(){
1036		var t = $(this);
1037		
1038		if( t.hasClass('ready') )
1039			return;
1040			
1041		t.addClass('ready').addClass('bcp-treeview');
1042		
1043		var opts = {
1044			fold: true,
1045			cookie: true
1046		};
1047		for(var prop in opts)
1048			if( t.data(prop)!=undefined )
1049				opts[prop] = t.data(prop);
1050		
1051		var cookie_name = 'bcp-treeview';
1052		if( t.attr('id') )
1053			cookie_name += '-' + t.attr('id');
1054		
1055		$('> li', t).addClass('root').each(function(){
1056			var li = $(this);
1057			var submenu = $('.children', li);
1058			if( submenu.length ){
1059				var arrow = $('<span class="arrow"/>').appendTo(this).click(function(){
1060					if( submenu.css('display')=='none' ){
1061						submenu.slideDown(200);
1062						li.removeClass('folded');
1063					}else{
1064						submenu.slideUp(200);
1065						li.addClass('folded');
1066					}
1067					update_status();
1068				});
1069			}
1070		});
1071		
1072		var update_status = function(){
1073			var d = [];
1074			$('.root', t).each(function(){
1075				var display = $(this).hasClass('folded') ? 0 : 1;
1076				d.push(display);
1077			});
1078			d = '['+d.join(',')+']';
1079			if( opts.cookie )
1080				bcp.set_cookie(cookie_name, d, {expires: 7, path:'/'});
1081		}
1082		
1083		var last_status = opts.cookie ? $.parseJSON(bcp.get_cookie(cookie_name)) : null;
1084		if( last_status && last_status.length==$('.root').length ){
1085			for(var i=0; i<last_status.length; i++){
1086				var li = $('.root', t).eq(i);
1087				if( last_status[i] ){
1088					li.find('.children').show();
1089				}else{
1090					li.addClass('folded');
1091				}
1092			}
1093		}else{
1094			if( opts.fold ){
1095				$('.root', t).addClass('folded');
1096				$('.current-cat').parents('.root:eq(0)').removeClass('folded').find('.children').show();
1097				$('.current-cat.folded').removeClass('folded').find('.children').show();
1098			}else{
1099				$('.children', t).show();
1100			}
1101		}
1102	});
1103}
1104
1105bcp.columns = function(){
1106	return this.each(function(){
1107		var t = $(this);
1108			
1109		t.addClass('bcp-columns');
1110		
1111		var draw = function() {
1112			t.css('width', 'auto');
1113			var container_w = t.width();
1114			var blocks = [];
1115			var col_w = $('.item:eq(0)', t).outerWidth();
1116			var margin = parseInt( $('.item:eq(0)', t).css('margin-left') );
1117			var margin_bottom = parseInt( $('.item:eq(0)', t).css('margin-bottom') );
1118			var cols = Math.floor((container_w+margin)/(col_w+margin));
1119			for(var i=0; i<cols; i++){
1120				blocks.push(0);
1121			}
1122			$('.item', t).each(function(i){
1123				var top = Math.min.apply(Math, blocks);
1124				var index = $.inArray(top, blocks);
1125				var left = index*(col_w+margin);
1126				$(this).addClass('ready').css({
1127					left: left - margin + 'px',
1128					top: top + 'px'
1129				});
1130				blocks[index] = top + $(this).outerHeight() + margin_bottom;
1131			});
1132			t.width(cols*(col_w+margin)-margin);
1133			t.height(Math.max.apply(Math, blocks)-margin_bottom);
1134		}
1135		
1136		t.draw = draw;
1137		$(window).resize(draw);
1138		draw();
1139	});
1140}
1141
1142bcp.image_link_popup = function(){
1143	return this.each(function(){
1144		var t = $(this);
1145		$('a > img', t).each(function(i){
1146			var a = $(this).parent('a');
1147			var patt = /.+\.(jpg|jpeg|gif|png)/i;
1148			if( patt.test(a.attr('href')) )
1149				a.attr('target', '_blank');
1150		});
1151	});
1152}
1153
1154bcp.toggle_next = function(){
1155	return this.each(function(){
1156		var t = $(this);
1157		var target = t.attr('rel') ? $('#'+t.attr('rel')) : t.next();
1158		if( target.length==0 ) return;
1159		target.addClass('hidden');
1160		t.click(function(e){
1161			e.preventDefault();
1162			target.toggleClass('hidden');
1163			t.toggleClass('selected');
1164		});
1165	});
1166}
1167
1168bcp.placeholder = function(){
1169	if('placeholder' in document.createElement('input'))
1170		return;
1171	
1172	this.each(function(i){
1173		var t = $(this);
1174		var str = t.attr('placeholder');
1175		t.val(str);
1176		
1177		t.focus(function(){
1178			if(t.val() == str)
1179				t.val('');
1180		});
1181		
1182		t.blur(function(){
1183			if(t.val() == '' || t.val() == str)
1184				t.val(str);
1185		});
1186	});
1187}
1188
1189bcp.textarea_autoheight = function(_opts) {
1190	
1191	var resize_handler = function(e) {
1192		var t = e.target || e;
1193		var opts = t.textarea_autoheight_setting;
1194		var w = t.offsetWidth;
1195		var overflow = 'hidden';
1196		
1197		if ( t.value != t.prev_value || w != t.prev_width ) {
1198			$(t).height(opts.min);
1199			
1200			var scroll_h = t.scrollHeight + opts.lineheight;
1201			var h = Math.max(opts.min, scroll_h);
1202			if( opts.max > opts.min ){
1203				h = Math.min(h, opts.max);
1204				if( scroll_h > h )
1205					overflow = 'auto';
1206			}
1207			
1208			$(t).css({overflow: overflow, height: h+'px'});
1209			
1210			t.prev_value = t.value;
1211			t.prev_width = w;
1212		}
1213	};
1214
1215	return this.each(function() {
1216		var t = $(this);
1217		
1218		if ( !t.is('textarea') || t.hasClass('ready') ) 
1219			return;
1220
1221		t.addClass('ready').css({
1222			resize: 'none',
1223			overflow: 'hidden',
1224			overflowY: 'hidden',
1225			wordWrap: 'break-word',
1226			boxSizing: 'border-box'
1227		});
1228		
1229		var defaults = {
1230			min: t.outerHeight(),
1231			max: 0
1232		};
1233		
1234		var opts = $.extend(defaults, _opts);
1235		
1236		for(var prop in opts)
1237			if( t.data(prop)!=undefined )
1238				opts[prop] = t.data(prop);
1239		
1240		var lineheight = parseFloat(t.css('line-height')) || 1;
1241		var fontsize = parseInt(t.css('font-size'));
1242		if( lineheight < fontsize )
1243			lineheight = lineheight*fontsize;
1244		
1245		this.textarea_autoheight_setting = {
1246			min: opts.min,
1247			max: opts.max,
1248			lineheight: lineheight
1249		}
1250		
1251		var value = t.val();
1252		
1253		t.bind('keyup change focus blur', resize_handler).val('');
1254		
1255		resize_handler(this);
1256		
1257		if( value ){
1258			t.val(value);
1259			resize_handler(this);
1260		}
1261			
1262	});
1263};
1264
1265/*
1266 * 우편번호찾기. jquery ui dialog 의존적입니다.
1267 * 
1268 * @param string 우편번호 필드 아이디
1269 * @param string 첫번째 주소 필드 아이디
1270 * @param string 두번째 주소 필드 아이디
1271 */
1272 
1273bcp.postcode_finder = function(postcode_id, address1_id, address2_id, _width, _height){
1274	if( !$.fn.dialog )
1275		return;
1276		
1277	var postcode = $('#'+postcode_id);
1278	var address1 = $('#'+address1_id);
1279	var address2 = $('#'+address2_id);
1280	var dialog, list, list_container, s_field, s_submit;
1281	
1282	var html = '';
1283	html+= '<div id="bcp-postcode-finder" title="우편번호찾기">';
1284	html+= '	<p class="desc">"동(읍/면/리)" 이름을 입력하세요.</p>';
1285	html+= '	<p class="fields"><input type="text" class="s input" value=""> <input type="button" class="s-submit button" value="검색"></p>';
1286	html+= '	<div class="s-result"><h4>
1286검색 결과</h4><ul></ul>	</div>';
1287	html+= '</div>';
1288	
1289	var open_dialog = function(){
1290		if( (this.id==address1_id || this.id==address2_id) && $.trim(postcode.val())!='' )
1291			return;
1292		this.blur();
1293		if( !dialog ){
1294			dialog = $(html).dialog({
1295				width: _width || Math.min($(window).width(), 400),
1296				height: _height || 400,
1297				autoOpen: false
1298			});
1299			list_container = $('.s-result', dialog).hide();
1300			list = $('.s-result ul', dialog);
1301			s_field = $('input.s', dialog).keyup(function(e){
1302				if( e.keyCode==13 ) 
1303					do_search();
1304			});
1305			s_submit = $('input.s-submit', dialog).click(do_search);
1306		}
1307		dialog.dialog('open');
1308		s_field.focus();
1309	}
1310	
1311	var do_search = function(){
1312		var s = $.trim(s_field.val());
1313		if( s=='' ){
1314			s_field.focus();
1315			return;
1316		}
1317		var data = {
1318			action: 'search_postcode',
1319			s: s
1320		}
1321		list.html('검색중…');
1322		list_container.show();
1323		
1324		$.post(bcp_vars.ajaxurl, data, function(rs){
1325			if( typeof rs != 'object' || rs.length==0 ){
1326				list.html("검색된 결과가 없습니다.");
1327			}else{
1328				var html = '';
1329				for(i in rs){
1330					var d = rs[i];
1331					var addr1 = d.sido + ' ' + d.gugun + ' ' + d.dong;
1332					var addr2 = d.ri + ' ' + d.bunji;
1333					var addr3 = (d.ri !='')? ' ' + d.ri.replace(/\(.*?\)/, ""):'';
1334					html += '<li><a href="#" data-postcode="' + d.postcode + '|' + addr1 + addr3 + '">[' + d.postcode + '] ' + addr1 + ' ' + addr2 + '</a></li>';
1335
1336				}
1337				list.html(html);
1338				list.find('a').click( send_result );
1339			}
1340			
1341		}, 'json');
1342	}
1343	
1344	var send_result = function(e){
1345		dialog.dialog('close');
1346		var data = $(this).data('postcode').split('|');
1347		postcode.val( data[0] );
1348		address1.val( data[1] );
1349		address2.focus();
1350		return false;
1351	}
1352	
1353	postcode.attr('readonly', 'readonly');
1354	postcode.focus( open_dialog );
1355	address1.focus( open_dialog );
1356	address2.focus( open_dialog );
1357}
1358
1359// 주소찾기 new
1360bcp.postcode_finder2 = function(){
1361	var t = $(this);
1362	var postcode = $('.postcode', t);
1363	var address1 = $('.address1', t);
1364	var address2 = $('.address2', t);
1365	var address3 = $('.address3', t);
1366	var finder = $('.finder', t);
1367	var btn = $('.search-btn', t);
1368	
1369	btn.click(function(e){
1370		e.preventDefault();
1371		
1372		$(this).toggleClass('active').blur();
1373		
1374		if( $(this).hasClass('active') ){
1375			finder.height(Math.min($(window).height()-100, 600)).show();
1376			new daum.Postcode({
1377				oncomplete: function(data) {
1378					var fullAddr = data.address;
1379					var extraAddr = '';
1380					if(data.addressType === 'R'){
1381						if(data.bname !== '')
1382							extraAddr += data.bname;
1383						if(data.buildingName !== '')
1384							extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
1385						fullAddr += (extraAddr !== '' ? ' ('+ extraAddr +')' : '');
1386					}
1387					finder.hide();
1388					postcode.val( data.zonecode );
1389					address1.val( fullAddr );
1390					address2.focus();
1391					update_input();
1392					t.trigger('bcp_postcode_finder', data);
1393				},
1394				width : '100%',
1395				height : '100%'
1396			}).embed(finder[0]);
1397		}else{
1398			finder.hide();
1399		}
1400	});
1401	
1402	var update_input = function(){
1403		var val = '';
1404		if( postcode.val() && address1.val() && address2.val() )
1405			val = postcode.val() + '|' + address1.val() + '|' + address2.val();
1406		address3.val(val);
1407	}
1408	
1409	$('input[type=text]:not(.address3)', t).keyup(update_input);
1410}
1411
1412bcp.login_popup = function(_opts){
1413	if( !$.fn.dialog )
1414		return;
1415		
1416	var opts = $.extend({title: '로그인', modal:false}, _opts);
1417	var form, loading;
1418	
1419	if( $('#loginform').length ){
1420		form = $('#loginform').dialog('open');
1421		form[0].reset();
1422		$('.loading', form).hide();
1423		$('.error-box, error', form).remove();
1424	
1425	}else{
1426		var data = {
1427			action: 'login_form',
1428			args: {redirect: location.href}
1429		}
1430		$.post(bcp_vars.ajaxurl, data, function(rs){
1431			form = $(rs).attr('title', opts.title).dialog({width:250, modal:opts.modal});
1432			
1433			$('#user_login, #user_pass', form).addClass('required');
1434			
1435			loading = $('<i class="loading"/>').appendTo(form);
1436			
1437			form.bcp().validate_form().submit(function(){
1438				$('.error-box', form).remove();
1439				if( this.form_valid==true ){
1440					loading.show();
1441					var data = 'action=signon&' + $(this).serialize();
1442					$.post(bcp_vars.ajaxurl, data, function(rs){
1443						if( rs== 1 ){
1444							form.dialog('close');
1445							form.trigger('login-success');
1446						}else{
1447							form.prepend('<div class="error-box">'+rs+'</div>');
1448							form.trigger('login-fail');
1449							loading.hide();
1450						}
1451					});
1452				}
1453				return false;
1454			});
1455		});
1456	}
1457}
1458
1459bcp.loading_overlay = function(){
1460	var t = $('#bcp-loading-overlay');
1461	if( t.length==0 )
1462		t = $('<div id="bcp-loading-overlay"><div class="bg"/><div class="loader"/></div>').appendTo('body');
1463	return t;
1464}
1465
1466bcp.remove_loading_overlay = function(){
1467	$('#bcp-loading-overlay').remove();
1468}
1469
1470bcp.user_dialog = function(){
1471	this.each(function(){
1472		var t = $(this);
1473		
1474		var user_id = t.data('user_id');
1475		var dialog;
1476		if( $('#user-dialog').length ){
1477			dialog = $('#user-dialog');
1478		}else{
1479			dialog = $('<div id="user-dialog" title="사용자 정보"/>').dialog({
1480				autoOpen: false,
1481				width: 400,
1482				height: 400
1483			});
1484		}
1485		
1486		t.attr('rel', 'user-dialog').bcp().jquery_ui_dialog_opener();
1487		t.click(function(e){
1488			e.preventDefault();
1489			load_data();
1490		});
1491		
1492		var load_data = function(){
1493			dialog.text('가져오는중...');
1494			var data = {
1495				action: 'userinfo_table',
1496				user_id: user_id
1497			}
1498			
1499			$.post(bcp_vars.ajaxurl, data, function(rs){
1500				dialog.html(rs);
1501			}, 'html');
1502		}
1503	});
1504}
1505
1506bcp.post_finder = function(_opts){
1507	return this.each(function(){
1508	
1509	var t = $(this);
1510	var defaults = {
1511		query_args: {
1512			post_type: 'any',
1513			posts_per_page: 50
1514		},
1515		selected_post_type: '',
1516		button_label: '포스트 연결하기',
1517		post_types: ''
1518	}
1519	var opts = $.extend(defaults, _opts);
1520	var win, s_select, s_field, s_submit, list, list_container, results;
1521	
1522	t.append('<p><a href="#" class="button add-post">'+opts.button_label+'</a></p>');
1523	
1524	var select = '';
1525	if( typeof opts.post_types == 'object' ){
1526		if( opts.query_args.post_type == 'any' ){
1527			select += '<option value="any">모든 포스트</option>';
1528		}
1529		for( type in opts.post_types ){
1530			var selected = type==opts.selected_post_type ? 'selected="selected"' : '';
1531			select += '<option value="'+type+'">'+opts.post_types[type]+'</option>';
1532		}
1533		select = '<select>'+select+'</select>';
1534	}
1535	
1536	var html = '';
1537	html+= '<div id="post-finder-dialog">';
1538	html+= '	<p class="fields">';
1539	html+= 			select;
1540	html+= '		<input type="text" class="s" value=""> ';
1541	html+= '		<input type="button" class="s-submit button" value="검색">';
1542	html+= '	</p>';
1543	html+= '	<div class="s-result"><h4>검색 결과</h4><ul></ul>	</div>';
1544	html+= '</div>';
1545	
1546	var open_dialog = function(){
1547		if( !win ){
1548			win = $(html).appendTo('body').dialog({
1549				title: '포스트 찾기',
1550				autoOpen: false,
1551				width: 400,
1552				height: 320
1553			});
1554			
1555			list_container = $('.s-result', win);
1556			list = $('.s-result ul', win);
1557			s_select = $('select', win);
1558			s_field = $('input.s', win);
1559			s_submit = $('input.s-submit', win);
1560			
1561			s_submit.click(do_search);
1562			s_field.keyup(function(e){
1563				if( e.keyCode==13 ) do_search();
1564			});
1565		}
1566		list_container.hide();
1567		list.empty();
1568		
1569		win.dialog('open');
1570		s_field.val('').focus();
1571	}
1572	
1573	var do_search = function(){
1574		var s = $.trim(s_field.val());
1575		if( s=='' ){
1576			s_field.focus();
1577			return;
1578		}
1579		opts.query_args.s = s;
1580		opts.query_args.post_type = s_select.val();
1581		
1582		var data = {
1583			action: 'search_posts',
1584			query_args: opts.query_args
1585		}
1586		$.post(bcp_vars.ajaxurl, data, function(r){
1587			if( !r || r.length==0 ){
1588				results = null;
1589				list.html("검색된 결과가 없습니다.");
1590			}else{
1591				results = r;
1592				var html = '';
1593				for(i in r){
1594					var d = r[i];
1595					if( d.post_status!='trash' )
1596						html += '<li><a href="#" rel="' + i + '" class="add">' + d.post_title + '</a> [<a href="'+bcp_vars.home_url+'?p='+d.ID+'" target="_blank">보기</a>]</li>';
1597				}
1598				list.html(html);
1599				list.find('a.add').click( reflect_result );
1600			}
1601		}, 'json');
1602		
1603		list.html('검색중...');
1604		list_container.show();
1605	}
1606	
1607	var reflect_result = function(e){
1608		t.trigger('post_selected', [results[this.rel]]);
1609		win.dialog('close');
1610		return false;
1611	}
1612	
1613	$('a.add-post', t).click(function(e){
1614		e.preventDefault();
1615		open_dialog();
1616	});
1617	
1618	});
1619}
1620
1621bcp.ajax_uploader = function(opts){
1622	if( this.length==0 )
1623		return;
1624	
1625	var t = this;
1626	
1627	var button = t.find('.button');
1628	
1629	var form = '<form id="' + opts.id + '-form" class="bcp-ajax-upload-form" target="' + opts.id + '-target" action="' + opts.action_url + '" method="post" enctype="multipart/form-data">';
1630	$.each(opts, function(k, v){
1631    	form += '<input type="text" name="' + k + '" value="' + v + '">';
1632	});
1633	form += '</form>';
1634	form = $(form);
1635	
1636	var form_target = '<iframe id="' + opts.id + '-target" name="' + opts.id + '-target" class="bcp-ajax-upload-form-target" frameborder="0" src="about:blank"></iframe>';
1637	form_target = $(form_target);
1638	
1639	$(function(){
1640		form.appendTo('body');
1641		form_target.appendTo('body');
1642	});
1643	
1644	var return_field = $('#' + opts.return_field);
1645	
1646	var max_size = Number(opts.max_size);
1647	
1648	var reset_uploader = function(){
1649		window.bcp_ajax_uploading = false;
1650		button.removeClass('uploading').find('input[type=file]').remove();
1651		form.find('input[type=file]').remove();
1652		
1653		$('<input type="file" name="file">').change(function(){
1654			window.bcp_ajax_uploading = true;
1655			button.addClass('uploading');
1656			form.append(this).submit();
1657		}).appendTo(button);
1658	}
1659	
1660	this.upload_complete = function(new_val, error, max_size, total_size, hashdata){
1661		if( error ){
1662			alert(error);
1663		
1664		}else{
1665			
1666			max_size = Number(max_size);
1667			total_size = Number(total_size);
1668			$('[name=max_size]', form).val(max_size);
1669			$('[name=total_size]', form).val(total_size);
1670			$('[name=hashdata]', form).val(hashdata);
1671			$('.max_size', t).text(Math.round(max_size*10)/10);
1672			
1673			if( return_field.length ){
1674				var val = return_field.val();
1675				
1676				switch( opts.return_method ){
1677					case 'prepend':
1678						return_field.val( new_val + (val ? "\n" + val : '') );
1679						break;
1680					
1681					case 'append':
1682						return_field.val( (val ? val + "\n" : '') + new_val );
1683						break;
1684					
1685					case 'insert':
1686						bcp.insert_to_textarea(new_val, opts.return_field);
1687						break;
1688					
1689					case 'replace':
1690					default:
1691						return_field.val( new_val );
1692						break;
1693				}
1694			}
1695			
1696			$(document).trigger('bcp_ajaxupload_complete', [new_val, opts]);
1697		}
1698		
1699		if( max_size > 0 ){
1700			reset_uploader();
1701		}else{
1702			t.hide();
1703		}
1704	}
1705	
1706	reset_uploader();
1707	
1708	return t;
1709}
1710
1711/* ######################################################################
1712
1713BCP EXTENSIONS
1714
1715###################################################################### */
1716
1717/**
1718 * widget-recent-posts 익스텐션
1719 */
1720bcp.recent_posts_widget = function(){	
1721	return this.each(function(){
1722		var t = $(this);
1723		var widget_id = t.data('widget_id');
1724		var cookie_name = 'bcp-recent-posts-' + widget_id + '-paged';
1725		var cookie_path = t.data('cookie_path');
1726		var list = $('ul', t);
1727		var nav = $('nav', t);
1728		var current_postid = '';
1729		
1730		var get_list = function( paged ) {
1731			var data = { 
1732				action: 'recent-posts', 
1733				widget_id: widget_id,
1734				paged: paged,
1735				current_postid: current_postid
1736			}
1737			
1738			$.post(bcp_vars.ajaxurl, data, function(html){
1739				t.html(html);
1740			});
1741			
1742			bcp.set_cookie(cookie_name, paged, {path:cookie_path});
1743		}
1744		
1745		nav.find('a').live('click', function(){
1746			var paged = Number(this.hash.replace('#', ''));
1747			$(this).addClass('loading');
1748			get_list(paged);
1749			return false;
1750		});
1751		
1752		if( $('body').hasClass('singular') ){
1753			var match = /singular-(\d+)/.exec( $('body').attr('class') );
1754			current_postid = match ? match[1] : '';
1755			
1756			// 현재 컨텍스트가 singular이고, 위젯 네비게이션 페이지가 1이 아닌 경우
1757			// 목록 내에 singular 페이지가 없으면 1페이지로 이동.
1758			if( current_postid ){
1759				if( !$('.page-numbers:eq(0)', nav).hasClass('current') ){
1760					var singular_in_list = false;
1761					$('li', list).each(function(){
1762						if( $(this).data('post_id')==current_postid ){
1763							singular_in_list = true;
1764							return;
1765						}
1766					});
1767					if( !singular_in_list ){
1768						bcp.remove_cookie(cookie_name, {path:cookie_path});
1769						get_list(1);
1770					}
1771				}
1772			}
1773		}else{
1774			bcp.remove_cookie(cookie_name, {path:cookie_path});
1775		}
1776	});
1777}
1778
1779/**
1780 * sns widget 익스텐션
1781 */
1782bcp.sns_widget = function(){	
1783	return this.each(function(){
1784		$(this).find('.use-tabs').addClass('full-size').bcp().tabs();
1785		
1786		$(this).find('.container').each(function(){
1787			var t = $(this);
1788			
1789			var widget_id = t.data('widget_id');
1790			
1791			var service = t.data('service');
1792			
1793			var data = { 
1794				action: 'sns-widget', 
1795				widget_id: widget_id,
1796				service: service
1797			}
1798			$.post(bcp_vars.ajaxurl, data, function(html){
1799				t.html(html).find('a').attr('target', '_blank');
1800				if( t.hasClass('scroll') )
1801					t.bcp().scrollpane();
1802				t.trigger('content_loaded');
1803			});
1804		});
1805	});	
1806}
1807
1808/* ######################################################################
1809
1810jquery ui
1811
1812###################################################################### */
1813bcp.jquery_ui_accordion = function(){
1814	if( !$.fn.accordion )
1815		return;
1816		
1817	return this.each(function(i){
1818		var t = $(this);
1819		var defaults = {
1820			collapsible: true,
1821			heightStyle: 'content'
1822		};
1823		var opts = $.extend(defaults, t.data('option'));
1824		t.accordion(opts);
1825	});
1826}
1827
1828bcp.jquery_ui_tabs = function(){
1829	if( !$.fn.tabs )
1830		return;
1831		
1832	return this.each(function(i){
1833		var t = $(this);
1834		var defaults = {};
1835		var opts = $.extend(defaults, t.data('option'));
1836		t.tabs(opts);
1837		
1838		var tabs_nav = $('.ui-tabs-nav li', t);
1839		var w = Math.floor( t.width()/tabs_nav.length ) - 1;
1840		tabs_nav.css({paddingLeft:0, paddingRight:0}).width(w);
1841	});
1842}
1843
1844bcp.jquery_ui_dialog = function(){
1845	if( !$.fn.dialog )
1846		return;
1847		
1848	return this.each(function(i){
1849		var t = $(this);
1850		var defaults = {
1851			autoOpen: false
1852		};
1853		var opts = $.extend(defaults, t.data('option'));
1854		t.dialog(opts);
1855	});
1856}
1857
1858bcp.jquery_ui_dialog_opener = function(){
1859	if( !$.fn.dialog )
1860		return;
1861		
1862	return this.each(function(i){
1863		var t = $(this);
1864		var dialog = $('#' + this.rel);
1865		var ui_dialog = dialog.parent('.ui-dialog');
1866		var position = t.data('position') || '';
1867		var offset_top = Number(t.data('offset_top')) || 0;
1868		var offset_left = Number(t.data('offset_left')) || 0;
1869		
1870		t.click(function(e){
1871			e.preventDefault();
1872			var offset = t.offset();
1873			var pos = [offset.left - $('body').scrollLeft(), offset.top - $('body').scrollTop()];
1874			switch( position ){
1875				case 'right':
1876					pos[0] = pos[0] + t.width() + 10 + offset_left;
1877					pos[1] = pos[1] - 13 + offset_top;
1878					break;
1879				
1880				case 'left':
1881					pos[0] = pos[0] - ui_dialog.width() - 10 + offset_left;
1882					pos[1] = pos[1] - 13 + offset_top;
1883					break;
1884				
1885				case 'top':
1886					pos[0] = pos[0] - (ui_dialog.width()-t.width())/2 + offset_left;
1887					pos[1] = pos[1] - ui_dialog.height() - 10 + offset_top;
1888					break;
1889				
1890				case 'bottom':
1891					pos[0] = pos[0] - (ui_dialog.width()-t.width())/2 + offset_left;
1892					pos[1] = pos[1] + t.height() + 10 + offset_top;
1893					break;
1894				
1895				case '':
1896					pos = 'center center';
1897					break;
1898				
1899				default:
1900					pos = position;
1901					pos[0] += offset_left;
1902					pos[1] += offset_top;
1903					break;
1904			}
1905			dialog.dialog('option', 'position', pos).dialog('open');
1906		});
1907	});
1908}
1909
1910bcp.jquery_ui_buttonset = function(){
1911	if( !$.fn.buttonset )
1912		return;
1913		
1914	return this.each(function(i){
1915		var t = $(this);
1916		var defaults = {};
1917		var opts = $.extend(defaults, t.data('option'));
1918		t.buttonset(opts);
1919	});
1920}
1921
1922bcp.jquery_ui_datepicker_config = function(){
1923	if( !$.datepicker )
1924		return;
1925	
1926	$.datepicker.regional['ko'] = {
1927		closeText: '닫기',
1928		prevText: '이전',
1929		nextText: '다음',
1930		currentText: '오늘',
1931		monthNames: ['1월','2월','3월','4월','5월','6월','7월','8월','9월','10월','11월','12월'],
1932		monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'],
1933		dayNames: ['일','월','화','수','목','금','토'],
1934		dayNamesShort: ['일','월','화','수','목','금','토'],
1935		dayNamesMin: ['일','월','화','수','목','금','토'],
1936		weekHeader: 'Wk',
1937		dateFormat: 'yy-mm-dd',
1938		firstDay: 0,
1939		isRTL: false,
1940		showMonthAfterYear: true,
1941		changeMonth: true,
1942        changeYear: true
1943	};
1944	$.datepicker.setDefaults( $.datepicker.regional['ko'] );
1945}
1946
1947bcp.jquery_ui_datepicker = function(){
1948	if( !$.fn.datepicker )
1949		return;
1950	
1951	bcp.jquery_ui_datepicker_config();
1952	
1953	return this.each(function(i){
1954		var t = $(this);
1955		var defaults = {};
1956		var opts = $.extend(defaults, t.data('option'));
1957		if( opts.showOn=='button' ){
1958			opts.buttonImage = 'http://jqueryui.com/resources/demos/datepicker/images/calendar.gif';
1959			opts.buttonImageOnly = true;
1960		}
1961		t.datepicker(opts);
1962	});
1963}
1964
1965bcp.jquery_ui_spinner = function(){
1966	if( !$.fn.spinner )
1967		return;
1968		
1969	return this.each(function(i){
1970		var t = $(this);
1971		var defaults = {};
1972		var opts = $.extend(defaults, t.data('option'));
1973		t.spinner(opts);
1974	});
1975}
1976
1977
1978/* ######################################################################
1979
1980plugins convinience
1981
1982###################################################################### */
1983
1984/**
1985 * fancybox 편의설정
1986 */
1987bcp.fancybox = function(){
1988	if( !$.fn.fancybox ) return;
1989	this.each(function(i){
1990		var t = $(this);
1991		var defaults = { 
1992			closeBtn: true, 
1993			nextEffect: 'fade', 
1994			prevEffect: 'fade', 
1995			padding: 0 
1996		};
1997		var opts = $.extend(defaults, t.data('option'));
1998		t.fancybox(opts);
1999	});
2000}
2001
2002/**
2003 * jScrollPane 편의 설정
2004 */
2005bcp.scrollpane = function(_opts){
2006	if( !$.fn.jScrollPane ) return;
2007	var defaults = {
2008		autoReinitialise: true
2009	};
2010	var opts = $.extend(defaults, _opts);
2011	return this.each(function(i){
2012		$(this).addClass('bcp-scrollpane');
2013		var display =  $(this).css('display');
2014		if( display=='none' )
2015			$(this).show();
2016			
2017		$(this).hover(
2018			function(){ $(this).addClass('hover'); },
2019			function(){ $(this).removeClass('hover'); }
2020		).jScrollPane(opts);
2021		
2022		if( display=='none' )
2023			$(this).hide();
2024	});
2025}
2026
2027
2028/* ######################################################################
2029
2030FUNCTIONS
2031
2032###################################################################### */
2033
2034/**
2035 * 새창 띄우기
2036 */
2037bcp.open_window = function(url, _opts) {
2038	var opts = $.extend({
2039		winnm: 'win',
2040		position: 'center', 
2041		width: 300, 
2042		height: 300, 
2043		scroll: 'no',
2044		resize: 'no'
2045	}, _opts);
2046	
2047	var a ='';
2048	a += 'height='+opts.height+',';
2049	a += 'width='+opts.width+',';
2050	if(opts.position == 'center'){
2051		a += 'left='+(screen.width-opts.width)/2+',';
2052		a += 'top='+(screen.height-opts.height)/2+',';
2053	}else{
2054		a += 'left=0,';
2055		a += 'top=0,';
2056	}
2057	a += 'scrollbars='+opts.scroll+',';
2058	a += 'resizable='+opts.resize+',';
2059	a += 'toolbar=no,location=no,directories=no,status=no,menubar=no';	
2060	return window.open(url, opts.winnm.replace(/\s/, ''), a);
2061}
2062
2063/**
2064 * 툴팁 같은 prong이 있는 오버레이(말풍선)의 위치 계산하여 리턴
2065 */
2066bcp.get_balloon_position = function(target, balloon, prong, opts){
2067	target = $(target);
2068	if( target.length == 0 )
2069		return;
2070	opts = $.extend({margin:10, direction:'auto'}, opts);
2071	var margin = opts.margin;
2072	var direction = opts.direction;
2073	var offset = target.offset();
2074	var target_w = target.outerWidth();
2075	var prong_h = prong.height();
2076	var balloon_w = balloon.outerWidth();
2077	var balloon_h = balloon.outerHeight() + prong_h;
2078	var window_w = $(window).width();
2079	var left = offset.left + Math.round((target_w-balloon_w)/2);
2080	var pos = {
2081		top: 0, 
2082		left: left, 
2083		right: 'auto', 
2084		prong_left: balloon_w/2
2085	};
2086	balloon.removeClass('top').removeClass('bottom');
2087	if( direction=='bottom' || (direction=='auto' && balloon_h + margin > offset.top) ){
2088		pos.top = offset.top + target.outerHeight() + prong_h;
2089		balloon.addClass('bottom');
2090	}else{
2091		pos.top = offset.top - balloon_h;
2092		balloon.addClass('top');
2093	}
2094	
2095	if( left < margin ){
2096		pos.left = margin;
2097		pos.prong_left += left - margin;
2098	}
2098else if( left + balloon_w > window_w - margin ){
2099		pos.left = 'auto';
2100		pos.right = margin;
2101		pos.prong_left += left + balloon_w - window_w + margin;
2102	}
2103	return pos;
2104}
2105
2106/**
2107 * PHP number_format과 동일
2108 */
2109bcp.number_format = function(number, decimals, dec_point, thousands_sep){
2110	number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
2111	var n = !isFinite(+number) ? 0 : +number,
2112    prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
2113    sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
2114    dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
2115    s = '',
2116    toFixedFix = function (n, prec) {
2117        var k = Math.pow(10, prec);
2118        return '' + Math.round(n * k) / k;
2119    };
2120	// Fix for IE parseFloat(0.55).toFixed(0) = 0;
2121	s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
2122	if (s[0].length > 3) {
2123	    s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
2124	}
2125	if ((s[1] || '').length < prec) {
2126	    s[1] = s[1] || '';
2127	    s[1] += new Array(prec - s[1].length + 1).join('0');
2128	}
2129	return s.join(dec);
2130}
2131
2132/**
2133 * textarea에 내용 넣기
2134 */
2135bcp.insert_to_textarea = function(content, textarea_id) {
2136	var sel, startPos, endPos, scrollTop, text, textarea = document.getElementById(textarea_id);
2137
2138	if ( !textarea )
2139		return false;
2140
2141	if ( document.selection ) { //IE
2142		textarea.focus();
2143		sel = document.selection.createRange();
2144		sel.text = content;
2145		textarea.focus();
2146	} else if ( textarea.selectionStart || textarea.selectionStart == '0' ) { // FF, WebKit, Opera
2147		text = textarea.value;
2148		startPos = textarea.selectionStart;
2149		endPos = textarea.selectionEnd;
2150		scrollTop = textarea.scrollTop;
2151
2152		textarea.value = text.substring(0, startPos) + content + text.substring(endPos, text.length);
2153
2154		textarea.focus();
2155		textarea.selectionStart = startPos + content.length;
2156		textarea.selectionEnd = startPos + content.length;
2157		textarea.scrollTop = scrollTop;
2158	} else {
2159		textarea.value += content;
2160		textarea.focus();
2161	}
2162	return true;
2163};
2164
2165bcp.set_cookie = function(name, value, options) {
2166	options = options || {};
2167	if (value === null) {
2168		value = '';
2169		options.expires = -1;
2170	}
2171	var expires = '';
2172	if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
2173		var date;
2174		if (typeof options.expires == 'number') {
2175			date = new Date();
2176			date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
2177		} else {
2178			date = options.expires;
2179		}
2180		// use expires attribute, max-age is not supported by IE
2181		expires = '; expires=' + date.toUTCString(); 
2182	}
2183	var path = options.path ? '; path=' + options.path : '';
2184	var domain = options.domain ? '; domain=' + options.domain : '';
2185	var secure = options.secure ? '; secure' : '';
2186	document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
2187}
2188
2189bcp.get_cookie = function(name) {
2190	var cookieValue = null;
2191	if (document.cookie && document.cookie != '') {
2192		var cookies = document.cookie.split(';');
2193		for (var i = 0; i < cookies.length; i++) {
2194			var cookie = jQuery.trim(cookies[i]);
2195			// Does this cookie string begin with the name we want?
2196			if (cookie.substring(0, name.length + 1) == (name + '=')) {
2197				cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
2198				break;
2199			}
2200		}
2201	}
2202	return cookieValue;
2203}
2204
2205bcp.remove_cookie = function(name, options){
2206	bcp.set_cookie(name, null, options);
2207}
2208
2209
2210/* ######################################################################
2211
2212javascript prototype
2213
2214###################################################################### */
2215/**
2216 * PHP nl2br과 동일
2217 */
2218String.prototype.nl2br = function(){
2219	return this.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br>$2');
2220}
2221
2222/**
2223 * 쿼리스트링을 오브젝트로 변환
2224 */
2225String.prototype.querystring_to_object = function(){
2226	var str = this;
2227	if( str.indexOf('?')!=-1 ){
2228		str = str.split('?').slice(1)[0];
2229	}
2230	var rows = str.split('&');
2231	var ret = {};
2232	for(var i=0; i<rows.length; i++){
2233		var pair = rows[i].split('=');
2234		ret[decodeURI(pair[0])] = decodeURIComponent(pair[1]);
2235	}
2236	return ret;
2237}
2238
2239/**
2240 * 쿼리스트링에서 키의 값 가져오기
2241 */
2242String.prototype.get_value_from_querystring = function(key){
2243	var str = this;
2244	if( str.indexOf('?')!=-1 ){
2245		str = str.split('?').slice(1)[0];
2246	}
2247	var vars = str.split("&");
2248	for (var i = 0; i < vars.length; i++) {
2249		var pair = vars[i].split("=");
2250		if (pair[0] == key) {
2251			return decodeURIComponent(pair[1]);
2252		}
2253	}
2254}
2255
2256
2257
2258/* ######################################################################
2259
2260DOM Ready
2261
2262###################################################################### */
2263
2264$(function(){
2265	
2266	bcp.is_logged_in = Number(bcp_vars.user_id)>0;
2267	bcp.is_admin = $('body').hasClass('wp-admin');
2268	bcp.is_mobile = $('body').hasClass('m');
2269	bcp.is_mobile_mode = $('body').hasClass('m-mobile');
2270	
2271	
2272	if( bcp.is_admin ){
2273		if( is_IE && browser_version<8 )
2274			alert("인터넷익스플로어 7이하에서는 제대로 동작하지 않을 수 있습니다.\n인터넷익스플로어 8이상으로 업그레이드해주세요.");
2275		
2276		bcp.jquery_ui_datepicker_config();
2277		
2278		$('.user-dialog').bcp().user_dialog();
2279		
2280		$('#view-post-btn a, .row-actions .view a').attr('target', '_blank');
2281		
2282		$(document).ajaxSuccess(function(e, xhr, settings) { 
2283			if( settings.data ){
2284				if( settings.data.search('action=save-widget') != -1 ){
2285					var d = decodeURIComponent(settings.data).querystring_to_object();
2286					$(document).trigger('widget-saved', d);
2287				}
2288			}
2289		}); 
2290		
2291	}else{
2292		// IE
2293		bcp.ie_hack();
2294		$('.entry-content, .comment-text').bcp().ie_image_resize();
2295		
2296		// wordpress
2297		$('.gallery').bcp().wp_gallery();
2298		$('.wp-caption').bcp().wp_caption_resize();
2299		$('.multipage-nav').bcp().wp_multipage_markup_enhance();
2300		$('.entry-content').bcp().image_link_popup();
2301		
2302		// bcp ui & util
2303		$('.bcp-tabs').bcp().tabs();
2304		$('.bcp-accordion').bcp().accordion();
2305		$('.bcp-tooltip').bcp().tooltip();
2306		$('.bcp-button-group').bcp().button_group();
2307		$('.bcp-slider').bcp().slider();
2308		$('.bcp-fontsizer').bcp().fontsizer();
2309		$('.bcp-treeview').bcp().treeview();
2310		$('.bcp-ajax-paginate').bcp().ajax_paginate();
2311		$('.bcp-toggle-next').bcp().toggle_next();
2312		$('.bcp-textarea-autoheight').bcp().textarea_autoheight();
2313		
2314		// bcp extension
2315		$('.bcp-recent-posts').bcp().recent_posts_widget();
2316		$('.widget_bcp-sns').bcp().sns_widget();
2317		$('.bcp-validate-form').bcp().validate_form();
2318		
2319		// plugins convinience
2320		$('.bcp-scrollpane').bcp().scrollpane();
2321		$('.bcp-fancybox').bcp().fancybox();
2322		$('.jquery-ui-accordion').bcp().jquery_ui_accordion();
2323		$('.jquery-ui-tabs').bcp().jquery_ui_tabs();
2324		$('.jquery-ui-dialog').bcp().jquery_ui_dialog();
2325		$('.jquery-ui-dialog-opener').bcp().jquery_ui_dialog_opener();
2326		$('.jquery-ui-datepicker').bcp().jquery_ui_datepicker();
2327		$('.jquery-ui-buttonset').bcp().jquery_ui_buttonset();
2328		$('.jquery-ui-spinner').bcp().jquery_ui_spinner();
2329		
2330		// misc
2331		$('.search-input').each(function(i){
2332			$(this).blur(function(){
2333				if( this.value )
2334					$(this).addClass('has-value');
2335				else
2336					$(this).removeClass('has-value');
2337				$(this).removeClass('focus')
2338			}).trigger('blur');
2339			$(this).focus(function(){
2340				$(this).addClass('focus');
2341			});
2342		});
2343		
2344		if( $('#sidebar').length )
2345			$('body').addClass('has-sidebar');
2346		
2347		$('body').addClass('js-ready');
2348	}
2349});

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.