PageSourceSearch

https://www.aimcharity.org/js/mixitup.js

js aimcharity.org collected 2026-09-24 12:31:30 UTC 52,224 bytes, 2,098 lines download raw bytes

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