PageSourceSearch

https://www.trbusiness.com/wp-content/themes/trbusiness/js/jquery.main.js?ver=1356836038

js trbusiness.com collected 2026-09-24 19:33:06 UTC 105,343 bytes, 5,282 lines download raw bytes

1// page init
2
3jQuery(function(){
4
5	initTabs();
6
7	if( (location.pathname != "/magazine-subscription") && (location.pathname != "/renew-subscriptions") )
8	{
9		jcf.customForms.replaceAll();
10	}
11
12	initCarousel();
13
14	initAccordion();
15
16	initSameHeight();
17
18	initFitVids();
19
20       //initDateRange();
21
22        advance_search();
23
24		addAnchorImage();
25
26        fancy_box();
27
28	jQuery('input, textarea').placeholder();
29
30	device();
31
32		jQuery('#homead5').mouseover(function()
33		{
34		jQuery(this).css('overflow','inherit')
35		}
36		);
37
38});
39jQuery(window).scroll(function(){
40
41if (jQuery(window).scrollTop() + jQuery(window).height() > jQuery('#footer').position().top-100){ 
42jQuery("#main.hmoe,#main.ros").css("background-attachment","inherit");
43jQuery("#main.hmoe,#main.ros").css("background-position-y","-691px").css("scroll-behavior","smooth");
44jQuery("#main.hmoe,#main.ros").css("background-position","bottom");
45} 
46else{
47jQuery("#main.hmoe,#main.ros").css("background-attachment","fixed");
48jQuery("#main.hmoe,#main.ros").css("background-position","top");
49jQuery("#main.hmoe,#main.ros").css("background-position-y","65px").css("scroll-behavior","smooth");
50}
51
52});
53function openFile(file) {
54
55	
56
57	if(typeof file ==='undefined' || file == null)
58
59	{
60
61		return false;
62
63	}
64
65    var extension = file.substr( (file.lastIndexOf('.') +1) );
66
67    switch(extension.toLowerCase()) {
68
69        case 'jpg':
70
71        case 'png':
72
73        case 'gif':
74
75            return true;  // There's was a typo in the example where
76
77        break;
78
79        default:
80
81           return false;
82
83    }
84
85};
86
87function device(){
88
89    var isMobile = false; //initiate as false
90
91// device detection
92
93if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) 
94
95    || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.
95substr(0,4))) isMobile = true;
96
97    
98
99if(isMobile == false) {
100
101    isMobiles();    
102
103    
104
105}   
106
107    
108
109}
110
111var sticky;
112window.onload = (event) => {
113	sticky = header.offsetTop;
114}
115window.onscroll = function() {stickyTakeOver()};
116
117var header = document.getElementById("navblock");
118
119
120function stickyTakeOver() {
121  if (window.pageYOffset > sticky) {
122    header.classList.add("sticky");
123  } else {
124    header.classList.remove("sticky");
125  }
126}
127
128function isMobiles(){
129
130    // Create a clone of the menu, right next to original.
131
132jQuery('.navigation-block').addClass('original').clone().insertAfter('.navigation-block').addClass('cloned').css('position','fixed').css('top','0').css('margin-top','0').css('z-index','1000000').removeClass('original').hide();
133
134//stickIt=stickIt();
135
136scrollIntervalID = setInterval(stickIt, 10);  
137
138
139
140
141
142function stickIt() {
143
144
145
146  var orgElementPos = jQuery('.original').offset();
147
148  orgElementTop = orgElementPos.top;               
149
150
151
152  if (jQuery(window).scrollTop() >= (orgElementTop)) {
153
154    // scrolled past the original position; now only show the cloned, sticky element.
155
156
157
158    // Cloned element should always have same left position and width as original element.     
159
160    orgElement = jQuery('.original');
161
162    coordsOrgElement = orgElement.offset();
163
164    leftOrgElement = coordsOrgElement.left;  
165
166    widthOrgElement = orgElement.css('width');
167
168    jQuery('.cloned').css('left',leftOrgElement+'px').css('top',0).css('width',widthOrgElement).show();
169
170    jQuery('.original').css('visibility','hidden');
171
172    jQuery('.original').css('overflow','hidden');
173
174  } 
175    /* sticky view  */
176  else if(jQuery(window).scrollTop() == 0){ 
177	  //confirm("yes"); 
178	  jQuery("#main.hmoe, .hmoe .left_grip,#main.ros, .ros .left_grip").css("background-position-y",jQuery('#header').height()).css("scroll-behavior","smooth");
179
180	 // jQuery("#main.hmoe, .hmoe .left_grip").css("background-position-y","225px";
181	  
182      //  jQuery("#main.hmoe, .hmoe .left_grip").css("background-position-y",jQuery('#header').height());
183     //jQuery("#main.hmoe, .hmoe .left_grip").css("background-position-y",);
184
185  } 
186  /*Normal view*/  
187  else {
188	  jQuery("#main.hmoe, .hmoe .left_grip, #main.ros, .ros .left_grip").css("background-position-y","65px").css("scroll-behavior","smooth");	
189    // not scrolled past the menu; only show the original menu.
190
191    jQuery('.cloned').hide();
192
193    jQuery('.original').css('overflow','visible');
194
195    jQuery('.original').css('visibility','visible');
196
197  }
198
199}
200
201}
202
203function fancy_box(){
204
205    jQuery("a.fancy_pop_up").fancybox();
206
207}
208
209function addAnchorImage() {
210    var imgTags = document.getElementsByTagName("img");
211    var imgArray = Array.from(imgTags);
212
213    for (var i = 0; i < imgArray.length; i++) {
214        var classNameImg = imgArray[i].getAttribute("class");
215
216        if (classNameImg != null && classNameImg != undefined) {
217            var trimName = classNameImg.trim();
218            var finalClass = trimName.substr(0, 3);
219
220            if (finalClass === "wp-" || finalClass === "ali") {
221                var imgSrc = imgArray[i].getAttribute("src");
222
223                // Use closest('a') to find the nearest ancestor anchor tag
224                var anchorTag = jQuery(imgArray[i]).closest('a');
225                var newLink = anchorTag.attr('href');
226
227                if (typeof newLink === 'undefined' || openFile(newLink)) {
228                    jQuery(imgArray[i]).wrap('<a href="' + imgSrc + '" class="fancy_pop_up" rel="group"></a>');
229                }
230            }
231        }
232    }
233}
234
235function addAnchorImage_old1(){
236	var imgTag = document.getElementsByTagName("img");
237	var listofarr = Array.from(imgTag);
238	
239	for(i=0; i < listofarr.length; i++){
240		var classNameImg = listofarr[i].getAttribute("class");
241		
242		if(classNameImg != null && classNameImg != undefined){
243		var trimName = classNameImg.trim()
244		var finalclass = trimName.substr(0,3);
245		if(finalclass == "wp-" || finalclass == "ali"){
246			var classNameImg = listofarr[i].getAttribute("class");
247			var trimClassName = classNameImg.trim()
248			var splitedClass = trimClassName.split(' ');
249    jQuery("." + splitedClass).each(function(i){
250
251var that = jQuery(this),img_src=that.attr("src");
252
253/*var newlink=that.parent('a').children('img').attr('src');*/
254
255var newlink=that.parent('a').attr('href');
256
257/*if(img_src != newlink){*/
258
259if((typeof newlink == 'undefined') || openFile(newlink)){
260
261that.wrap('<a href="'+img_src+'" class="fancy_pop_up" rel="group"></a>');
262
263}
264
265});
266	}
267	}
268	}
269}
270
271function addAnchorImage_old(){
272
273    jQuery(".page-content img").each(function(i){
274
275var that = jQuery(this),img_src=that.attr("src");
276
277/*var newlink=that.parent('a').children('img').attr('src');*/
278
279var newlink=that.parent('a').attr('href');
280
281/*if(img_src != newlink){*/
282
283if((typeof newlink == 'undefined') || openFile(newlink)){
284
285that.wrap('<a href="'+img_src+'" class="fancy_pop_up" rel="group"></a>');
286
287}
288
289});
290
291}
292
293jQuery(window).on('load', function(){
294
295	initRightSide();
296
297});
298
299
300
301function initDateRange(){
302
303    var d = new Date();
304
305
306
307    var month = d.getMonth()+1;
308
309    var day = d.getDate();
310
311
312
313    var output = d.getFullYear() + '-' + ((''+month).length<2 ? '0' : '') + month + '-' +  ((''+day).length<2 ? '0' : '') + day;
314
315    jQuery('.input-daterange').datepicker({
316
317                    todayBtn: "linked",
318
319                    format: 'yyyy-mm-dd',
320
321                    endDate: output,
322
323                    autoclose:true
324
325                });
326
327}
328
329
330
331function advance_search(){
332
333    var clicked=jQuery(".advanced-search").attr('data-active');
334
335
336
337jQuery(".advanced-search").on('click', function(e){
338
339    if(clicked == 1)
340
341    {
342
343        clicked=0;
344
345        e.preventDefault();
346
347      jQuery("#normal-search").hide();
348
349      jQuery(".advance_search_form").slideDown(1000).show();
350
351    }
352
353    else
354
355    {
356
357        clicked=true;
358
359        e.preventDefault();
360
361        var v1,v2;
362
363        v1=jQuery("#datepicker input[name=start]").val();
364
365        v2=jQuery("#datepicker input[name=end]").val();
366
367      jQuery(".advance_search_form").slideUp(1000);
368
369      if(v1 !="" && v2 !=""){
370
371      jQuery("#datepicker input[name=start],#datepicker input[name=end]").val("");    
372
373      }else{
374
375      jQuery("#datepicker input[name=start],#datepicker input[name=end]").val("");    
376
377      }
378
379      
380
381      jQuery("#normal-search").show();
382
383    }
384
385});
386
387
388}
389
390
391
392// right side open close
393
394function initRightSide(){
395
396	var activeClass = 'active';
397
398	var animSpeed = 500;
399
400	jQuery('.fixed-popup').each(function(){
401
402		var hold = jQuery(this);
403
404		var opener = hold.find('.popup-opener');
405
406		var slide = hold.find('.popup-content');
407
408		slide.show().css({marginRight: -slide.width()});
409
410	
411                    opener.mouseover( function(e){
412
413			e.preventDefault();
414
415			if(!hold.hasClass(activeClass)){
416
417				hold.addClass(activeClass);
418
419				slide.stop().animate({marginRight: ''}, animSpeed);
420
421			}
422
423			else{
424
425				hold.removeClass(activeClass);
426
427				slide.stop().animate({marginRight: -slide.width()}, animSpeed);
428
429			}
430
431		});
432
433	});
434
435}
436
437
438
439// scroll gallery init
440
441function initCarousel() {
442
443	jQuery('.carousel').scrollGallery({
444
445		mask: '.mask',
446
447		slider: '.slideset',
448
449		slides: '.slide',
450
451		btnPrev: 'a.btn-prev',
452
453		btnNext: 'a.btn-next',
454
455		pagerLinks: '.pagination li',
456
457		autoRotation: false,
458
459		switchTime: 3000,
460
461		animSpeed: 500,
462
463		step: 1
464
465	});
466
467}
468
469
470
471// content tabs init
472
473function initTabs() {
474
475	jQuery('ul.tabset').contentTabs({
476
477		tabLinks: 'a'
478
479	});
480
481}
482
483
484
485// accordion menu init
486
487function initAccordion() {
488
489	jQuery('ul.nav-accordion').slideAccordion({
490
491		opener: 'a.nav-opener',
492
493		slider: 'div.nav-slide',
494
495		animSpeed: 300
496
497	});
498
499}
500
501
502
503// align blocks height
504
505function initSameHeight() {
506
507	jQuery('.main-holder').sameHeight({
508
509		elements: '.same-height',
510
511		flexible: true,
512
513		multiLine: true
514
515	});
516
517}
518
519
520
521// handle flexible video size
522
523function initFitVids() {
524
525	jQuery('.video-holder').fitVids();
526
527}
528
529
530
531/*
532
533 * jQuery Carousel plugin
534
535 */
536
537;(function($){
538
539	function ScrollGallery(options) {
540
541		this.options = $.extend({
542
543			mask: 'div.mask',
544
545			slider: '>*',
546
547			slides: '>*',
548
549			activeClass:'active',
550
551			disabledClass:'disabled',
552
553			btnPrev: 'a.btn-prev',
554
555			btnNext: 'a.btn-next',
556
557			generatePagination: false,
558
559			pagerList: '<ul>',
560
561			pagerListItem: '<li><a href="#"></a></li>',
562
563			pagerListItemText: 'a',
564
565			pagerLinks: '.pagination li',
566
567			currentNumber: 'span.current-num',
568
569			totalNumber: 'span.total-num',
570
571			btnPlay: '.btn-play',
572
573			btnPause: '.btn-pause',
574
575			btnPlayPause: '.btn-play-pause',
576
577			galleryReadyClass: 'gallery-js-ready',
578
579			autorotationActiveClass: 'autorotation-active',
580
581			autorotationDisabledClass: 'autorotation-disabled',
582
583			stretchSlideToMask: false,
584
585			circularRotation: true,
586
587			disableWhileAnimating: false,
588
589			autoRotation: false,
590
591			pauseOnHover: isTouchDevice ? false : true,
592
593			maskAutoSize: false,
594
595			switchTime: 4000,
596
597			animSpeed: 600,
598
599			event:'click',
600
601			swipeThreshold: 15,
602
603			handleTouch: true,
604
605			vertical: false,
606
607			useTranslate3D: false,
608
609			step: false
610
611		}, options);
612
613		this.init();
614
615	}
616
617	ScrollGallery.prototype = {
618
619		init: function() {
620
621			if(this.options.holder) {
622
623				this.findElements();
624
625				this.attachEvents();
626
627				this.refreshPosition();
628
629				this.refreshState(true);
630
631				this.resumeRotation();
632
633				this.makeCallback('onInit', this);
634
635			}
636
637		},
638
639		findElements: function() {
640
641			// define dimensions proporties
642
643			this.fullSizeFunction = this.options.vertical ? 'outerHeight' : 'outerWidth';
644
645			this.innerSizeFunction = this.options.vertical ? 'height' : 'width';
646
647			this.slideSizeFunction = 'outerHeight';
648
649			this.maskSizeProperty = 'height';
650
651			this.animProperty = this.options.vertical ? 'marginTop' : 'marginLeft';
652
653
654
655			// control elements
656
657			this.gallery = jQuery(this.options.holder).addClass(this.options.galleryReadyClass);
658
659			this.mask = this.gallery.find(this.options.mask);
660
661			this.slider = this.mask.find(this.options.slider);
662
663			this.slides = this.slider.find(this.options.slides);
664
665			this.btnPrev = this.gallery.find(this.options.btnPrev);
666
667			this.btnNext = this.gallery.find(this.options.btnNext);
668
669			this.currentStep = 0; this.stepsCount = 0;
670
671
672
673			// get start index
674
675			if(this.options.step === false) {
676
677				var activeSlide = this.slides.filter('.'+this.options.activeClass);
678
679				if(activeSlide.length) {
680
681					this.currentStep = this.slides.index(activeSlide);
682
683				}
684
685			}
686
687
688
689			// calculate offsets
690
691			this.calculateOffsets();
692
693
694
695			// create gallery pagination
696
697			if(typeof this.options.generatePagination === 'string') {
698
699				this.pagerLinks = jQuery();
700
701				this.buildPagination();
702
703			} else {
704
705				this.pagerLinks = this.gallery.find(this.options.pagerLinks);
706
707				this.attachPaginationEvents();
708
709			}
710
711
712
713			// autorotation control buttons
714
715			this.btnPlay = this.gallery.find(this.options.btnPlay);
716
717			this.btnPause = this.gallery.find(this.options.btnPause);
718
719			this.btnPlayPause = this.gallery.find(this.options.btnPlayPause);
720
721
722
723			// misc elements
724
725			this.curNum = this.gallery.find(this.options.currentNumber);
726
727			this.allNum = this.gallery.find(this.options.totalNumber);
728
729		},
730
731		attachEvents: function() {
732
733			// bind handlers scope
734
735			var self = this;
736
737			this.bindHandlers(['onWindowResize']);
738
739			jQuery(window).bind('load resize orientationchange', this.onWindowResize);
740
741
742
743			// previous and next button handlers
744
745			if(this.btnPrev.length) {
746
747				this.prevSlideHandler = function(e) {
748
749					e.preventDefault();
750
751					self.prevSlide();
752
753				};
754
755				this.btnPrev.bind(this.options.event, this.prevSlideHandler);
756
757			}
758
759			if(this.btnNext.length) {
760
761				this.nextSlideHandler = function(e) {
762
763					e.preventDefault();
764
765					self.nextSlide();
766
767				};
768
769				this.btnNext.bind(this.options.event, this.nextSlideHandler);
770
771			}
772
773
774
775			// pause on hover handling
776
777			if(this.options.pauseOnHover && !isTouchDevice) {
778
779				this.hoverHandler = function() {
780
781					if(self.options.autoRotation) {
782
783						self.galleryHover = true;
784
785						self.pauseRotation();
786
787					}
788
789				};
790
791				this.leaveHandler = function() {
792
793					if(self.options.autoRotation) {
794
795						self.galleryHover = false;
796
797						self.resumeRotation();
798
799					}
800
801				};
802
803				this.gallery.bind({mouseenter: this.hoverHandler, mouseleave: this.leaveHandler});
804
805			}
806
807
808
809			// autorotation buttons handler
810
811			if(this.btnPlay.length) {
812
813				this.btnPlayHandler = function(e) {
814
815					e.preventDefault();
816
817					self.startRotation();
818
819				};
820
821				this.btnPlay.bind(this.options.event, this.btnPlayHandler);
822
823			}
824
825			if(this.btnPause.length) {
826
827				this.btnPauseHandler = function(e) {
828
829					e.preventDefault();
830
831					self.stopRotation();
832
833				};
834
835				this.btnPause.bind(this.options.event, this.btnPauseHandler);
836
837			}
838
839			if(this.btnPlayPause.length) {
840
841				this.btnPlayPauseHandler = function(e) {
842
843					e.preventDefault();
844
845					if(!self.gallery.hasClass(self.options.autorotationActiveClass)) {
846
847						self.startRotation();
848
849					} else {
850
851						self.stopRotation();
852
853					}
854
855				};
856
857				this.btnPlayPause.bind(this.options.event, this.btnPlayPauseHandler);
858
859			}
860
861
862
863			// enable hardware acceleration
864
865			if(isTouchDevice && this.options.useTranslate3D) {
866
867				this.slider.css({'-webkit-transform': 'translate3d(0px, 0px, 0px)'});
868
869			}
870
871
872
873			// swipe event handling
874
875			if(isTouchDevice && this.options.handleTouch && window.Hammer && this.mask.length) {
876
877				this.swipeHandler = Hammer(this.mask[0], {
878
879					dragBlockHorizontal: !this.options.vertical,
880
881					dragBlockVertical: this.options.vertical,
882
883					dragMinDistance: 1,
884
885					behavior: {
886
887						touchAction: this.options.vertical ? 'pan-x' : 'pan-y'
888
889					}
890
891				}).on('touch release ' + (self.options.vertical ? 'dragup dragdown' : 'dragleft dragright'), function(e) {
892
893					switch(e.type) {
894
895						case 'touch':
896
897							if(self.galleryAnimating) {
898
899								e.gesture.stopDetect();
900
901							} else {
902
903								self.pauseRotation();
904
905								self.originalOffset = parseFloat(self.slider.css(self.animProperty));
906
907							}
908
909							break;
910
911						case 'dragup':
912
913						case 'dragdown':
914
915						case 'dragleft':
916
917						case 'dragright':
918
919							e.gesture.preventDefault();
920
921							var tmpOffset = self.originalOffset + e.gesture[self.options.vertical ? 'deltaY' : 'deltaX'];
922
923							tmpOffset = Math.max(Math.min(0, tmpOffset), self.maxOffset);
924
925							self.slider.css(self.animProperty, tmpOffset);
926
927							break;
928
929						case 'release':
930
931							self.resumeRotation();
932
933							if(Math.abs(e.gesture[self.options.vertical ? 'deltaY' : 'deltaX']) > self.options.swipeThreshold) {
934
935								if(e.gesture.direction == 'left' || e.gesture.direction == 'up') {
936
937									self.nextSlide();
938
939								} else {
940
941									self.prevSlide();
942
943								}
944
945							} else {
946
947								self.switchSlide();
948
949							}
950
951					}
952
953				});
954
955			}
956
957		},
958
959		onWindowResize: function() {
960
961			if(!this.galleryAnimating) {
962
963				this.calculateOffsets();
964
965				this.refreshPosition();
966
967				this.buildPagination();
968
969				this.refreshState();
970
971				this.resizeQueue = false;
972
973			} else {
974
975				this.resizeQueue = true;
976
977			}
978
979		},
980
981		refreshPosition: function() {
982
983			this.currentStep = Math.min(this.currentStep, this.stepsCount - 1);
984
985			this.tmpProps = {};
986
987			this.tmpProps[this.animProperty] = this.getStepOffset();
988
989			this.slider.stop().css(this.tmpProps);
990
991		},
992
993		calculateOffsets: function() {
994
995			var self = this, tmpOffset, tmpStep;
996
997			if(this.options.stretchSlideToMask) {
998
999				var tmpObj = {};
1000
1001				tmpObj[this.innerSizeFunction] = this.mask[this.innerSizeFunction]();
1002
1003				this.slides.css(tmpObj);
1004
1005			}
1006
1007
1008
1009			this.maskSize = this.mask[this.innerSizeFunction]();
1010
1011			this.sumSize = this.getSumSize();
1012
1013			this.maxOffset = this.maskSize - this.sumSize;
1014
1015
1016
1017			// vertical gallery with single size step custom behavior
1018
1019			if(this.options.vertical && this.options.maskAutoSize) {
1020
1021				this.options.step = 1;
1022
1023				this.stepsCount = this.slides.length;
1024
1025				this.stepOffsets = [0];
1026
1027				tmpOffset = 0;
1028
1029				for(var i = 0; i < this.slides.length; i++) {
1030
1031					tmpOffset -= jQuery(this.slides[i])[this.fullSizeFunction](true);
1032
1033					this.stepOffsets.push(tmpOffset);
1034
1035				}
1036
1037				this.maxOffset = tmpOffset;
1038
1039				return;
1040
1041			}
1042
1043
1044
1045			// scroll by slide size
1046
1047			if(typeof this.options.step === 'number' && this.options.step > 0) {
1048
1049				this.slideDimensions = [];
1050
1051				this.slides.each($.proxy(function(ind, obj){
1052
1053					self.slideDimensions.push( jQuery(obj)[self.fullSizeFunction](true) );
1054
1055				},this));
1056
1057
1058
1059				// calculate steps count
1060
1061				this.stepOffsets = [0];
1062
1063				this.stepsCount = 1;
1064
1065				tmpOffset = tmpStep = 0;
1066
1067				while(tmpOffset > this.maxOffset) {
1068
1069					tmpOffset -= this.getSlideSize(tmpStep, tmpStep + this.options.step);
1070
1071					tmpStep += this.options.step;
1072
1073					this.stepOffsets.push(Math.max(tmpOffset, this.maxOffset));
1074
1075					this.stepsCount++;
1076
1077				}
1078
1079			}
1080
1081			// scroll by mask size
1082
1083			else {
1084
1085				// define step size
1086
1087				this.stepSize = this.maskSize;
1088
1089
1090
1091				// calculate steps count
1092
1093				this.stepsCount = 1;
1094
1095				tmpOffset = 0;
1096
1097				while(tmpOffset > this.maxOffset) {
1098
1099					tmpOffset -= this.stepSize;
1100
1101					this.stepsCount++;
1102
1103				}
1104
1105			}
1106
1107		},
1108
1109		getSumSize: function() {
1110
1111			var sum = 0;
1112
1113			this.slides.each($.proxy(function(ind, obj){
1114
1115				sum += jQuery(obj)[this.fullSizeFunction](true);
1116
1117			},this));
1118
1119			this.slider.css(this.innerSizeFunction, sum);
1120
1121			return sum;
1122
1123		},
1124
1125		getStepOffset: function(step) {
1126
1127			step = step || this.currentStep;
1128
1129			if(typeof this.options.step === 'number') {
1130
1131				return this.stepOffsets[this.currentStep];
1132
1133			} else {
1134
1135				return Math.min(0, Math.max(-this.currentStep * this.stepSize, this.maxOffset));
1136
1137			}
1138
1139		},
1140
1141		getSlideSize: function(i1, i2) {
1142
1143			var sum = 0;
1144
1145			for(var i = i1; i < Math.min(i2, this.slideDimensions.length); i++) {
1146
1147				sum += this.slideDimensions[i];
1148
1149			}
1150
1151			return sum;
1152
1153		},
1154
1155		buildPagination: function() {
1156
1157			if(typeof this.options.generatePagination === 'string') {
1158
1159				if(!this.pagerHolder) {
1160
1161					this.pagerHolder = this.gallery.find(this.options.generatePagination);
1162
1163				}
1164
1165				if(this.pagerHolder.length && this.oldStepsCount != this.stepsCount) {
1166
1167					this.oldStepsCount = this.stepsCount;
1168
1169					this.pagerHolder.empty();
1170
1171					this.pagerList = jQuery(this.options.pagerList).appendTo(this.pagerHolder);
1172
1173					for(var i = 0; i < this.stepsCount; i++) {
1174
1175						jQuery(this.options.pagerListItem).appendTo(this.pagerList).find(this.options.pagerListItemText).text(i+1);
1176
1177					}
1178
1179					this.pagerLinks = this.pagerList.children();
1180
1181					this.attachPaginationEvents();
1182
1183				}
1184
1185			}
1186
1187		},
1188
1189		attachPaginationEvents: function() {
1190
1191			var self = this;
1192
1193			this.pagerLinksHandler = function(e) {
1194
1195				e.preventDefault();
1196
1197				self.numSlide(self.pagerLinks.index(e.currentTarget));
1198
1199			};
1200
1201			this.pagerLinks.bind(this.options.event, this.pagerLinksHandler);
1202
1203		},
1204
1205		prevSlide: function() {
1206
1207			if(!(this.options.disableWhileAnimating && this.galleryAnimating)) {
1208
1209				if(this.currentStep > 0) {
1210
1211					this.currentStep--;
1212
1213					this.switchSlide();
1214
1215				} else if(this.options.circularRotation) {
1216
1217					this.currentStep = this.stepsCount - 1;
1218
1219					this.switchSlide();
1220
1221				}
1222
1223			}
1224
1225		},
1226
1227		nextSlide: function(fromAutoRotation) {
1228
1229			if(!(this.options.disableWhileAnimating && this.galleryAnimating)) {
1230
1231				if(this.currentStep < this.stepsCount - 1) {
1232
1233					this.currentStep++;
1234
1235					this.switchSlide();
1236
1237				} else if(this.options.circularRotation || fromAutoRotation === true) {
1238
1239					this.currentStep = 0;
1240
1241					this.switchSlide();
1242
1243				}
1244
1245			}
1246
1247		},
1248
1249		numSlide: function(c) {
1250
1251			if(this.currentStep != c) {
1252
1253				this.currentStep = c;
1254
1255				this.switchSlide();
1256
1257			}
1258
1259		},
1260
1261		switchSlide: function() {
1262
1263			var self = this;
1264
1265			this.galleryAnimating = true;
1266
1267			this.tmpProps = {};
1268
1269			this.tmpProps[this.animProperty] = this.getStepOffset();
1270
1271			this.slider.stop().animate(this.tmpProps, {duration: this.options.animSpeed, complete: function(){
1272
1273				// animation complete
1274
1275				self.galleryAnimating = false;
1276
1277				if(self.resizeQueue) {
1278
1279					self.onWindowResize();
1280
1281				}
1282
1283
1284
1285				// onchange callback
1286
1287				self.makeCallback('onChange', self);
1288
1289				self.autoRotate();
1290
1291			}});
1292
1293			this.refreshState();
1294
1295
1296
1297			// onchange callback
1298
1299			this.makeCallback('onBeforeChange', this);
1300
1301		},
1302
1303		refreshState: function(initial) {
1304
1305			if(this.options.step === 1 || this.stepsCount === this.slides.length) {
1306
1307				this.slides.removeClass(this.options.activeClass).eq(this.currentStep).addClass(this.options.activeClass);
1308
1309			}
1310
1311			this.pagerLinks.removeClass(this.options.activeClass).eq(this.currentStep).addClass(this.options.activeClass);
1312
1313			this.curNum.html(this.currentStep+1);
1314
1315			this.allNum.html(this.stepsCount);
1316
1317
1318
1319			// initial refresh
1320
1321			if(this.options.maskAutoSize && typeof this.options.step === 'number') {
1322
1323				this.tmpProps = {};
1324
1325				this.tmpProps[this.maskSizeProperty] = this.slides.eq(Math.min(this.currentStep,this.slides.length-1))[this.slideSizeFunction](true);
1326
1327				this.mask.stop()[initial ? 'css' : 'animate'](this.tmpProps);
1328
1329			}
1330
1331
1332
1333			// disabled state
1334
1335			if(!this.options.circularRotation) {
1336
1337				this.btnPrev.add(this.btnNext).removeClass(this.options.disabledClass);
1338
1339				if(this.currentStep === 0) this.btnPrev.addClass(this.options.disabledClass);
1340
1341				if(this.currentStep === this.stepsCount - 1) this.btnNext.addClass(this.options.disabledClass);
1342
1343			}
1344
1345
1346
1347			// add class if not enough slides
1348
1349			this.gallery.toggleClass('not-enough-slides', this.sumSize <= this.maskSize);
1350
1351		},
1352
1353		startRotation: function() {
1354
1355			this.options.autoRotation = true;
1356
1357			this.galleryHover = false;
1358
1359			this.autoRotationStopped = false;
1360
1361			this.resumeRotation();
1362
1363		},
1364
1365		stopRotation: function() {
1366
1367			this.galleryHover = true;
1368
1369			this.autoRotationStopped = true;
1370
1371			this.pauseRotation();
1372
1373		},
1374
1375		pauseRotation: function() {
1376
1377			this.gallery.addClass(this.options.autorotationDisabledClass);
1378
1379			this.gallery.removeClass(this.options.autorotationActiveClass);
1380
1381			clearTimeout(this.timer);
1382
1383		},
1384
1385		resumeRotation: function() {
1386
1387			if(!this.autoRotationStopped) {
1388
1389				this.gallery.addClass(this.options.autorotationActiveClass);
1390
1391				this.gallery.removeClass(this.options.autorotationDisabledClass);
1392
1393				this.autoRotate();
1394
1395			}
1396
1397		},
1398
1399		autoRotate: function() {
1400
1401			var self = this;
1402
1403			clearTimeout(this.timer);
1404
1405			if(this.options.autoRotation && !this.galleryHover && !this.autoRotationStopped) {
1406
1407				this.timer = setTimeout(function(){
1408
1409					self.nextSlide(true);
1410
1411				}, this.options.switchTime);
1412
1413			} else {
1414
1415				this.pauseRotation();
1416
1417			}
1418
1419		},
1420
1421		bindHandlers: function(handlersList) {
1422
1423			var self = this;
1424
1425			$.each(handlersList, function(index, handler) {
1426
1427				var origHandler = self[handler];
1428
1429				self[handler] = function() {
1430
1431					return origHandler.apply(self, arguments);
1432
1433				};
1434
1435			});
1436
1437		},
1438
1439		makeCallback: function(name) {
1440
1441			if(typeof this.options[name] === 'function') {
1442
1443				var args = Array.prototype.slice.call(arguments);
1444
1445				args.shift();
1446
1447				this.options[name].apply(this, args);
1448
1449			}
1450
1451		},
1452
1453		destroy: function() {
1454
1455			// destroy handler
1456
1457			jQuery(window).unbind('load resize orientationchange', this.onWindowResize);
1458
1459			this.btnPrev.unbind(this.options.event, this.prevSlideHandler);
1460
1461			this.btnNext.unbind(this.options.event, this.nextSlideHandler);
1462
1463			this.pagerLinks.unbind(this.options.event, this.pagerLinksHandler);
1464
1465			this.gallery.unbind({mouseenter: this.hoverHandler, mouseleave: this.leaveHandler});
1466
1467
1468
1469			// autorotation buttons handlers
1470
1471			this.stopRotation();
1472
1473			this.btnPlay.unbind(this.options.event, this.btnPlayHandler);
1474
1475			this.btnPause.unbind(this.options.event, this.btnPauseHandler);
1476
1477			this.btnPlayPause.unbind(this.options.event, this.btnPlayPauseHandler);
1478
1479
1480
1481			// destroy swipe handler
1482
1483			if(this.swipeHandler) {
1484
1485				this.swipeHandler.dispose();
1486
1487			}
1488
1489
1490
1491			// remove inline styles, classes and pagination
1492
1493			var unneededClasses = [this.options.galleryReadyClass, this.options.autorotationActiveClass, this.options.autorotationDisabledClass];
1494
1495			this.gallery.removeClass(unneededClasses.join(' '));
1496
1497			this.slider.add(this.slides).removeAttr('style');
1498
1499			if(typeof this.options.generatePagination === 'string') {
1500
1501				this.pagerHolder.empty();
1502
1503			}
1504
1505		}
1506
1507	};
1508
1509
1510
1511	// detect device type
1512
1513	var isTouchDevice = /MSIE 10.*Touch/.test(navigator.userAgent) || ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
1514
1515
1516
1517	// jquery plugin
1518
1519	$.fn.scrollGallery = function(opt){
1520
1521		return this.each(function(){
1522
1523			jQuery(this).data('ScrollGallery', new ScrollGallery($.extend(opt,{holder:this})));
1524
1525		});
1526
1527	};
1528
1529}(jQuery));
1530
1531
1532
1533/*
1534
1535 * jQuery Tabs plugin
1536
1537 */
1538
1539;(function($){
1540
1541	$.fn.contentTabs = function(o){
1542
1543		// default options
1544
1545		var options = $.extend({
1546
1547			activeClass:'active',
1548
1549			addToParent:false,
1550
1551			autoHeight:false,
1552
1553			autoRotate:false,
1554
1555			checkHash:false,
1556
1557			animSpeed:400,
1558
1559			switchTime:3000,
1560
1561			effect: 'none', // "fade", "slide"
1562
1563			tabLinks:'a',
1564
1565			attrib:'href',
1566
1567			event:'click'
1568
1569		},o);
1570
1571
1572
1573		return this.each(function(){
1574
1575			var tabset = jQuery(this), tabs = jQuery();
1576
1577			var tabLinks = tabset.find(options.tabLinks);
1578
1579			var tabLinksParents = tabLinks.parent();
1580
1581			var prevActiveLink = tabLinks.eq(0), currentTab, animating;
1582
1583			var tabHolder;
1584
1585
1586
1587			// handle location hash
1588
1589			if(options.checkHash && tabLinks.filter('[' + options.attrib + '="' + location.hash + '"]').length) {
1590
1591				(options.addToParent ? tabLinksParents : tabLinks).removeClass(options.activeClass);
1592
1593				setTimeout(function() {
1594
1595					window.scrollTo(0,0);
1596
1597				},1);
1598
1599			}
1600
1601
1602
1603			// init tabLinks
1604
1605			tabLinks.each(function(){
1606
1607				var link = jQuery(this);
1608
1609				var href = link.attr(options.attrib);
1610
1611				var parent = link.parent();
1612
1613				href = href.substr(href.lastIndexOf('#'));
1614
1615
1616
1617				// get elements
1618
1619				var tab = jQuery(href).hide();
1620
1621				tabs = tabs.add(tab);
1622
1623				link.data('cparent', parent);
1624
1625				link.data('ctab', tab);
1626
1627
1628
1629				// find tab holder
1630
1631				if(!tabHolder && tab.length) {
1632
1633					tabHolder = tab.parent();
1634
1635				}
1636
1637
1638
1639				// show only active tab
1640
1641				var classOwner = options.addToParent ? parent : link;
1642
1643				if(classOwner.hasClass(options.activeClass) || (options.checkHash && location.hash === href)) {
1644
1645					classOwner.addClass(options.activeClass);
1646
1647					prevActiveLink = link; currentTab = tab;
1648
1649					tab.removeClass(tabHiddenClass).width('');
1650
1651					contentTabsEffect[options.effect].show({tab:tab, fast:true});
1652
1653				} else {
1654
1655					var tabWidth = tab.width();
1656
1657					if(tabWidth) {
1658
1659						tab.width(tabWidth);
1660
1661					}
1662
1663					tab.addClass(tabHiddenClass);
1664
1665				}
1666
1667
1668
1669				// event handler
1670
1671				link.bind(options.event, function(e){
1672
1673					if(link != prevActiveLink && !animating) {
1674
1675						switchTab(prevActiveLink, link);
1676
1677						prevActiveLink = link;
1678
1679					}
1680
1681				});
1682
1683				if(options.attrib === 'href') {
1684
1685					link.bind('click', function(e){
1686
1687						e.preventDefault();
1688
1689					});
1690
1691				}
1692
1693			});
1694
1695
1696
1697			// tab switch function
1698
1699			function switchTab(oldLink, newLink) {
1700
1701				animating = true;
1702
1703				var oldTab = oldLink.data('ctab');
1704
1705				var newTab = newLink.data('ctab');
1706
1707				prevActiveLink = newLink;
1708
1709				currentTab = newTab;
1710
1711
1712
1713				// refresh pagination links
1714
1715				(options.addToParent ? tabLinksParents : tabLinks).removeClass(options.activeClass);
1716
1717				(options.addToParent ? newLink.data('cparent') : newLink).addClass(options.activeClass);
1718
1719
1720
1721				// hide old tab
1722
1723				resizeHolder(oldTab, true);
1724
1725				contentTabsEffect[options.effect].hide({
1726
1727					speed: options.animSpeed,
1728
1729					tab:oldTab,
1730
1731					complete: function() {
1732
1733						// show current tab
1734
1735						resizeHolder(newTab.removeClass(tabHiddenClass).width(''));
1736
1737						contentTabsEffect[options.effect].show({
1738
1739							speed: options.animSpeed,
1740
1741							tab:newTab,
1742
1743							complete: function() {
1744
1745								if(!oldTab.is(newTab)) {
1746
1747									oldTab.width(oldTab.width()).addClass(tabHiddenClass);
1748
1749								}
1750
1751								animating = false;
1752
1753								resizeHolder(newTab, false);
1754
1755								autoRotate();
1756
1757							}
1758
1759						});
1760
1761					}
1762
1763				});
1764
1765			}
1766
1767
1768
1769			// holder auto height
1770
1771			function resizeHolder(block, state) {
1772
1773				var curBlock = block && block.length ? block : currentTab;
1774
1775				if(options.autoHeight && curBlock) {
1776
1777					tabHolder.stop();
1778
1779					if(state === false) {
1780
1781						tabHolder.css({height:''});
1782
1783					} else {
1784
1785						var origStyles = curBlock.attr('style');
1786
1787						curBlock.show().css({width:curBlock.width()});
1788
1789						var tabHeight = curBlock.outerHeight(true);
1790
1791						if(!origStyles) curBlock.removeAttr('style'); else curBlock.attr('style', origStyles);
1792
1793						if(state === true) {
1794
1795							tabHolder.css({height: tabHeight});
1796
1797						} else {
1798
1799							tabHolder.animate({height: tabHeight}, {duration: options.animSpeed});
1800
1801						}
1802
1803					}
1804
1805				}
1806
1807			}
1808
1809			if(options.autoHeight) {
1810
1811				jQuery(window).bind('resize orientationchange', function(){
1812
1813					tabs.not(currentTab).removeClass(tabHiddenClass).show().each(function(){
1814
1815						var tab = jQuery(this), tabWidth = tab.css({width:''}).width();
1816
1817						if(tabWidth) {
1818
1819							tab.width(tabWidth);
1820
1821						}
1822
1823					}).hide().addClass(tabHiddenClass);
1824
1825
1826
1827					resizeHolder(currentTab, false);
1828
1829				});
1830
1831			}
1832
1833
1834
1835			// autorotation handling
1836
1837			var rotationTimer;
1838
1839			function nextTab() {
1840
1841				var activeItem = (options.addToParent ? tabLinksParents : tabLinks).filter('.' + options.activeClass);
1842
1843				var activeIndex = (options.addToParent ? tabLinksParents : tabLinks).index(activeItem);
1844
1845				var newLink = tabLinks.eq(activeIndex < tabLinks.length - 1 ? activeIndex + 1 : 0);
1846
1847				prevActiveLink = tabLinks.eq(activeIndex);
1848
1849				switchTab(prevActiveLink, newLink);
1850
1851			}
1852
1853			function autoRotate() {
1854
1855				if(options.autoRotate && tabLinks.length > 1) {
1856
1857					clearTimeout(rotationTimer);
1858
1859					rotationTimer = setTimeout(function() {
1860
1861						if(!animating) {
1862
1863							nextTab();
1864
1865						} else {
1866
1867							autoRotate();
1868
1869						}
1870
1871					}, options.switchTime);
1872
1873				}
1874
1875			}
1876
1877			autoRotate();
1878
1879		});
1880
1881	};
1882
1883
1884
1885	// add stylesheet for tabs on DOMReady
1886
1887	var tabHiddenClass = 'js-tab-hidden';
1888
1889	jQuery(function() {
1890
1891		var tabStyleSheet = jQuery('<style type="text/css">')[0];
1892
1893		var tabStyleRule = '.'+tabHiddenClass;
1894
1895		tabStyleRule += '{position:absolute !important;left:-9999px !important;top:-9999px !important;display:block !important}';
1896
1897		if (tabStyleSheet.styleSheet) {
1898
1899			tabStyleSheet.styleSheet.cssText = tabStyleRule;
1900
1901		} else {
1902
1903			tabStyleSheet.appendChild(document.createTextNode(tabStyleRule));
1904
1905		}
1906
1907		jQuery('head').append(tabStyleSheet);
1908
1909	});
1910
1911
1912
1913	// tab switch effects
1914
1915	var contentTabsEffect = {
1916
1917		none: {
1918
1919			show: function(o) {
1920
1921				o.tab.css({display:'block'});
1922
1923				if(o.complete) o.complete();
1924
1925			},
1926
1927			hide: function(o) {
1928
1929				o.tab.css({display:'none'});
1930
1931				if(o.complete) o.complete();
1932
1933			}
1934
1935		},
1936
1937		fade: {
1938
1939			show: function(o) {
1940
1941				if(o.fast) o.speed = 1;
1942
1943				o.tab.fadeIn(o.speed);
1944
1945				if(o.complete) setTimeout(o.complete, o.speed);
1946
1947			},
1948
1949			hide: function(o) {
1950
1951				if(o.fast) o.speed = 1;
1952
1953				o.tab.fadeOut(o.speed);
1954
1955				if(o.complete) setTimeout(o.complete, o.speed);
1956
1957			}
1958
1959		},
1960
1961		slide: {
1962
1963			show: function(o) {
1964
1965				var tabHeight = o.tab.show().css({width:o.tab.width()}).outerHeight(true);
1966
1967				var tmpWrap = jQuery('<div class="effect-div">').insertBefore(o.tab).append(o.tab);
1968
1969				tmpWrap.css({width:'100%', overflow:'hidden', position:'relative'}); o.tab.css({marginTop:-tabHeight,display:'block'});
1970
1971				if(o.fast) o.speed = 1;
1972
1973				o.tab.animate({marginTop: 0}, {duration: o.speed, complete: function(){
1974
1975					o.tab.css({marginTop: '', width: ''}).insertBefore(tmpWrap);
1976
1977					tmpWrap.remove();
1978
1979					if(o.complete) o.complete();
1980
1981				}});
1982
1983			},
1984
1985			hide: function(o) {
1986
1987				var tabHeight = o.tab.show().css({width:o.tab.width()}).outerHeight(true);
1988
1989				var tmpWrap = jQuery('<div class="effect-div">').insertBefore(o.tab).append(o.tab);
1990
1991				tmpWrap.css({width:'100%', overflow:'hidden', position:'relative'});
1992
1993
1994
1995				if(o.fast) o.speed = 1;
1996
1997				o.tab.animate({marginTop: -tabHeight}, {duration: o.speed, complete: function(){
1998
1999					o.tab.css({display:'none', marginTop:'', width:''}).insertBefore(tmpWrap);
2000
2001					tmpWrap.remove();
2002
2003					if(o.complete) o.complete();
2004
2005				}});
2006
2007			}
2008
2009		}
2010
2011	};
2012
2013}(jQuery));
2014
2015
2016
2017/*
2018
2019 * jQuery Accordion plugin
2020
2021 */
2022
2023;(function($){
2024
2025	$.fn.slideAccordion = function(opt){
2026
2027		// default options
2028
2029		var options = $.extend({
2030
2031			addClassBeforeAnimation: false,
2032
2033			allowClickWhenExpanded: false,
2034
2035			activeClass:'active',
2036
2037			opener:'.opener',
2038
2039			slider:'.slide',
2040
2041			animSpeed: 300,
2042
2043			collapsible:true,
2044
2045			event:'click'
2046
2047		},opt);
2048
2049
2050
2051		return this.each(function(){
2052
2053			// options
2054
2055			var accordion = jQuery(this);
2056
2057			var items = accordion.find(':has('+options.slider+')');
2058
2059
2060
2061			items.each(function(){
2062
2063				var item = jQuery(this);
2064
2065				var opener = item.find(options.opener);
2066
2067				var slider = item.find(options.slider);
2068
2069				opener.bind(options.event, function(e){
2070
2071					if(!slider.is(':animated')) {
2072
2073						if(item.hasClass(options.activeClass)) {
2074
2075							if(options.allowClickWhenExpanded) {
2076
2077								return;
2078
2079							} else if(options.collapsible) {
2080
2081								slider.slideUp(options.animSpeed, function(){
2082
2083									hideSlide(slider);
2084
2085									item.removeClass(options.activeClass);
2086
2087								});
2088
2089							}
2090
2091						} else {
2092
2093							// show active
2094
2095							var levelItems = item.siblings('.'+options.activeClass);
2096
2097							var sliderElements = levelItems.find(options.slider);
2098
2099							item.addClass(options.activeClass);
2100
2101							showSlide(slider).hide().slideDown(options.animSpeed);
2102
2103						
2104
2105							// collapse others
2106
2107							sliderElements.slideUp(options.animSpeed, function(){
2108
2109								levelItems.removeClass(options.activeClass);
2110
2111								hideSlide(sliderElements);
2112
2113							});
2114
2115						}
2116
2117					}
2118
2119					e.preventDefault();
2120
2121				});
2122
2123				if(item.hasClass(options.activeClass)) showSlide(slider); else hideSlide(slider);
2124
2125			});
2126
2127		});
2128
2129	};
2130
2131
2132
2133	// accordion slide visibility
2134
2135	var showSlide = function(slide) {
2136
2137		return slide.css({position:'', top: '', left: '', width: '' });
2138
2139	};
2140
2141	var hideSlide = function(slide) {
2142
2143		return slide.show().css({position:'absolute', top: -9999, left: -9999, width: slide.width() });
2144
2145	};
2146
2147}(jQuery));
2148
2149
2150
2151/*
2152
2153 * jQuery SameHeight plugin
2154
2155 */
2156
2157;(function($){
2158
2159	$.fn.sameHeight = function(opt) {
2160
2161		var options = $.extend({
2162
2163			skipClass: 'same-height-ignore',
2164
2165			leftEdgeClass: 'same-height-left',
2166
2167			rightEdgeClass: 'same-height-right',
2168
2169			elements: '>*',
2170
2171			flexible: false,
2172
2173			multiLine: false,
2174
2175			useMinHeight: false,
2176
2177			biggestHeight: false
2178
2179		},opt);
2180
2181		return this.each(function(){
2182
2183			var holder = jQuery(this), postResizeTimer, ignoreResize;
2184
2185			var elements = holder.find(options.elements).not('.' + options.skipClass);
2186
2187			if(!elements.length) return;
2188
2189
2190
2191			// resize handler
2192
2193			function doResize() {
2194
2195				elements.css(options.useMinHeight && supportMinHeight ? 'minHeight' : 'height', '');
2196
2197				if(options.multiLine) {
2198
2199					// resize elements row by row
2200
2201					resizeElementsByRows(elements, options);
2202
2203				} else {
2204
2205					// resize elements by holder
2206
2207					resizeElements(elements, holder, options);
2208
2209				}
2210
2211			}
2212
2213			doResize();
2214
2215
2216
2217			// handle flexible layout / font resize
2218
2219			var delayedResizeHandler = function() {
2220
2221				if(!ignoreResize) {
2222
2223					ignoreResize = true;
2224
2225					doResize();
2226
2227					clearTimeout(postResizeTimer);
2228
2229					postResizeTimer = setTimeout(function() {
2230
2231						doResize();
2232
2233						setTimeout(function(){
2234
2235							ignoreResize = false;
2236
2237						}, 10);
2238
2239					}, 100);
2240
2241				}
2242
2243			};
2244
2245
2246
2247			// handle flexible/responsive layout
2248
2249			if(options.flexible) {
2250
2251				jQuery(window).bind('resize orientationchange fontresize', delayedResizeHandler);
2252
2253			}
2254
2255
2256
2257			// handle complete page load including images and fonts
2258
2259			jQuery(window).bind('load', delayedResizeHandler);
2260
2261		});
2262
2263	};
2264
2265
2266
2267	// detect css min-height support
2268
2269	var supportMinHeight = typeof document.documentElement.style.maxHeight !== 'undefined';
2270
2271
2272
2273	// get elements by rows
2274
2275	function resizeElementsByRows(boxes, options) {
2276
2277		var currentRow = jQuery(), maxHeight, maxCalcHeight = 0, firstOffset = boxes.eq(0).offset().top;
2278
2279		boxes.each(function(ind){
2280
2281			var curItem = jQuery(this);
2282
2283			if(curItem.offset().top === firstOffset) {
2284
2285				currentRow = currentRow.add(this);
2286
2287			} else {
2288
2289				maxHeight = getMaxHeight(currentRow);
2290
2291				maxCalcHeight = Math.max(maxCalcHeight, resizeElements(currentRow, maxHeight, options));
2292
2293				currentRow = curItem;
2294
2295				firstOffset = curItem.offset().top;
2296
2297			}
2298
2299		});
2300
2301		if(currentRow.length) {
2302
2303			maxHeight = getMaxHeight(currentRow);
2304
2305			maxCalcHeight = Math.max(maxCalcHeight, resizeElements(currentRow, maxHeight, options));
2306
2307		}
2308
2309		if(options.biggestHeight) {
2310
2311			boxes.css(options.useMinHeight && supportMinHeight ? 'minHeight' : 'height', maxCalcHeight);
2312
2313		}
2314
2315	}
2316
2317
2318
2319	// calculate max element height
2320
2321	function getMaxHeight(boxes) {
2322
2323		var maxHeight = 0;
2324
2325		boxes.each(function(){
2326
2327			maxHeight = Math.max(maxHeight, jQuery(this).outerHeight());
2328
2329		});
2330
2331		return maxHeight;
2332
2333	}
2334
2335
2336
2337	// resize helper function
2338
2339	function resizeElements(boxes, parent, options) {
2340
2341		var calcHeight;
2342
2343		var parentHeight = typeof parent === 'number' ? parent : parent.height();
2344
2345		boxes.removeClass(options.leftEdgeClass).removeClass(options.rightEdgeClass).each(function(i){
2346
2347			var element = jQuery(this);
2348
2349			var depthDiffHeight = 0;
2350
2351			var isBorderBox = element.css('boxSizing') === 'border-box' || element.css('-moz-box-sizing') === 'border-box' || element.css('-webkit-box-sizing') === 'border-box';
2352
2353
2354
2355			if(typeof parent !== 'number') {
2356
2357				element.parents().each(function(){
2358
2359					var tmpParent = jQuery(this);
2360
2361					if(parent.is(this)) {
2362
2363						return false;
2364
2365					} else {
2366
2367						depthDiffHeight += tmpParent.outerHeight() - tmpParent.height();
2368
2369					}
2370
2371				});
2372
2373			}
2374
2375			calcHeight = parentHeight - depthDiffHeight;
2376
2377			calcHeight -= isBorderBox ? 0 : element.outerHeight() - element.height();
2378
2379
2380
2381			if(calcHeight > 0) {
2382
2383				element.css(options.useMinHeight && supportMinHeight ? 'minHeight' : 'height', calcHeight);
2384
2385			}
2386
2387		});
2388
2389		boxes.filter(':first').addClass(options.leftEdgeClass);
2390
2391		boxes.filter(':last').addClass(options.rightEdgeClass);
2392
2393		return calcHeight;
2394
2395	}
2396
2397}(jQuery));
2398
2399
2400
2401/*
2402
2403 * jQuery FontResize Event
2404
2405 */
2406
2407jQuery.onFontResize = (function($) {
2408
2409	jQuery(function() {
2410
2411		var randomID = 'font-resize-frame-' + Math.floor(Math.random() * 1000);
2412
2413		var resizeFrame = jQuery('<iframe>').attr('id', randomID).addClass('font-resize-helper');
2414
2415
2416
2417		// required styles
2418
2419		resizeFrame.css({
2420
2421			width: '100em',
2422
2423			height: '10px',
2424
2425			position: 'absolute',
2426
2427			borderWidth: 0,
2428
2429			top: '-9999px',
2430
2431			left: '-9999px'
2432
2433		}).appendTo('body');
2434
2435
2436
2437		// use native IE resize event if possible
2438
2439		if (window.attachEvent && !window.addEventListener) {
2440
2441			resizeFrame.bind('resize', function () {
2442
2443				$.onFontResize.trigger(resizeFrame[0].offsetWidth / 100);
2444
2445			});
2446
2447		}
2448
2449		// use script inside the iframe to detect resize for other browsers
2450
2451		else {
2452
2453			var doc = resizeFrame[0].contentWindow.document;
2454
2455			doc.open();
2456
2457			doc.write('<scri' + 'pt>window.onload = function(){var em = parent.jQuery("#' + randomID + '")[0];window.onresize = function(){if(parent.jQuery.onFontResize){parent.jQuery.onFontResize.trigger(em.offsetWidth / 100);}}};</scri' + 'pt>');
2458
2459			doc.close();
2460
2461		}
2462
2463		jQuery.onFontResize.initialSize = resizeFrame[0].offsetWidth / 100;
2464
2465	});
2466
2467	return {
2468
2469		// public method, so it can be called from within the iframe
2470
2471		trigger: function (em) {
2472
2473			jQuery(window).trigger("fontresize", [em]);
2474
2475		}
2476
2477	};
2478
2479}(jQuery));
2480
2481
2482
2483/*! http://mths.be/placeholder v2.0.7 by @mathias */
2484
2485;(function(window, document, $) {
2486
2487
2488
2489	// Opera Mini v7 doesn’t support placeholder although its DOM seems to indicate so
2490
2491	var isOperaMini = Object.prototype.toString.call(window.operamini) == '[object OperaMini]';
2492
2493	var isInputSupported = 'placeholder' in document.createElement('input') && !isOperaMini;
2494
2495	var isTextareaSupported = 'placeholder' in document.createElement('textarea') && !isOperaMini;
2496
2497	var prototype = $.fn;
2498
2499	var valHooks = $.valHooks;
2500
2501	var propHooks = $.propHooks;
2502
2503	var hooks;
2504
2505	var placeholder;
2506
2507
2508
2509	if (isInputSupported && isTextareaSupported) {
2510
2511
2512
2513		placeholder = prototype.placeholder = function() {
2514
2515			return this;
2516
2517		};
2518
2519
2520
2521		placeholder.input = placeholder.textarea = true;
2522
2523
2524
2525	} else {
2526
2527
2528
2529		placeholder = prototype.placeholder = function() {
2530
2531			var $this = this;
2532
2533			$this
2534
2535				.filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]')
2536
2537				.not('.placeholder')
2538
2539				.bind({
2540
2541					'focus.placeholder': clearPlaceholder,
2542
2543					'blur.placeholder': setPlaceholder
2544
2545				})
2546
2547				.data('placeholder-enabled', true)
2548
2549				.trigger('blur.placeholder');
2550
2551			return $this;
2552
2553		};
2554
2555
2556
2557		placeholder.input = isInputSupported;
2558
2559		placeholder.textarea = isTextareaSupported;
2560
2561
2562
2563		hooks = {
2564
2565			'get': function(element) {
2566
2567				var $element = jQuery(element);
2568
2569
2570
2571				var $passwordInput = $element.data('placeholder-password');
2572
2573				if ($passwordInput) {
2574
2575					return $passwordInput[0].value;
2576
2577				}
2578
2579
2580
2581				return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value;
2582
2583			},
2584
2585			'set': function(element, value) {
2586
2587				var $element = jQuery(element);
2588
2589
2590
2591				var $passwordInput = $element.data('placeholder-password');
2592
2593				if ($passwordInput) {
2594
2595					return $passwordInput[0].value = value;
2596
2597				}
2598
2599
2600
2601				if (!$element.data('placeholder-enabled')) {
2602
2603					return element.value = value;
2604
2605				}
2606
2607				if (value == '') {
2608
2609					element.value = value;
2610
2611					// Issue #56: Setting the placeholder causes problems if the element continues to have focus.
2612
2613					if (element != safeActiveElement()) {
2614
2615						// We can't use `triggerHandler` here because of dummy text/password inputs :(
2616
2617						setPlaceholder.call(element);
2618
2619					}
2620
2621				} else if ($element.hasClass('placeholder')) {
2622
2623					clearPlaceholder.call(element, true, value) || (element.value = value);
2624
2625				} else {
2626
2627					element.value = value;
2628
2629				}
2630
2631				// `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363
2632
2633				return $element;
2634
2635			}
2636
2637		};
2638
2639
2640
2641		if (!isInputSupported) {
2642
2643			valHooks.input = hooks;
2644
2645			propHooks.value = hooks;
2646
2647		}
2648
2649		if (!isTextareaSupported) {
2650
2651			valHooks.textarea = hooks;
2652
2653			propHooks.value = hooks;
2654
2655		}
2656
2657
2658
2659		jQuery(function() {
2660
2661			// Look for forms
2662
2663			jQuery(document).delegate('form', 'submit.placeholder', function() {
2664
2665				// Clear the placeholder values so they don't get submitted
2666
2667				var $inputs = jQuery('.placeholder', this).each(clearPlaceholder);
2668
2669				setTimeout(function() {
2670
2671					$inputs.each(setPlaceholder);
2672
2673				}, 10);
2674
2675			});
2676
2677		});
2678
2679
2680
2681		// Clear placeholder values upon page reload
2682
2683		jQuery(window).bind('beforeunload.placeholder', function() {
2684
2685			jQuery('.placeholder').each(function() {
2686
2687				this.value = '';
2688
2689			});
2690
2691		});
2692
2693
2694
2695	}
2696
2697
2698
2699	function args(elem) {
2700
2701		// Return an object of element attributes
2702
2703		var newAttrs = {};
2704
2705		var rinlinejQuery = /^jQuery\d+$/;
2706
2707		$.each(elem.attributes, function(i, attr) {
2708
2709			if (attr.specified && !rinlinejQuery.test(attr.name)) {
2710
2711				newAttrs[attr.name] = attr.value;
2712
2713			}
2714
2715		});
2716
2717		return newAttrs;
2718
2719	}
2720
2721
2722
2723	function clearPlaceholder(event, value) {
2724
2725		var input = this;
2726
2727		var $input = jQuery(input);
2728
2729		if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) {
2730
2731			if ($input.data('placeholder-password')) {
2732
2733				$input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id'));
2734
2735				// If `clearPlaceholder` was called from `$.valHooks.input.set`
2736
2737				if (event === true) {
2738
2739					return $input[0].value = value;
2740
2741				}
2742
2743				$input.focus();
2744
2745			} else {
2746
2747				input.value = '';
2748
2749				$input.removeClass('placeholder');
2750
2751				input == safeActiveElement() && input.select();
2752
2753			}
2754
2755		}
2756
2757	}
2758
2759
2760
2761	function setPlaceholder() {
2762
2763		var $replacement;
2764
2765		var input = this;
2766
2767		var $input = jQuery(input);
2768
2769		var id = this.id;
2770
2771		if (input.value == '') {
2772
2773			if (input.type == 'password') {
2774
2775				if (!$input.data('placeholder-textinput')) {
2776
2777					try {
2778
2779						$replacement = $input.clone().attr({ 'type': 'text' });
2780
2781					} catch(e) {
2782
2783						$replacement = jQuery('<input>').attr($.extend(args(this), { 'type': 'text' }));
2784
2785					}
2786
2787					$replacement
2788
2789						.removeAttr('name')
2790
2791						.data({
2792
2793							'placeholder-password': $input,
2794
2795							'placeholder-id': id
2796
2797						})
2798
2799						.bind('focus.placeholder', clearPlaceholder);
2800
2801					$input
2802
2803						.data({
2804
2805							'placeholder-textinput': $replacement,
2806
2807							'placeholder-id': id
2808
2809						})
2810
2811						.before($replacement);
2812
2813				}
2814
2815				$input = $input.removeAttr('id').hide().prev().attr('id', id).show();
2816
2817				// Note: `$input[0] != input` now!
2818
2819			}
2820
2821			$input.addClass('placeholder');
2822
2823			$input[0].value = $input.attr('placeholder');
2824
2825		} else {
2826
2827			$input.removeClass('placeholder');
2828
2829		}
2830
2831	}
2832
2833
2834
2835	function safeActiveElement() {
2836
2837		// Avoid IE9 `document.activeElement` of death
2838
2839		// https://github.com/mathiasbynens/jquery-placeholder/pull/99
2840
2841		try {
2842
2843			return document.activeElement;
2844
2845		} catch (err) {}
2846
2847	}
2848
2849
2850
2851}(this, document, jQuery));
2852
2853
2854
2855/*
2856
2857 * JavaScript Custom Forms Module
2858
2859 */
2860
2861jcf = {
2862
2863	// global options
2864
2865	modules: {},
2866
2867	plugins: {},
2868
2869	baseOptions: {
2870
2871		unselectableClass:'jcf-unselectable',
2872
2873		labelActiveClass:'jcf-label-active',
2874
2875		labelDisabledClass:'jcf-label-disabled',
2876
2877		classPrefix: 'jcf-class-',
2878
2879		hiddenClass:'jcf-hidden',
2880
2881		focusClass:'jcf-focus',
2882
2883		wrapperTag: 'div'
2884
2885	},
2886
2887	// replacer function
2888
2889	customForms: {
2890
2891		setOptions: function(obj) {
2892
2893			for(var p in obj) {
2894
2895				if(obj.hasOwnProperty(p) && typeof obj[p] === 'object') {
2896
2897					jcf.lib.extend(jcf.modules[p].prototype.defaultOptions, obj[p]);
2898
2899				}
2900
2901			}
2902
2903		},
2904
2905		replaceAll: function(context) {
2906
2907			for(var k in jcf.modules) {
2908
2909				var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector, context);
2910
2911				for(var i = 0; i<els.length; i++) {
2912
2913					if(els[i].jcf) {
2914
2915						// refresh form element state
2916
2917						els[i].jcf.refreshState();
2918
2919					} else {
2920
2921						// replace form element
2922
2923						if(!jcf.lib.hasClass(els[i], 'default') && jcf.modules[k].prototype.checkElement(els[i])) {
2924
2925							new jcf.modules[k]({
2926
2927								replaces:els[i]
2928
2929							});
2930
2931						}
2932
2933					}
2934
2935				}
2936
2937			}
2938
2939		},
2940
2941		refreshAll: function(context) {
2942
2943			for(var k in jcf.modules) {
2944
2945				var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector, context);
2946
2947				for(var i = 0; i<els.length; i++) {
2948
2949					if(els[i].jcf) {
2950
2951						// refresh form element state
2952
2953						els[i].jcf.refreshState();
2954
2955					}
2956
2957				}
2958
2959			}
2960
2961		},
2962
2963		refreshElement: function(obj) {
2964
2965			if(obj && obj.jcf) {
2966
2967				obj.jcf.refreshState();
2968
2969			}
2970
2971		},
2972
2973		destroyAll: function() {
2974
2975			for(var k in jcf.modules) {
2976
2977				var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector);
2978
2979				for(var i = 0; i<els.length; i++) {
2980
2981					if(els[i].jcf) {
2982
2983						els[i].jcf.destroy();
2984
2985					}
2986
2987				}
2988
2989			}
2990
2991		}
2992
2993	},
2994
2995	// detect device type
2996
2997	isTouchDevice: ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch,
2998
2999	isWinPhoneDevice: navigator.msPointerEnabled && /MSIE 10.*Touch/.test(navigator.userAgent),
3000
3001	// define base module
3002
3003	setBaseModule: function(obj) {
3004
3005		jcf.customControl = function(opt){
3006
3007			this.options = jcf.lib.extend({}, jcf.baseOptions, this.defaultOptions, opt);
3008
3009			this.init();
3010
3011		};
3012
3013		for(var p in obj) {
3014
3015			jcf.customControl.prototype[p] = obj[p];
3016
3017		}
3018
3019	},
3020
3021	// add module to jcf.modules
3022
3023	addModule: function(obj) {
3024
3025		if(obj.name){
3026
3027			// create new module proto class
3028
3029			jcf.modules[obj.name] = function(){
3030
3031				jcf.modules[obj.name].superclass.constructor.apply(this, arguments);
3032
3033			}
3034
3035			jcf.lib.inherit(jcf.modules[obj.name], jcf.customControl);
3036
3037			for(var p in obj) {
3038
3039				jcf.modules[obj.name].prototype[p] = obj[p]
3040
3041			}
3042
3043			// on create module
3044
3045			jcf.modules[obj.name].prototype.onCreateModule();
3046
3047			// make callback for exciting modules
3048
3049			for(var mod in jcf.modules) {
3050
3051				if(jcf.modules[mod] != jcf.modules[obj.name]) {
3052
3053					jcf.modules[mod].prototype.onModuleAdded(jcf.modules[obj.name]);
3054
3055				}
3056
3057			}
3058
3059		}
3060
3061	},
3062
3063	// add plugin to jcf.plugins
3064
3065	addPlugin: function(obj) {
3066
3067		if(obj && obj.name) {
3068
3069			jcf.plugins[obj.name] = function() {
3070
3071				this.init.apply(this, arguments);
3072
3073			}
3074
3075			for(var p in obj) {
3076
3077				jcf.plugins[obj.name].prototype[p] = obj[p];
3078
3079			}
3080
3081		}
3082
3083	},
3084
3085	// miscellaneous init
3086
3087	init: function(){
3088
3089		if(navigator.pointerEnabled || navigator.msPointerEnabled) {
3090
3091			// use pointer events instead of mouse events
3092
3093			this.eventPress = navigator.pointerEnabled ? 'pointerdown' : 'MSPointerDown';
3094
3095			this.eventMove = navigator.pointerEnabled ? 'pointermove' : 'MSPointerMove';
3096
3097			this.eventRelease = navigator.pointerEnabled ? 'pointerup' : 'MSPointerUp';
3098
3099		} else {
3100
3101			// handle default desktop mouse events
3102
3103			this.eventPress = 'mousedown';
3104
3105			this.eventMove = 'mousemove';
3106
3107			this.eventRelease = 'mouseup';
3108
3109		}
3110
3111		if(this.isTouchDevice) {
3112
3113			// handle touch events also
3114
3115			this.eventPress += ' touchstart';
3116
3117			this.eventMove += ' touchmove';
3118
3119			this.eventRelease += ' touchend';
3120
3121		}
3122
3123
3124
3125		setTimeout(function(){
3126
3127			jcf.lib.domReady(function(){
3128
3129				jcf.initStyles();
3130
3131			});
3132
3133		},1);
3134
3135		return this;
3136
3137	},
3138
3139	initStyles: function() {
3140
3141		// create <style> element and rules
3142
3143		var head = document.getElementsByTagName('head')[0],
3144
3145			style = document.createElement('style'),
3146
3147			rules = document.createTextNode('.'+jcf.baseOptions.unselectableClass+'{'+
3148
3149				'-moz-user-select:none;'+
3150
3151				'-webkit-tap-highlight-color:rgba(255,255,255,0);'+
3152
3153				'-webkit-user-select:none;'+
3154
3155				'user-select:none;'+
3156
3157			'}');
3158
3159
3160
3161		// append style element
3162
3163		style.type = 'text/css';
3164
3165		if(style.styleSheet) {
3166
3167			style.styleSheet.cssText = rules.nodeValue;
3168
3169		} else {
3170
3171			style.appendChild(rules);
3172
3173		}
3174
3175		head.appendChild(style);
3176
3177	}
3178
3179}.init();
3180
3181
3182
3183/*
3184
3185 * Custom Form Control prototype
3186
3187 */
3188
3189jcf.setBaseModule({
3190
3191	init: function(){
3192
3193		if(this.options.replaces) {
3194
3195			this.realElement = this.options.replaces;
3196
3197			this.realElement.jcf = this;
3198
3199			this.replaceObject();
3200
3201		}
3202
3203	},
3204
3205	defaultOptions: {
3206
3207		// default module options (will be merged with base options)
3208
3209	},
3210
3211	checkElement: function(el){
3212
3213		return true;
3213 // additional check for correct form element
3214
3215	},
3216
3217	replaceObject: function(){
3218
3219		this.createWrapper();
3220
3221		this.attachEvents();
3222
3223		this.fixStyles();
3224
3225		this.setupWrapper();
3226
3227	},
3228
3229	createWrapper: function(){
3230
3231		this.fakeElement = jcf.lib.createElement(this.options.wrapperTag);
3232
3233		this.labelFor = jcf.lib.getLabelFor(this.realElement);
3234
3235		jcf.lib.disableTextSelection(this.fakeElement);
3236
3237		jcf.lib.addClass(this.fakeElement, jcf.lib.getAllClasses(this.realElement.className, this.options.classPrefix));
3238
3239		jcf.lib.addClass(this.realElement, jcf.baseOptions.hiddenClass);
3240
3241	},
3242
3243	attachEvents: function(){
3244
3245		jcf.lib.event.add(this.realElement, 'focus', this.onFocusHandler, this);
3246
3247		jcf.lib.event.add(this.realElement, 'blur', this.onBlurHandler, this);
3248
3249		jcf.lib.event.add(this.fakeElement, 'click', this.onFakeClick, this);
3250
3251		jcf.lib.event.add(this.fakeElement, jcf.eventPress, this.onFakePressed, this);
3252
3253		jcf.lib.event.add(this.fakeElement, jcf.eventRelease, this.onFakeReleased, this);
3254
3255
3256
3257		if(this.labelFor) {
3258
3259			this.labelFor.jcf = this;
3260
3261			jcf.lib.event.add(this.labelFor, 'click', this.onFakeClick, this);
3262
3263			jcf.lib.event.add(this.labelFor, jcf.eventPress, this.onFakePressed, this);
3264
3265			jcf.lib.event.add(this.labelFor, jcf.eventRelease, this.onFakeReleased, this);
3266
3267		}
3268
3269	},
3270
3271	fixStyles: function() {
3272
3273		// hide mobile webkit tap effect
3274
3275		if(jcf.isTouchDevice) {
3276
3277			var tapStyle = 'rgba(255,255,255,0)';
3278
3279			this.realElement.style.webkitTapHighlightColor = tapStyle;
3280
3281			this.fakeElement.style.webkitTapHighlightColor = tapStyle;
3282
3283			if(this.labelFor) {
3284
3285				this.labelFor.style.webkitTapHighlightColor = tapStyle;
3286
3287			}
3288
3289		}
3290
3291	},
3292
3293	setupWrapper: function(){
3294
3295		// implement in subclass
3296
3297	},
3298
3299	refreshState: function(){
3300
3301		// implement in subclass
3302
3303	},
3304
3305	destroy: function() {
3306
3307		if(this.fakeElement && this.fakeElement.parentNode) {
3308
3309			this.fakeElement.parentNode.insertBefore(this.realElement, this.fakeElement);
3310
3311			this.fakeElement.parentNode.removeChild(this.fakeElement);
3312
3313		}
3314
3315		jcf.lib.removeClass(this.realElement, jcf.baseOptions.hiddenClass);
3316
3317		this.realElement.jcf = null;
3318
3319	},
3320
3321	onFocus: function(){
3322
3323		// emulated focus event
3324
3325		jcf.lib.addClass(this.fakeElement,this.options.focusClass);
3326
3327	},
3328
3329	onBlur: function(cb){
3330
3331		// emulated blur event
3332
3333		jcf.lib.removeClass(this.fakeElement,this.options.focusClass);
3334
3335	},
3336
3337	onFocusHandler: function() {
3338
3339		// handle focus loses
3340
3341		if(this.focused) return;
3342
3343		this.focused = true;
3344
3345
3346
3347		// handle touch devices also
3348
3349		if(jcf.isTouchDevice) {
3350
3351			if(jcf.focusedInstance && jcf.focusedInstance.realElement != this.realElement) {
3352
3353				jcf.focusedInstance.onBlur();
3354
3355				jcf.focusedInstance.realElement.blur();
3356
3357			}
3358
3359			jcf.focusedInstance = this;
3360
3361		}
3362
3363		this.onFocus.apply(this, arguments);
3364
3365	},
3366
3367	onBlurHandler: function() {
3368
3369		// handle focus loses
3370
3371		if(!this.pressedFlag) {
3372
3373			this.focused = false;
3374
3375			this.onBlur.apply(this, arguments);
3376
3377		}
3378
3379	},
3380
3381	onFakeClick: function(){
3382
3383		if(jcf.isTouchDevice) {
3384
3385			this.onFocus();
3386
3387		} else if(!this.realElement.disabled) {
3388
3389			this.realElement.focus();
3390
3391		}
3392
3393	},
3394
3395	onFakePressed: function(e){
3396
3397		this.pressedFlag = true;
3398
3399	},
3400
3401	onFakeReleased: function(){
3402
3403		this.pressedFlag = false;
3404
3405	},
3406
3407	onCreateModule: function(){
3408
3409		// implement in subclass
3410
3411	},
3412
3413	onModuleAdded: function(module) {
3414
3415		// implement in subclass
3416
3417	},
3418
3419	onControlReady: function() {
3420
3421		// implement in subclass
3422
3423	}
3424
3425});
3426
3427
3428
3429/*
3430
3431 * JCF Utility Library
3432
3433 */
3434
3435jcf.lib = {
3436
3437	bind: function(func, scope){
3438
3439		return function() {
3440
3441			return func.apply(scope, arguments);
3442
3443		};
3444
3445	},
3446
3447	browser: (function() {
3448
3449		var ua = navigator.userAgent.toLowerCase(), res = {},
3450
3451		match = /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version)?[ \/]([\w.]+)/.exec(ua) ||
3452
3453				/(msie) ([\w.]+)/.exec(ua) || ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(ua) || [];
3454
3455		res[match[1]] = true;
3456
3457		res.version = match[2] || "0";
3458
3459		res.safariMac = ua.indexOf('mac') != -1 && ua.indexOf('safari') != -1;
3460
3461		return res;
3462
3463	})(),
3464
3465	getOffset: function (obj) {
3466
3467		if (obj.getBoundingClientRect && !jcf.isWinPhoneDevice) {
3468
3469			var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
3470
3471			var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
3472
3473			var clientLeft = document.documentElement.clientLeft || document.body.clientLeft || 0;
3474
3475			var clientTop = document.documentElement.clientTop || document.body.clientTop || 0;
3476
3477			return {
3478
3479				top:Math.round(obj.getBoundingClientRect().top + scrollTop - clientTop),
3480
3481				left:Math.round(obj.getBoundingClientRect().left + scrollLeft - clientLeft)
3482
3483			};
3484
3485		} else {
3486
3487			var posLeft = 0, posTop = 0;
3488
3489			while (obj.offsetParent) {posLeft += obj.offsetLeft; posTop += obj.offsetTop; obj = obj.offsetParent;}
3490
3491			return {top:posTop,left:posLeft};
3492
3493		}
3494
3495	},
3496
3497	getScrollTop: function() {
3498
3499		return window.pageYOffset || document.documentElement.scrollTop;
3500
3501	},
3502
3503	getScrollLeft: function() {
3504
3505		return window.pageXOffset || document.documentElement.scrollLeft;
3506
3507	},
3508
3509	getWindowWidth: function(){
3510
3511		return document.compatMode=='CSS1Compat' ? document.documentElement.clientWidth : document.body.clientWidth;
3512
3513	},
3514
3515	getWindowHeight: function(){
3516
3517		return document.compatMode=='CSS1Compat' ? document.documentElement.clientHeight : document.body.clientHeight;
3518
3519	},
3520
3521	getStyle: function(el, prop) {
3522
3523		if (document.defaultView && document.defaultView.getComputedStyle) {
3524
3525			return document.defaultView.getComputedStyle(el, null)[prop];
3526
3527		} else if (el.currentStyle) {
3528
3529			return el.currentStyle[prop];
3530
3531		} else {
3532
3533			return el.style[prop];
3534
3535		}
3536
3537	},
3538
3539	getParent: function(obj, selector) {
3540
3541		while(obj.parentNode && obj.parentNode != document.body) {
3542
3543			if(obj.parentNode.tagName.toLowerCase() == selector.toLowerCase()) {
3544
3545				return obj.parentNode;
3546
3547			}
3548
3549			obj = obj.parentNode;
3550
3551		}
3552
3553		return false;
3554
3555	},
3556
3557	isParent: function(parent, child) {
3558
3559		while(child.parentNode) {
3560
3561			if(child.parentNode === parent) {
3562
3563				return true;
3564
3565			}
3566
3567			child = child.parentNode;
3568
3569		}
3570
3571		return false;
3572
3573	},
3574
3575	getLabelFor: function(object) {
3576
3577		var parentLabel = jcf.lib.getParent(object,'label');
3578
3579		if(parentLabel) {
3580
3581			return parentLabel;
3582
3583		} else if(object.id) {
3584
3585			return jcf.lib.queryBySelector('label[for="' + object.id + '"]')[0];
3586
3587		}
3588
3589	},
3590
3591	disableTextSelection: function(el){
3592
3593		if (typeof el.onselectstart !== 'undefined') {
3594
3595			el.onselectstart = function() {return false;};
3596
3597		} else if(window.opera) {
3598
3599			el.setAttribute('unselectable', 'on');
3600
3601		} else {
3602
3603			jcf.lib.addClass(el, jcf.baseOptions.unselectableClass);
3604
3605		}
3606
3607	},
3608
3609	enableTextSelection: function(el) {
3610
3611		if (typeof el.onselectstart !== 'undefined') {
3612
3613			el.onselectstart = null;
3614
3615		} else if(window.opera) {
3616
3617			el.removeAttribute('unselectable');
3618
3619		} else {
3620
3621			jcf.lib.removeClass(el, jcf.baseOptions.unselectableClass);
3622
3623		}
3624
3625	},
3626
3627	queryBySelector: function(selector, scope){
3628
3629		if(typeof scope === 'string') {
3630
3631			var result = [];
3632
3633			var holders = this.getElementsBySelector(scope);
3634
3635			for (var i = 0, contextNodes; i < holders.length; i++) {
3636
3637				contextNodes = Array.prototype.slice.call(this.getElementsBySelector(selector, holders[i]));
3638
3639				result = result.concat(contextNodes);
3640
3641			}
3642
3643			return result;
3644
3645		} else {
3646
3647			return this.getElementsBySelector(selector, scope);
3648
3649		}
3650
3651	},
3652
3653	prevSibling: function(node) {
3654
3655		while(node = node.previousSibling) if(node.nodeType == 1) break;
3656
3657		return node;
3658
3659	},
3660
3661	nextSibling: function(node) {
3662
3663		while(node = node.nextSibling) if(node.nodeType == 1) break;
3664
3665		return node;
3666
3667	},
3668
3669	fireEvent: function(element,event) {
3670
3671		if(element.dispatchEvent){
3672
3673			var evt = document.createEvent('HTMLEvents');
3674
3675			evt.initEvent(event, true, true );
3676
3677			return !element.dispatchEvent(evt);
3678
3679		}else if(document.createEventObject){
3680
3681			var evt = document.createEventObject();
3682
3683			return element.fireEvent('on'+event,evt);
3684
3685		}
3686
3687	},
3688
3689	inherit: function(Child, Parent) {
3690
3691		var F = function() { }
3692
3693		F.prototype = Parent.prototype
3694
3695		Child.prototype = new F()
3696
3697		Child.prototype.constructor = Child
3698
3699		Child.superclass = Parent.prototype
3700
3701	},
3702
3703	extend: function(obj) {
3704
3705		for(var i = 1; i < arguments.length; i++) {
3706
3707			for(var p in arguments[i]) {
3708
3709				if(arguments[i].hasOwnProperty(p)) {
3710
3711					obj[p] = arguments[i][p];
3712
3713				}
3714
3715			}
3716
3717		}
3718
3719		return obj;
3720
3721	},
3722
3723	hasClass: function (obj,cname) {
3724
3725		return (obj.className ? obj.className.match(new RegExp('(\\s|^)'+cname+'(\\s|$)')) : false);
3726
3727	},
3728
3729	addClass: function (obj,cname) {
3730
3731		if (!this.hasClass(obj,cname)) obj.className += (!obj.className.length || obj.className.charAt(obj.className.length - 1) === ' ' ? '' : ' ') + cname;
3732
3733	},
3734
3735	removeClass: function (obj,cname) {
3736
3737		if (this.hasClass(obj,cname)) obj.className=obj.className.replace(new RegExp('(\\s|^)'+cname+'(\\s|$)'),' ').replace(/\s+$/, '');
3738
3739	},
3740
3741	toggleClass: function(obj, cname, condition) {
3742
3743		if(condition) this.addClass(obj, cname); else this.removeClass(obj, cname);
3744
3745	},
3746
3747	createElement: function(tagName, options) {
3748
3749		var el = document.createElement(tagName);
3750
3751		for(var p in options) {
3752
3753			if(options.hasOwnProperty(p)) {
3754
3755				switch (p) {
3756
3757					case 'class': el.className = options[p]; break;
3758
3759					case 'html': el.innerHTML = options[p]; break;
3760
3761					case 'style': this.setStyles(el, options[p]); break;
3762
3763					default: el.setAttribute(p, options[p]);
3764
3765				}
3766
3767			}
3768
3769		}
3770
3771		return el;
3772
3773	},
3774
3775	setStyles: function(el, styles) {
3776
3777		for(var p in styles) {
3778
3779			if(styles.hasOwnProperty(p)) {
3780
3781				switch (p) {
3782
3783					case 'float': el.style.cssFloat = styles[p]; break;
3784
3785					case 'opacity': el.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity='+styles[p]*100+')'; el.style.opacity = styles[p]; break;
3786
3787					default: el.style[p] = (typeof styles[p] === 'undefined' ? 0 : styles[p]) + (typeof styles[p] === 'number' ? 'px' : '');
3788
3789				}
3790
3791			}
3792
3793		}
3794
3795		return el;
3796
3797	},
3798
3799	getInnerWidth: function(el) {
3800
3801		return el.offsetWidth - (parseInt(this.getStyle(el,'paddingLeft')) || 0) - (parseInt(this.getStyle(el,'paddingRight')) || 0);
3802
3803	},
3804
3805	getInnerHeight: function(el) {
3806
3807		return el.offsetHeight - (parseInt(this.getStyle(el,'paddingTop')) || 0) - (parseInt(this.getStyle(el,'paddingBottom')) || 0);
3808
3809	},
3810
3811	getAllClasses: function(cname, prefix, skip) {
3812
3813		if(!skip) skip = '';
3814
3815		if(!prefix) prefix = '';
3816
3817		return cname ? cname.replace(new RegExp('(\\s|^)'+skip+'(\\s|$)'),' ').replace(/[\s]*([\S]+)+[\s]*/gi,prefix+"$1 ") : '';
3818
3819	},
3820
3821	getElementsBySelector: function(selector, scope) {
3822
3823		if(typeof document.querySelectorAll === 'function') {
3824
3825			return (scope || document).querySelectorAll(selector);
3826
3827		}
3828
3829		var selectors = selector.split(',');
3830
3831		var resultList = [];
3832
3833		for(var s = 0; s < selectors.length; s++) {
3834
3835			var currentContext = [scope || document];
3836
3837			var tokens = selectors[s].replace(/^\s+/,'').replace(/\s+$/,'').split(' ');
3838
3839			for (var i = 0; i < tokens.length; i++) {
3840
3841				token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');
3842
3843				if (token.indexOf('#') > -1) {
3844
3845					var bits = token.split('#'), tagName = bits[0], id = bits[1];
3846
3847					var element = document.getElementById(id);
3848
3849					if (tagName && element.nodeName.toLowerCase() != tagName) {
3850
3851						return [];
3852
3853					}
3854
3855					currentContext = [element];
3856
3857					continue;
3858
3859				}
3860
3861				if (token.indexOf('.') > -1) {
3862
3863					var bits = token.split('.'), tagName = bits[0] || '*', className = bits[1], found = [], foundCount = 0;
3864
3865					for (var h = 0; h < currentContext.length; h++) {
3866
3867						var elements;
3868
3869						if (tagName == '*') {
3870
3871							elements = currentContext[h].getElementsByTagName('*');
3872
3873						} else {
3874
3875							elements = currentContext[h].getElementsByTagName(tagName);
3876
3877						}
3878
3879						for (var j = 0; j < elements.length; j++) {
3880
3881							found[foundCount++] = elements[j];
3882
3883						}
3884
3885					}
3886
3887					currentContext = [];
3888
3889					var currentContextIndex = 0;
3890
3891					for (var k = 0; k < found.length; k++) {
3892
3893						if (found[k].className && found[k].className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'))) {
3894
3895							currentContext[currentContextIndex++] = found[k];
3896
3897						}
3898
3899					}
3900
3901					continue;
3902
3903				}
3904
3905				if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^"]*)"?\]$/)) {
3906
3907					var tagName = RegExp.$1 || '*', attrName = RegExp.$2, attrOperator = RegExp.$3, attrValue = RegExp.$4;
3908
3909					if(attrName.toLowerCase() == 'for' && this.browser.msie && this.browser.version < 8) {
3910
3911						attrName = 'htmlFor';
3912
3913					}
3914
3915					var found = [], foundCount = 0;
3916
3917					for (var h = 0; h < currentContext.length; h++) {
3918
3919						var elements;
3920
3921						if (tagName == '*') {
3922
3923							elements = currentContext[h].getElementsByTagName('*');
3924
3925						} else {
3926
3927							elements = currentContext[h].getElementsByTagName(tagName);
3928
3929						}
3930
3931						for (var j = 0; elements[j]; j++) {
3932
3933							found[foundCount++] = elements[j];
3934
3935						}
3936
3937					}
3938
3939					currentContext = [];
3940
3941					var currentContextIndex = 0, checkFunction;
3942
3943					switch (attrOperator) {
3944
3945						case '=': checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue) }; break;
3946
3947						case '~': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('(\\s|^)'+attrValue+'(\\s|$)'))) }; break;
3948
3949						case '|': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))) }; break;
3950
3951						case '^': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0) }; break;
3952
3953						case '$': checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length) }; break;
3954
3955						case '*': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1) }; break;
3956
3957						default : checkFunction = function(e) { return e.getAttribute(attrName) };
3958
3959					}
3960
3961					currentContext = [];
3962
3963					var currentContextIndex = 0;
3964
3965					for (var k = 0; k < found.length; k++) {
3966
3967						if (checkFunction(found[k])) {
3968
3969							currentContext[currentContextIndex++] = found[k];
3970
3971						}
3972
3973					}
3974
3975					continue;
3976
3977				}
3978
3979				tagName = token;
3980
3981				var found = [], foundCount = 0;
3982
3983				for (var h = 0; h < currentContext.length; h++) {
3984
3985					var elements = currentContext[h].getElementsByTagName(tagName);
3986
3987					for (var j = 0; j < elements.length; j++) {
3988
3989						found[foundCount++] = elements[j];
3990
3991					}
3992
3993				}
3994
3995				currentContext = found;
3996
3997			}
3998
3999			resultList = [].concat(resultList,currentContext);
4000
4001		}
4002
4003		return resultList;
4004
4005	},
4006
4007	scrollSize: (function(){
4008
4009		var content, hold, sizeBefore, sizeAfter;
4010
4011		function buildSizer(){
4012
4013			if(hold) removeSizer();
4014
4015			content = document.createElement('div');
4016
4017			hold = document.createElement('div');
4018
4019			hold.style.cssText = 'position:absolute;overflow:hidden;width:100px;height:100px';
4020
4021			hold.appendChild(content);
4022
4023			document.body.appendChild(hold);
4024
4025		}
4026
4027		function removeSizer(){
4028
4029			document.body.removeChild(hold);
4030
4031			hold = null;
4032
4033		}
4034
4035		function calcSize(vertical) {
4036
4037			buildSizer();
4038
4039			content.style.cssText = 'height:'+(vertical ? '100%' : '200px');
4040
4041			sizeBefore = (vertical ? content.offsetHeight : content.offsetWidth);
4042
4043			hold.style.overflow = 'scroll'; content.innerHTML = 1;
4044
4045			sizeAfter = (vertical ? content.offsetHeight : content.offsetWidth);
4046
4047			if(vertical && hold.clientHeight) sizeAfter = hold.clientHeight;
4048
4049			removeSizer();
4050
4051			return sizeBefore - sizeAfter;
4052
4053		}
4054
4055		return {
4056
4057			getWidth:function(){
4058
4059				return calcSize(false);
4060
4061			},
4062
4063			getHeight:function(){
4064
4065				return calcSize(true)
4066
4067			}
4068
4069		}
4070
4071	}()),
4072
4073	domReady: function (handler){
4074
4075		var called = false
4076
4077		function ready() {
4078
4079			if (called) return;
4080
4081			called = true;
4082
4083			handler();
4084
4085		}
4086
4087		if (document.addEventListener) {
4088
4089			document.addEventListener("DOMContentLoaded", ready, false);
4090
4091		} else if (document.attachEvent) {
4092
4093			if (document.documentElement.doScroll && window == window.top) {
4094
4095				function tryScroll(){
4096
4097					if (called) return
4098
4099					if (!document.body) return
4100
4101					try {
4102
4103						document.documentElement.doScroll("left")
4104
4105						ready()
4106
4107					} catch(e) {
4108
4109						setTimeout(tryScroll, 0)
4110
4111					}
4112
4113				}
4114
4115				tryScroll()
4116
4117			}
4118
4119			document.attachEvent("onreadystatechange", function(){
4120
4121				if (document.readyState === "complete") {
4122
4123					ready()
4124
4125				}
4126
4127			})
4128
4129		}
4130
4131		if (window.addEventListener) window.addEventListener('load', ready, false)
4132
4133		else if (window.attachEvent) window.attachEvent('onload', ready)
4134
4135	},
4136
4137	event: (function(){
4138
4139		var guid = 0;
4140
4141		function fixEvent(e) {
4142
4143			e = e || window.event;
4144
4145			if (e.isFixed) {
4146
4147				return e;
4148
4149			}
4150
4151			e.isFixed = true; 
4152
4153			e.preventDefault = e.preventDefault || function(){this.returnValue = false}
4154
4155			e.stopPropagation = e.stopPropagation || function(){this.cancelBubble = true}
4156
4157			if (!e.target) {
4158
4159				e.target = e.srcElement
4160
4161			}
4162
4163			if (!e.relatedTarget && e.fromElement) {
4164
4165				e.relatedTarget = e.fromElement == e.target ? e.toElement : e.fromElement;
4166
4167			}
4168
4169			if (e.pageX == null && e.clientX != null) {
4170
4171				var html = document.documentElement, body = document.body;
4172
4173				e.pageX = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0);
4174
4175				e.pageY = e.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0);
4176
4177			}
4178
4179			if (!e.which && e.button) {
4180
4181				e.which = e.button & 1 ? 1 : (e.button & 2 ? 3 : (e.button & 4 ? 2 : 0));
4182
4183			}
4184
4185			if(e.type === "DOMMouseScroll" || e.type === 'mousewheel') {
4186
4187				e.mWheelDelta = 0;
4188
4189				if (e.wheelDelta) {
4190
4191					e.mWheelDelta = e.wheelDelta/120;
4192
4193				} else if (e.detail) {
4194
4195					e.mWheelDelta = -e.detail/3;
4196
4197				}
4198
4199			}
4200
4201			return e;
4202
4203		}
4204
4205		function commonHandle(event, customScope) {
4206
4207			event = fixEvent(event);
4208
4209			var handlers = this.events[event.type];
4210
4211			for (var g in handlers) {
4212
4213				var handler = handlers[g];
4214
4215				var ret = handler.call(customScope || this, event);
4216
4217				if (ret === false) {
4218
4219					event.preventDefault()
4220
4221					event.stopPropagation()
4222
4223				}
4224
4225			}
4226
4227		}
4228
4229		var publicAPI = {
4230
4231			add: function(elem, type, handler, forcedScope) {
4232
4233				// handle multiple events
4234
4235				if(type.indexOf(' ') > -1) {
4236
4237					var eventList = type.split(' ');
4238
4239					for(var i = 0; i < eventList.length; i++) {
4240
4241						publicAPI.add(elem, eventList[i], handler, forcedScope);
4242
4243					}
4244
4245					return;
4246
4247				}
4248
4249
4250
4251				if (elem.setInterval && (elem != window && !elem.frameElement)) {
4252
4253					elem = window;
4254
4255				}
4256
4257				if (!handler.guid) {
4258
4259					handler.guid = ++guid;
4260
4261				}
4262
4263				if (!elem.events) {
4264
4265					elem.events = {};
4266
4267					elem.handle = function(event) {
4268
4269						return commonHandle.call(elem, event);
4270
4271					}
4272
4273				}
4274
4275				if (!elem.events[type]) {
4276
4277					elem.events[type] = {};
4278
4279					if (elem.addEventListener) elem.addEventListener(type, elem.handle, false);
4280
4281					else if (elem.attachEvent) elem.attachEvent("on" + type, elem.handle);
4282
4283					if(type === 'mousewheel') {
4284
4285						publicAPI.add(elem, 'DOMMouseScroll', handler, forcedScope);
4286
4287					}
4288
4289				}
4290
4291				var fakeHandler = jcf.lib.bind(handler, forcedScope);
4292
4293				fakeHandler.guid = handler.guid;
4294
4295				elem.events[type][handler.guid] = forcedScope ? fakeHandler : handler;
4296
4297			},
4298
4299			remove: function(elem, type, handler) {
4300
4301				// handle multiple events
4302
4303				if(type.indexOf(' ') > -1) {
4304
4305					var eventList = type.split(' ');
4306
4307					for(var i = 0; i < eventList.length; i++) {
4308
4309						publicAPI.remove(elem, eventList[i], handler);
4310
4311					}
4312
4313					return;
4314
4315				}
4316
4317
4318
4319				var handlers = elem.events && elem.events[type];
4320
4321				if (!handlers) return;
4322
4323				delete handlers[handler.guid];
4324
4325				for(var any in handlers) return;
4326
4327				if (elem.removeEventListener) elem.removeEventListener(type, elem.handle, false);
4328
4329				else if (elem.detachEvent) elem.detachEvent("on" + type, elem.handle);
4330
4331				delete elem.events[type];
4332
4333				for (var any in elem.events) return;
4334
4335				try {
4336
4337					delete elem.handle;
4338
4339					delete elem.events;
4340
4341				} catch(e) {
4342
4343					if(elem.removeAttribute) {
4344
4345						elem.removeAttribute("handle");
4346
4347						elem.removeAttribute("events");
4348
4349					}
4350
4351				}
4352
4353				if(type === 'mousewheel') {
4354
4355					publicAPI.remove(elem, 'DOMMouseScroll', handler);
4356
4357				}
4358
4359			}
4360
4361		}
4362
4363		return publicAPI;
4364
4365	}())
4366
4367}
4368
4369
4370
4371// custom select module
4372
4373jcf.addModule({
4374
4375	name:'select',
4376
4377	selector:'select',
4378
4379	defaultOptions: {
4380
4381		useNativeDropOnMobileDevices: true,
4382
4383		hideDropOnScroll: true,
4384
4385		showNativeDrop: false,
4386
4387		handleDropPosition: false,
4388
4389		selectDropPosition: 'bottom', // or 'top'
4390
4391		wrapperClass:'select-area',
4392
4393		focusClass:'select-focus',
4394
4395		dropActiveClass:'select-active',
4396
4397		selectedClass:'item-selected',
4398
4399		currentSelectedClass:'current-selected',
4400
4401		disabledClass:'select-disabled',
4402
4403		valueSelector:'span.center', 
4404
4405		optGroupClass:'optgroup',
4406
4407		openerSelector:'a.select-opener',		
4408
4409		selectStructure:'<span class="left"></span><span class="center"></span><a class="select-opener"></a>',
4410
4411		wrapperTag: 'span',
4412
4413		classPrefix:'select-',
4414
4415		dropMaxHeight: 300,
4416
4417		dropFlippedClass: 'select-options-flipped',
4418
4419		dropHiddenClass:'options-hidden',
4420
4421		dropScrollableClass:'options-overflow',
4422
4423		dropClass:'select-options',
4424
4425		dropClassPrefix:'drop-',
4426
4427		dropStructure:'<div class="drop-holder"><div class="drop-list"></div></div>',
4428
4429		dropSelector:'div.drop-list'
4430
4431	},
4432
4433	checkElement: function(el){
4434
4435		return (!el.size && !el.multiple);
4436
4437	},
4438
4439	setupWrapper: function(){
4440
4441		jcf.lib.addClass(this.fakeElement, this.options.wrapperClass);
4442
4443		this.realElement.parentNode.insertBefore(this.fakeElement, this.realElement.nextSibling);
4444
4445		this.fakeElement.innerHTML = this.options.selectStructure;
4446
4447		this.fakeElement.style.width = (this.realElement.offsetWidth > 0 ? this.realElement.offsetWidth + 'px' : 'auto');
4448
4449
4450
4451		// show native drop if specified in options
4452
4453		if(this.options.useNativeDropOnMobileDevices && (jcf.isTouchDevice || jcf.isWinPhoneDevice)) {
4454
4455			this.options.showNativeDrop = true;
4456
4457		}
4458
4459		if(this.options.showNativeDrop) {
4460
4461			this.fakeElement.appendChild(this.realElement);
4462
4463			jcf.lib.removeClass(this.realElement, this.options.hiddenClass);
4464
4465			jcf.lib.setStyles(this.realElement, {
4466
4467				top:0,
4468
4469				left:0,
4470
4471				margin:0,
4472
4473				padding:0,
4474
4475				opacity:0,
4476
4477				border:'none',
4478
4479				position:'absolute',
4480
4481				width: jcf.lib.getInnerWidth(this.fakeElement) - 1,
4482
4483				height: jcf.lib.getInnerHeight(this.fakeElement) - 1
4484
4485			});
4486
4487			jcf.lib.event.add(this.realElement, jcf.eventPress, function(){
4488
4489				this.realElement.title = '';
4490
4491			}, this)
4492
4493		}
4494
4495		
4496
4497		// create select body
4498
4499		this.opener = jcf.lib.queryBySelector(this.options.openerSelector, this.fakeElement)[0];
4500
4501		this.valueText = jcf.lib.queryBySelector(this.options.valueSelector, this.fakeElement)[0];
4502
4503		jcf.lib.disableTextSelection(this.valueText);
4504
4505		this.opener.jcf = this;
4506
4507
4508
4509		if(!this.options.showNativeDrop) {
4510
4511			this.createDropdown();
4512
4513			this.refreshState();
4514
4515			this.onControlReady(this);
4516
4517			this.hideDropdown();
4518
4519		} else {
4520
4521			this.refreshState();
4522
4523		}
4524
4525		this.addEvents();
4526
4527	},
4528
4529	addEvents: function(){
4530
4531		if(this.options.showNativeDrop) {
4532
4533			jcf.lib.event.add(this.realElement, 'click', this.onChange, this);
4534
4535		} else {
4536
4537			jcf.lib.event.add(this.fakeElement, 'click', this.toggleDropdown, this);
4538
4539		}
4540
4541		jcf.lib.event.add(this.realElement, 'change', this.onChange, this);
4542
4543	},
4544
4545	onFakeClick: function() {
4546
4547		// do nothing (drop toggles by toggleDropdown method)
4548
4549	},
4550
4551	onFocus: function(){
4552
4553		jcf.modules[this.name].superclass.onFocus.apply(this, arguments);
4554
4555		if(!this.options.showNativeDrop) {
4556
4557			// Mac Safari Fix
4558
4559			if(jcf.lib.browser.safariMac) {
4560
4561				this.realElement.setAttribute('size','2');
4562
4563			}
4564
4565			jcf.lib.event.add(this.realElement, 'keydown', this.onKeyDown, this);
4566
4567			if(jcf.activeControl && jcf.activeControl != this) {
4568
4569				jcf.activeControl.hideDropdown();
4570
4571				jcf.activeControl = this;
4572
4573			}
4574
4575		}
4576
4577	},
4578
4579	onBlur: function(){
4580
4581		if(!this.options.showNativeDrop) {
4582
4583			// Mac Safari Fix
4584
4585			if(jcf.lib.browser.safariMac) {
4586
4587				this.realElement.removeAttribute('size');
4588
4589			}
4590
4591			if(!this.isActiveDrop() || !this.isOverDrop()) {
4592
4593				jcf.modules[this.name].superclass.onBlur.apply(this);
4594
4595				if(jcf.activeControl === this) jcf.activeControl = null;
4596
4597				if(!jcf.isTouchDevice) {
4598
4599					this.hideDropdown();
4600
4601				}
4602
4603			}
4604
4605			jcf.lib.event.remove(this.realElement, 'keydown', this.onKeyDown);
4606
4607		} else {
4608
4609			jcf.modules[this.name].superclass.onBlur.apply(this);
4610
4611		}
4612
4613	},
4614
4615	onChange: function() {
4616
4617		this.refreshState();
4618
4619	},
4620
4621	onKeyDown: function(e){
4622
4623		this.dropOpened = true;
4624
4625		jcf.tmpFlag = true;
4626
4627		setTimeout(function(){jcf.tmpFlag = false},100);
4628
4629		var context = this;
4630
4631		context.keyboardFix = true;
4632
4633		setTimeout(function(){
4634
4635			context.refreshState();
4636
4637		},10);
4638
4639		if(e.keyCode == 13) {
4640
4641			context.toggleDropdown.apply(context);
4642
4643			return false;
4644
4645		}
4646
4647	},
4648
4649	onResizeWindow: function(e){
4650
4651		if(this.isActiveDrop()) {
4652
4653			this.hideDropdown();
4654
4655		}
4656
4657	},
4658
4659	onScrollWindow: function(e){
4660
4661		if(this.options.hideDropOnScroll) {
4662
4663			this.hideDropdown();
4664
4665		} else if(this.isActiveDrop()) {
4666
4667			this.positionDropdown();
4668
4669		}
4670
4671	},
4672
4673	onOptionClick: function(e){
4674
4675		var opener = e.target && e.target.tagName && e.target.tagName.toLowerCase() == 'li' ? e.target : jcf.lib.getParent(e.target, 'li');
4676
4677		if(opener && !jcf.lib.hasClass(opener, 'opt-disabled')) {
4678
4679			this.dropOpened = true;
4680
4681			this.realElement.selectedIndex = parseInt(opener.getAttribute('rel'));
4682
4683			if(jcf.isTouchDevice) {
4684
4685				this.onFocus();
4686
4687			} else {
4688
4689				this.realElement.focus();
4690
4691			}
4692
4693			this.refreshState();
4694
4695			this.hideDropdown();
4696
4697			jcf.lib.fireEvent(this.realElement, 'change');
4698
4699		}
4700
4701		return false;
4702
4703	},
4704
4705	onClickOutside: function(e){
4706
4707		if(jcf.tmpFlag) {
4708
4709			jcf.tmpFlag = false;
4710
4711			return;
4712
4713		}
4714
4715		if(!jcf.lib.isParent(this.fakeElement, e.target) && !jcf.lib.isParent(this.selectDrop, e.target)) {
4716
4717			this.hideDropdown();
4718
4719		}
4720
4721	},
4722
4723	onDropHover: function(e){
4724
4725		if(!this.keyboardFix) {
4726
4727			this.hoverFlag = true;
4728
4729			var opener = e.target && e.target.tagName && e.target.tagName.toLowerCase() == 'li' ? e.target : jcf.lib.getParent(e.target, 'li');
4730
4731			if(opener) {
4732
4733				this.realElement.selectedIndex = parseInt(opener.getAttribute('rel'));
4734
4735				this.refreshSelectedClass(parseInt(opener.getAttribute('rel')));
4736
4737			}
4738
4739		} else {
4740
4741			this.keyboardFix = false;
4742
4743		}
4744
4745	},
4746
4747	onDropLeave: function(){
4748
4749		this.hoverFlag = false;
4750
4751	},
4752
4753	isActiveDrop: function(){
4754
4755		return !jcf.lib.hasClass(this.selectDrop, this.options.dropHiddenClass);
4756
4757	},
4758
4759	isOverDrop: function(){
4760
4761		return this.hoverFlag;
4762
4763	},
4764
4765	createDropdown: function(){
4766
4767		// remove old dropdown if exists
4768
4769		if(this.selectDrop && this.selectDrop.parentNode) {
4770
4771			this.selectDrop.parentNode.removeChild(this.selectDrop);
4772
4773		}
4774
4775
4776
4777		// create dropdown holder
4778
4779		this.selectDrop = document.createElement('div');
4780
4781		this.selectDrop.className = this.options.dropClass;
4782
4783		this.selectDrop.innerHTML = this.options.dropStructure;
4784
4785		jcf.lib.setStyles(this.selectDrop, {position:'absolute'});
4786
4787		this.selectList = jcf.lib.queryBySelector(this.options.dropSelector,this.selectDrop)[0];
4788
4789		jcf.lib.addClass(this.selectDrop, this.options.dropHiddenClass);
4790
4791		document.body.appendChild(this.selectDrop);
4792
4793		this.selectDrop.jcf = this;
4794
4795		jcf.lib.event.add(this.selectDrop, 'click', this.onOptionClick, this);
4796
4797		jcf.lib.event.add(this.selectDrop, 'mouseover', this.onDropHover, this);
4798
4799		jcf.lib.event.add(this.selectDrop, 'mouseout', this.onDropLeave, this);
4800
4801		this.buildDropdown();
4802
4803	},
4804
4805	buildDropdown: function() {
4806
4807		// build select options / optgroups
4808
4809		this.buildDropdownOptions();
4810
4811
4812
4813		// position and resize dropdown
4814
4815		this.positionDropdown();
4816
4817
4818
4819		// cut dropdown if height exceedes
4820
4821		this.buildDropdownScroll();
4822
4823	},
4824
4825	buildDropdownOptions: function() {
4826
4827		this.resStructure = '';
4828
4829		this.optNum = 0;
4830
4831		for(var i = 0; i < this.realElement.children.length; i++) {
4832
4833			this.resStructure += this.buildElement(this.realElement.children[i], i) +'\n';
4834
4835		}
4836
4837		this.selectList.innerHTML = this.resStructure;
4838
4839	},
4840
4841	buildDropdownScroll: function() {
4842
4843		jcf.lib.addClass(this.selectDrop, jcf.lib.getAllClasses(this.realElement.className, this.options.dropClassPrefix, jcf.baseOptions.hiddenClass));
4844
4845		if(this.options.dropMaxHeight) {
4846
4847			if(this.selectDrop.offsetHeight > this.options.dropMaxHeight) {
4848
4849				this.selectList.style.height = this.options.dropMaxHeight+'px';
4850
4851				this.selectList.style.overflow = 'auto';
4852
4853				this.selectList.style.overflowX = 'hidden';
4854
4855				jcf.lib.addClass(this.selectDrop, this.options.dropScrollableClass);
4856
4857			}
4858
4859		}
4860
4861	},
4862
4863	parseOptionTitle: function(optTitle) {
4864
4865		return (typeof optTitle === 'string' && /\.(jpg|gif|png|bmp|jpeg)(.*)?$/i.test(optTitle)) ? optTitle : '';
4866
4867	},
4868
4869	buildElement: function(obj, index){
4870
4871		// build option
4872
4873		var res = '', optImage;
4874
4875		if(obj.tagName.toLowerCase() == 'option') {
4876
4877			if(!jcf.lib.prevSibling(obj) || jcf.lib.prevSibling(obj).tagName.toLowerCase() != 'option') {
4878
4879				res += '<ul>';
4880
4881			}
4882
4883			
4884
4885			optImage = this.parseOptionTitle(obj.title);
4886
4887			res += '<li rel="'+(this.optNum++)+'" class="'+(obj.className? obj.className + ' ' : '')+(obj.disabled? 'opt-disabled ' : '')+(index % 2 ? 'option-even ' : '')+'jcfcalc"><a href="#">'+(optImage ? '<img src="'+optImage+'" alt="" />' : '')+'<span>' + obj.innerHTML + '</span></a></li>';
4888
4889			if(!jcf.lib.nextSibling(obj) || jcf.lib.nextSibling(obj).tagName.toLowerCase() != 'option') {
4890
4891				res += '</ul>';
4892
4893			}
4894
4895			return res;
4896
4897		}
4898
4899		// build option group with options
4900
4901		else if(obj.tagName.toLowerCase() == 'optgroup' && obj.label) {
4902
4903			res += '<div class="'+this.options.optGroupClass+'">';
4904
4905			res += '<strong class="jcfcalc"><em>'+(obj.label)+'</em></strong>';
4906
4907			for(var i = 0; i < obj.children.length; i++) {
4908
4909				res += this.buildElement(obj.children[i], i);
4910
4911			}
4912
4913			res += '</div>';
4914
4915			return res;
4916
4917		}
4918
4919	},
4920
4921	positionDropdown: function(){
4922
4923		var ofs = jcf.lib.getOffset(this.fakeElement), selectAreaHeight = this.fakeElement.offsetHeight, selectDropHeight = this.selectDrop.offsetHeight;
4924
4925		var fitInTop = ofs.top - selectDropHeight >= jcf.lib.getScrollTop() && jcf.lib.getScrollTop() + jcf.lib.getWindowHeight() < ofs.top + selectAreaHeight + selectDropHeight;
4926
4927		
4928
4929		
4930
4931		if((this.options.handleDropPosition && fitInTop) || this.options.selectDropPosition === 'top') {
4932
4933			this.selectDrop.style.top = (ofs.top - selectDropHeight)+'px';
4934
4935			jcf.lib.addClass(this.selectDrop, this.options.dropFlippedClass);
4936
4937			jcf.lib.addClass(this.fakeElement, this.options.dropFlippedClass);
4938
4939		} else {
4940
4941			this.selectDrop.style.top = (ofs.top + selectAreaHeight)+'px';
4942
4943			jcf.lib.removeClass(this.selectDrop, this.options.dropFlippedClass);
4944
4945			jcf.lib.removeClass(this.fakeElement, this.options.dropFlippedClass);
4946
4947		}
4948
4949		this.selectDrop.style.left = ofs.left+'px';
4950
4951		this.selectDrop.style.width = this.fakeElement.offsetWidth+'px';
4952
4953	},
4954
4955	showDropdown: function(){
4956
4957		document.body.appendChild(this.selectDrop);
4958
4959		jcf.lib.removeClass(this.selectDrop, this.options.dropHiddenClass);
4960
4961		jcf.lib.addClass(this.fakeElement,this.options.dropActiveClass);
4962
4963		this.positionDropdown();
4964
4965
4966
4967		// highlight current active item
4968
4969		var activeItem = this.getFakeActiveOption();
4970
4971		this.removeClassFromItems(this.options.currentSelectedClass);
4972
4973		jcf.lib.addClass(activeItem, this.options.currentSelectedClass);
4974
4975		
4976
4977		// show current dropdown
4978
4979		jcf.lib.event.add(window, 'resize', this.onResizeWindow, this);
4980
4981		jcf.lib.event.add(window, 'scroll', this.onScrollWindow, this);
4982
4983		jcf.lib.event.add(document, jcf.eventPress, this.onClickOutside, this);
4984
4985		this.positionDropdown();
4986
4987	},
4988
4989	hideDropdown: function(){
4990
4991		if(this.selectDrop.parentNode) {
4992
4993			this.selectDrop.parentNode.removeChild(this.selectDrop);
4994
4995		}
4996
4997		if(typeof this.origSelectedIndex === 'number') {
4998
4999			this.realElement.selectedIndex = this.origSelectedIndex;
5000
5001		}
5002
5003		jcf.lib.removeClass(this.fakeElement,this.options.dropActiveClass);
5004
5005		jcf.lib.addClass(this.selectDrop, this.options.dropHiddenClass);
5006
5007		jcf.lib.event.remove(window, 'resize', this.onResizeWindow);
5008
5009		jcf.lib.event.remove(window, 'scroll', this.onScrollWindow);
5010
5011		jcf.lib.event.remove(document.documentElement, jcf.eventPress, this.onClickOutside);
5012
5013		if(jcf.isTouchDevice) {
5014
5015			this.onBlur();
5016
5017		}
5018
5019	},
5020
5021	toggleDropdown: function(){
5022
5023		if(!this.realElement.disabled && this.realElement.options.length) {
5024
5025			if(jcf.isTouchDevice) {
5026
5027				this.onFocus();
5028
5029			} else {
5030
5031				this.realElement.focus();
5032
5033			}
5034
5035			if(this.isActiveDrop()) {
5036
5037				this.hideDropdown();
5038
5039			} else {
5040
5041				this.showDropdown();
5042
5043			}
5044
5045			this.refreshState();
5046
5047		}
5048
5049	},
5050
5051	scrollToItem: function(){
5052
5053		if(this.isActiveDrop()) {
5054
5055			var dropHeight = this.selectList.offsetHeight;
5056
5057			var offsetTop = this.calcOptionOffset(this.getFakeActiveOption());
5058
5059			var sTop = this.selectList.scrollTop;
5060
5061			var oHeight = this.getFakeActiveOption().offsetHeight;
5062
5063			//offsetTop+=sTop;
5064
5065
5066
5067			if(offsetTop >= sTop + dropHeight) {
5068
5069				this.selectList.scrollTop = offsetTop - dropHeight + oHeight;
5070
5071			} else if(offsetTop < sTop) {
5072
5073				this.selectList.scrollTop = offsetTop;
5074
5075			}
5076
5077		}
5078
5079	},
5080
5081	getFakeActiveOption: function(c) {
5082
5083		return jcf.lib.queryBySelector('li[rel="'+(typeof c === 'number' ? c : this.realElement.selectedIndex) +'"]',this.selectList)[0];
5084
5085	},
5086
5087	calcOptionOffset: function(fake) {
5088
5089		var h = 0;
5090
5091		var els = jcf.lib.queryBySelector('.jcfcalc',this.selectList);
5092
5093		for(var i = 0; i < els.length; i++) {
5094
5095			if(els[i] == fake) break;
5096
5097			h+=els[i].offsetHeight;
5098
5099		}
5100
5101		return h;
5102
5103	},
5104
5105	childrenHasItem: function(hold,item) {
5106
5107		var items = hold.getElementsByTagName('*');
5108
5109		for(i = 0; i < items.length; i++) {
5110
5111			if(items[i] == item) return true;
5112
5113		}
5114
5115		return false;
5116
5117	},
5118
5119	removeClassFromItems: function(className){
5120
5121		var children = jcf.lib.queryBySelector('li',this.selectList);
5122
5123		for(var i = children.length - 1; i >= 0; i--) {
5124
5125			jcf.lib.removeClass(children[i], className);
5126
5127		}
5128
5129	},
5130
5131	setSelectedClass: function(c){
5132
5133		var activeOption = this.getFakeActiveOption(c);
5134
5135		if(activeOption) {
5136
5137			jcf.lib.addClass(activeOption, this.options.selectedClass);
5138
5139		}
5140
5141	},
5142
5143	refreshSelectedClass: function(c){
5144
5145		if(!this.options.showNativeDrop) {
5146
5147			this.removeClassFromItems(this.options.selectedClass);
5148
5149			this.setSelectedClass(c);
5150
5151		}
5152
5153		if(this.realElement.disabled) {
5154
5155			jcf.lib.addClass(this.fakeElement, this.options.disabledClass);
5156
5157			if(this.labelFor) {
5158
5159				jcf.lib.addClass(this.labelFor, this.options.labelDisabledClass);
5160
5161			}
5162
5163		} else {
5164
5165			jcf.lib.removeClass(this.fakeElement, this.options.disabledClass);
5166
5167			if(this.labelFor) {
5168
5169				jcf.lib.removeClass(this.labelFor, this.options.labelDisabledClass);
5170
5171			}
5172
5173		}
5174
5175	},
5176
5177	refreshSelectedText: function() {
5178
5179		if(!this.dropOpened && this.realElement.title) {
5180
5181			this.valueText.innerHTML = this.realElement.title;
5182
5183		} else {
5184
5185			var activeOption = this.realElement.options[this.realElement.selectedIndex];
5186
5187			if(activeOption) {
5188
5189				if(activeOption.title) {
5190
5191					var optImage = this.parseOptionTitle(this.realElement.options[this.realElement.selectedIndex].title);
5192
5193					this.valueText.innerHTML = (optImage ? '<img src="'+optImage+'" alt="" />' : '') + this.realElement.options[this.realElement.selectedIndex].innerHTML;
5194
5195				} else {
5196
5197					this.valueText.innerHTML = this.realElement.options[this.realElement.selectedIndex].innerHTML;
5198
5199				}
5200
5201			}
5202
5203		}
5204
5205
5206
5207		var selectedOption = this.realElement.options[this.realElement.selectedIndex];
5208
5209		if(selectedOption && selectedOption.className) {
5210
5211			this.fakeElement.setAttribute('data-option-class', jcf.lib.getAllClasses(selectedOption.className, 'option-').replace(/^\s+|\s+$/g, ''));
5212
5213		} else {
5214
5215			this.fakeElement.removeAttribute('data-option-class');
5216
5217		}
5218
5219	},
5220
5221	refreshState: function(){
5222
5223		this.origSelectedIndex = this.realElement.selectedIndex;
5224
5225		this.refreshSelectedClass();
5226
5227		this.refreshSelectedText();
5228
5229		if(!this.options.showNativeDrop) {
5230
5231			this.positionDropdown();
5232
5233			if(this.selectDrop.offsetWidth) {
5234
5235				this.scrollToItem();
5236
5237			}
5238
5239		}
5240
5241	}
5242
5243});
5244
5245
5246
5247
5248
5249/*! Hammer.JS - v1.1.3 - 2014-05-20
5250
5251 * http://eightmedia.github.io/hammer.js
5252
5253 *
5254
5255 * Copyright (c) 2014 Jorik Tangelder <[email protected]>;
5256
5257 * Licensed under the MIT license */
5258
5259!function(a,b){"use strict";function c(){d.READY||(s.determineEventTypes(),r.each(d.gestures,function(a){u.register(a)}),s.onTouch(d.DOCUMENT,n,u.detect),s.onTouch(d.DOCUMENT,o,u.detect),d.READY=!0)}var d=function v(a,b){return new v.Instance(a,b||{})};d.VERSION="1.1.3",d.defaults={behavior:{userSelect:"none",touchAction:"pan-y",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}},d.DOCUMENT=document,d.HAS_POINTEREVENTS=navigator.pointerEnabled||navigator.msPointerEnabled,d.HAS_TOUCHEVENTS="ontouchstart"in a,d.IS_MOBILE=/mobile|tablet|ip(ad|hone|od)|android|silk/i.test(navigator.userAgent),d.NO_MOUSEEVENTS=d.HAS_TOUCHEVENTS&&d.IS_MOBILE||d.HAS_POINTEREVENTS,d.CALCULATE_INTERVAL=25;var e={},f=d.DIRECTION_DOWN="down",g=d.DIRECTION_LEFT="left",h=d.DIRECTION_UP="up",i=d.DIRECTION_RIGHT="right",j=d.POINTER_MOUSE="mouse",k=d.POINTER_TOUCH="touch",l=d.POINTER_PEN="pen",m=d.EVENT_START="start",n=d.EVENT_MOVE="move",o=d.EVENT_END="end",p=d.EVENT_RELEASE="release",q=d.EVENT_TOUCH="touch";d.READY=!1,d.plugins=d.plugins||{},d.gestures=d.gestures||{};var r=d.utils={extend:function(a,c,d){for(var e in c)!c.hasOwnProperty(e)||a[e]!==b&&d||(a[e]=c[e]);return a},on:function(a,b,c){a.addEventListener(b,c,!1)},off:function(a,b,c){a.removeEventListener(b,c,!1)},each:function(a,c,d){var e,f;
5259if("forEach"in a)a.forEach(c,d);else if(a.length!==b){for(e=0,f=a.length;f>e;e++)if(c.call(d,a[e],e,a)===!1)return}else for(e in a)if(a.hasOwnProperty(e)&&c.call(d,a[e],e,a)===!1)return},inStr:function(a,b){return a.indexOf(b)>-1},inArray:function(a,b){if(a.indexOf){var c=a.indexOf(b);return-1===c?!1:c}for(var d=0,e=a.length;e>d;d++)if(a[d]===b)return d;return!1},toArray:function(a){return Array.prototype.slice.call(a,0)},hasParent:function(a,b){for(;a;){if(a==b)return!0;a=a.parentNode}return!1},getCenter:function(a){var b=[],c=[],d=[],e=[],f=Math.min,g=Math.max;return 1===a.length?{pageX:a[0].pageX,pageY:a[0].pageY,clientX:a[0].clientX,clientY:a[0].clientY}:(r.each(a,function(a){b.push(a.pageX),c.push(a.pageY),d.push(a.clientX),e.push(a.clientY)}),{pageX:(f.apply(Math,b)+g.apply(Math,b))/2,pageY:(f.apply(Math,c)+g.apply(Math,c))/2,clientX:(f.apply(Math,d)+g.apply(Math,d))/2,clientY:(f.apply(Math,e)+g.apply(Math,e))/2})},getVelocity:function(a,b,c){return{x:Math.abs(b/a)||0,y:Math.abs(c/a)||0}},getAngle:function(a,b){var c=b.clientX-a.clientX,d=b.clientY-a.clientY;return 180*Math.atan2(d,c)/Math.PI},getDirection:function(a,b){var c=Math.abs(a.clientX-b.clientX),d=Math.abs(a.clientY-b.clientY);return c>=d?a.clientX-b.clientX>0?g:i:a.clientY-b.clientY>0?h:f},getDistance:function(a,b){var c=b.clientX-a.clientX,d=b.clientY-a.clientY;return Math.sqrt(c*c+d*d)},getScale:function(a,b){return a.length>=2&&b.length>=2?this.getDistance(b[0],b[1])/this.getDistance(a[0],a[1]):1},getRotation:function(a,b){return a.length>=2&&b.length>=2?this.getAngle(b[1],b[0])-this.getAngle(a[1],a[0]):0},isVertical:function(a){return a==h||a==f},setPrefixedCss:function(a,b,c,d){var e=["","Webkit","Moz","O","ms"];b=r.toCamelCase(b);for(var f=0;f<e.length;f++){var g=b;if(e[f]&&(g=e[f]+g.slice(0,1).toUpperCase()+g.slice(1)),g in a.style){a.style[g]=(null==d||d)&&c||"";break}}},toggleBehavior:function(a,b,c){if(b&&a&&a.style){r.each(b,function(b,d){r.setPrefixedCss(a,d,b,c)});var d=c&&function(){return!1};"none"==b.userSelect&&(a.onselectstart=d),"none"==b.userDrag&&(a.ondragstart=d)}},toCamelCase:function(a){return a.replace(/[_-]([a-z])/g,function(a){return a[1].toUpperCase()})}},s=d.event={preventMouseEvents:!1,started:!1,shouldDetect:!1,on:function(a,b,c,d){var e=b.split(" ");r.each(e,function(b){r.on(a,b,c),d&&d(b)})},off:function(a,b,c,d){var e=b.split(" ");r.each(e,function(b){r.off(a,b,c),d&&d(b)})},onTouch:function(a,b,c){var f=this,g=function(e){var g,h=e.type.toLowerCase(),i=d.HAS_POINTEREVENTS,j=r.inStr(h,"mouse");j&&f.preventMouseEvents||(j&&b==m&&0===e.button?(f.preventMouseEvents=!1,f.shouldDetect=!0):i&&b==m?f.shouldDetect=1===e.buttons||t.matchType(k,e):j||b!=m||(f.preventMouseEvents=!0,f.shouldDetect=!0),i&&b!=o&&t.updatePointer(b,e),f.shouldDetect&&(g=f.doDetect.call(f,e,b,a,c)),g==o&&(f.preventMouseEvents=!1,f.shouldDetect=!1,t.reset()),i&&b==o&&t.updatePointer(b,e))};return this.on(a,e[b],g),g},doDetect:function(a,b,c,d){var e=this.getTouchList(a,b),f=e.length,g=b,h=e.trigger,i=f;b==m?h=q:b==o&&(h=p,i=e.length-(a.changedTouches?a.changedTouches.length:1)),i>0&&this.started&&(g=n),this.started=!0;var j=this.collectEventData(c,g,e,a);return b!=o&&d.call(u,j),h&&(j.changedLength=i,j.eventType=h,d.call(u,j),j.eventType=g,delete j.changedLength),g==o&&(d.call(u,j),this.started=!1),g},determineEventTypes:function(){var b;return b=d.HAS_POINTEREVENTS?a.PointerEvent?["pointerdown","pointermove","pointerup pointercancel lostpointercapture"]:["MSPointerDown","MSPointerMove","MSPointerUp MSPointerCancel MSLostPointerCapture"]:d.NO_MOUSEEVENTS?["touchstart","touchmove","touchend touchcancel"]:["touchstart mousedown","touchmove mousemove","touchend touchcancel mouseup"],e[m]=b[0],e[n]=b[1],e[o]=b[2],e},getTouchList:function(a,b){if(d.HAS_POINTEREVENTS&&!(navigator.msPointerEnabled&&!navigator.pointerEnabled))return t.getTouchList();if(a.touches){if(b==n)return a.touches;var c=[],e=[].concat(r.toArray(a.touches),r.toArray(a.changedTouches)),f=[];return r.each(e,function(a){r.inArray(c,a.identifier)===!1&&f.push(a),c.push(a.identifier)}),f}return a.identifier=1,[a]},collectEventData:function(a,b,c,d){var e=k;return r.inStr(d.type,"mouse")||t.matchType(j,d)?e=j:t.matchType(l,d)&&(e=l),{center:r.getCenter(c),timeStamp:Date.now(),target:d.target,touches:c,eventType:b,pointerType:e,srcEvent:d,preventDefault:function(){var a=this.srcEvent;a.preventManipulation&&a.preventManipulation(),a.preventDefault&&a.preventDefault()},stopPropagation:function(){this.srcEvent.stopPropagation()},stopDetect:function(){return u.stopDetect()}}}},t=d.PointerEvent={pointers:{},getTouchList:function(){var a=[];return r.each(this.pointers,function(b){a.push(b)}),a},updatePointer:function(a,b){a==o||a!=o&&1!==b.buttons?delete this.pointers[b.pointerId]:(b.identifier=b.pointerId,this.pointers[b.pointerId]=b)},matchType:function(a,b){if(!b.pointerType)return!1;var c=b.pointerType,d={};return d[j]=c===(b.MSPOINTER_TYPE_MOUSE||j),d[k]=c===(b.MSPOINTER_TYPE_TOUCH||k),d[l]=c===(b.MSPOINTER_TYPE_PEN||l),d[a]},reset:function(){this.pointers={}}}
5259,u=d.detection={gestures:[],current:null,previous:null,stopped:!1,startDetect:function(a,b){this.current||(this.stopped=!1,this.current={inst:a,startEvent:r.extend({},b),lastEvent:!1,lastCalcEvent:!1,futureCalcEvent:!1,lastCalcData:{},name:""},this.detect(b))},detect:function(a){if(this.current&&!this.stopped){a=this.extendEventData(a);var b=this.current.inst,c=b.options;return r.each(this.gestures,function(d){!this.stopped&&b.enabled&&c[d.name]&&d.handler.call(d,a,b)},this),this.current&&(this.current.lastEvent=a),a.eventType==o&&this.stopDetect(),a}},stopDetect:function(){this.previous=r.extend({},this.current),this.current=null,this.stopped=!0},getCalculatedData:function(a,b,c,e,f){var g=this.current,h=!1,i=g.lastCalcEvent,j=g.lastCalcData;i&&a.timeStamp-i.timeStamp>d.CALCULATE_INTERVAL&&(b=i.center,c=a.timeStamp-i.timeStamp,e=a.center.clientX-i.center.clientX,f=a.center.clientY-i.center.clientY,h=!0),(a.eventType==q||a.eventType==p)&&(g.futureCalcEvent=a),(!g.lastCalcEvent||h)&&(j.velocity=r.getVelocity(c,e,f),j.angle=r.getAngle(b,a.center),j.direction=r.getDirection(b,a.center),g.lastCalcEvent=g.futureCalcEvent||a,g.futureCalcEvent=a),a.velocityX=j.velocity.x,a.velocityY=j.velocity.y,a.interimAngle=j.angle,a.interimDirection=j.direction},extendEventData:function(a){var b=this.current,c=b.startEvent,d=b.lastEvent||c;(a.eventType==q||a.eventType==p)&&(c.touches=[],r.each(a.touches,function(a){c.touches.push({clientX:a.clientX,clientY:a.clientY})}));var e=a.timeStamp-c.timeStamp,f=a.center.clientX-c.center.clientX,g=a.center.clientY-c.center.clientY;return this.getCalculatedData(a,d.center,e,f,g),r.extend(a,{startEvent:c,deltaTime:e,deltaX:f,deltaY:g,distance:r.getDistance(c.center,a.center),angle:r.getAngle(c.center,a.center),direction:r.getDirection(c.center,a.center),scale:r.getScale(c.touches,a.touches),rotation:r.getRotation(c.touches,a.touches)}),a},register:function(a){var c=a.defaults||{};return c[a.name]===b&&(c[a.name]=!0),r.extend(d.defaults,c,!0),a.index=a.index||1e3,this.gestures.push(a),this.gestures.sort(function(a,b){return a.index<b.index?-1:a.index>b.index?1:0}),this.gestures}};d.Instance=function(a,b){var e=this;c(),this.element=a,this.enabled=!0,r.each(b,function(a,c){delete b[c],b[r.toCamelCase(c)]=a}),this.options=r.extend(r.extend({},d.defaults),b||{}),this.options.behavior&&r.toggleBehavior(this.element,this.options.behavior,!0),this.eventStartHandler=s.onTouch(a,m,function(a){e.enabled&&a.eventType==m?u.startDetect(e,a):a.eventType==q&&u.detect(a)}),this.eventHandlers=[]},d.Instance.prototype={on:function(a,b){var c=this;return s.on(c.element,a,b,function(a){c.eventHandlers.push({gesture:a,handler:b})}),c},off:function(a,b){var c=this;return s.off(c.element,a,b,function(a){var d=r.inArray({gesture:a,handler:b});d!==!1&&c.eventHandlers.splice(d,1)}),c},trigger:function(a,b){b||(b={});var c=d.DOCUMENT.createEvent("Event");c.initEvent(a,!0,!0),c.gesture=b;var e=this.element;return r.hasParent(b.target,e)&&(e=b.target),e.dispatchEvent(c),this},enable:function(a){return this.enabled=a,this},dispose:function(){var a,b;for(r.toggleBehavior(this.element,this.options.behavior,!1),a=-1;b=this.eventHandlers[++a];)r.off(this.element,b.gesture,b.handler);return this.eventHandlers=[],s.off(this.element,e[m],this.eventStartHandler),null}},function(a){function b(b,d){var e=u.current;if(!(d.options.dragMaxTouches>0&&b.touches.length>d.options.dragMaxTouches))switch(b.eventType){case m:c=!1;break;case n:if(b.distance<d.options.dragMinDistance&&e.name!=a)return;var j=e.startEvent.center;if(e.name!=a&&(e.name=a,d.options.dragDistanceCorrection&&b.distance>0)){var k=Math.abs(d.options.dragMinDistance/b.distance);j.pageX+=b.deltaX*k,j.pageY+=b.deltaY*k,j.clientX+=b.deltaX*k,j.clientY+=b.deltaY*k,b=u.extendEventData(b)}(e.lastEvent.dragLockToAxis||d.options.dragLockToAxis&&d.options.dragLockMinDistance<=b.distance)&&(b.dragLockToAxis=!0);var l=e.lastEvent.direction;b.dragLockToAxis&&l!==b.direction&&(b.direction=r.isVertical(l)?b.deltaY<0?h:f:b.deltaX<0?g:i),c||(d.trigger(a+"start",b),c=!0),d.trigger(a,b),d.trigger(a+b.direction,b);var q=r.isVertical(b.direction);(d.options.dragBlockVertical&&q||d.options.dragBlockHorizontal&&!q)&&b.preventDefault();break;case p:c&&b.changedLength<=d.options.dragMaxTouches&&(d.trigger(a+"end",b),c=!1);break;case o:c=!1}}var c=!1;d.gestures.Drag={name:a,index:50,handler:b,defaults:{dragMinDistance:10,dragDistanceCorrection:!0,dragMaxTouches:1,dragBlockHorizontal:!1,dragBlockVertical:!1,dragLockToAxis:!1,dragLockMinDistance:25}}}("drag"),d.gestures.Gesture={name:"gesture",index:1337,handler:function(a,b){b.trigger(this.name,a)}},function(a){function b(b,d){var e=d.options,f=u.current;switch(b.eventType){case m:clearTimeout(c),f.name=a,c=setTimeout(function(){f&&f.name==a&&d.trigger(a,b)},e.holdTimeout);break;case n:b.distance>e.holdThreshold&&clearTimeout(c);break;case p:clearTimeout(c)}}var c;d.gestures.Hold={name:a,index:10,defaults:{holdTimeout:500,holdThreshold:2},handler:b}}("hold"),d.gestures.Release={name:"release",index:1/0,handler:function(a,b){a.eventType==p&&b.trigger(this.name,a)}},d.gestures.Swipe={name:"swipe",index:40,defaults:{swipeMinTouches:1,swipeMaxTouches:1,swipeVelocityX:.6,swipeVelocityY:.6},handler:function(a,b){if(a.eventType==p){var c=a.touches.length,d=b.options;if(c<d.swipeMinTouches||c>d.swipeMaxTouches)return;(a.velocityX>d.swipeVelocityX||a.velocityY>d.swipeVelocityY)&&(b.trigger(this.name,a),b.trigger(this.name+a.direction,a))}}},function(a){function b(b,d){var e,f,g=d.options,h=u.current,i=u.previous;switch(b.eventType){case m:c=!1;break;case n:c=c||b.distance>g.tapMaxDistance;break;case o:!r.inStr(b.srcEvent.type,"cancel")&&b.deltaTime<g.tapMaxTime&&!c&&(e=i&&i.lastEvent&&b.timeStamp-i.lastEvent.timeStamp,f=!1,i&&i.name==a&&e&&e<g.doubleTapInterval&&b.distance<g.doubleTapDistance&&(d.trigger("doubletap",b),f=!0),(!f||g.tapAlways)&&(h.name=a,d.trigger(h.name,b)))}}var c=!1;d.gestures.Tap={name:a,index:100,handler:b,defaults:{tapMaxTime:250,tapMaxDistance:10,tapAlways:!0,doubleTapDistance:20,doubleTapInterval:300}}}("tap"),d.gestures.Touch={name:"touch",index:-1/0,defaults:{preventDefault:!1,preventMouse:!1},handler:function(a,b){return b.options.preventMouse&&a.pointerType==j?void a.stopDetect():(b.options.preventDefault&&a.preventDefault(),void(a.eventType==q&&b.trigger("touch",a)))}},function(a){function b(b,d){switch(b.eventType){case m:c=!1;break;case n:if(b.touches.length<2)return;var e=Math.abs(1-b.scale),f=Math.abs(b.rotation);if(e<d.options.transformMinScale&&f<d.options.transformMinRotation)return;u.current.name=a,c||(d.trigger(a+"start",b),c=!0),d.trigger(a,b),f>d.options.transformMinRotation&&d.trigger("rotate",b),e>d.options.transformMinScale&&(d.trigger("pinch",b),d.trigger("pinch"+(b.scale<1?"in":"out"),b));break;case p:c&&b.changedLength<2&&(d.trigger(a+"end",b),c=!1)}}var c=!1;d.gestures.Transform={name:a,index:45,defaults:{transformMinScale:.01,transformMinRotation:1},handler:b}}("transform"),"function"==typeof define&&define.amd?define(function(){return d}):"undefined"!=typeof module&&module.exports?module.exports=d:a.Hammer=d}(window);
5260
5261
5262
5263/*!
5264
5265* FitVids 1.0.3
5266
5267*
5268
5269* Copyright 2013, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com
5270
5271* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/
5272
5273* Released under the WTFPL license - http://sam.zoy.org/wtfpl/
5274
5275*
5276
5277* Date: Thu Sept 01 18:00:00 2011 -0500
5278
5279*/
5280
5281;(function(a){a.fn.fitVids=function(b){var c={customSelector:null};if(!document.getElementById("fit-vids-style")){var f=document.createElement("div"),d=document.getElementsByTagName("base")[0]||document.getElementsByTagName("script")[0],e="&shy;<style>.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}</style>";f.className="fit-vids-style";f.id="fit-vids-style";f.style.display="none";f.innerHTML=e;d.parentNode.insertBefore(f,d)}if(b){a.extend(c,b)}return this.each(function(){var g=["iframe[src*='player.vimeo.com']","iframe[src*='youtube.com']","iframe[src*='youtube-nocookie.com']","iframe[src*='kickstarter.com'][src*='video.html']","object","embed"];if(c.customSelector){g.push(c.customSelector)}var h=a(this).find(g.join(","));h=h.not("object object");h.each(function(){var m=a(this);if(this.tagName.toLowerCase()==="embed"&&m.parent("object").length||m.parent(".fluid-width-video-wrapper").length){return}var i=(this.tagName.toLowerCase()==="object"||(m.attr("height")&&!isNaN(parseInt(m.attr("height"),10))))?parseInt(m.attr("height"),10):m.height(),j=!isNaN(parseInt(m.attr("width"),10))?parseInt(m.attr("width"),10):m.width(),k=i/j;if(!m.attr("id")){var l="fitvid"+Math.floor(Math.random()*999999);m.attr("id",l)}m.wrap('<div class="fluid-width-video-wrapper"></div>').parent(".fluid-width-video-wrapper").css("padding-top",(k*100)+"%");m.removeAttr("height").removeAttr("width")})})}})(window.jQuery||window.Zepto);
5282

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.