PageSourceSearch

https://costabrava.org/wp-content/themes/costabrava/resources/v1/js/jquery.mixitup.js?ver=20261001202806

js costabrava.org collected 2026-10-02 05:45:34 UTC 52,172 bytes, 2,093 lines download raw bytes

1/**!
2 * MixItUp v2.1.8
3 *
4 * @copyright Copyright 2015 KunkaLabs Limited.
5 * @author    KunkaLabs Limited.
6 * @link      https://mixitup.kunkalabs.com
7 *
8 * @license   Commercial use requires a commercial license.
9 *            https://mixitup.kunkalabs.com/licenses/
10 *
11 *            Non-commercial use permitted under terms of CC-BY-NC license.
12 *            http://creativecommons.org/licenses/by-nc/3.0/
13 */
14
15(function($, undf){
16	
17	/**
18	 * MixItUp Constructor Function
19	 * @constructor
20	 * @extends jQuery
21	 */
22	
23	$.MixItUp = function(){
24		var self = this;
25		
26		self._execAction('_constructor', 0);
27		
28		$.extend(self, {
29			
30			/* Public Properties
31			---------------------------------------------------------------------- */
32			
33			selectors: {
34				target: '.mix',
35				filter: '.filter',
36				sort: '.sort'
37			},
38				
39			animation: {
40				enable: true,
41				effects: 'fade scale',
42				duration: 600,
43				easing: 'ease',
44				perspectiveDistance: '3000',
45				perspectiveOrigin: '50% 50%',
46				queue: true,
47				queueLimit: 1,
48				animateChangeLayout: false,
49				animateResizeContainer: true,
50				animateResizeTargets: false,
51				staggerSequence: false,
52				reverseOut: false
53			},
54				
55			callbacks: {
56				onMixLoad: false,
57				onMixStart: false,
58				onMixBusy: false,
59				onMixEnd: false,
60				onMixFail: false,
61				_user: false
62			},
63				
64			controls: {
65				enable: true,
66				live: false,
67				toggleFilterButtons: false,
68				toggleLogic: 'or',
69				activeClass: 'active'
70			},
71
72			layout: {
73				display: 'inline-block',
74				containerClass: '',
75				containerClassFail: 'fail'
76			},
77			
78			load: {
79				filter: 'all',
80				sort: false
81			},
82			
83			/* Private Properties
84			---------------------------------------------------------------------- */
85				
86			_$body: null,
87			_$container: null,
88			_$targets: null,
89			_$parent: null,
90			_$sortButtons: null,
91			_$filterButtons: null,
92		
93			_suckMode: false,
94			_mixing: false,
95			_sorting: false,
96			_clicking: false,
97			_loading: true,
98			_changingLayout: false,
99			_changingClass: false,
100			_changingDisplay: false,
101			
102			_origOrder: [],
103			_startOrder: [],
104			_newOrder: [],
105			_activeFilter: null,
106			_toggleArray: [],
107			_toggleString: '',
108			_activeSort: 'default:asc',
109			_newSort: null,
110			_startHeight: null,
111			_newHeight: null,
112			_incPadding: true,
113			_newDisplay: null,
114			_newClass: null,
115			_targetsBound: 0,
116			_targetsDone: 0,
117			_queue: [],
118				
119			_$show: $(),
120			_$hide: $()
121		});
122	
123		self._execAction('_constructor', 1);
124	};
125	
126	/**
127	 * MixItUp Prototype
128	 * @override
129	 */
130	
131	$.MixItUp.prototype = {
132		constructor: $.MixItUp,
133		
134		/* Static Properties
135		---------------------------------------------------------------------- */
136		
137		_instances: {},
138		_handled: {
139			_filter: {},
140			_sort: {}
141		},
142		_bound: {
143			_filter: {},
144			_sort: {}
145		},
146		_actions: {},
147		_filters: {},
148		
149		/* Static Methods
150		---------------------------------------------------------------------- */
151		
152		/**
153		 * Extend
154		 * @since 2.1.0
155		 * @param {object} new properties/methods
156		 * @extends {object} prototype
157		 */
158		
159		extend: function(extension){
160			for(var key in extension){
161				$.MixItUp.prototype[key] = extension[key];
162			}
163		},
164		
165		/**
166		 * Add Action
167		 * @since 2.1.0
168		 * @param {string} hook name
169		 * @param {string} namespace
170		 * @param {function} function to execute
171		 * @param {number} priority
172		 * @extends {object} $.MixItUp.prototype._actions
173		 */
174		
175		addAction: function(hook, name, func, priority){
176			$.MixItUp.prototype._addHook('_actions', hook, name, func, priority);
177		},
178		
179		/**
180		 * Add Filter
181		 * @since 2.1.0
182		 * @param {string} hook name
183		 * @param {string} namespace
184		 * @param {function} function to execute
185		 * @param {number} priority
186		 * @extends {object} $.MixItUp.prototype._filters
187		 */
188		
189		addFilter: function(hook, name, func, priority){
190			$.MixItUp.prototype._addHook('_filters', hook, name, func, priority);
191		},
192		
193		/**
194		 * Add Hook
195		 * @since 2.1.0
196		 * @param {string} type of hook
197		 * @param {string} hook name
198		 * @param {function} function to execute
199		 * @param {number} priority
200		 * @extends {object} $.MixItUp.prototype._filters
201		 */
202		
203		_addHook: function(type, hook, name, func, priority){
204			var collection = $.MixItUp.prototype[type],
205				obj = {};
206				
207			priority = (priority === 1 || priority === 'post') ? 'post' : 'pre';
208				
209			obj[hook] = {};
210			obj[hook][priority] = {};
211			obj[hook][priority][name] = func;
212
213			$.extend(true, collection, obj);
214		},
215		
216		
217		/* Private Methods
218		---------------------------------------------------------------------- */
219		
220		/**
221		 * Initialise
222		 * @since 2.0.0
223		 * @param {object} domNode
224		 * @param {object} config
225		 */
226		
227		_init: function(domNode, config){
228			var self = this;
229			
230			self._execAction('_init', 0, arguments);
231			
232			config && $.extend(true, self, config);
233			
234			self._$body = $('body');
235			self._domNode = domNode;
236			self._$container = $(domNode);
237			self._$container.addClass(self.layout.containerClass);
238			self._id = domNode.id;
239			
240			self._platformDetect();
241			
242			self._brake = self._getPrefixedCSS('transition', 'none');
243			
244			self._refresh(true);
245			
246			self._$parent = self._$targets.parent().length ? self._$targets.parent() : self._$container;
247			
248			if(self.load.sort){
249				self._newSort = self._parseSort(self.load.sort);
250				self._newSortString = self.load.sort;
251				self._activeSort = self.load.sort;
252				self._sort();
253				self._printSort();
254			}
255			
256			self._activeFilter = self.load.filter === 'all' ? 
257				self.selectors.target : 
258				self.load.filter === 'none' ?
259					'' :
260					self.load.filter;
261			
262			self.controls.enable && self._bindHandlers();
263			
264			if(self.controls.toggleFilterButtons){
265				self._buildToggleArray();
266				
267				for(var i = 0; i < self._toggleArray.length; i++){
268					self._updateControls({filter: self._toggleArray[i], sort: self._activeSort}, true);
269				};
270			} else if(self.controls.enable){
271				self._updateControls({filter: self._activeFilter, sort: self._activeSort});
272			}
273			
274			self._filter();
275			
276			self._init = true;
277			
278			self._$container.data('mixItUp',self);
279			
280			self._execAction('_init', 1, arguments);
281			
282			self._buildState();
283			
284			self._$targets.css(self._brake);
285		
286			self._goMix(self.animation.enable);
287		},
288		
289		/**
290		 * Platform Detect
291		 * @since 2.0.0
292		 */
293		
294		_platformDetect: function(){
295			var self = this,
296				vendorsTrans = ['Webkit', 'Moz', 'O', 'ms'],
297				vendorsRAF = ['webkit', 'moz'],
298				chrome = window.navigator.appVersion.match(/Chrome\/(\d+)\./) || false,
299				ff = typeof InstallTrigger !== 'undefined',
300				prefix = function(el){
301					for (var i = 0; i < vendorsTrans.length; i++){
302						if (vendorsTrans[i] + 'Transition' in el.style){
303							return {
304								prefix: '-'+vendorsTrans[i].toLowerCase()+'-',
305								vendor: vendorsTrans[i]
306							};
307						};
308					}; 
309					return 'transition' in el.style ? '' : false;
310				},
311				transPrefix = prefix(self._domNode);
312				
313			self._execAction('_platformDetect', 0);
314			
315			self._chrome = chrome ? parseInt(chrome[1], 10) : false;
316			self._ff = ff ? parseInt(window.navigator.userAgent.match(/rv:([^)]+)\)/)[1]) : false;
317			self._prefix = transPrefix.prefix;
318			self._vendor = transPrefix.vendor;
319			self._suckMode = window.atob && self._prefix ? false : true;
320
321			self._suckMode && (self.animation.enable = false);
322			(self._ff && self._ff <= 4) && (self.animation.enable = false);
323			
324			/* Polyfills
325			---------------------------------------------------------------------- */
326			
327			/**
328			 * window.requestAnimationFrame
329			 */
330			
331			for(var x = 0; x < vendorsRAF.length && !window.requestAnimationFrame; x++){
332				window.requestAnimationFrame = window[vendorsRAF[x]+'RequestAnimationFrame'];
333			}
334
335			/**
336			 * Object.getPrototypeOf
337			 */
338
339			if(typeof Object.getPrototypeOf !== 'function'){
340				if(typeof 'test'.__proto__ === 'object'){
341					Object.getPrototypeOf = function(object){
342						return object.__proto__;
343					};
344				} else {
345					Object.getPrototypeOf = function(object){
346						return object.constructor.prototype;
347					};
348				}
349			}
350
351			/**
352			 * Element.nextElementSibling
353			 */
354			
355			if(self._domNode.nextElementSibling === undf){
356				Object.defineProperty(Element.prototype, 'nextElementSibling',{
357					get: function(){
358						var el = this.nextSibling;
359						
360						while(el){
361							if(el.nodeType ===1){
362								return el;
363							}
364							el = el.nextSibling;
365						}
366						return null;
367					}
368				});
369			}
370			
371			self._execAction('_platformDetect', 1);
372		},
373		
374		/**
375		 * Refresh
376		 * @since 2.0.0
377		 * @param {boolean} init
378		 * @param {boolean} force
379		 */
380		
381		_refresh: function(init, force){
382			var self = this;
383				
384			self._execAction('_refresh', 0, arguments);
385
386			self._$targets = self._$container.find(self.selectors.target);
387			
388			for(var i = 0; i < self._$targets.length; i++){
389				var target = self._$targets[i];
390					
391				if(target.dataset === undf || force){
392						
393					target.dataset = {};
394					
395					for(var j = 0; j < target.attributes.length; j++){
396						
397						var attr = target.attributes[j],
398							name = attr.name,
399							val = attr.value;
400							
401						if(name.indexOf('data-') > -1){
402							var dataName = self._helpers._camelCase(name.substring(5,name.length));
403							target.dataset[dataName] = val;
404						}
405					}
406				}
407				
408				if(target.mixParent === undf){
409					target.mixParent = self._id;
410				}
411			}
412			
413			if(
414				(self._$targets.length && init) ||
415				(!self._origOrder.length && self._$targets.length)
416			){
417				self._origOrder = [];
418				
419				for(var i = 0; i < self._$targets.length; i++){
420					var target = self._$targets[i];
421					
422					self._origOrder.push(target);
423				}
424			}
425			
426			self._execAction('_refresh', 1, arguments);
427		},
428		
429		/**
430		 * Bind Handlers
431		 * @since 2.0.0
432		 */
433		
434		_bindHandlers: function(){
435			var self = this,
436				filters = $.MixItUp.prototype._bound._filter,
437				sorts = $.MixItUp.prototype._bound._sort;
438			
439			self._execAction('_bindHandlers', 0);
440			
441			if(self.controls.live){
442				self._$body
443					.on('click.mixItUp.'+self._id, self.selectors.sort, function(){
444						self._processClick($(this), 'sort');
445					})
446					.on('click.mixItUp.'+self._id, self.selectors.filter, function(){
447						self._processClick($(this), 'filter');
448					});
449			} else {
450				self._$sortButtons = $(self.selectors.sort);
451				self._$filterButtons = $(self.selectors.filter);
452				
453				self._$sortButtons.on('click.mixItUp.'+self._id, function(){
454					self._processClick($(this), 'sort');
455				});
456				
457				self._$filterButtons.on('click.mixItUp.'+self._id, function(){
458					self._processClick($(this), 'filter');
459				});
460			}
461
462			filters[self.selectors.filter] = (filters[self.selectors.filter] === undf) ? 1 : filters[self.selectors.filter] + 1;
463			sorts[self.selectors.sort] = (sorts[self.selectors.sort] === undf) ? 1 : sorts[self.selectors.sort] + 1;
464			
465			self._execAction('_bindHandlers', 1);
466		},
467		
468		/**
469		 * Process Click
470		 * @since 2.0.0
471		 * @param {object} $button
472		 * @param {string} type
473		 */
474		
475		_processClick: function($button, type){
476			var self = this,
477				trackClick = function($button, type, off){
478					var proto = $.MixItUp.prototype;
479						
480					proto._handled['_'+type][self.selectors[type]] = (proto._handled['_'+type][self.selectors[type]] === undf) ? 
481						1 : 
482						proto._handled['_'+type][self.selectors[type]] + 1;
483
484					if(proto._handled['_'+type][self.selectors[type]] === proto._bound['_'+type][self.selectors[type]]
484){
485						$button[(off ? 'remove' : 'add')+'Class'](self.controls.activeClass);
486						delete proto._handled['_'+type][self.selectors[type]];
487					}
488				};
489			
490			self._execAction('_processClick', 0, arguments);
491			
492			if(!self._mixing || (self.animation.queue && self._queue.length < self.animation.queueLimit)){
493				self._clicking = true;
494				
495				if(type === 'sort'){
496					var sort = $button.attr('data-sort');
497					
498					if(!$button.hasClass(self.controls.activeClass) || sort.indexOf('random') > -1){
499						$(self.selectors.sort).removeClass(self.controls.activeClass);
500						trackClick($button, type);
501						self.sort(sort);
502					}
503				}
504				
505				if(type === 'filter') {
506					var filter = $button.attr('data-filter'),
507						ndx,
508						seperator = self.controls.toggleLogic === 'or' ? ',' : '';
509					
510					if(!self.controls.toggleFilterButtons){
511						if(!$button.hasClass(self.controls.activeClass)){
512							$(self.selectors.filter).removeClass(self.controls.activeClass);
513							trackClick($button, type);
514							self.filter(filter);
515						}
516					} else {
517						self._buildToggleArray();
518						
519						if(!$button.hasClass(self.controls.activeClass)){
520							trackClick($button, type);
521							
522							self._toggleArray.push(filter);
523						} else {
524							trackClick($button, type, true);
525							ndx = self._toggleArray.indexOf(filter);
526							self._toggleArray.splice(ndx, 1);
527						}
528						
529						self._toggleArray = $.grep(self._toggleArray,function(n){return(n);});
530						
531						self._toggleString = self._toggleArray.join(seperator);
532
533						self.filter(self._toggleString);
534					}
535				}
536				
537				self._execAction('_processClick', 1, arguments);
538			} else {
539				if(typeof self.callbacks.onMixBusy === 'function'){
540					self.callbacks.onMixBusy.call(self._domNode, self._state, self);
541				}
542				self._execAction('_processClickBusy', 1, arguments);
543			}
544		},
545		
546		/**
547		 * Build Toggle Array
548		 * @since 2.0.0
549		 */
550		
551		_buildToggleArray: function(){
552			var self = this,
553				activeFilter = self._activeFilter.replace(/\s/g, '');
554			
555			self._execAction('_buildToggleArray', 0, arguments);
556			
557			if(self.controls.toggleLogic === 'or'){
558				self._toggleArray = activeFilter.split(',');
559			} else {
560				self._toggleArray = activeFilter.split('.');
561				
562				!self._toggleArray[0] && self._toggleArray.shift();
563				
564				for(var i = 0, filter; filter = self._toggleArray[i]; i++){
565					self._toggleArray[i] = '.'+filter;
566				}
567			}
568			
569			self._execAction('_buildToggleArray', 1, arguments);
570		},
571		
572		/**
573		 * Update Controls
574		 * @since 2.0.0
575		 * @param {object} command
576		 * @param {boolean} multi
577		 */
578		
579		_updateControls: function(command, multi){
580			var self = this,
581				output = {
582					filter: command.filter,
583					sort: command.sort
584				},
585				update = function($el, filter){
586					try {
587						(multi && type === 'filter' && !(output.filter === 'none' || output.f
587ilter === '')) ?
588								$el.filter(filter).addClass(self.controls.activeClass) :
589								$el.removeClass(self.controls.activeClass).filter(filter).addClass(self.controls.activeClass);
590					} catch(e) {}
591				},
592				type = 'filter',
593				$el = null;
594				
595			self._execAction('_updateControls', 0, arguments);
596				
597			(command.filter === undf) && (output.filter = self._activeFilter);
598			(command.sort === undf) && (output.sort = self._activeSort);
599			(output.filter === self.selectors.target) && (output.filter = 'all');
600			
601			for(var i = 0; i < 2; i++){
602				$el = self.controls.live ? $(self.selectors[type]) : self['_$'+type+'Buttons'];
603				$el && update($el, '[data-'+type+'="'+output[type]+'"]');
604				type = 'sort';
605			}
606			
607			self._execAction('_updateControls', 1, arguments);
608		},
609		
610		/**
611		 * Filter (private)
612		 * @since 2.0.0
613		 */
614		
615		_filter: function(){
616			var self = this;
617			
618			self._execAction('_filter', 0);
619			
620			for(var i = 0; i < self._$targets.length; i++){
621				var $target = $(self._$targets[i]);
622				
623				if($target.is(self._activeFilter)){
624					self._$show = self._$show.add($target);
625				} else {
626					self._$hide = self._$hide.add($target);
627				}
628			}
629			
630			self._execAction('_filter', 1);
631		},
632		
633		/**
634		 * Sort (private)
635		 * @since 2.0.0
636		 */
637		
638		_sort: function(){
639			var self = this,
640				arrayShuffle = function(oldArray){
641					var newArray = oldArray.slice(),
642						len = newArray.length,
643						i = len;
644
645					while(i--){
646						var p = parseInt(Math.random()*len);
647						var t = newArray[i];
648						newArray[i] = newArray[p];
649						newArray[p] = t;
650					};
651					return newArray; 
652				};
653				
654			self._execAction('_sort', 0);
655			
656			self._startOrder = [];
657			
658			for(var i = 0; i < self._$targets.length; i++){
659				var target = self._$targets[i];
660				
661				self._startOrder.push(target);
662			}
663			
664			switch(self._newSort[0].sortBy){
665				case 'default':
666					self._newOrder = self._origOrder;
667					break;
668				case 'random':
669					self._newOrder = arrayShuffle(self._startOrder);
670					break;
671				case 'custom':
672					self._newOrder = self._newSort[0].order;
673					break;
674				default:
675					self._newOrder = self._startOrder.concat().sort(function(a, b){
676						return self._compare(a, b);
677					});
678			}
679			
680			self._execAction('_sort', 1);
681		},
682		
683		/**
684		 * Compare Algorithm
685		 * @since 2.0.0
686		 * @param {string|number} a
687		 * @param {string|number} b
688		 * @param {number} depth (recursion)
689		 * @return {number}
690		 */
691		
692		_compare: function(a, b, depth){
693			depth = depth ? depth : 0;
694		
695			var self = this,
696				order = self._newSort[depth].order,
697				getData = function(el){
698					return el.dataset[self._newSort[depth].sortBy] || 0;
699				},
700				attrA = isNaN(getData(a) * 1) ? getData(a).toLowerCase() : getData(a) * 1,
701				attrB = isNaN(getData(b) * 1) ? getData(b).toLowerCase() : getData(b) * 1;
702				
703			if(attrA < attrB)
704				return order === 'asc' ? -1 : 1;
705			if(attrA > attrB)
706				return order === 'asc' ? 1 : -1;
707			if(attrA === attrB && self._newSort.length > depth+1)
708				return self._compare(a, b, depth+1);
709
710			return 0;
711		},
712		
713		/**
714		 * Print Sort
715		 * @since 2.0.0
716		 * @param {boolean} reset
717		 */
718		
719		_printSort: function(reset){
720			var self = this,
721				order = reset ? self._startOrder : self._newOrder,
722				targets = self._$parent[0].querySelectorAll(self.selectors.target),
723				nextSibling = targets.length ? targets[targets.length -1].nextElementSibling : null,
724				frag = document.createDocumentFragment();
725				
726			self._execAction('_printSort', 0, arguments);
727			
728			for(var i = 0; i < targets.length; i++){
729				var target = targets[i],
730					whiteSpace = target.nextSibling;
731
732				if(target.style.position === 'absolute') continue;
733			
734				if(whiteSpace && whiteSpace.nodeName === '#text'){
735					self._$parent[0].removeChild(whiteSpace);
736				}
737				
738				self._$parent[0].removeChild(target);
739			}
740			
741			for(var i = 0; i < order.length; i++){
742				var el = order[i];
743
744				if(self._newSort[0].sortBy === 'default' && self._newSort[0].order === 'desc' && !reset){
745					var firstChild = frag.firstChild;
746					frag.insertBefore(el, firstChild);
747					frag.insertBefore(document.createTextNode(' '), el);
748				} else {
749					frag.appendChild(el);
750					frag.appendChild(document.createTextNode(' '));
751				}
752			}
753			
754			nextSibling ? 
755				self._$parent[0].insertBefore(frag, nextSibling) :
756				self._$parent[0].appendChild(frag);
757				
758			self._execAction('_printSort', 1, arguments);
759		},
760		
761		/**
762		 * Parse Sort
763		 * @since 2.0.0
764		 * @param {string} sortString
765		 * @return {array} newSort
766		 */
767		
768		_parseSort: function(sortString){
769			var self = this,
770				rules = typeof sortString === 'string' ? sortString.split(' ') : [sortString],
771				newSort = [];
772				
773			for(var i = 0; i < rules.length; i++){
774				var rule = typeof sortString === 'string' ? rules[i].split(':') : ['custom', rules[i]],
775					ruleObj = {
776						sortBy: self._helpers._camelCase(rule[0]),
777						order: rule[1] || 'asc'
778					};
779					
780				newSort.push(ruleObj);
781				
782				if(ruleObj.sortBy === 'default' || ruleObj.sortBy === 'random') break;
783			}
784			
785			return self._execFilter('_parseSort', newSort, arguments);
786		},
787		
788		/**
789		 * Parse Effects
790		 * @since 2.0.0
791		 * @return {object} effects
792		 */
793		
794		_parseEffects: function(){
795			var self = this,
796				effects = {
797					opacity: '',
798					transformIn: '',
799					transformOut: '',
800					filter: ''
801				},
802				parse = function(effect, extract, reverse){
803					if(self.animation.effects.indexOf(effect) > -1){
804						if(extract){
805							var propIndex = self.animation.effects.indexOf(effect+'(');
806							if(propIndex > -1){
807								var str = self.animation.effects.substring(propIndex),
808									match = /\(([^)]+)\)/.exec(str),
809									val = match[1];
810
811									return {val: val};
812							}
813						}
814						return true;
815					} else {
816						return false;
817					}
818				},
819				negate = function(value, invert){
820					if(invert){
821						return value.charAt(0) === '-' ? value.substr(1, value.length) : '-'+value;
822					} else {
823						return value;
824					}
825				},
826				buildTransform = function(key, invert){
827					var transforms = [
828						['scale', '.01'],
829						['translateX', '20px'],
830						['translateY', '20px'],
831						['translateZ', '20px'],
832						['rotateX', '90deg'],
833						['rotateY', '90deg'],
834						['rotateZ', '180deg'],
835					];
836					
837					for(var i = 0; i < transforms.length; i++){
838						var prop = transforms[i][0],
839							def = transforms[i][1],
840							inverted = invert && prop !== 'scale';
841							
842						effects[key] += parse(prop) ? prop+'('+negate(parse(prop, true).val || def, inverted)+') ' : '';
843					}
844				};
845			
846			effects.opacity = parse('fade') ? parse('fade',true).val || '0' : '1';
847			
848			buildTransform('transformIn');
849			
850			self.animation.reverseOut ? buildTransform('transformOut', true) : (effects.transformOut = effects.transformIn);
851
852			effects.transition = {};
853			
854			effects.transition = self._getPrefixedCSS('transition','all '+self.animation.duration+'ms '+self.animation.easing+', opacity '+self.animation.duration+'ms linear');
855		
856			self.animation.stagger = parse('stagger') ? true : false;
857			self.animation.staggerDuration = parseInt(parse('stagger') ? (parse('stagger',true).val ? parse('stagger',true).val : 100) : 100);
858
859			return self._execFilter('_parseEffects', effects);
860		},
861		
862		/**
863		 * Build State
864		 * @since 2.0.0
865		 * @param {boolean} future
866		 * @return {object} futureState
867		 */
868		
869		_buildState: function(future){
870			var self = this,
871				state = {};
872			
873			self._execAction('_buildState', 0);
874			
875			state = {
876				activeFilter: self._activeFilter === '' ? 'none' : self._activeFilter,
877				activeSort: future && self._newSortString ? self._newSortString : self._activeSort,
878				fail: !self._$show.length && self._activeFilter !== '',
879				$targets: self._$targets,
880				$show: self._$show,
881				$hide: self._$hide,
882				totalTargets: self._$targets.length,
883				totalShow: self._$show.length,
884				totalHide: self._$hide.length,
885				display: future && self._newDisplay ? self._newDisplay : self.layout.display
886			};
887			
888			if(future){
889				return self._execFilter('_buildState', state);
890			} else {
891				self._state = state;
892				
893				self._execAction('_buildState', 1);
894			}
895		},
896		
897		/**
898		 * Go Mix
899		 * @since 2.0.0
900		 * @param {boolean} animate
901		 */
902		
903		_goMix: function(animate){
904			var self = this,
905				phase1 = function(){
906					if(self._chrome && (self._chrome === 31)){
907						chromeFix(self._$parent[0]);
908					}
909					
910					self._setInter();
911					
912					phase2();
913				},
914				phase2 = function(){
915					var scrollTop = window.pageYOffset,
916						scrollLeft = window.pageXOffset,
917						docHeight = document.documentElement.scrollHeight;
918
919					self._getInterMixData();
920					
921					self._setFinal();
922
923					self._getFinalMixData();
924
925					(window.pageYOffset !== scrollTop) && window.scrollTo(scrollLeft, scrollTop);
926
927					self._prepTargets();
928					
929					if(window.requestAnimationFrame){
930						requestAnimationFrame(phase3);
931					} else {
932						setTimeout(function(){
933							phase3();
934						},20);
935					}
936				},
937				phase3 = function(){
938					self._animateTargets();
939
940					if(self._targetsBound === 0){
941						self._cleanUp();
942					}
943				},
944				chromeFix = function(grid){
945					var parent = grid.parentElement,
946						placeholder = document.createElement('div'),
947						frag = document.createDocumentFragment();
948
949					parent.insertBefore(placeholder, grid);
950					frag.appendChild(grid);
951					parent.replaceChild(grid, placeholder);
952				},
953				futureState = self._buildState(true);
954				
955			self._execAction('_goMix', 0, arguments);
956				
957			!self.animation.duration && (animate = false);
958
959			self._mixing = true;
960			
961			self._$container.removeClass(self.layout.containerClassFail);
962			
963			if(typeof self.callbacks.onMixStart === 'function'){
964				self.callbacks.onMixStart.call(self._domNode, self._state, futureState, self);
965			}
966			
967			self._$container.trigger('mixStart', [self._state, futureState, self]);
968			
969			self._getOrigMixData();
970			
971			if(animate && !self._suckMode){
972			
973				window.requestAnimationFrame ?
974					requestAnimationFrame(phase1) :
975					phase1();
976			
977			} else {
978				self._cleanUp();
979			}
980			
981			self._execAction('_goMix', 1, arguments);
982		},
983		
984		/**
985		 * Get Target Data
986		 * @since 2.0.0
987		 */
988		
989		_getTargetData: function(el, stage){
990			var self = this,
991				elStyle;
992			
993			el.dataset[stage+'PosX'] = el.offsetLeft;
994			el.dataset[stage+'PosY'] = el.offsetTop;
995
996			if(self.animation.animateResizeTargets){
997				elStyle = !self._suckMode ? 
998					window.getComputedStyle(el) : 
999					{
1000						marginBottom: '',
1001						marginRight: ''
1002					};
1003			
1004				el.dataset[stage+'MarginBottom'] = parseInt(elStyle.marginBottom);
1005				el.dataset[stage+'MarginRight'] = parseInt(elStyle.marginRight);
1006				el.dataset[stage+'Width'] = el.offsetWidth;
1007				el.dataset[stage+'Height'] = el.offsetHeight;
1008			}
1009		},
1010		
1011		/**
1012		 * Get Original Mix Data
1013		 * @since 2.0.0
1014		 */
1015		
1016		_getOrigMixData: function(){
1017			var self = this,
1018				parentStyle = !self._suckMode ? window.getComputedStyle(self._$parent[0]) : {boxSizing: ''},
1019				parentBS = parentStyle.boxSizing || parentStyle[self._vendor+'BoxSizing'];
1020	
1021			self._incPadding = (parentBS === 'border-box');
1022			
1023			self._execAction('_getOrigMixData', 0);
1024			
1025			!self._suckMode && (self.effects = self._parseEffects());
1026		
1027			self._$toHide = self._$hide.filter(':visible');
1028			self._$toShow = self._$show.filter(':hidden');
1029			self._$pre = self._$targets.filter(':visible');
1030
1031			self._startHeight = self._incPadding ? 
1032				self._$parent.outerHeight() : 
1033				self._$parent.height();
1034				
1035			for(var i = 0; i < self._$pre.length; i++){
1036				var el = self._$pre[i];
1037				
1038				self._getTargetData(el, 'orig');
1039			}
1040			
1041			self._execAction('_getOrigMixData', 1);
1042		},
1043		
1044		/**
1045		 * Set Intermediate Positions
1046		 * @since 2.0.0
1047		 */
1048		
1049		_setInter: function(){
1050			var self = this;
1051			
1052			self._execAction('_setInter', 0);
1053			
1054			if(self._changingLayout && self.animation.animateChangeLayout){
1055				self._$toShow.css('display',self._newDisplay);
1056
1057				if(self._changingClass){
1058					self._$container
1059						.removeClass(self.layout.containerClass)
1060						.addClass(self._newClass);
1061				}
1062			} else {
1063				self._$toShow.css('display', self.layout.display);
1064			}
1065			
1066			self._execAction('_setInter', 1);
1067		},
1068		
1069		/**
1070		 * Get Intermediate Mix Data
1071		 * @since 2.0.0
1072		 */
1073		
1074		_getInterMixData: function(){
1075			var self = this;
1076			
1077			self._execAction('_getInterMixData', 0);
1078			
1079			for(var i = 0; i < self._$toShow.length; i++){
1080				var el = self._$toShow[i];
1081					
1082				self._getTargetData(el, 'inter');
1083			}
1084			
1085			for(var i = 0; i < self._$pre.length; i++){
1086				var el = self._$pre[i];
1087					
1088				self._getTargetData(el, 'inter');
1089			}
1090			
1091			self._execAction('_getInterMixData', 1);
1092		},
1093		
1094		/**
1095		 * Set Final Positions
1096		 * @since 2.0.0
1097		 */
1098		
1099		_setFinal: function(){
1100			var self = this;
1101			
1102			self._execAction('_setFinal', 0);
1103			
1104			self._sorting && self._printSort();
1105
1106			self._$toHide.removeStyle('display');
1107			
1108			if(self._changingLayout && self.animation.animateChangeLayout){
1109				self._$pre.css('display',self._newDisplay);
1110			}
1111			
1112			self._execAction('_setFinal', 1);
1113		},
1114		
1115		/**
1116		 * Get Final Mix Data
1117		 * @since 2.0.0
1118		 */
1119		
1120		_getFinalMixData: function(){
1121			var self = this;
1122			
1123			self._execAction('_getFinalMixData', 0);
1124	
1125			for(var i = 0; i < self._$toShow.length; i++){
1126				var el = self._$toShow[i];
1127					
1128				self._getTargetData(el, 'final');
1129			}
1130			
1131			for(var i = 0; i < self._$pre.length; i++){
1132				var el = self._$pre[i];
1133					
1134				self._getTargetData(el, 'final');
1135			}
1136			
1137			self._newHeight = self._incPadding ? 
1138				self._$parent.outerHeight() : 
1139				self._$parent.height();
1140
1141			self._sorting && self._printSort(true);
1142	
1143			self._$toShow.removeStyle('display');
1144			
1145			self._$pre.css('display',self.layout.display);
1146			
1147			if(self._changingClass && self.animation.animateChangeLayout){
1148				self._$container
1149					.removeClass(self._newClass)
1150					.addClass(self.layout.containerClass);
1151			}
1152			
1153			self._execAction('_getFinalMixData', 1);
1154		},
1155		
1156		/**
1157		 * Prepare Targets
1158		 * @since 2.0.0
1159		 */
1160		
1161		_prepTargets: function(){
1162			var self = this,
1163				transformCSS = {
1164					_in: self._getPrefixedCSS('transform', self.effects.transformIn),
1165					_out: self._getPrefixedCSS('transform', self.effects.transformOut)
1166				};
1167
1168			self._execAction('_prepTargets', 0);
1169			
1170			if(self.animation.animateResizeContainer){
1171				self._$parent.css('height',self._startHeight+'px');
1172			}
1173			
1174			for(var i = 0; i < self._$toShow.length; i++){
1175				var el = self._$toShow[i],
1176					$el = $(el);
1177				
1178				el.style.opacity = self.effects.opacity;
1179				el.style.display = (self._changingLayout && self.animation.animateChangeLayout) ?
1180					self._newDisplay :
1181					self.layout.display;
1182					
1183				$el.css(transformCSS._in);
1184				
1185				if(self.animation.animateResizeTargets){
1186					el.style.width = el.dataset.finalWidth+'px';
1187					el.style.height = el.dataset.finalHeight+'px';
1188					el.style.marginRight = -(el.dataset.finalWidth - el.dataset.interWidth) + (el.dataset.finalMarginRight * 1)+'px';
1189					el.style.marginBottom = -(el.dataset.finalHeight - el.dataset.interHeight) + (el.dataset.finalMarginBottom * 1)+'px';
1190				}
1191			}
1192
1193			for(var i = 0; i < self._$pre.length; i++){
1194				var el = self._$pre[i],
1195					$el = $(el),
1196					translate = {
1197						x: el.dataset.origPosX - el.dataset.interPosX,
1198						y: el.dataset.origPosY - el.dataset.interPosY
1199					},
1200					transformCSS = self._getPrefixedCSS('transform','translate('+translate.x+'px,'+translate.y+'px)');
1201
1202				$el.css(transformCSS);
1203				
1204				if(self.animation.animateResizeTargets){
1205					el.style.width = el.dataset.origWidth+'px';
1206					el.style.height = el.dataset.origHeight+'px';
1207					
1208					if(el.dataset.origWidth - el.dataset.finalWidth){
1209						el.style.marginRight = -(el.dataset.origWidth - el.dataset.interWidth) + (el.dataset.origMarginRight * 1)+'px';
1210					}
1211					
1212					if(el.dataset.origHeight - el.dataset.finalHeight){
1213						el.style.marginBottom = -(el.dataset.origHeight - el.dataset.interHeight) + (el.dataset.origMarginBottom * 1) +'px';
1214					}
1215				}
1216			}
1217			
1218			self._execAction('_prepTargets', 1);
1219		},
1220		
1221		/**
1222		 * Animate Targets
1223		 * @since 2.0.0
1224		 */
1225		
1226		_animateTargets: function(){
1227			var self = this;
1228
1229			self._execAction('_animateTargets', 0);
1230			
1231			self._targetsDone = 0;
1232			self._targetsBound = 0;
1233			
1234			self._$parent
1235				.css(self._getPrefixedCSS('perspective', self.animation.perspectiveDistance+'px'))
1236				.css(self._getPrefixedCSS('perspective-origin', self.animation.perspectiveOrigin));
1237			
1238			if(self.animation.animateResizeContainer){
1239				self._$parent
1240					.css(self._getPrefixedCSS('transition','height '+self.animation.duration+'ms ease'))
1241					.css('height',self._newHeight+'px');
1242			}
1243			
1244			for(var i = 0; i < self._$toShow.length; i++){
1245				var el = self._$toShow[i],
1246					$el = $(el),
1247					translate = {
1248						x: el.dataset.finalPosX - el.dataset.interPosX,
1249						y: el.dataset.finalPosY - el.dataset.interPosY
1250					},
1251					delay = self._getDelay(i),
1252					toShowCSS = {};
1253				
1254				el.style.opacity = '';
1255				
1256				for(var j = 0; j < 2; j++){
1257					var a = j === 0 ? a = self._prefix : '';
1258					
1259					if(self._ff && self._ff <= 20){
1260						toShowCSS[a+'transition-property'] = 'all';
1261						toShowCSS[a+'transition-timing-function'] = self.animation.easing+'ms';
1262						toShowCSS[a+'transition-duration'] = self.animation.duration+'ms';
1263					}
1264					
1265					toShowCSS[a+'transition-delay'] = delay+'ms';
1266					toShowCSS[a+'transform'] = 'translate('+translate.x+'px,'+translate.y+'px)';
1267				}
1268				
1269				if(self.effects.transform || self.effects.opacity){
1270					self._bindTargetDone($el);
1271				}
1272				
1273				(self._ff && self._ff <= 20) ? 
1274					$el.css(toShowCSS) : 
1275					$el.css(self.effects.transition).css(toShowCSS);
1276			}
1277			
1278			for(var i = 0; i < self._$pre.length; i++){
1279				var el = self._$pre[i],
1280					$el = $(el),
1281					translate = {
1282						x: el.dataset.finalPosX - el.dataset.interPosX,
1283						y: el.dataset.finalPosY - el.dataset.interPosY
1284					},
1285					delay = self._getDelay(i);
1286					
1287				if(!(
1288					el.dataset.finalPosX === el.dataset.origPosX &&
1289					el.dataset.finalPosY === el.dataset.origPosY
1290				)){
1291					self._bindTargetDone($el);
1292				}
1293				
1294				$el.css(self._getPrefixedCSS('transition', 'all '+self.animation.duration+'ms '+self.animation.easing+' '+delay+'ms'));
1295				$el.css(self._getPrefixedCSS('transform', 'translate('+translate.x+'px,'+translate.y+'px)'));
1296				
1297				if(self.animation.animateResizeTargets){
1298					if(el.dataset.origWidth - el.dataset.finalWidth && el.dataset.finalWidth * 1){
1299						el.style.width = el.dataset.finalWidth+'px';
1300						el.style.marginRight = -(el.dataset.finalWidth - el.dataset.interWidth)+(el.dataset.finalMarginRight * 1)+'px';
1301					}
1302					
1303					if(el.dataset.origHeight - el.dataset.finalHeight && el.dataset.finalHeight * 1){
1304						el.style.height = el.dataset.finalHeight+'px';
1305						el.style.marginBottom = -(el.dataset.finalHeight - el.dataset.interHeight)+(el.dataset.finalMarginBottom * 1) +'px';
1306					}
1307				}
1308			}
1309			
1310			if(self._changingClass){
1311				self._$container
1312					.removeClass(self.layout.containerClass)
1313					.addClass(self._newClass);
1314			}
1315			
1316			for(var i = 0; i < self._$toHide.length; i++){
1317				var el = self._$toHide[i],
1318					$el = $(el),
1319					delay = self._getDelay(i),
1320					toHideCSS = {};
1321
1322				for(var j = 0; j<2; j++){
1323					var a = j === 0 ? a = self._prefix : '';
1324
1325					toHideCSS[a+'transition-delay'] = delay+'ms';
1326					toHideCSS[a+'transform'] = self.effects.transformOut;
1327					toHideCSS.opacity = self.effects.opacity;
1328				}
1329				
1330				$el.css(self.effects.transition).css(toHideCSS);
1331			
1332				if(self.effects.transform || self.effects.opacity){
1333					self._bindTargetDone($el);
1334				};
1335			}
1336			
1337			self._execAction('_animateTargets', 1);
1338
1339		},
1340		
1341		/**
1342		 * Bind Targets TransitionEnd
1343		 * @since 2.0.0
1344		 * @param {object} $el
1345		 */
1346		
1347		_bindTargetDone: function($el){
1348			var self = this,
1349				el = $el[0];
1350				
1351			self._execAction('_bindTargetDone', 0, arguments);
1352			
1353			if(!el.dataset.bound){
1354				
1355				el.dataset.bound = true;
1356				self._targetsBound++;
1357			
1358				$el.on('webkitTransitionEnd.mixItUp transitionend.mixItUp',function(e){
1359					if(
1360						(e.originalEvent.propertyName.indexOf('transform') > -1 || 
1361						e.originalEvent.propertyName.indexOf('opacity') > -1) &&
1362						$(e.originalEvent.target).is(self.selectors.target)
1363					){
1364						$el.off('.mixItUp');
1365						delete el.dataset.bound;
1366						self._targetDone();
1367					}
1368				});
1369			}
1370			
1371			self._execAction('_bindTargetDone', 1, arguments);
1372		},
1373		
1374		/**
1375		 * Target Done
1376		 * @since 2.0.0
1377		 */
1378		
1379		_targetDone: function(){
1380			var self = this;
1381			
1382			self._execAction('_targetDone', 0);
1383			
1384			self._targetsDone++;
1385			
1386			(self._targetsDone === self._targetsBound) && self._cleanUp();
1387			
1388			self._execAction('_targetDone', 1);
1389		},
1390		
1391		/**
1392		 * Clean Up
1393		 * @since 2.0.0
1394		 */
1395		
1396		_cleanUp: function(){
1397			var self = this,
1398				targetStyles = self.animation.animateResizeTargets ? 'transform opacity width height margin-bottom margin-right' : 'transform opacity';
1399				unBrake = function(){
1400					self._$targets.removeStyle('transition', self._prefix);
1401				};
1402				
1403			self._execAction('_cleanUp', 0);
1404			
1405			!self._changingLayout ?
1406				self._$show.css('display',self.layout.display) :
1407				self._$show.css('display',self._newDisplay);
1408			
1409			self._$targets.css(self._brake);
1410			
1411			self._$targets
1412				.removeStyle(targetStyles, self._prefix)
1413				.removeAttr('data-inter-pos-x data-inter-pos-y data-final-pos-x data-final-pos-y data-orig-pos-x data-orig-pos-y data-orig-height data-orig-width data-final-height data-final-width data-inter-width data-inter-height data-orig-margin-right data-orig-margin-bottom data-inter-margin-right data-inter-margin-bottom data-final-margin-right data-final-margin-bottom');
1414				
1415			self._$hide.removeStyle('display');
1416			
1417			self._$parent.removeStyle('height transition perspective-distance perspective perspective-origin-x perspective-origin-y perspective-origin perspectiveOrigin', self._prefix);
1418			
1419			if(self._sorting){
1420				self._printSort();
1421				self._activeSort = self._newSortString;
1422				self._sorting = false;
1423			}
1424			
1425			if(self._changingLayout){
1426				if(self._changingDisplay){
1427					self.layout.display = self._newDisplay;
1428					self._changingDisplay = false;
1429				}
1430				
1431				if(self._changingClass){
1432					self._$parent.removeClass(self.layout.containerClass).addClass(self._newClass);
1433					self.layout.containerClass = self._newClass;
1434					self._changingClass = false;
1435				}
1436				
1437				self._changingLayout = false;
1438			}
1439			
1440			self._refresh();
1441			
1442			self._buildState();
1443			
1444			if(self._state.fail){
1445				self._$container.addClass(self.layout.containerClassFail);
1446			}
1447			
1448			self._$show = $();
1449			self._$hide = $();
1450			
1451			if(window.requestAnimationFrame){
1452				requestAnimationFrame(unBrake);
1453			}
1454			
1455			self._mixing = false;
1456			
1457			if(typeof self.callbacks._user === 'function'){
1458				self.callbacks._user.call(self._domNode, self._state, self);
1459			}
1460			
1461			if(typeof self.callbacks.onMixEnd === 'function'){
1462				self.callbacks.onMixEnd.call(self._domNode, self._state, self);
1463			}
1464			
1465			self._$container.trigger('mixEnd', [self._state, self]);
1466			
1467			if(self._state.fail){
1468				(typeof self.callbacks.onMixFail === 'function') && self.callbacks.onMixFail.call(self._domNode, self._state, self);
1469				self._$container.trigger('mixFail', [self._state, self]);
1470			}
1471			
1472			if(self._loading){
1473				(typeof self.callbacks.onMixLoad === 'function') && self.callbacks.onMixLoad.call(self._domNode, self._state, self);
1474				self._$container.trigger('mixLoad', [self._state, self]);
1475			}
1476			
1477			if(self._queue.length){
1478				self._execAction('_queue', 0);
1479				
1480				self.multiMix(self._queue[0][0],self._queue[0][1],self._queue[0][2]);
1481				self._queue.splice(0, 1);
1482			}
1483			
1484			self._execAction('_cleanUp', 1);
1485			
1486			self._loading = false;
1487		},
1488		
1489		/**
1490		 * Get Prefixed CSS
1491		 * @since 2.0.0
1492		 * @param {string} property
1493		 * @param {string} value
1494		 * @param {boolean} prefixValue
1495		 * @return {object} styles
1496		 */
1497		
1498		_getPrefixedCSS: function(property, value, prefixValue){
1499			var self = this,
1500				styles = {};
1501		
1502			for(i = 0; i < 2; i++){
1503				var prefix = i === 0 ? self._prefix : '';
1504				prefixValue ? styles[prefix+property] = prefix+value : styles[prefix+property] = value;
1505			}
1506			
1507			return self._execFilter('_getPrefixedCSS', styles, arguments);
1508		},
1509		
1510		/**
1511		 * Get Delay
1512		 * @since 2.0.0
1513		 * @param {number} i
1514		 * @return {number} delay
1515		 */
1516		
1517		_getDelay: function(i){
1518			var self = this,
1519				n = typeof self.animation.staggerSequence === 'function' ? self.animation.staggerSequence.call(self._domNode, i, self._state) : i,
1520				delay = self.animation.stagger ? n * self.animation.staggerDuration : 0;
1521				
1522			return self._execFilter('_getDelay', delay, arguments);
1523		},
1524		
1525		/**
1526		 * Parse MultiMix Arguments
1527		 * @since 2.0.0
1528		 * @param {array} args
1529		 * @return {object} output
1530		 */
1531		
1532		_parseMultiMixArgs: function(args){
1533			var self = this,
1534				output = {
1535					command: null,
1536					animate: self.animation.enable,
1537					callback: null
1538				};
1539				
1540			for(var i = 0; i < args.length; i++){
1541				var arg = args[i];
1542
1543				if(arg !== null){
1544					if(typeof arg === 'object' || typeof arg === 'string'){
1545						output.command = arg;
1546					} else if(typeof arg === 'boolean'){
1547						output.animate = arg;
1548					} else if(typeof arg === 'function'){
1549						output.callback = arg;
1550					}
1551				}
1552			}
1553			
1554			return self._execFilter('_parseMultiMixArgs', output, arguments);
1555		},
1556		
1557		/**
1558		 * Parse Insert Arguments
1559		 * @since 2.0.0
1560		 * @param {array} args
1561		 * @return {object} output
1562		 */
1563		
1564		_parseInsertArgs: function(args){
1565			var self = this,
1566				output = {
1567					index: 0,
1568					$object: $(),
1569					multiMix: {filter: self._state.activeFilter},
1570					callback: null
1571				};
1572			
1573			for(var i = 0; i < args.length; i++){
1574				var arg = args[i];
1575				
1576				if(typeof arg === 'number'){
1577					output.index = arg;
1578				} else if(typeof arg === 'object' && arg instanceof $){
1579					output.$object = arg;
1580				} else if(typeof arg === 'object' && self._helpers._isElement(arg)){
1581					output.$object = $(arg);
1582				} else if(typeof arg === 'object' && arg !== null){
1583					output.multiMix = arg;
1584				} else if(typeof arg === 'boolean' && !arg){
1585					output.multiMix = false;
1586				} else if(typeof arg === 'function'){
1587					output.callback = arg;
1588				}
1589			}
1590			
1591			return self._execFilter('_parseInsertArgs', output, arguments);
1592		},
1593		
1594		/**
1595		 * Execute Action
1596		 * @since 2.0.0
1597		 * @param {string} methodName
1598		 * @param {boolean} isPost
1599		 * @param {array} args
1600		 */
1601		
1602		_execAction: function(methodName, isPost, args){
1603			var self = this,
1604				context = isPost ? 'post' : 'pre';
1605
1606			if(!self._actions.isEmptyObject && self._actions.hasOwnProperty(methodName)){
1607				for(var key in self._actions[methodName][context]){
1608					self._actions[methodName][context][key].call(self, args);
1609				}
1610			}
1611		},
1612		
1613		/**
1614		 * Execute Filter
1615		 * @since 2.0.0
1616		 * @param {string} methodName
1617		 * @param {mixed} value
1618		 * @return {mixed} value
1619		 */
1620		
1621		_execFilter: function(methodName, value, args){
1622			var self = this;
1623			
1624			if(!self._filters.isEmptyObject && self._filters.hasOwnProperty(methodName)){
1625				for(var key in self._filters[methodName]){
1626					return self._filters[methodName][key].call(self, args);
1627				}
1628			} else {
1629				return value;
1630			}
1631		},
1632		
1633		/* Helpers
1634		---------------------------------------------------------------------- */
1635
1636		_helpers: {
1637			
1638			/**
1639			 * CamelCase
1640			 * @since 2.0.0
1641			 * @param {string}
1642			 * @return {string}
1643			 */
1644
1645			_camelCase: function(string){
1646				return string.replace(/-([a-z])/g, function(g){
1647						return g[1].toUpperCase();
1648				});
1649			},
1650			
1651			/**
1652			 * Is Element
1653			 * @since 2.1.3
1654			 * @param {object} element to test
1655			 * @return {boolean}
1656			 */
1657			
1658			_isElement: function(el){
1659				if(window.HTMLElement){
1660					return el instanceof HTMLElement;
1661				} else {
1662					return (
1663						el !== null && 
1664						el.nodeType === 1 &&
1665						el.nodeName === 'string'
1666					);
1667				}
1668			}
1669		},
1670		
1671		/* Public Methods
1672		---------------------------------------------------------------------- */
1673		
1674		/**
1675		 * Is Mixing
1676		 * @since 2.0.0
1677		 * @return {boolean}
1678		 */
1679		
1680		isMixing: function(){
1681			var self = this;
1682			
1683			return self._execFilter('isMixing', self._mixing);
1684		},
1685		
1686		/**
1687		 * Filter (public)
1688		 * @since 2.0.0
1689		 * @param {array} arguments
1690		 */
1691		
1692		filter: function(){
1693			var self = this,
1694				args = self._parseMultiMixArgs(arguments);
1695
1696			self._clicking && (self._toggleString = '');
1697			
1698			self.multiMix({filter: args.command}, args.animate, args.callback);
1699		},
1700		
1701		/**
1702		 * Sort (public)
1703		 * @since 2.0.0
1704		 * @param {array} arguments
1705		 */
1706		
1707		sort: function(){
1708			var self = this,
1709				args = self._parseMultiMixArgs(arguments);
1710
1711			self.multiMix({sort: args.command}, args.animate, args.callback);
1712		},
1713
1714		/**
1715		 * Change Layout (public)
1716		 * @since 2.0.0
1717		 * @param {array} arguments
1718		 */
1719		
1720		changeLayout: function(){
1721			var self = this,
1722				args = self._parseMultiMixArgs(arguments);
1723				
1724			self.multiMix({changeLayout: args.command}, args.animate, args.callback);
1725		},
1726		
1727		/**
1728		 * MultiMix
1729		 * @since 2.0.0
1730		 * @param {array} arguments
1731		 */
1732		
1733		multiMix: function(){
1734			var self = this,
1735				args = self._parseMultiMixArgs(arguments);
1736
1737			self._execAction('multiMix', 0, arguments);
1738
1739			if(!self._mixing){
1740				if(self.controls.enable && !self._clicking){
1741					self.controls.toggleFilterButtons && self._buildToggleArray();
1742					self._updateControls(args.command, self.controls.toggleFilterButtons);
1743				}
1744				
1745				(self._queue.length < 2) && (self._clicking = false);
1746			
1747				delete self.callbacks._user;
1748				if(args.callback) self.callbacks._user = args.callback;
1749			
1750				var sort = args.command.sort,
1751					filter = args.command.filter,
1752					changeLayout = args.command.changeLayout;
1753
1754				self._refresh();
1755
1756				if(sort){
1757					self._newSort = self._parseSort(sort);
1758					self._newSortString = sort;
1759					
1760					self._sorting = true;
1761					self._sort();
1762				}
1763				
1764				if(filter !== undf){
1765					filter = (filter === 'all') ? self.selectors.target : filter;
1766	
1767					self._activeFilter = filter;
1768				}
1769				
1770				self._filter();
1771				
1772				if(changeLayout){
1773					self._newDisplay = (typeof changeLayout === 'string') ? changeLayout : changeLayout.display || self.layout.display;
1774					self._newClass = changeLayout.containerClass || '';
1775
1776					if(
1777						self._newDisplay !== self.layout.display ||
1778						self._newClass !== self.layout.containerClass
1779					){
1780						self._changingLayout = true;
1781						
1782						self._changingClass = (self._newClass !== self.layout.containerClass);
1783						self._changingDisplay = (self._newDisplay !== self.layout.display);
1784					}
1785				}
1786				
1787				self._$targets.css(self._brake);
1788				
1789				self._goMix(args.animate ^ self.animation.enable ? args.animate : self.animation.enable);
1790				
1791				self._execAction('multiMix', 1, arguments);
1792				
1793			} else {
1794				if(self.animation.queue && self._queue.length < self.animation.queueLimit){
1795					self._queue.push(arguments);
1796					
1797					(self.controls.enable && !self._clicking) && self._updateControls(args.command);
1798					
1799					self._execAction('multiMixQueue', 1, arguments);
1800					
1801				} else {
1802					if(typeof self.callbacks.onMixBusy === 'function'){
1803						self.callbacks.onMixBusy.call(self._domNode, self._state, self);
1804					}
1805					self._$container.trigger('mixBusy', [self._state, self]);
1806					
1807					self._execAction('multiMixBusy', 1, arguments);
1808				}
1809			}
1810		},
1811		
1812		/**
1813		 * Insert
1814		 * @since 2.0.0
1815		 * @param {array} arguments
1816		 */
1817		
1818		insert: function(){
1819			var self = this,
1820				args = self._parseInsertArgs(arguments),
1821				callback = (typeof args.callback === 'function') ? args.callback : null,
1822				frag = document.createDocumentFragment(),
1823				target = (function(){
1824					self._refresh();
1825					
1826					if(self._$targets.length){
1827						return (args.index < self._$targets.length || !self._$targets.length) ? 
1828							self._$targets[args.index] :
1829							self._$targets[self._$targets.length-1].nextElementSibling;
1830					} else {
1831						return self._$parent[0].children[0];
1832					}
1833				})();
1834						
1835			self._execAction('insert', 0, arguments);
1836				
1837			if(args.$object){
1838				for(var i = 0; i < args.$object.length; i++){
1839					var el = args.$object[i];
1840					
1841					frag.appendChild(el);
1842					frag.appendChild(document.createTextNode(' '));
1843				}
1844
1845				self._$parent[0].insertBefore(frag, target);
1846			}
1847			
1848			self._execAction('insert', 1, arguments);
1849			
1850			if(typeof args.multiMix === 'object'){
1851				self.multiMix(args.multiMix, callback);
1852			}
1853		},
1854
1855		/**
1856		 * Prepend
1857		 * @since 2.0.0
1858		 * @param {array} arguments
1859		 */
1860		
1861		prepend: function(){
1862			var self = this,
1863				args = self._parseInsertArgs(arguments);
1864				
1865			self.insert(0, args.$object, args.multiMix, args.callback);
1866		},
1867		
1868		/**
1869		 * Append
1870		 * @since 2.0.0
1871		 * @param {array} arguments
1872		 */
1873		
1874		append: function(){
1875			var self = this,
1876				args = self._parseInsertArgs(arguments);
1877		
1878			self.insert(self._state.totalTargets, args.$object, args.multiMix, args.callback);
1879		},
1880		
1881		/**
1882		 * Get Option
1883		 * @since 2.0.0
1884		 * @param {string} string
1885		 * @return {mixed} value
1886		 */
1887		
1888		getOption: function(string){
1889			var self = this,
1890				getProperty = function(obj, prop){
1891					var parts = prop.split('.'),
1892						last = parts.pop(),
1893						l = parts.length,
1894						i = 1,
1895						current = parts[0] || prop;
1896
1897					while((obj = obj[current]) && i < l){
1898						current = parts[i];
1899						i++;
1900					}
1901
1902					if(obj !== undf){
1903						return obj[last] !== undf ? obj[last] : obj;
1904					}
1905				};
1906
1907			return string ? self._execFilter('getOption', getProperty(self, string), arguments) : self;
1908		},
1909		
1910		/**
1911		 * Set Options
1912		 * @since 2.0.0
1913		 * @param {object} config
1914		 */
1915		
1916		setOptions: function(config){
1917			var self = this;
1918			
1919			self._execAction('setOptions', 0, arguments);
1920			
1921			typeof config === 'object' && $.extend(true, self, config);
1922			
1923			self._execAction('setOptions', 1, arguments);
1924		},
1925		
1926		/**
1927		 * Get State
1928		 * @since 2.0.0
1929		 * @return {object} state
1930		 */
1931		
1932		getState: function(){
1933			var self = this;
1934			
1935			return self._execFilter('getState', self._state, self);
1936		},
1937		
1938		/**
1939		 * Force Refresh
1940		 * @since 2.1.2
1941		 */
1942		
1943		forceRefresh: function(){
1944			var self = this;
1945			
1946			self._refresh(false, true);
1947		},
1948		
1949		/**
1950		 * Destroy
1951		 * @since 2.0.0
1952		 * @param {boolean} hideAll
1953		 */
1954		
1955		destroy: function(hideAll){
1956			var self = this,
1957				filters = $.MixItUp.prototype._bound._filter,
1958				sorts = $.MixItUp.prototype._bound._sort;
1959			
1960			self._execAction('destroy', 0, arguments);
1961		
1962			self._$body
1963				.add($(self.selectors.sort))
1964				.add($(self.selectors.filter))
1965				.off('.mixItUp');
1966			
1967			for(var i = 0; i < self._$targets.length; i++){
1968				var target = self._$targets[i];
1969
1970				hideAll && (target.style.display = '');
1971
1972				delete target.mixParent;
1973			}
1974			
1975			self._execAction('destroy', 1, arguments);
1976
1977			if(filters[self.selectors.filter] && filters[self.selectors.filter] > 1) {
1978				filters[self.selectors.filter]--;
1979			} else if(filters[self.selectors.filter] === 1) {
1980				delete filters[self.selectors.filter];
1981			}
1982
1983			if(sorts[self.selectors.sort] && sorts[self.selectors.sort] > 1) {
1984				sorts[self.selectors.sort]--;
1985			} else if(sorts[self.selectors.sort] === 1) {
1986				delete sorts[self.selectors.sort];
1987			}
1988
1989			delete $.MixItUp.prototype._instances[self._id];
1990		}
1991		
1992	};
1993	
1994	/* jQuery Methods
1995	---------------------------------------------------------------------- */
1996	
1997	/**
1998	 * jQuery .mixItUp() method
1999	 * @since 2.0.0
2000	 * @extends $.fn
2001	 */
2002	
2003	$.fn.mixItUp = function(){
2004		var args = arguments,
2005			dataReturn = [],
2006			eachReturn,
2007			_instantiate = function(domNode, settings){
2008				var instance = new $.MixItUp(),
2009					rand = function(){
2010						return ('00000'+(Math.random()*16777216<<0).toString(16)).substr(-6).toUpperCase();
2011					};
2012					
2013				instance._execAction('_instantiate', 0, arguments);
2014
2015				domNode.id = !domNode.id ? 'MixItUp'+rand() : domNode.id;
2016				
2017				if(!instance._instances[domNode.id]){
2018					instance._instances[domNode.id] = instance;
2019					instance._init(domNode, settings);
2020				}
2021				
2022				instance._execAction('_instantiate', 1, arguments);
2023			};
2024			
2025		eachReturn = this.each(function(){
2026			if(args && typeof args[0] === 'string'){
2027				var instance = $.MixItUp.prototype._instances[this.id];
2028				if(args[0] === 'isLoaded'){
2029					dataReturn.push(instance ? true : false);
2030				} else {
2031					var data = instance[args[0]](args[1], args[2], args[3]);
2032					if(data !== undf)dataReturn.push(data);
2033				}
2034			} else {
2035				_instantiate(this, args[0]);
2036			}
2037		});
2038		
2039		if(dataReturn.length){
2040			return dataReturn.length > 1 ? dataReturn : dataReturn[0];
2041		} else {
2042			return eachReturn;
2043		}
2044	};
2045	
2046	/**
2047	 * jQuery .removeStyle() method
2048	 * @since 2.0.0
2049	 * @extends $.fn
2050	 */
2051	
2052	$.fn.removeStyle = function(style, prefix){
2053		prefix = prefix ? prefix : '';
2054	
2055		return this.each(function(){
2056			var el = this,
2057				styles = style.split(' ');
2058				
2059			for(var i = 0; i < styles.length; i++){
2060				for(var j = 0; j < 4; j++){
2061					switch (j) {
2062						case 0:
2063							var prop = styles[i];
2064							break;
2065						case 1:
2066							var prop = $.MixItUp.prototype._helpers._camelCase(prop);
2067							break;
2068						case 2:
2069							var prop = prefix+styles[i];
2070							break;
2071						case 3:
2072							var prop = $.MixItUp.prototype._helpers._camelCase(prefix+styles[i]);
2073					}
2074					
2075					if(
2076						el.style[prop] !== undf && 
2077						typeof el.style[prop] !== 'unknown' &&
2078						el.style[prop].length > 0
2079					){
2080						el.style[prop] = '';
2081					}
2082					
2083					if(!prefix && j === 1)break;
2084				}
2085			}
2086			
2087			if(el.attributes && el.attributes.style && el.attributes.style !== undf && el.attributes.style.value === ''){
2088				el.attributes.removeNamedItem('style');
2089			}
2090		});
2091	};
2092	
2093})(jQuery);

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.