PageSourceSearch

https://www.losnotrequired.com/static/content_page-6d0843f94c45121…fcd3cd2bd60bee768bed6760422145af4ecd3bff.js

js losnotrequired.com collected 2026-09-26 05:52:23 UTC 530,142 bytes, 16,888 lines download raw bytes

1/**
2 * jQuery Validation Plugin @VERSION
3 *
4 * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
5 * http://docs.jquery.com/Plugins/Validation
6 *
7 * Copyright (c) 2006 - 2011 Jörn Zaefferer
8 *
9 * Dual licensed under the MIT and GPL licenses:
10 *   http://www.opensource.org/licenses/mit-license.php
11 *   http://www.gnu.org/licenses/gpl.html
12 */
13
14
15(function($) {
16
17$.extend($.fn, {
18	// http://docs.jquery.com/Plugins/Validation/validate
19	validate: function( options ) {
20
21		// if nothing is selected, return nothing; can't chain anyway
22		if (!this.length) {
23			options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" );
24			return;
25		}
26
27		// check if a validator for this form was already created
28		var validator = $.data(this[0], 'validator');
29		if ( validator ) {
30			return validator;
31		}
32
33		validator = new $.validator( options, this[0] );
34		$.data(this[0], 'validator', validator);
35
36		if ( validator.settings.onsubmit ) {
37
38			// allow suppresing validation by adding a cancel class to the submit button
39			this.find("input, button").filter(".cancel").click(function() {
40				validator.cancelSubmit = true;
41			});
42
43			// when a submitHandler is used, capture the submitting button
44			if (validator.settings.submitHandler) {
45				this.find("input, button").filter(":submit").click(function() {
46					validator.submitButton = this;
47				});
48			}
49
50			// validate the form on submit
51			this.submit( function( event ) {
52				if ( validator.settings.debug )
53					// prevent form submit to be able to see console output
54					event.preventDefault();
55
56				function handle() {
57					if ( validator.settings.submitHandler ) {
58						if (validator.submitButton) {
59							// insert a hidden input as a replacement for the missing submit button
60							var hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);
61						}
62						validator.settings.submitHandler.call( validator, validator.currentForm );
63						if (validator.submitButton) {
64							// and clean up afterwards; thanks to no-block-scope, hidden can be referenced
65							hidden.remove();
66						}
67						return false;
68					}
69					return true;
70				}
71
72				// prevent submit for invalid forms or custom submit handlers
73				if ( validator.cancelSubmit ) {
74					validator.cancelSubmit = false;
75					return handle();
76				}
77				if ( validator.form() ) {
78					if ( validator.pendingRequest ) {
79						validator.formSubmitted = true;
80						return false;
81					}
82					return handle();
83				} else {
84					validator.focusInvalid();
85					return false;
86				}
87			});
88		}
89
90		return validator;
91	},
92	// http://docs.jquery.com/Plugins/Validation/valid
93	valid: function() {
94        if ( $(this[0]).is('form')) {
95            return this.validate().form();
96        } else {
97            var valid = true;
98            var validator = $(this[0].form).validate();
99            this.each(function() {
100				valid &= validator.element(this);
101            });
102            return valid;
103        }
104    },
105	// attributes: space seperated list of attributes to retrieve and remove
106	removeAttrs: function(attributes) {
107		var result = {},
108			$element = this;
109		$.each(attributes.split(/\s/), function(index, value) {
110			result[value] = $element.attr(value);
111			$element.removeAttr(value);
112		});
113		return result;
114	},
115	// http://docs.jquery.com/Plugins/Validation/rules
116	rules: function(command, argument) {
117		var element = this[0];
118
119		if (command) {
120			var settings = $.data(element.form, 'validator').settings;
121			var staticRules = settings.rules;
122			var existingRules = $.validator.staticRules(element);
123			switch(command) {
124			case "add":
125				$.extend(existingRules, $.validator.normalizeRule(argument));
126				staticRules[element.name] = existingRules;
127				if (argument.messages)
128					settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
129				break;
130			case "remove":
131				if (!argument) {
132					delete staticRules[element.name];
133					return existingRules;
134				}
135				var filtered = {};
136				$.each(argument.split(/\s/), function(index, method) {
137					filtered[method] = existingRules[method];
138					delete existingRules[method];
139				});
140				return filtered;
141			}
142		}
143
144		var data = $.validator.normalizeRules(
145		$.extend(
146			{},
147			$.validator.metadataRules(element),
148			$.validator.classRules(element),
149			$.validator.attributeRules(element),
150			$.validator.staticRules(element)
151		), element);
152
153		// make sure required is at front
154		if (data.required) {
155			var param = data.required;
156			delete data.required;
157			data = $.extend({required: param}, data);
158		}
159
160		return data;
161	}
162});
163
164// Custom selectors
165$.extend($.expr[":"], {
166	// http://docs.jquery.com/Plugins/Validation/blank
167	blank: function(a) {return !$.trim("" + a.value);},
168	// http://docs.jquery.com/Plugins/Validation/filled
169	filled: function(a) {return !!$.trim("" + a.value);},
170	// http://docs.jquery.com/Plugins/Validation/unchecked
171	unchecked: function(a) {return !a.checked;}
172});
173
174// constructor for validator
175$.validator = function( options, form ) {
176	this.settings = $.extend( true, {}, $.validator.defaults, options );
177	this.currentForm = form;
178	this.init();
179};
180
181$.validator.format = function(source, params) {
182	if ( arguments.length == 1 )
183		return function() {
184			var args = $.makeArray(arguments);
185			args.unshift(source);
186			return $.validator.format.apply( this, args );
187		};
188	if ( arguments.length > 2 && params.constructor != Array  ) {
189		params = $.makeArray(arguments).slice(1);
190	}
191	if ( params.constructor != Array ) {
192		params = [ params ];
193	}
194	$.each(params, function(i, n) {
195		source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
196	});
197	return source;
198};
199
200$.extend($.validator, {
201
202	defaults: {
203		messages: {},
204		groups: {},
205		rules: {},
206		errorClass: "error",
207		validClass: "valid",
208		errorElement: "label",
209		focusInvalid: true,
210		errorContainer: $( [] ),
211		errorLabelContainer: $( [] ),
212		onsubmit: true,
213		ignore: [],
214		ignoreTitle: false,
215		onfocusin: function(element) {
216			this.lastActive = element;
217
218			// hide error label and remove error class on focus if enabled
219			if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
220				this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
221				this.addWrapper(this.errorsFor(element)).hide();
222			}
223		},
224		onfocusout: function(element) {
225			if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
226				this.element(element);
227			}
228		},
229		onkeyup: function(element) {
230			if ( element.name in this.submitted || element == this.lastElement ) {
231				this.element(element);
232			}
233		},
234		onclick: function(element) {
235			// click on selects, radiobuttons and checkboxes
236			if ( element.name in this.submitted )
237				this.element(element);
238			// or option elements, check parent select in that case
239			else if (element.parentNode.name in this.submitted)
240				this.element(element.parentNode);
241		},
242		highlight: function(element, errorClass, validClass) {
243			if (element.type === 'radio') {
244				this.findByName(element.name).addClass(errorClass).removeClass(validClass);
245			} else {
246				$(element).addClass(errorClass).removeClass(validClass);
247			}
248		},
249		unhighlight: function(element, errorClass, validClass) {
250			if (element.type === 'radio') {
251				this.findByName(element.name).removeClass(errorClass).addClass(validClass);
252			} else {
253				$(element).removeClass(errorClass).addClass(validClass);
254			}
255		}
256	},
257
258	// http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
259	setDefaults: function(settings) {
260		$.extend( $.validator.defaults, settings );
261	},
262
263	messages: {
264		required: "This field is required.",
265		remote: "Please fix this field.",
266		email: "Please enter a valid email address.",
267		url: "Please enter a valid URL.",
268		date: "Please enter a valid date.",
269		dateISO: "Please enter a valid date (ISO).",
270		number: "Please enter a valid number.",
271		digits: "Please enter only digits.",
272		creditcard: "Please enter a valid credit card number.",
273		equalTo: "Please enter the same value again.",
274		accept: "Please enter a value with a valid extension.",
275		maxlength: $.validator.format("Please enter no more than {0} characters."),
276		minlength: $.validator.format("Please enter at least {0} characters."),
277		rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
278		range: $.validator.format("Please enter a value between {0} and {1}."),
279		max: $.validator.format("Please enter a value less than or equal to {0}."),
280		min: $.validator.format("Please enter a value greater than or equal to {0}.")
281	},
282
283	autoCreateRanges: false,
284
285	prototype: {
286
287		init: function() {
288			this.labelContainer = $(this.settings.errorLabelContainer);
289			this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
290			this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
291			this.submitted = {};
292			this.valueCache = {};
293			this.pendingRequest = 0;
294			this.pending = {};
295			this.invalid = {};
296			this.reset();
297
298			var groups = (this.groups = {});
299			$.each(this.settings.groups, function(key, value) {
300				$.each(value.split(/\s/), function(index, name) {
301					groups[name] = key;
302				});
303			});
304			var rules = this.settings.rules;
305			$.each(rules, function(key, value) {
306				rules[key] = $.validator.normalizeRule(value);
307			});
308
309			function delegate(event) {
310				var validator = $.data(this[0].form, "validator"),
311					eventType = "on" + event.type.replace(/^validate/, "");
312				validator.settings[eventType] && validator.settings[eventType].call(validator, this[0] );
313			}
314			$(this.currentForm)
315				.validateDelegate(":text, :password, :file, select, textarea", "focusin focusout keyup", delegate)
316				.validateDelegate(":radio, :checkbox, select, option", "click", delegate);
317
318			if (this.settings.invalidHandler)
319				$(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
320		},
321
322		// http://docs.jquery.com/Plugins/Validation/Validator/form
323		form: function() {
324			this.checkForm();
325			$.extend(this.submitted, this.errorMap);
326			this.invalid = $.extend({}, this.errorMap);
327			if (!this.valid())
328				$(this.currentForm).triggerHandler("invalid-form", [this]);
329			this.showErrors();
330			return this.valid();
331		},
332
333		checkForm: function() {
334			this.prepareForm();
335			for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
336				this.check( elements[i] );
337			}
338			return this.valid();
339		},
340
341		// http://docs.jquery.com/Plugins/Validation/Validator/element
342		element: function( element ) {
343			element = this.clean( element );
344			this.lastElement = element;
345			this.prepareElement( element );
346			this.currentElements = $(element);
347			var result = this.check( element );
348			if ( result ) {
349				delete this.invalid[element.name];
350			} else {
351				this.invalid[element.name] = true;
352			}
353			if ( !this.numberOfInvalids() ) {
354				// Hide error containers on last error
355				this.toHide = this.toHide.add( this.containers );
356			}
357			this.showErrors();
358			return result;
359		},
360
361		// http://docs.jquery.com/Plugins/Validation/Validator/showErrors
362		showErrors: function(errors) {
363			if(errors) {
364				// add items to error list and map
365				$.extend( this.errorMap, errors );
366				this.errorList = [];
367				for ( var name in errors ) {
368					this.errorList.push({
369						message: errors[name],
370						element: this.findByName(name)[0]
371					});
372				}
373				// remove items from success list
374				this.successList = $.grep( this.successList, function(element) {
375					return !(element.name in errors);
376				});
377			}
378			this.settings.showErrors
379				? this.settings.showErrors.call( this, this.errorMap, this.errorList )
380				: this.defaultShowErrors();
381		},
382
383		// http://docs.jquery.com/Plugins/Validation/Validator/resetForm
384		resetForm: function() {
385			if ( $.fn.resetForm )
386				$( this.currentForm ).resetForm();
387			this.submitted = {};
388			this.prepareForm();
389			this.hideErrors();
390			this.elements().removeClass( this.settings.errorClass );
391		},
392
393		numberOfInvalids: function() {
394			return this.objectLength(this.invalid);
395		},
396
397		objectLength: function( obj ) {
398			var count = 0;
399			for ( var i in obj )
400				count++;
401			return count;
402		},
403
404		hideErrors: function() {
405			this.addWrapper( this.toHide ).hide();
406		},
407
408		valid: function() {
409			return this.size() == 0;
410		},
411
412		size: function() {
413			return this.errorList.length;
414		},
415
416		focusInvalid: function() {
417			if( this.settings.focusInvalid ) {
418				try {
419					$(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
420					.filter(":visible")
421					.focus()
422					// manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
423					.trigger("focusin");
424				} catch(e) {
425					// ignore IE throwing errors when focusing hidden elements
426				}
427			}
428		},
429
430		findLastActive: function() {
431			var lastActive = this.lastActive;
432			return lastActive && $.grep(this.errorList, function(n) {
433				return n.element.name == lastActive.name;
434			}).length == 1 && lastActive;
435		},
436
437		elements: function() {
438			var validator = this,
439				rulesCache = {};
440
441			// select all valid inputs inside the form (no submit or reset buttons)
442			return $(this.currentForm)
443			.find("input, select, textarea")
444			.not(":submit, :reset, :image, [disabled]")
445			.not( this.settings.ignore )
446			.filter(function() {
447				!this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this);
448
449				// select only the first element for each name, and only those with rules specified
450				if ( this.name in rulesCache || !validator.objectLength($(this).rules()) )
451					return false;
452
453				rulesCache[this.name] = true;
454				return true;
455			});
456		},
457
458		clean: function( selector ) {
459			return $( selector )[0];
460		},
461
462		errors: function() {
463			return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext );
464		},
465
466		reset: function() {
467			this.successList = [];
468			this.errorList = [];
469			this.errorMap = {};
470			this.toShow = $([]);
471			this.toHide = $([]);
472			this.currentElements = $([]);
473		},
474
475		prepareForm: function() {
476			this.reset();
477			this.toHide = this.errors().add( this.containers );
478		},
479
480		prepareElement: function( element ) {
481			this.reset();
482			this.toHide = this.errorsFor(element);
483		},
484
485		check: function( element ) {
486			element = this.clean( element );
487
488			// if radio/checkbox, validate first element in group instead
489			if (this.checkable(element)) {
490				element = this.findByName( element.name ).not(this.settings.ignore)[0];
491			}
492
493			var rules = $(element).rules();
494			var dependencyMismatch = false;
495			for (var method in rules ) {
496				var rule = { method: method, parameters: rules[method] };
497				try {
498					var result = $.validator.methods[method].call( this, element.value.replace(/\r/g, ""), element, rule.parameters );
499
500					// if a method indicates that the field is optional and therefore valid,
501					// don't mark it as valid when there are no other rules
502					if ( result == "dependency-mismatch" ) {
503						dependencyMismatch = true;
504						continue;
505					}
506					dependencyMismatch = false;
507
508					if ( result == "pending" ) {
509						this.toHide = this.toHide.not( this.errorsFor(element) );
510						return;
511					}
512
513					if( !result ) {
514						this.formatAndAdd( element, rule );
515						return false;
516					}
517				} catch(e) {
518					this.settings.debug && window.console && console.log("exception occurred when checking element " + element.id
519						 + ", check the '" + rule.method + "' method", e);
520					throw e;
521				}
522			}
523			if (dependencyMismatch)
524				return;
525			if ( this.objectLength(rules) )
526				this.successList.push(element);
527			return true;
528		},
529
530		// return the custom message for the given element and validation method
531		// specified in the element's "messages" metadata
532		customMetaMessage: function(element, method) {
533			if (!$.metadata)
534				return;
535
536			var meta = this.settings.meta
537				? $(element).metadata()[this.settings.meta]
538				: $(element).metadata();
539
540			return meta && meta.messages && meta.messages[method];
541		},
542
543		// return the custom message for the given element name and validation method
544		customMessage: function( name, method ) {
545			var m = this.settings.messages[name];
546			return m && (m.constructor == String
547				? m
548				: m[method]);
549		},
550
551		// return the first defined argument, allowing empty strings
552		findDefined: function() {
553			for(var i = 0; i < arguments.length; i++) {
554				if (arguments[i] !== undefined)
555					return arguments[i];
556			}
557			return undefined;
558		},
559
560		defaultMessage: function( element, method) {
561			return this.findDefined(
562				this.customMessage( element.name, method ),
563				this.customMetaMessage( element, method ),
564				// title is never undefined, so handle empty string as undefined
565				!this.settings.ignoreTitle && element.title || undefined,
566				$.validator.messages[method],
567				"<strong>Warning: No message defined for " + element.name + "</strong>"
568			);
569		},
570
571		formatAndAdd: function( element, rule ) {
572			var message = this.defaultMessage( element, rule.method ),
573				theregex = /\$?\{(\d+)\}/g;
574			if ( typeof message == "function" ) {
575				message = message.call(this, rule.parameters, element);
576			} else if (theregex.test(message)) {
577				message = $.format(message.replace(theregex, '{$1}'), rule.parameters);
578			}
579			this.errorList.push({
580				message: message,
581				element: element
582			});
583
584			this.errorMap[element.name] = message;
585			this.submitted[element.name] = message;
586		},
587
588		addWrapper: function(toToggle) {
589			if ( this.settings.wrapper )
590				toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
591			return toToggle;
592		},
593
594		defaultShowErrors: function() {
595			for ( var i = 0; this.errorList[i]; i++ ) {
596				var error = this.errorList[i];
597				this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.val
597idClass );
598				this.showLabel( error.element, error.message );
599			}
600			if( this.errorList.length ) {
601				this.toShow = this.toShow.add( this.containers );
602			}
603			if (this.settings.success) {
604				for ( var i = 0; this.successList[i]; i++ ) {
605					this.showLabel( this.successList[i] );
606				}
607			}
608			if (this.settings.unhighlight) {
609				for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {
610					this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );
611				}
612			}
613			this.toHide = this.toHide.not( this.toShow );
614			this.hideErrors();
615			this.addWrapper( this.toShow ).show();
616		},
617
618		validElements: function() {
619			return this.currentElements.not(this.invalidElements());
620		},
621
622		invalidElements: function() {
623			return $(this.errorList).map(function() {
624				return this.element;
625			});
626		},
627
628		showLabel: function(element, message) {
629			var label = this.errorsFor( element );
630			if ( label.length ) {
631				// refresh error/success class
632				label.removeClass().addClass( this.settings.errorClass );
633
634				// check if we have a generated label, replace the message then
635				label.attr("generated") && label.html(message);
636			} else {
637				// create label
638				label = $("<" + this.settings.errorElement + "/>")
639					.attr({"for":  this.idOrName(element), generated: true})
640					.addClass(this.settings.errorClass)
641					.html(message || "");
642				if ( this.settings.wrapper ) {
643					// make sure the element is visible, even in IE
644					// actually showing the wrapped element is handled elsewhere
645					label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
646				}
647				if ( !this.labelContainer.append(label).length )
648					this.settings.errorPlacement
649						? this.settings.errorPlacement(label, $(element) )
650						: label.insertAfter(element);
651			}
652			if ( !message && this.settings.success ) {
653				label.text("");
654				typeof this.settings.success == "string"
655					? label.addClass( this.settings.success )
656					: this.settings.success( label );
657			}
658			this.toShow = this.toShow.add(label);
659		},
660
661		errorsFor: function(element) {
662			var name = this.idOrName(element);
663    		return this.errors().filter(function() {
664				return $(this).attr('for') == name;
665			});
666		},
667
668		idOrName: function(element) {
669			return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
670		},
671
672		checkable: function( element ) {
673			return /radio|checkbox/i.test(element.type);
674		},
675
676		findByName: function( name ) {
677			// select by name and filter by form for performance over form.find("[name=...]")
678			var form = this.currentForm;
679			return $(document.getElementsByName(name)).map(function(index, element) {
680				return element.form == form && element.name == name && element  || null;
681			});
682		},
683
684		getLength: function(value, element) {
685			switch( element.nodeName.toLowerCase() ) {
686			case 'select':
687				return $("option:selected", element).length;
688			case 'input':
689				if( this.checkable( element) )
690					return this.findByName(element.name).filter(':checked').length;
691			}
692			return value.length;
693		},
694
695		depend: function(param, element) {
696			return this.dependTypes[typeof param]
697				? this.dependTypes[typeof param](param, element)
698				: true;
699		},
700
701		dependTypes: {
702			"boolean": function(param, element) {
703				return param;
704			},
705			"string": function(param, element) {
706				return !!$(param, element.form).length;
707			},
708			"function": function(param, element) {
709				return param(element);
710			}
711		},
712
713		optional: function(element) {
714			return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch";
715		},
716
717		startRequest: function(element) {
718			if (!this.pending[element.name]) {
719				this.pendingRequest++;
720				this.pending[element.name] = true;
721			}
722		},
723
724		stopRequest: function(element, valid) {
725			this.pendingRequest--;
726			// sometimes synchronization fails, make sure pendingRequest is never < 0
727			if (this.pendingRequest < 0)
728				this.pendingRequest = 0;
729			delete this.pending[element.name];
730			if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) {
731				$(this.currentForm).submit();
732				this.formSubmitted = false;
733			} else if (!valid && this.pendingRequest == 0 && this.formSubmitted) {
734				$(this.currentForm).triggerHandler("invalid-form", [this]);
735				this.formSubmitted = false;
736			}
737		},
738
739		previousValue: function(element) {
740			return $.data(element, "previousValue") || $.data(element, "previousValue", {
741				old: null,
742				valid: true,
743				message: this.defaultMessage( element, "remote" )
744			});
745		}
746
747	},
748
749	classRuleSettings: {
750		required: {required: true},
751		email: {email: true},
752		url: {url: true},
753		date: {date: true},
754		dateISO: {dateISO: true},
755		dateDE: {dateDE: true},
756		number: {number: true},
757		numberDE: {numberDE: true},
758		digits: {digits: true},
759		creditcard: {creditcard: true}
760	},
761
762	addClassRules: function(className, rules) {
763		className.constructor == String ?
764			this.classRuleSettings[className] = rules :
765			$.extend(this.classRuleSettings, className);
766	},
767
768	classRules: function(element) {
769		var rules = {};
770		var classes = $(element).attr('class');
771		classes && $.each(classes.split(' '), function() {
772			if (this in $.validator.classRuleSettings) {
773				$.extend(rules, $.validator.classRuleSettings[this]);
774			}
775		});
776		return rules;
777	},
778
779	attributeRules: function(element) {
780		var rules = {};
781		var $element = $(element);
782
783		for (var method in $.validator.methods) {
784			var value = $element.attr(method);
785			if (value) {
786				rules[method] = value;
787			}
788		}
789
790		// maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
791		if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
792			delete rules.maxlength;
793		}
794
795		return rules;
796	},
797
798	metadataRules: function(element) {
799		if (!$.metadata) return {};
800
801		var meta = $.data(element.form, 'validator').settings.meta;
802		return meta ?
803			$(element).metadata()[meta] :
804			$(element).metadata();
805	},
806
807	staticRules: function(element) {
808		var rules = {};
809		var validator = $.data(element.form, 'validator');
810		if (validator.settings.rules) {
811			rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
812		}
813		return rules;
814	},
815
816	normalizeRules: function(rules, element) {
817		// handle dependency check
818		$.each(rules, function(prop, val) {
819			// ignore rule when param is explicitly false, eg. required:false
820			if (val === false) {
821				delete rules[prop];
822				return;
823			}
824			if (val.param || val.depends) {
825				var keepRule = true;
826				switch (typeof val.depends) {
827					case "string":
828						keepRule = !!$(val.depends, element.form).length;
829						break;
830					case "function":
831						keepRule = val.depends.call(element, element);
832						break;
833				}
834				if (keepRule) {
835					rules[prop] = val.param !== undefined ? val.param : true;
836				} else {
837					delete rules[prop];
838				}
839			}
840		});
841
842		// evaluate parameters
843		$.each(rules, function(rule, parameter) {
844			rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
845		});
846
847		// clean number parameters
848		$.each(['minlength', 'maxlength', 'min', 'max'], function() {
849			if (rules[this]) {
850				rules[this] = Number(rules[this]);
851			}
852		});
853		$.each(['rangelength', 'range'], function() {
854			if (rules[this]) {
855				rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
856			}
857		});
858
859		if ($.validator.autoCreateRanges) {
860			// auto-create ranges
861			if (rules.min && rules.max) {
862				rules.range = [rules.min, rules.max];
863				delete rules.min;
864				delete rules.max;
865			}
866			if (rules.minlength && rules.maxlength) {
867				rules.rangelength = [rules.minlength, rules.maxlength];
868				delete rules.minlength;
869				delete rules.maxlength;
870			}
871		}
872
873		// To support custom messages in metadata ignore rule methods titled "messages"
874		if (rules.messages) {
875			delete rules.messages;
876		}
877
878		return rules;
879	},
880
881	// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
882	normalizeRule: function(data) {
883		if( typeof data == "string" ) {
884			var transformed = {};
885			$.each(data.split(/\s/), function() {
886				transformed[this] = true;
887			});
888			data = transformed;
889		}
890		return data;
891	},
892
893	// http://docs.jquery.com/Plugins/Validation/Validator/addMethod
894	addMethod: function(name, method, message) {
895		$.validator.methods[name] = method;
896		$.validator.messages[name] = message != undefined ? message : $.validator.messages[name];
897		if (method.length < 3) {
898			$.validator.addClassRules(name, $.validator.normalizeRule(name));
899		}
900	},
901
902	methods: {
903
904		// http://docs.jquery.com/Plugins/Validation/Methods/required
905		required: function(value, element, param) {
906			// check if dependency is met
907			if ( !this.depend(param, element) )
908				return "dependency-mismatch";
909			switch( element.nodeName.toLowerCase() ) {
910			case 'select':
911				// could be an array for select-multiple or a string, both are fine this way
912				var val = $(element).val();
913				return val && val.length > 0;
914			case 'input':
915				if ( this.checkable(element) )
916					return this.getLength(value, element) > 0;
917			default:
918				return $.trim(value).length > 0;
919			}
920		},
921
922		// http://docs.jquery.com/Plugins/Validation/Methods/remote
923		remote: function(value, element, param) {
924			if ( this.optional(element) )
925				return "dependency-mismatch";
926
927			var previous = this.previousValue(element);
928			if (!this.settings.messages[element.name] )
929				this.settings.messages[element.name] = {};
930			previous.originalMessage = this.settings.messages[element.name].remote;
931			this.settings.messages[element.name].remote = previous.message;
932
933			param = typeof param == "string" && {url:param} || param;
934
935			if ( this.pending[element.name] ) {
936				return "pending";
937			}
938			if ( previous.old === value ) {
939				return previous.valid;
940			}
941
942			previous.old = value;
943			var validator = this;
944			this.startRequest(element);
945			var data = {};
946			data[element.name] = value;
947			$.ajax($.extend(true, {
948				url: param,
949				mode: "abort",
950				port: "validate" + element.name,
951				dataType: "json",
952				data: data,
953				success: function(response) {
954					validator.settings.messages[element.name].remote = previous.originalMessage;
955					var valid = response === true;
956					if ( valid ) {
957						var submitted = validator.formSubmitted;
958						validator.prepareElement(element);
959						validator.formSubmitted = submitted;
960						validator.successList.push(element);
961						validator.showErrors();
962					} else {
963						var errors = {};
964						var message = response || validator.defaultMessage( element, "remote" );
965						errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
966						validator.showErrors(errors);
967					}
968					previous.valid = valid;
969					validator.stopRequest(element, valid);
970				}
971			}, param));
972			return "pending";
973		},
974
975		// http://docs.jquery.com/Plugins/Validation/Methods/minlength
976		minlength: function(value, element, param) {
977			return this.optional(element) || this.getLength($.trim(value), element) >= param;
978		},
979
980		// http://docs.jquery.com/Plugins/Validation/Methods/maxlength
981		maxlength: function(value, element, param) {
982			return this.optional(element) || this.getLength($.trim(value), element) <= param;
983		},
984
985		// http://docs.jquery.com/Plugins/Validation/Methods/rangelength
986		rangelength: function(value, element, param) {
987			var length = this.getLength($.trim(value), element);
988			return this.optional(element) || ( length >= param[0] && length <= param[1] );
989		},
990
991		// http://docs.jquery.com/Plugins/Validation/Methods/min
992		min: function( value, element, param ) {
993			return this.optional(element) || value >= param;
994		},
995
996		// http://docs.jquery.com/Plugins/Validation/Methods/max
997		max: function( value, element, param ) {
998			return this.optional(element) || value <= param;
999		},
1000
1001		// http://docs.jquery.com/Plugins/Validation/Methods/range
1002		range: function( value, element, param ) {
1003			return this.optional(element) || ( value >= param[0] && value <= param[1] );
1004		},
1005
1006		// http://docs.jquery.com/Plugins/Validation/Methods/email
1007		email: function(value, element) {
1008			// dfcarney - updated from StackOverflow
1009			// http://stackoverflow.com/questions/2855865/jquery-validate-e-mail-address-regex
1010			// http://ask.altervista.org/demo/jquery-validate-e-mail-address-regex/
1011			// return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);
1012
1013  		// KISS: copied from authentication.rb
1014  		return this.optional(element) || /^.+@.+\..+$/i.test(value);
1015		},
1016
1017		// http://docs.jquery.com/Plugins/Validation/Methods/url
1018		url: function(value, element) {
1019			// contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
1020			return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
1021		},
1022
1023		// http://docs.jquery.com/Plugins/Validation/Methods/date
1024		date: function(value, element) {
1025			return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
1026		},
1027
1028		// http://docs.jquery.com/Plugins/Validation/Methods/dateISO
1029		dateISO: function(value, element) {
1030			return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);
1031		},
1032
1033		// http://docs.jquery.com/Plugins/Validation/Methods/number
1034		number: function(value, element) {
1035			return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);
1036		},
1037
1038		// http://docs.jquery.com/Plugins/Validation/Methods/digits
1039		digits: function(value, element) {
1040			return this.optional(element) || /^\d+$/.test(value);
1041		},
1042
1043		// http://docs.jquery.com/Plugins/Validation/Methods/creditcard
1044		// based on http://en.wikipedia.org/wiki/Luhn
1045		creditcard: function(value, element) {
1046			if ( this.optional(element) )
1047				return "dependency-mismatch";
1048			// accept only digits and dashes
1049			if (/[^0-9-]+/.test(value))
1050				return false;
1051			var nCheck = 0,
1052				nDigit = 0,
1053				bEven = false;
1054
1055			value = value.replace(/\D/g, "");
1056
1057			for (var n = value.length - 1; n >= 0; n--) {
1058				var cDigit = value.charAt(n);
1059				var nDigit = parseInt(cDigit, 10);
1060				if (bEven) {
1061					if ((nDigit *= 2) > 9)
1062						nDigit -= 9;
1063				}
1064				nCheck += nDigit;
1065				bEven = !bEven;
1066			}
1067
1068			return (nCheck % 10) == 0;
1069		},
1070
1071		// http://docs.jquery.com/Plugins/Validation/Methods/accept
1072		accept: function(value, element, param) {
1073			param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif";
1074			return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
1075		},
1076
1077		// http://docs.jquery.com/Plugins/Validation/Methods/equalTo
1078		equalTo: function(value, element, param) {
1079			// bind to the blur event of the target in order to revalidate whenever the target field is updated
1080			// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
1081			var target = $(param).unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {
1082				$(element).valid();
1083			});
1084			return value == target.val();
1085		}
1086
1087	}
1088
1089});
1090
1091// deprecated, use $.validator.format instead
1092$.format = $.validator.format;
1093
1094})(_4ORMAT.$);
1095
1096// ajax mode: abort
1097// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1098// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1099;(function($) {
1100	var pendingRequests = {};
1101	// Use a prefilter if available (1.5+)
1102	if ( $.ajaxPrefilter ) {
1103		$.ajaxPrefilter(function(settings, _, xhr) {
1104			var port = settings.port;
1105			if (settings.mode == "abort") {
1106				if ( pendingRequests[port] ) {
1107					pendingRequests[port].abort();
1108				}
1109				pendingRequests[port] = xhr;
1110			}
1111		});
1112	} else {
1113		// Proxy ajax
1114		var ajax = $.ajax;
1115		$.ajax = function(settings) {
1116			var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
1117				port = ( "port" in settings ? settings : $.ajaxSettings ).port;
1118			if (mode == "abort") {
1119				if ( pendingRequests[port] ) {
1120					pendingRequests[port].abort();
1121				}
1122				return (pendingRequests[port] = ajax.apply(this, arguments));
1123			}
1124			return ajax.apply(this, arguments);
1125		};
1126	}
1127})(_4ORMAT.$);
1128
1129// provides cross-browser focusin and focusout events
1130// IE has native support, in other browsers, use event caputuring (neither bubbles)
1131
1132// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
1133// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
1134;(function($) {
1135	// only implement if not provided by jQuery core (since 1.4)
1136	// TODO verify if jQuery 1.4's implementation is compatible with older jQuery special-event APIs
1137	if (!$.event.special.focusin && !$.event.special.focusout && document.addEventListener) {
1138		$.each({
1139			focus: 'focusin',
1140			blur: 'focusout'
1141		}, function( original, fix ){
1142			$.event.special[fix] = {
1143				setup:function() {
1144					this.addEventListener( original, handler, true );
1145				},
1146				teardown:function() {
1147					this.removeEventListener( original, handler, true );
1148				},
1149				handler: function(e) {
1150					arguments[0] = $.event.fix(e);
1151					arguments[0].type = fix;
1152					return $.event.handle.apply(this, arguments);
1153				}
1154			};
1155			function handler(e) {
1156				e = $.event.fix(e);
1157				e.type = fix;
1158				return $.event.handle.call(this, e);
1159			}
1160		});
1161	};
1162	$.extend($.fn, {
1163		validateDelegate: function(delegate, type, handler) {
1164			return this.bind(type, function(event) {
1165				var target = $(event.target);
1166				if (target.is(delegate)) {
1167					return handler.apply(target, arguments);
1168				}
1169			});
1170		}
1171	});
1172})(_4ORMAT.$);
1173
1174 _4ORMAT.$.validator.addMethod("alphanumeric", function(value, element) {                                                                                                                                                                                                     
1175  return this.optional(element) || /^\w+$/i.test(value);
1176}, "");
1177
1178/*! jQuery UI - v1.10.4 - 2014-04-02
1179* http://jqueryui.com
1180* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.slider.js, jquery.ui.sortable.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js
1181* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
1182
1183
1184(function( $, undefined ) {
1185
1186var uuid = 0,
1187  runiqueId = /^ui-id-\d+$/;
1188
vendor: 5,456 bytes, lines 1189-1376
1189// $.ui might exist from components with no dependencies, e.g., $.ui.position
1190$.ui = $.ui || {};
1191
1192$.extend( $.ui, {
1193  version: "1.10.4",
1194
1195  keyCode: {
1196    BACKSPACE: 8,
1197    COMMA: 188,
1198    DELETE: 46,
1199    DOWN: 40,
1200    END: 35,
1201    ENTER: 13,
1202    ESCAPE: 27,
1203    HOME: 36,
1204    LEFT: 37,
1205    NUMPAD_ADD: 107,
1206    NUMPAD_DECIMAL: 110,
1207    NUMPAD_DIVIDE: 111,
1208    NUMPAD_ENTER: 108,
1209    NUMPAD_MULTIPLY: 106,
1210    NUMPAD_SUBTRACT: 109,
1211    PAGE_DOWN: 34,
1212    PAGE_UP: 33,
1213    PERIOD: 190,
1214    RIGHT: 39,
1215    SPACE: 32,
1216    TAB: 9,
1217    UP: 38
1218  }
1219});
1220
1221// plugins
1222$.fn.extend({
1223  focus: (function( orig ) {
1224    return function( delay, fn ) {
1225      return typeof delay === "number" ?
1226        this.each(function() {
1227          var elem = this;
1228          setTimeout(function() {
1229            $( elem ).focus();
1230            if ( fn ) {
1231              fn.call( elem );
1232            }
1233          }, delay );
1234        }) :
1235        orig.apply( this, arguments );
1236    };
1237  })( $.fn.focus ),
1238
1239  scrollParent: function() {
1240    var scrollParent;
1241    if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
1242      scrollParent = this.parents().filter(function() {
1243        return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
1244      }).eq(0);
1245    } else {
1246      scrollParent = this.parents().filter(function() {
1247        return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
1248      }).eq(0);
1249    }
1250
1251    return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
1252  },
1253
1254  zIndex: function( zIndex ) {
1255    if ( zIndex !== undefined ) {
1256      return this.css( "zIndex", zIndex );
1257    }
1258
1259    if ( this.length ) {
1260      var elem = $( this[ 0 ] ), position, value;
1261      while ( elem.length && elem[ 0 ] !== document ) {
1262        // Ignore z-index if position is set to a value where z-index is ignored by the browser
1263        // This makes behavior of this function consistent across browsers
1264        // WebKit always returns auto if the element is positioned
1265        position = elem.css( "position" );
1266        if ( position === "absolute" || position === "relative" || position === "fixed" ) {
1267          // IE returns 0 when zIndex is not specified
1268          // other browsers return a string
1269          // we ignore the case of nested elements with an explicit value of 0
1270          // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
1271          value = parseInt( elem.css( "zIndex" ), 10 );
1272          if ( !isNaN( value ) && value !== 0 ) {
1273            return value;
1274          }
1275        }
1276        elem = elem.parent();
1277      }
1278    }
1279
1280    return 0;
1281  },
1282
1283  uniqueId: function() {
1284    return this.each(function() {
1285      if ( !this.id ) {
1286        this.id = "ui-id-" + (++uuid);
1287      }
1288    });
1289  },
1290
1291  removeUniqueId: function() {
1292    return this.each(function() {
1293      if ( runiqueId.test( this.id ) ) {
1294        $( this ).removeAttr( "id" );
1295      }
1296    });
1297  }
1298});
1299
1300// selectors
1301function focusable( element, isTabIndexNotNaN ) {
1302  var map, mapName, img,
1303    nodeName = element.nodeName.toLowerCase();
1304  if ( "area" === nodeName ) {
1305    map = element.parentNode;
1306    mapName = map.name;
1307    if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
1308      return false;
1309    }
1310    img = $( "img[usemap=#" + mapName + "]" )[0];
1311    return !!img && visible( img );
1312  }
1313  return ( /input|select|textarea|button|object/.test( nodeName ) ?
1314    !element.disabled :
1315    "a" === nodeName ?
1316      element.href || isTabIndexNotNaN :
1317      isTabIndexNotNaN) &&
1318    // the element and all of its ancestors must be visible
1319    visible( element );
1320}
1321
1322function visible( element ) {
1323  return $.expr.filters.visible( element ) &&
1324    !$( element ).parents().addBack().filter(function() {
1325      return $.css( this, "visibility" ) === "hidden";
1326    }).length;
1327}
1328
1329$.extend( $.expr[ ":" ], {
1330  data: $.expr.createPseudo ?
1331    $.expr.createPseudo(function( dataName ) {
1332      return function( elem ) {
1333        return !!$.data( elem, dataName );
1334      };
1335    }) :
1336    // support: jQuery <1.8
1337    function( elem, i, match ) {
1338      return !!$.data( elem, match[ 3 ] );
1339    },
1340
1341  focusable: function( element ) {
1342    return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
1343  },
1344
1345  tabbable: function( element ) {
1346    var tabIndex = $.attr( element, "tabindex" ),
1347      isTabIndexNaN = isNaN( tabIndex );
1348    return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
1349  }
1350});
1351
1352// support: jQuery <1.8
1353if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
1354  $.each( [ "Width", "Height" ], function( i, name ) {
1355    var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
1356      type = name.toLowerCase(),
1357      orig = {
1358        innerWidth: $.fn.innerWidth,
1359        innerHeight: $.fn.innerHeight,
1360        outerWidth: $.fn.outerWidth,
1361        outerHeight: $.fn.outerHeight
1362      };
1363
1364    function reduce( elem, size, border, margin ) {
1365      $.each( side, function() {
1366        size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
1367        if ( border ) {
1368          size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
1369        }
1370        if ( margin ) {
1371          size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
1372        }
1373      });
1374      return size;
1375    }
1376
1377    $.fn[ "inner" + name ] = function( size ) {
1378      if ( size === undefined ) {
1379        return orig[ "inner" + name ].call( this );
1380      }
1381
1382      return this.each(function() {
1383        $( this ).css( type, reduce( this, size ) + "px" );
1384      });
1385    };
1386
1387    $.fn[ "outer" + name] = function( size, margin ) {
1388      if ( typeof size !== "number" ) {
1389        return orig[ "outer" + name ].call( this, size );
1390      }
1391
1392      return this.each(function() {
1393        $( this).css( type, reduce( this, size, true, margin ) + "px" );
1394      });
1395    };
1396  });
1397}
1398
1399// support: jQuery <1.8
1400if ( !$.fn.addBack ) {
1401  $.fn.addBack = function( selector ) {
1402    return this.add( selector == null ?
1403      this.prevObject : this.prevObject.filter( selector )
1404    );
1405  };
1406}
1407
1408// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
1409if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
1410  $.fn.removeData = (function( removeData ) {
1411    return function( key ) {
1412      if ( arguments.length ) {
1413        return removeData.call( this, $.camelCase( key ) );
1414      } else {
1415        return removeData.call( this );
1416      }
1417    };
1418  })( $.fn.removeData );
1419}
1420
1421
1422
1423
1424
1425// deprecated
1426$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
1427
1428$.support.selectstart = "onselectstart" in document.createElement( "div" );
1429$.fn.extend({
1430  disableSelection: function() {
1431    return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
1432      ".ui-disableSelection", function( event ) {
1433        event.preventDefault();
1434      });
1435  },
1436
1437  enableSelection: function() {
1438    return this.unbind( ".ui-disableSelection" );
1439  }
1440});
1441
1442$.extend( $.ui, {
1443  // $.ui.plugin is deprecated. Use $.widget() extensions instead.
1444  plugin: {
1445    add: function( module, option, set ) {
1446      var i,
1447        proto = $.ui[ module ].prototype;
1448      for ( i in set ) {
1449        proto.plugins[ i ] = proto.plugins[ i ] || [];
1450        proto.plugins[ i ].push( [ option, set[ i ] ] );
1451      }
1452    },
1453    call: function( instance, name, args ) {
1454      var i,
1455        set = instance.plugins[ name ];
1456      if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
1457        return;
1458      }
1459
1460      for ( i = 0; i < set.length; i++ ) {
1461        if ( instance.options[ set[ i ][ 0 ] ] ) {
1462          set[ i ][ 1 ].apply( instance.element, args );
1463        }
1464      }
1465    }
1466  },
1467
1468  // only used by resizable
1469  hasScroll: function( el, a ) {
1470
1471    //If overflow is hidden, the element might have extra content, but the user wants to hide it
1472    if ( $( el ).css( "overflow" ) === "hidden") {
1473      return false;
1474    }
1475
1476    var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
1477      has = false;
1478
1479    if ( el[ scroll ] > 0 ) {
1480      return true;
1481    }
1482
1483    // TODO: determine which cases actually cause this to happen
1484    // if the element doesn't have the scroll set, see if it's possible to
1485    // set the scroll
1486    el[ scroll ] = 1;
1487    has = ( el[ scroll ] > 0 );
1488    el[ scroll ] = 0;
1489    return has;
1490  }
1491});
1492
1493})( _4ORMAT.$ );
1494(function( $, undefined ) {
1495
1496var uuid = 0,
1497  slice = Array.prototype.slice,
1498  _cleanData = $.cleanData;
1499$.cleanData = function( elems ) {
1500  for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
1501    try {
1502      $( elem ).triggerHandler( "remove" );
1503    // http://bugs.jquery.com/ticket/8235
1504    } catch( e ) {}
1505  }
1506  _cleanData( elems );
1507};
1508
1509$.widget = function( name, base, prototype ) {
1510  var fullName, existingConstructor, constructor, basePrototype,
1511    // proxiedPrototype allows the provided prototype to remain unmodified
1512    // so that it can be used as a mixin for multiple widgets (#8876)
1513    proxiedPrototype = {},
1514    namespace = name.split( "." )[ 0 ];
1515
1516  name = name.split( "." )[ 1 ];
1517  fullName = namespace + "-" + name;
1518
1519  if ( !prototype ) {
1520    prototype = base;
1521    base = $.Widget;
1522  }
1523
1524  // create selector for plugin
1525  $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
1526    return !!$.data( elem, fullName );
1527  };
1528
1529  $[ namespace ] = $[ namespace ] || {};
1530  existingConstructor = $[ namespace ][ name ];
1531  constructor = $[ namespace ][ name ] = function( options, element ) {
1532    // allow instantiation without "new" keyword
1533    if ( !this._createWidget ) {
1534      return new constructor( options, element );
1535    }
1536
1537    // allow instantiation without initializing for simple inheritance
1538    // must use "new" keyword (the code above always passes args)
1539    if ( arguments.length ) {
1540      this._createWidget( options, element );
1541    }
1542  };
1543  // extend with the existing constructor to carry over any static properties
1544  $.extend( constructor, existingConstructor, {
1545    version: prototype.version,
1546    // copy the object used to create the prototype in case we need to
1547    // redefine the widget later
1548    _proto: $.extend( {}, prototype ),
1549    // track widgets that inherit from this widget in case this widget is
1550    // redefined after a widget inherits from it
1551    _childConstructors: []
1552  });
1553
1554  basePrototype = new base();
1555  // we need to make the options hash a property directly on the new instance
1556  // otherwise we'll modify the options hash on the prototype that we're
1557  // inheriting from
1558  basePrototype.options = $.widget.extend( {}, basePrototype.options );
1559  $.each( prototype, function( prop, value ) {
1560    if ( !$.isFunction( value ) ) {
1561      proxiedPrototype[ prop ] = value;
1562      return;
1563    }
1564    proxiedPrototype[ prop ] = (function() {
1565      var _super = function() {
1566          return base.prototype[ prop ].apply( this, arguments );
1567        },
1568        _superApply = function( args ) {
1569          return base.prototype[ prop ].apply( this, args );
1570        };
1571      return function() {
1572        var __super = this._super,
1573          __superApply = this._superApply,
1574          returnValue;
1575
1576        this._super = _super;
1577        this._superApply = _superApply;
1578
vendor: 12,900 bytes, lines 1579-1990
1579        returnValue = value.apply( this, arguments );
1580
1581        this._super = __super;
1582        this._superApply = __superApply;
1583
1584        return returnValue;
1585      };
1586    })();
1587  });
1588  constructor.prototype = $.widget.extend( basePrototype, {
1589    // TODO: remove support for widgetEventPrefix
1590    // always use the name + a colon as the prefix, e.g., draggable:start
1591    // don't prefix for widgets that aren't DOM-based
1592    widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
1593  }, proxiedPrototype, {
1594    constructor: constructor,
1595    namespace: namespace,
1596    widgetName: name,
1597    widgetFullName: fullName
1598  });
1599
1600  // If this widget is being redefined then we need to find all widgets that
1601  // are inheriting from it and redefine all of them so that they inherit from
1602  // the new version of this widget. We're essentially trying to replace one
1603  // level in the prototype chain.
1604  if ( existingConstructor ) {
1605    $.each( existingConstructor._childConstructors, function( i, child ) {
1606      var childPrototype = child.prototype;
1607
1608      // redefine the child widget using the same prototype that was
1609      // originally used, but inherit from the new version of the base
1610      $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
1611    });
1612    // remove the list of existing child constructors from the old constructor
1613    // so the old child constructors can be garbage collected
1614    delete existingConstructor._childConstructors;
1615  } else {
1616    base._childConstructors.push( constructor );
1617  }
1618
1619  $.widget.bridge( name, constructor );
1620};
1621
1622$.widget.extend = function( target ) {
1623  var input = slice.call( arguments, 1 ),
1624    inputIndex = 0,
1625    inputLength = input.length,
1626    key,
1627    value;
1628  for ( ; inputIndex < inputLength; inputIndex++ ) {
1629    for ( key in input[ inputIndex ] ) {
1630      value = input[ inputIndex ][ key ];
1631      if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
1632        // Clone objects
1633        if ( $.isPlainObject( value ) ) {
1634          target[ key ] = $.isPlainObject( target[ key ] ) ?
1635            $.widget.extend( {}, target[ key ], value ) :
1636            // Don't extend strings, arrays, etc. with objects
1637            $.widget.extend( {}, value );
1638        // Copy everything else by reference
1639        } else {
1640          target[ key ] = value;
1641        }
1642      }
1643    }
1644  }
1645  return target;
1646};
1647
1648$.widget.bridge = function( name, object ) {
1649  var fullName = object.prototype.widgetFullName || name;
1650  $.fn[ name ] = function( options ) {
1651    var isMethodCall = typeof options === "string",
1652      args = slice.call( arguments, 1 ),
1653      returnValue = this;
1654
1655    // allow multiple hashes to be passed on init
1656    options = !isMethodCall && args.length ?
1657      $.widget.extend.apply( null, [ options ].concat(args) ) :
1658      options;
1659
1660    if ( isMethodCall ) {
1661      this.each(function() {
1662        var methodValue,
1663          instance = $.data( this, fullName );
1664        if ( !instance ) {
1665          return $.error( "cannot call methods on " + name + " prior to initialization; " +
1666            "attempted to call method '" + options + "'" );
1667        }
1668        if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
1669          return $.error( "no such method '" + options + "' for " + name + " widget instance" );
1670        }
1671        methodValue = instance[ options ].apply( instance, args );
1672        if ( methodValue !== instance && methodValue !== undefined ) {
1673          returnValue = methodValue && methodValue.jquery ?
1674            returnValue.pushStack( methodValue.get() ) :
1675            methodValue;
1676          return false;
1677        }
1678      });
1679    } else {
1680      this.each(function() {
1681        var instance = $.data( this, fullName );
1682        if ( instance ) {
1683          instance.option( options || {} )._init();
1684        } else {
1685          $.data( this, fullName, new object( options, this ) );
1686        }
1687      });
1688    }
1689
1690    return returnValue;
1691  };
1692};
1693
1694$.Widget = function( /* options, element */ ) {};
1695$.Widget._childConstructors = [];
1696
1697$.Widget.prototype = {
1698  widgetName: "widget",
1699  widgetEventPrefix: "",
1700  defaultElement: "<div>",
1701  options: {
1702    disabled: false,
1703
1704    // callbacks
1705    create: null
1706  },
1707  _createWidget: function( options, element ) {
1708    element = $( element || this.defaultElement || this )[ 0 ];
1709    this.element = $( element );
1710    this.uuid = uuid++;
1711    this.eventNamespace = "." + this.widgetName + this.uuid;
1712    this.options = $.widget.extend( {},
1713      this.options,
1714      this._getCreateOptions(),
1715      options );
1716
1717    this.bindings = $();
1718    this.hoverable = $();
1719    this.focusable = $();
1720
1721    if ( element !== this ) {
1722      $.data( element, this.widgetFullName, this );
1723      this._on( true, this.element, {
1724        remove: function( event ) {
1725          if ( event.target === element ) {
1726            this.destroy();
1727          }
1728        }
1729      });
1730      this.document = $( element.style ?
1731        // element within the document
1732        element.ownerDocument :
1733        // element is window or document
1734        element.document || element );
1735      this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
1736    }
1737
1738    this._create();
1739    this._trigger( "create", null, this._getCreateEventData() );
1740    this._init();
1741  },
1742  _getCreateOptions: $.noop,
1743  _getCreateEventData: $.noop,
1744  _create: $.noop,
1745  _init: $.noop,
1746
1747  destroy: function() {
1748    this._destroy();
1749    // we can probably remove the unbind calls in 2.0
1750    // all event bindings should go through this._on()
1751    this.element
1752      .unbind( this.eventNamespace )
1753      // 1.9 BC for #7810
1754      // TODO remove dual storage
1755      .removeData( this.widgetName )
1756      .removeData( this.widgetFullName )
1757      // support: jquery <1.6.3
1758      // http://bugs.jquery.com/ticket/9413
1759      .removeData( $.camelCase( this.widgetFullName ) );
1760    this.widget()
1761      .unbind( this.eventNamespace )
1762      .removeAttr( "aria-disabled" )
1763      .removeClass(
1764        this.widgetFullName + "-disabled " +
1765        "ui-state-disabled" );
1766
1767    // clean up events and states
1768    this.bindings.unbind( this.eventNamespace );
1769    this.hoverable.removeClass( "ui-state-hover" );
1770    this.focusable.removeClass( "ui-state-focus" );
1771  },
1772  _destroy: $.noop,
1773
1774  widget: function() {
1775    return this.element;
1776  },
1777
1778  option: function( key, value ) {
1779    var options = key,
1780      parts,
1781      curOption,
1782      i;
1783
1784    if ( arguments.length === 0 ) {
1785      // don't return a reference to the internal hash
1786      return $.widget.extend( {}, this.options );
1787    }
1788
1789    if ( typeof key === "string" ) {
1790      // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
1791      options = {};
1792      parts = key.split( "." );
1793      key = parts.shift();
1794      if ( parts.length ) {
1795        curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
1796        for ( i = 0; i < parts.length - 1; i++ ) {
1797          curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
1798          curOption = curOption[ parts[ i ] ];
1799        }
1800        key = parts.pop();
1801        if ( arguments.length === 1 ) {
1802          return curOption[ key ] === undefined ? null : curOption[ key ];
1803        }
1804        curOption[ key ] = value;
1805      } else {
1806        if ( arguments.length === 1 ) {
1807          return this.options[ key ] === undefined ? null : this.options[ key ];
1808        }
1809        options[ key ] = value;
1810      }
1811    }
1812
1813    this._setOptions( options );
1814
1815    return this;
1816  },
1817  _setOptions: function( options ) {
1818    var key;
1819
1820    for ( key in options ) {
1821      this._setOption( key, options[ key ] );
1822    }
1823
1824    return this;
1825  },
1826  _setOption: function( key, value ) {
1827    this.options[ key ] = value;
1828
1829    if ( key === "disabled" ) {
1830      this.widget()
1831        .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
1832        .attr( "aria-disabled", value );
1833      this.hoverable.removeClass( "ui-state-hover" );
1834      this.focusable.removeClass( "ui-state-focus" );
1835    }
1836
1837    return this;
1838  },
1839
1840  enable: function() {
1841    return this._setOption( "disabled", false );
1842  },
1843  disable: function() {
1844    return this._setOption( "disabled", true );
1845  },
1846
1847  _on: function( suppressDisabledCheck, element, handlers ) {
1848    var delegateElement,
1849      instance = this;
1850
1851    // no suppressDisabledCheck flag, shuffle arguments
1852    if ( typeof suppressDisabledCheck !== "boolean" ) {
1853      handlers = element;
1854      element = suppressDisabledCheck;
1855      suppressDisabledCheck = false;
1856    }
1857
1858    // no element argument, shuffle and use this.element
1859    if ( !handlers ) {
1860      handlers = element;
1861      element = this.element;
1862      delegateElement = this.widget();
1863    } else {
1864      // accept selectors, DOM elements
1865      element = delegateElement = $( element );
1866      this.bindings = this.bindings.add( element );
1867    }
1868
1869    $.each( handlers, function( event, handler ) {
1870      function handlerProxy() {
1871        // allow widgets to customize the disabled handling
1872        // - disabled as an array instead of boolean
1873        // - disabled class as method for disabling individual parts
1874        if ( !suppressDisabledCheck &&
1875            ( instance.options.disabled === true ||
1876              $( this ).hasClass( "ui-state-disabled" ) ) ) {
1877          return;
1878        }
1879        return ( typeof handler === "string" ? instance[ handler ] : handler )
1880          .apply( instance, arguments );
1881      }
1882
1883      // copy the guid so direct unbinding works
1884      if ( typeof handler !== "string" ) {
1885        handlerProxy.guid = handler.guid =
1886          handler.guid || handlerProxy.guid || $.guid++;
1887      }
1888
1889      var match = event.match( /^(\w+)\s*(.*)$/ ),
1890        eventName = match[1] + instance.eventNamespace,
1891        selector = match[2];
1892      if ( selector ) {
1893        delegateElement.delegate( selector, eventName, handlerProxy );
1894      } else {
1895        element.bind( eventName, handlerProxy );
1896      }
1897    });
1898  },
1899
1900  _off: function( element, eventName ) {
1901    eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
1902    element.unbind( eventName ).undelegate( eventName );
1903  },
1904
1905  _delay: function( handler, delay ) {
1906    function handlerProxy() {
1907      return ( typeof handler === "string" ? instance[ handler ] : handler )
1908        .apply( instance, arguments );
1909    }
1910    var instance = this;
1911    return setTimeout( handlerProxy, delay || 0 );
1912  },
1913
1914  _hoverable: function( element ) {
1915    this.hoverable = this.hoverable.add( element );
1916    this._on( element, {
1917      mouseenter: function( event ) {
1918        $( event.currentTarget ).addClass( "ui-state-hover" );
1919      },
1920      mouseleave: function( event ) {
1921        $( event.currentTarget ).removeClass( "ui-state-hover" );
1922      }
1923    });
1924  },
1925
1926  _focusable: function( element ) {
1927    this.focusable = this.focusable.add( element );
1928    this._on( element, {
1929      focusin: function( event ) {
1930        $( event.currentTarget ).addClass( "ui-state-focus" );
1931      },
1932      focusout: function( event ) {
1933        $( event.currentTarget ).removeClass( "ui-state-focus" );
1934      }
1935    });
1936  },
1937
1938  _trigger: function( type, event, data ) {
1939    var prop, orig,
1940      callback = this.options[ type ];
1941
1942    data = data || {};
1943    event = $.Event( event );
1944    event.type = ( type === this.widgetEventPrefix ?
1945      type :
1946      this.widgetEventPrefix + type ).toLowerCase();
1947    // the original event may come from any element
1948    // so we need to reset the target on the new event
1949    event.target = this.element[ 0 ];
1950
1951    // copy original event properties over to the new event
1952    orig = event.originalEvent;
1953    if ( orig ) {
1954      for ( prop in orig ) {
1955        if ( !( prop in event ) ) {
1956          event[ prop ] = orig[ prop ];
1957        }
1958      }
1959    }
1960
1961    this.element.trigger( event, data );
1962    return !( $.isFunction( callback ) &&
1963      callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
1964      event.isDefaultPrevented() );
1965  }
1966};
1967
1968$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
1969  $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
1970    if ( typeof options === "string" ) {
1971      options = { effect: options };
1972    }
1973    var hasOptions,
1974      effectName = !options ?
1975        method :
1976        options === true || typeof options === "number" ?
1977          defaultEffect :
1978          options.effect || defaultEffect;
1979    options = options || {};
1980    if ( typeof options === "number" ) {
1981      options = { duration: options };
1982    }
1983    hasOptions = !$.isEmptyObject( options );
1984    options.complete = callback;
1985    if ( options.delay ) {
1986      element.delay( options.delay );
1987    }
1988    if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
1989      element[ method ]( options );
1990    } else if ( effectName !== method && element[ effectName ] ) {
vendor: 61,186 bytes, lines 1991-3992
1991      element[ effectName ]( options.duration, options.easing, callback );
1992    } else {
1993      element.queue(function( next ) {
1994        $( this )[ method ]();
1995        if ( callback ) {
1996          callback.call( element[ 0 ] );
1997        }
1998        next();
1999      });
2000    }
2001  };
2002});
2003
2004})( _4ORMAT.$ );
2005(function( $, undefined ) {
2006
2007var mouseHandled = false;
2008$( document ).mouseup( function() {
2009  mouseHandled = false;
2010});
2011
2012$.widget("ui.mouse", {
2013  version: "1.10.4",
2014  options: {
2015    cancel: "input,textarea,button,select,option",
2016    distance: 1,
2017    delay: 0
2018  },
2019  _mouseInit: function() {
2020    var that = this;
2021
2022    this.element
2023      .bind("mousedown."+this.widgetName, function(event) {
2024        return that._mouseDown(event);
2025      })
2026      .bind("click."+this.widgetName, function(event) {
2027        if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
2028          $.removeData(event.target, that.widgetName + ".preventClickEvent");
2029          event.stopImmediatePropagation();
2030          return false;
2031        }
2032      });
2033
2034    this.started = false;
2035  },
2036
2037  // TODO: make sure destroying one instance of mouse doesn't mess with
2038  // other instances of mouse
2039  _mouseDestroy: function() {
2040    this.element.unbind("."+this.widgetName);
2041    if ( this._mouseMoveDelegate ) {
2042      $(document)
2043        .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
2044        .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
2045    }
2046  },
2047
2048  _mouseDown: function(event) {
2049    // don't let more than one widget handle mouseStart
2050    if( mouseHandled ) { return; }
2051
2052    // we may have missed mouseup (out of window)
2053    (this._mouseStarted && this._mouseUp(event));
2054
2055    this._mouseDownEvent = event;
2056
2057    var that = this,
2058      btnIsLeft = (event.which === 1),
2059      // event.target.nodeName works around a bug in IE 8 with
2060      // disabled inputs (#7620)
2061      elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
2062    if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
2063      return true;
2064    }
2065
2066    this.mouseDelayMet = !this.options.delay;
2067    if (!this.mouseDelayMet) {
2068      this._mouseDelayTimer = setTimeout(function() {
2069        that.mouseDelayMet = true;
2070      }, this.options.delay);
2071    }
2072
2073    if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
2074      this._mouseStarted = (this._mouseStart(event) !== false);
2075      if (!this._mouseStarted) {
2076        event.preventDefault();
2077        return true;
2078      }
2079    }
2080
2081    // Click event may never have fired (Gecko & Opera)
2082    if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
2083      $.removeData(event.target, this.widgetName + ".preventClickEvent");
2084    }
2085
2086    // these delegates are required to keep context
2087    this._mouseMoveDelegate = function(event) {
2088      return that._mouseMove(event);
2089    };
2090    this._mouseUpDelegate = function(event) {
2091      return that._mouseUp(event);
2092    };
2093    $(document)
2094      .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
2095      .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
2096
2097    event.preventDefault();
2098
2099    mouseHandled = true;
2100    return true;
2101  },
2102
2103  _mouseMove: function(event) {
2104    // IE mouseup check - mouseup happened when mouse was out of window
2105    if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
2106      return this._mouseUp(event);
2107    }
2108
2109    if (this._mouseStarted) {
2110      this._mouseDrag(event);
2111      return event.preventDefault();
2112    }
2113
2114    if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
2115      this._mouseStarted =
2116        (this._mouseStart(this._mouseDownEvent, event) !== false);
2117      (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
2118    }
2119
2120    return !this._mouseStarted;
2121  },
2122
2123  _mouseUp: function(event) {
2124    $(document)
2125      .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
2126      .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
2127
2128    if (this._mouseStarted) {
2129      this._mouseStarted = false;
2130
2131      if (event.target === this._mouseDownEvent.target) {
2132        $.data(event.target, this.widgetName + ".preventClickEvent", true);
2133      }
2134
2135      this._mouseStop(event);
2136    }
2137
2138    return false;
2139  },
2140
2141  _mouseDistanceMet: function(event) {
2142    return (Math.max(
2143        Math.abs(this._mouseDownEvent.pageX - event.pageX),
2144        Math.abs(this._mouseDownEvent.pageY - event.pageY)
2145      ) >= this.options.distance
2146    );
2147  },
2148
2149  _mouseDelayMet: function(/* event */) {
2150    return this.mouseDelayMet;
2151  },
2152
2153  // These are placeholder methods, to be overriden by extending plugin
2154  _mouseStart: function(/* event */) {},
2155  _mouseDrag: function(/* event */) {},
2156  _mouseStop: function(/* event */) {},
2157  _mouseCapture: function(/* event */) { return true; }
2158});
2159
2160})( _4ORMAT.$ );
2161(function( $, undefined ) {
2162
2163$.ui = $.ui || {};
2164
2165var cachedScrollbarWidth,
2166  max = Math.max,
2167  abs = Math.abs,
2168  round = Math.round,
2169  rhorizontal = /left|center|right/,
2170  rvertical = /top|center|bottom/,
2171  roffset = /[\+\-]\d+(\.[\d]+)?%?/,
2172  rposition = /^\w+/,
2173  rpercent = /%$/,
2174  _position = $.fn.position;
2175
2176function getOffsets( offsets, width, height ) {
2177  return [
2178    parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
2179    parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
2180  ];
2181}
2182
2183function parseCss( element, property ) {
2184  return parseInt( $.css( element, property ), 10 ) || 0;
2185}
2186
2187function getDimensions( elem ) {
2188  var raw = elem[0];
2189  if ( raw.nodeType === 9 ) {
2190    return {
2191      width: elem.width(),
2192      height: elem.height(),
2193      offset: { top: 0, left: 0 }
2194    };
2195  }
2196  if ( $.isWindow( raw ) ) {
2197    return {
2198      width: elem.width(),
2199      height: elem.height(),
2200      offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
2201    };
2202  }
2203  if ( raw.preventDefault ) {
2204    return {
2205      width: 0,
2206      height: 0,
2207      offset: { top: raw.pageY, left: raw.pageX }
2208    };
2209  }
2210  return {
2211    width: elem.outerWidth(),
2212    height: elem.outerHeight(),
2213    offset: elem.offset()
2214  };
2215}
2216
2217$.position = {
2218  scrollbarWidth: function() {
2219    if ( cachedScrollbarWidth !== undefined ) {
2220      return cachedScrollbarWidth;
2221    }
2222    var w1, w2,
2223      div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
2224      innerDiv = div.children()[0];
2225
2226    $( "body" ).append( div );
2227    w1 = innerDiv.offsetWidth;
2228    div.css( "overflow", "scroll" );
2229
2230    w2 = innerDiv.offsetWidth;
2231
2232    if ( w1 === w2 ) {
2233      w2 = div[0].clientWidth;
2234    }
2235
2236    div.remove();
2237
2238    return (cachedScrollbarWidth = w1 - w2);
2239  },
2240  getScrollInfo: function( within ) {
2241    var overflowX = within.isWindow || within.isDocument ? "" :
2242        within.element.css( "overflow-x" ),
2243      overflowY = within.isWindow || within.isDocument ? "" :
2244        within.element.css( "overflow-y" ),
2245      hasOverflowX = overflowX === "scroll" ||
2246        ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
2247      hasOverflowY = overflowY === "scroll" ||
2248        ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
2249    return {
2250      width: hasOverflowY ? $.position.scrollbarWidth() : 0,
2251      height: hasOverflowX ? $.position.scrollbarWidth() : 0
2252    };
2253  },
2254  getWithinInfo: function( element ) {
2255    var withinElement = $( element || window ),
2256      isWindow = $.isWindow( withinElement[0] ),
2257      isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
2258    return {
2259      element: withinElement,
2260      isWindow: isWindow,
2261      isDocument: isDocument,
2262      offset: withinElement.offset() || { left: 0, top: 0 },
2263      scrollLeft: withinElement.scrollLeft(),
2264      scrollTop: withinElement.scrollTop(),
2265      width: isWindow ? withinElement.width() : withinElement.outerWidth(),
2266      height: isWindow ? withinElement.height() : withinElement.outerHeight()
2267    };
2268  }
2269};
2270
2271$.fn.position = function( options ) {
2272  if ( !options || !options.of ) {
2273    return _position.apply( this, arguments );
2274  }
2275
2276  // make a copy, we don't want to modify arguments
2277  options = $.extend( {}, options );
2278
2279  var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
2280    target = $( options.of ),
2281    within = $.position.getWithinInfo( options.within ),
2282    scrollInfo = $.position.getScrollInfo( within ),
2283    collision = ( options.collision || "flip" ).split( " " ),
2284    offsets = {};
2285
2286  dimensions = getDimensions( target );
2287  if ( target[0].preventDefault ) {
2288    // force left top to allow flipping
2289    options.at = "left top";
2290  }
2291  targetWidth = dimensions.width;
2292  targetHeight = dimensions.height;
2293  targetOffset = dimensions.offset;
2294  // clone to reuse original targetOffset later
2295  basePosition = $.extend( {}, targetOffset );
2296
2297  // force my and at to have valid horizontal and vertical positions
2298  // if a value is missing or invalid, it will be converted to center
2299  $.each( [ "my", "at" ], function() {
2300    var pos = ( options[ this ] || "" ).split( " " ),
2301      horizontalOffset,
2302      verticalOffset;
2303
2304    if ( pos.length === 1) {
2305      pos = rhorizontal.test( pos[ 0 ] ) ?
2306        pos.concat( [ "center" ] ) :
2307        rvertical.test( pos[ 0 ] ) ?
2308          [ "center" ].concat( pos ) :
2309          [ "center", "center" ];
2310    }
2311    pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
2312    pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
2313
2314    // calculate offsets
2315    horizontalOffset = roffset.exec( pos[ 0 ] );
2316    verticalOffset = roffset.exec( pos[ 1 ] );
2317    offsets[ this ] = [
2318      horizontalOffset ? horizontalOffset[ 0 ] : 0,
2319      verticalOffset ? verticalOffset[ 0 ] : 0
2320    ];
2321
2322    // reduce to just the positions without the offsets
2323    options[ this ] = [
2324      rposition.exec( pos[ 0 ] )[ 0 ],
2325      rposition.exec( pos[ 1 ] )[ 0 ]
2326    ];
2327  });
2328
2329  // normalize collision option
2330  if ( collision.length === 1 ) {
2331    collision[ 1 ] = collision[ 0 ];
2332  }
2333
2334  if ( options.at[ 0 ] === "right" ) {
2335    basePosition.left += targetWidth;
2336  } else if ( options.at[ 0 ] === "center" ) {
2337    basePosition.left += targetWidth / 2;
2338  }
2339
2340  if ( options.at[ 1 ] === "bottom" ) {
2341    basePosition.top += targetHeight;
2342  } else if ( options.at[ 1 ] === "center" ) {
2343    basePosition.top += targetHeight / 2;
2344  }
2345
2346  atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
2347  basePosition.left += atOffset[ 0 ];
2348  basePosition.top += atOffset[ 1 ];
2349
2350  return this.each(function() {
2351    var collisionPosition, using,
2352      elem = $( this ),
2353      elemWidth = elem.outerWidth(),
2354      elemHeight = elem.outerHeight(),
2355      marginLeft = parseCss( this, "marginLeft" ),
2356      marginTop = parseCss( this, "marginTop" ),
2357      collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
2358      collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
2359      position = $.extend( {}, basePosition ),
2360      myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
2361
2362    if ( options.my[ 0 ] === "right" ) {
2363      position.left -= elemWidth;
2364    } else if ( options.my[ 0 ] === "center" ) {
2365      position.left -= elemWidth / 2;
2366    }
2367
2368    if ( options.my[ 1 ] === "bottom" ) {
2369      position.top -= elemHeight;
2370    } else if ( options.my[ 1 ] === "center" ) {
2371      position.top -= elemHeight / 2;
2372    }
2373
2374    position.left += myOffset[ 0 ];
2375    position.top += myOffset[ 1 ];
2376
2377    // if the browser doesn't support fractions, then round for consistent results
2378    if ( !$.support.offsetFractions ) {
2379      position.left = round( position.left );
2380      position.top = round( position.top );
2381    }
2382
2383    collisionPosition = {
2384      marginLeft: marginLeft,
2385      marginTop: marginTop
2386    };
2387
2388    $.each( [ "left", "top" ], function( i, dir ) {
2389      if ( $.ui.position[ collision[ i ] ] ) {
2390        $.ui.position[ collision[ i ] ][ dir ]( position, {
2391          targetWidth: targetWidth,
2392          targetHeight: targetHeight,
2393          elemWidth: elemWidth,
2394          elemHeight: elemHeight,
2395          collisionPosition: collisionPosition,
2396          collisionWidth: collisionWidth,
2397          collisionHeight: collisionHeight,
2398          offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
2399          my: options.my,
2400          at: options.at,
2401          within: within,
2402          elem : elem
2403        });
2404      }
2405    });
2406
2407    if ( options.using ) {
2408      // adds feedback as second argument to using callback, if present
2409      using = function( props ) {
2410        var left = targetOffset.left - position.left,
2411          right = left + targetWidth - elemWidth,
2412          top = targetOffset.top - position.top,
2413          bottom = top + targetHeight - elemHeight,
2414          feedback = {
2415            target: {
2416              element: target,
2417              left: targetOffset.left,
2418              top: targetOffset.top,
2419              width: targetWidth,
2420              height: targetHeight
2421            },
2422            element: {
2423              element: elem,
2424              left: position.left,
2425              top: position.top,
2426              width: elemWidth,
2427              height: elemHeight
2428            },
2429            horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
2430            vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
2431          };
2432        if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
2433          feedback.horizontal = "center";
2434        }
2435        if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
2436          feedback.vertical = "middle";
2437        }
2438        if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
2439          feedback.important = "horizontal";
2440        } else {
2441          feedback.important = "vertical";
2442        }
2443        options.using.call( this, props, feedback );
2444      };
2445    }
2446
2447    elem.offset( $.extend( position, { using: using } ) );
2448  });
2449};
2450
2451$.ui.position = {
2452  fit: {
2453    left: function( position, data ) {
2454      var within = data.within,
2455        withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
2456        outerWidth = within.width,
2457        collisionPosLeft = position.left - data.collisionPosition.marginLeft,
2458        overLeft = withinOffset - collisionPosLeft,
2459        overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
2460        newOverRight;
2461
2462      // element is wider than within
2463      if ( data.collisionWidth > outerWidth ) {
2464        // element is initially over the left side of within
2465        if ( overLeft > 0 && overRight <= 0 ) {
2466          newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
2467          position.left += overLeft - newOverRight;
2468        // element is initially over right side of within
2469        } else if ( overRight > 0 && overLeft <= 0 ) {
2470          position.left = withinOffset;
2471        // element is initially over both left and right sides of within
2472        } else {
2473          if ( overLeft > overRight ) {
2474            position.left = withinOffset + outerWidth - data.collisionWidth;
2475          } else {
2476            position.left = withinOffset;
2477          }
2478        }
2479      // too far left -> align with left edge
2480      } else if ( overLeft > 0 ) {
2481        position.left += overLeft;
2482      // too far right -> align with right edge
2483      } else if ( overRight > 0 ) {
2484        position.left -= overRight;
2485      // adjust based on position and margin
2486      } else {
2487        position.left = max( position.left - collisionPosLeft, position.left );
2488      }
2489    },
2490    top: function( position, data ) {
2491      var within = data.within,
2492        withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
2493        outerHeight = data.within.height,
2494        collisionPosTop = position.top - data.collisionPosition.marginTop,
2495        overTop = withinOffset - collisionPosTop,
2496        overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
2497        newOverBottom;
2498
2499      // element is taller than within
2500      if ( data.collisionHeight > outerHeight ) {
2501        // element is initially over the top of within
2502        if ( overTop > 0 && overBottom <= 0 ) {
2503          newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
2504          position.top += overTop - newOverBottom;
2505        // element is initially over bottom of within
2506        } else if ( overBottom > 0 && overTop <= 0 ) {
2507          position.top = withinOffset;
2508        // element is initially over both top and bottom of within
2509        } else {
2510          if ( overTop > overBottom ) {
2511            position.top = withinOffset + outerHeight - data.collisionHeight;
2512          } else {
2513            position.top = withinOffset;
2514          }
2515        }
2516      // too far up -> align with top
2517      } else if ( overTop > 0 ) {
2518        position.top += overTop;
2519      // too far down -> align with bottom edge
2520      } else if ( overBottom > 0 ) {
2521        position.top -= overBottom;
2522      // adjust based on position and margin
2523      } else {
2524        position.top = max( position.top - collisionPosTop, position.top );
2525      }
2526    }
2527  },
2528  flip: {
2529    left: function( position, data ) {
2530      var within = data.within,
2531        withinOffset = within.offset.left + within.scrollLeft,
2532        outerWidth = within.width,
2533        offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
2534        collisionPosLeft = position.left - data.collisionPosition.marginLeft,
2535        overLeft = collisionPosLeft - offsetLeft,
2536        overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
2537        myOffset = data.my[ 0 ] === "left" ?
2538          -data.elemWidth :
2539          data.my[ 0 ] === "right" ?
2540            data.elemWidth :
2541            0,
2542        atOffset = data.at[ 0 ] === "left" ?
2543          data.targetWidth :
2544          data.at[ 0 ] === "right" ?
2545            -data.targetWidth :
2546            0,
2547        offset = -2 * data.offset[ 0 ],
2548        newOverRight,
2549        newOverLeft;
2550
2551      if ( overLeft < 0 ) {
2552        newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
2553        if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
2554          position.left += myOffset + atOffset + offset;
2555        }
2556      }
2557      else if ( overRight > 0 ) {
2558        newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
2559        if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
2560          position.left += myOffset + atOffset + offset;
2561        }
2562      }
2563    },
2564    top: function( position, data ) {
2565      var within = data.within,
2566        withinOffset = within.offset.top + within.scrollTop,
2567        outerHeight = within.height,
2568        offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
2569        collisionPosTop = position.top - data.collisionPosition.marginTop,
2570        overTop = collisionPosTop - offsetTop,
2571        overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
2572        top = data.my[ 1 ] === "top",
2573        myOffset = top ?
2574          -data.elemHeight :
2575          data.my[ 1 ] === "bottom" ?
2576            data.elemHeight :
2577            0,
2578        atOffset = data.at[ 1 ] === "top" ?
2579          data.targetHeight :
2580          data.at[ 1 ] === "bottom" ?
2581            -data.targetHeight :
2582            0,
2583        offset = -2 * data.offset[ 1 ],
2584        newOverTop,
2585        newOverBottom;
2586      if ( overTop < 0 ) {
2587        newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
2588        if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
2589          position.top += myOffset + atOffset + offset;
2590        }
2591      }
2592      else if ( overBottom > 0 ) {
2593        newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
2594        if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
2595          position.top += myOffset + atOffset + offset;
2596        }
2597      }
2598    }
2599  },
2600  flipfit: {
2601    left: function() {
2602      $.ui.position.flip.left.apply( this, arguments );
2603      $.ui.position.fit.left.apply( this, arguments );
2604    },
2605    top: function() {
2606      $.ui.position.flip.top.apply( this, arguments );
2607      $.ui.position.fit.top.apply( this, arguments );
2608    }
2609  }
2610};
2611
2612// fraction support test
2613(function () {
2614  var testElement, testElementParent, testElementStyle, offsetLeft, i,
2615    body = document.getElementsByTagName( "body" )[ 0 ],
2616    div = document.createElement( "div" );
2617
2618  //Create a "fake body" for testing based on method used in jQuery.support
2619  testElement = document.createElement( body ? "div" : "body" );
2620  testElementStyle = {
2621    visibility: "hidden",
2622    width: 0,
2623    height: 0,
2624    border: 0,
2625    margin: 0,
2626    background: "none"
2627  };
2628  if ( body ) {
2629    $.extend( testElementStyle, {
2630      position: "absolute",
2631      left: "-1000px",
2632      top: "-1000px"
2633    });
2634  }
2635  for ( i in testElementStyle ) {
2636    testElement.style[ i ] = testElementStyle[ i ];
2637  }
2638  testElement.appendChild( div );
2639  testElementParent = body || document.documentElement;
2640  testElementParent.insertBefore( testElement, testElementParent.firstChild );
2641
2642  div.style.cssText = "position: absolute; left: 10.7432222px;";
2643
2644  offsetLeft = $( div ).offset().left;
2645  $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
2646
2647  testElement.innerHTML = "";
2648  testElementParent.removeChild( testElement );
2649})();
2650
2651}( _4ORMAT.$ ) );
2652(function( $, undefined ) {
2653
2654var uid = 0,
2655  hideProps = {},
2656  showProps = {};
2657
2658hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
2659  hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
2660showProps.height = showProps.paddingTop = showProps.paddingBottom =
2661  showProps.borderTopWidth = showProps.borderBottomWidth = "show";
2662
2663$.widget( "ui.accordion", {
2664  version: "1.10.4",
2665  options: {
2666    active: 0,
2667    animate: {},
2668    collapsible: false,
2669    event: "click",
2670    header: "> li > :first-child,> :not(li):even",
2671    heightStyle: "auto",
2672    icons: {
2673      activeHeader: "ui-icon-triangle-1-s",
2674      header: "ui-icon-triangle-1-e"
2675    },
2676
2677    // callbacks
2678    activate: null,
2679    beforeActivate: null
2680  },
2681
2682  _create: function() {
2683    var options = this.options;
2684    this.prevShow = this.prevHide = $();
2685    this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
2686      // ARIA
2687      .attr( "role", "tablist" );
2688
2689    // don't allow collapsible: false and active: false / null
2690    if ( !options.collapsible && (options.active === false || options.active == null) ) {
2691      options.active = 0;
2692    }
2693
2694    this._processPanels();
2695    // handle negative values
2696    if ( options.active < 0 ) {
2697      options.active += this.headers.length;
2698    }
2699    this._refresh();
2700  },
2701
2702  _getCreateEventData: function() {
2703    return {
2704      header: this.active,
2705      panel: !this.active.length ? $() : this.active.next(),
2706      content: !this.active.length ? $() : this.active.next()
2707    };
2708  },
2709
2710  _createIcons: function() {
2711    var icons = this.options.icons;
2712    if ( icons ) {
2713      $( "<span>" )
2714        .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
2715        .prependTo( this.headers );
2716      this.active.children( ".ui-accordion-header-icon" )
2717        .removeClass( icons.header )
2718        .addClass( icons.activeHeader );
2719      this.headers.addClass( "ui-accordion-icons" );
2720    }
2721  },
2722
2723  _destroyIcons: function() {
2724    this.headers
2725      .removeClass( "ui-accordion-icons" )
2726      .children( ".ui-accordion-header-icon" )
2727        .remove();
2728  },
2729
2730  _destroy: function() {
2731    var contents;
2732
2733    // clean up main element
2734    this.element
2735      .removeClass( "ui-accordion ui-widget ui-helper-reset" )
2736      .removeAttr( "role" );
2737
2738    // clean up headers
2739    this.headers
2740      .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
2741      .removeAttr( "role" )
2742      .removeAttr( "aria-expanded" )
2743      .removeAttr( "aria-selected" )
2744      .removeAttr( "aria-controls" )
2745      .removeAttr( "tabIndex" )
2746      .each(function() {
2747        if ( /^ui-accordion/.test( this.id ) ) {
2748          this.removeAttribute( "id" );
2749        }
2750      });
2751    this._destroyIcons();
2752
2753    // clean up content panels
2754    contents = this.headers.next()
2755      .css( "display", "" )
2756      .removeAttr( "role" )
2757      .removeAttr( "aria-hidden" )
2758      .removeAttr( "aria-labelledby" )
2759      .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
2760      .each(function() {
2761        if ( /^ui-accordion/.test( this.id ) ) {
2762          this.removeAttribute( "id" );
2763        }
2764      });
2765    if ( this.options.heightStyle !== "content" ) {
2766      contents.css( "height", "" );
2767    }
2768  },
2769
2770  _setOption: function( key, value ) {
2771    if ( key === "active" ) {
2772      // _activate() will handle invalid values and update this.options
2773      this._activate( value );
2774      return;
2775    }
2776
2777    if ( key === "event" ) {
2778      if ( this.options.event ) {
2779        this._off( this.headers, this.options.event );
2780      }
2781      this._setupEvents( value );
2782    }
2783
2784    this._super( key, value );
2785
2786    // setting collapsible: false while collapsed; open first panel
2787    if ( key === "collapsible" && !value && this.options.active === false ) {
2788      this._activate( 0 );
2789    }
2790
2791    if ( key === "icons" ) {
2792      this._destroyIcons();
2793      if ( value ) {
2794        this._createIcons();
2795      }
2796    }
2797
2798    // #5332 - opacity doesn't cascade to positioned elements in IE
2799    // so we need to add the disabled class to the headers and panels
2800    if ( key === "disabled" ) {
2801      this.headers.add( this.headers.next() )
2802        .toggleClass( "ui-state-disabled", !!value );
2803    }
2804  },
2805
2806  _keydown: function( event ) {
2807    if ( event.altKey || event.ctrlKey ) {
2808      return;
2809    }
2810
2811    var keyCode = $.ui.keyCode,
2812      length = this.headers.length,
2813      currentIndex = this.headers.index( event.target ),
2814      toFocus = false;
2815
2816    switch ( event.keyCode ) {
2817      case keyCode.RIGHT:
2818      case keyCode.DOWN:
2819        toFocus = this.headers[ ( currentIndex + 1 ) % length ];
2820        break;
2821      case keyCode.LEFT:
2822      case keyCode.UP:
2823        toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
2824        break;
2825      case keyCode.SPACE:
2826      case keyCode.ENTER:
2827        this._eventHandler( event );
2828        break;
2829      case keyCode.HOME:
2830        toFocus = this.headers[ 0 ];
2831        break;
2832      case keyCode.END:
2833        toFocus = this.headers[ length - 1 ];
2834        break;
2835    }
2836
2837    if ( toFocus ) {
2838      $( event.target ).attr( "tabIndex", -1 );
2839      $( toFocus ).attr( "tabIndex", 0 );
2840      toFocus.focus();
2841      event.preventDefault();
2842    }
2843  },
2844
2845  _panelKeyDown : function( event ) {
2846    if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
2847      $( event.currentTarget ).prev().focus();
2848    }
2849  },
2850
2851  refresh: function() {
2852    var options = this.options;
2853    this._processPanels();
2854
2855    // was collapsed or no panel
2856    if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
2857      options.active = false;
2858      this.active = $();
2859    // active false only when collapsible is true
2860    } else if ( options.active === false ) {
2861      this._activate( 0 );
2862    // was active, but active panel is gone
2863    } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
2864      // all remaining panel are disabled
2865      if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
2866        options.active = false;
2867        this.active = $();
2868      // activate previous panel
2869      } else {
2870        this._activate( Math.max( 0, options.active - 1 ) );
2871      }
2872    // was active, active panel still exists
2873    } else {
2874      // make sure active index is correct
2875      options.active = this.headers.index( this.active );
2876    }
2877
2878    this._destroyIcons();
2879
2880    this._refresh();
2881  },
2882
2883  _processPanels: function() {
2884    this.headers = this.element.find( this.options.header )
2885      .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
2886
2887    this.headers.next()
2888      .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
2889      .filter(":not(.ui-accordion-content-active)")
2890      .hide();
2891  },
2892
2893  _refresh: function() {
2894    var maxHeight,
2895      options = this.options,
2896      heightStyle = options.heightStyle,
2897      parent = this.element.parent(),
2898      accordionId = this.accordionId = "ui-accordion-" +
2899        (this.element.attr( "id" ) || ++uid);
2900
2901    this.active = this._findActive( options.active )
2902      .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
2903      .removeClass( "ui-corner-all" );
2904    this.active.next()
2905      .addClass( "ui-accordion-content-active" )
2906      .show();
2907
2908    this.headers
2909      .attr( "role", "tab" )
2910      .each(function( i ) {
2911        var header = $( this ),
2912          headerId = header.attr( "id" ),
2913          panel = header.next(),
2914          panelId = panel.attr( "id" );
2915        if ( !headerId ) {
2916          headerId = accordionId + "-header-" + i;
2917          header.attr( "id", headerId );
2918        }
2919        if ( !panelId ) {
2920          panelId = accordionId + "-panel-" + i;
2921          panel.attr( "id", panelId );
2922        }
2923        header.attr( "aria-controls", panelId );
2924        panel.attr( "aria-labelledby", headerId );
2925      })
2926      .next()
2927        .attr( "role", "tabpanel" );
2928
2929    this.headers
2930      .not( this.active )
2931      .attr({
2932        "aria-selected": "false",
2933        "aria-expanded": "false",
2934        tabIndex: -1
2935      })
2936      .next()
2937        .attr({
2938          "aria-hidden": "true"
2939        })
2940        .hide();
2941
2942    // make sure at least one header is in the tab order
2943    if ( !this.active.length ) {
2944      this.headers.eq( 0 ).attr( "tabIndex", 0 );
2945    } else {
2946      this.active.attr({
2947        "aria-selected": "true",
2948        "aria-expanded": "true",
2949        tabIndex: 0
2950      })
2951      .next()
2952        .attr({
2953          "aria-hidden": "false"
2954        });
2955    }
2956
2957    this._createIcons();
2958
2959    this._setupEvents( options.event );
2960
2961    if ( heightStyle === "fill" ) {
2962      maxHeight = parent.height();
2963      this.element.siblings( ":visible" ).each(function() {
2964        var elem = $( this ),
2965          position = elem.css( "position" );
2966
2967        if ( position === "absolute" || position === "fixed" ) {
2968          return;
2969        }
2970        maxHeight -= elem.outerHeight( true );
2971      });
2972
2973      this.headers.each(function() {
2974        maxHeight -= $( this ).outerHeight( true );
2975      });
2976
2977      this.headers.next()
2978        .each(function() {
2979          $( this ).height( Math.max( 0, maxHeight -
2980            $( this ).innerHeight() + $( this ).height() ) );
2981        })
2982        .css( "overflow", "auto" );
2983    } else if ( heightStyle === "auto" ) {
2984      maxHeight = 0;
2985      this.headers.next()
2986        .each(function() {
2987          maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
2988        })
2989        .height( maxHeight );
2990    }
2991  },
2992
2993  _activate: function( index ) {
2994    var active = this._findActive( index )[ 0 ];
2995
2996    // trying to activate the already active panel
2997    if ( active === this.active[ 0 ] ) {
2998      return;
2999    }
3000
3001    // trying to collapse, simulate a click on the currently active header
3002    active = active || this.active[ 0 ];
3003
3004    this._eventHandler({
3005      target: active,
3006      currentTarget: active,
3007      preventDefault: $.noop
3008    });
3009  },
3010
3011  _findActive: function( selector ) {
3012    return typeof selector === "number" ? this.headers.eq( selector ) : $();
3013  },
3014
3015  _setupEvents: function( event ) {
3016    var events = {
3017      keydown: "_keydown"
3018    };
3019    if ( event ) {
3020      $.each( event.split(" "), function( index, eventName ) {
3021        events[ eventName ] = "_eventHandler";
3022      });
3023    }
3024
3025    this._off( this.headers.add( this.headers.next() ) );
3026    this._on( this.headers, events );
3027    this._on( this.headers.next(), { keydown: "_panelKeyDown" });
3028    this._hoverable( this.headers );
3029    this._focusable( this.headers );
3030  },
3031
3032  _eventHandler: function( event ) {
3033    var options = this.options,
3034      active = this.active,
3035      clicked = $( event.currentTarget ),
3036      clickedIsActive = clicked[ 0 ] === active[ 0 ],
3037      collapsing = clickedIsActive && options.collapsible,
3038      toShow = collapsing ? $() : clicked.next(),
3039      toHide = active.next(),
3040      eventData = {
3041        oldHeader: active,
3042        oldPanel: toHide,
3043        newHeader: collapsing ? $() : clicked,
3044        newPanel: toShow
3045      };
3046
3047    event.preventDefault();
3048
3049    if (
3050        // click on active header, but not collapsible
3051        ( clickedIsActive && !options.collapsible ) ||
3052        // allow canceling activation
3053        ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
3054      return;
3055    }
3056
3057    options.active = collapsing ? false : this.headers.index( clicked );
3058
3059    // when the call to ._toggle() comes after the class changes
3060    // it causes a very odd bug in IE 8 (see #6720)
3061    this.active = clickedIsActive ? $() : clicked;
3062    this._toggle( eventData );
3063
3064    // switch classes
3065    // corner classes on the previously active header stay after the animation
3066    active.removeClass( "ui-accordion-header-active ui-state-active" );
3067    if ( options.icons ) {
3068      active.children( ".ui-accordion-header-icon" )
3069        .removeClass( options.icons.activeHeader )
3070        .addClass( options.icons.header );
3071    }
3072
3073    if ( !clickedIsActive ) {
3074      clicked
3075        .removeClass( "ui-corner-all" )
3076        .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
3077      if ( options.icons ) {
3078        clicked.children( ".ui-accordion-header-icon" )
3079          .removeClass( options.icons.header )
3080          .addClass( options.icons.activeHeader );
3081      }
3082
3083      clicked
3084        .next()
3085        .addClass( "ui-accordion-content-active" );
3086    }
3087  },
3088
3089  _toggle: function( data ) {
3090    var toShow = data.newPanel,
3091      toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
3092
3093    // handle activating a panel during the animation for another activation
3094    this.prevShow.add( this.prevHide ).stop( true, true );
3095    this.prevShow = toShow;
3096    this.prevHide = toHide;
3097
3098    if ( this.options.animate ) {
3099      this._animate( toShow, toHide, data );
3100    } else {
3101      toHide.hide();
3102      toShow.show();
3103      this._toggleComplete( data );
3104    }
3105
3106    toHide.attr({
3107      "aria-hidden": "true"
3108    });
3109    toHide.prev().attr( "aria-selected", "false" );
3110    // if we're switching panels, remove the old header from the tab order
3111    // if we're opening from collapsed state, remove the previous header from the tab order
3112    // if we're collapsing, then keep the collapsing header in the tab order
3113    if ( toShow.length && toHide.length ) {
3114      toHide.prev().attr({
3115        "tabIndex": -1,
3116        "aria-expanded": "false"
3117      });
3118    } else if ( toShow.length ) {
3119      this.headers.filter(function() {
3120        return $( this ).attr( "tabIndex" ) === 0;
3121      })
3122      .attr( "tabIndex", -1 );
3123    }
3124
3125    toShow
3126      .attr( "aria-hidden", "false" )
3127      .prev()
3128        .attr({
3129          "aria-selected": "true",
3130          tabIndex: 0,
3131          "aria-expanded": "true"
3132        });
3133  },
3134
3135  _animate: function( toShow, toHide, data ) {
3136    var total, easing, duration,
3137      that = this,
3138      adjust = 0,
3139      down = toShow.length &&
3140        ( !toHide.length || ( toShow.index() < toHide.index() ) ),
3141      animate = this.options.animate || {},
3142      options = down && animate.down || animate,
3143      complete = function() {
3144        that._toggleComplete( data );
3145      };
3146
3147    if ( typeof options === "number" ) {
3148      duration = options;
3149    }
3150    if ( typeof options === "string" ) {
3151      easing = options;
3152    }
3153    // fall back from options to animation in case of partial down settings
3154    easing = easing || options.easing || animate.easing;
3155    duration = duration || options.duration || animate.duration;
3156
3157    if ( !toHide.length ) {
3158      return toShow.animate( showProps, duration, easing, complete );
3159    }
3160    if ( !toShow.length ) {
3161      return toHide.animate( hideProps, duration, easing, complete );
3162    }
3163
3164    total = toShow.show().outerHeight();
3165    toHide.animate( hideProps, {
3166      duration: duration,
3167      easing: easing,
3168      step: function( now, fx ) {
3169        fx.now = Math.round( now );
3170      }
3171    });
3172    toShow
3173      .hide()
3174      .animate( showProps, {
3175        duration: duration,
3176        easing: easing,
3177        complete: complete,
3178        step: function( now, fx ) {
3179          fx.now = Math.round( now );
3180          if ( fx.prop !== "height" ) {
3181            adjust += fx.now;
3182          } else if ( that.options.heightStyle !== "content" ) {
3183            fx.now = Math.round( total - toHide.outerHeight() - adjust );
3184            adjust = 0;
3185          }
3186        }
3187      });
3188  },
3189
3190  _toggleComplete: function( data ) {
3191    var toHide = data.oldPanel;
3192
3193    toHide
3194      .removeClass( "ui-accordion-content-active" )
3195      .prev()
3196        .removeClass( "ui-corner-top" )
3197        .addClass( "ui-corner-all" );
3198
3199    // Work around for rendering bug in IE (#5421)
3200    if ( toHide.length ) {
3201      toHide.parent()[0].className = toHide.parent()[0].className;
3202    }
3203    this._trigger( "activate", null, data );
3204  }
3205});
3206
3207})( _4ORMAT.$ );
3208(function( $, undefined ) {
3209
3210$.widget( "ui.autocomplete", {
3211  version: "1.10.4",
3212  defaultElement: "<input>",
3213  options: {
3214    appendTo: null,
3215    autoFocus: false,
3216    delay: 300,
3217    minLength: 1,
3218    position: {
3219      my: "left top",
3220      at: "left bottom",
3221      collision: "none"
3222    },
3223    source: null,
3224
3225    // callbacks
3226    change: null,
3227    close: null,
3228    focus: null,
3229    open: null,
3230    response: null,
3231    search: null,
3232    select: null
3233  },
3234
3235  requestIndex: 0,
3236  pending: 0,
3237
3238  _create: function() {
3239    // Some browsers only repeat keydown events, not keypress events,
3240    // so we use the suppressKeyPress flag to determine if we've already
3241    // handled the keydown event. #7269
3242    // Unfortunately the code for & in keypress is the same as the up arrow,
3243    // so we use the suppressKeyPressRepeat flag to avoid handling keypress
3244    // events when we know the keydown event was used to modify the
3245    // search term. #7799
3246    var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
3247      nodeName = this.element[0].nodeName.toLowerCase(),
3248      isTextarea = nodeName === "textarea",
3249      isInput = nodeName === "input";
3250
3251    this.isMultiLine =
3252      // Textareas are always multi-line
3253      isTextarea ? true :
3254      // Inputs are always single-line, even if inside a contentEditable element
3255      // IE also treats inputs as contentEditable
3256      isInput ? false :
3257      // All other element types are determined by whether or not they're contentEditable
3258      this.element.prop( "isContentEditable" );
3259
3260    this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
3261    this.isNewMenu = true;
3262
3263    this.element
3264      .addClass( "ui-autocomplete-input" )
3265      .attr( "autocomplete", "off" );
3266
3267    this._on( this.element, {
3268      keydown: function( event ) {
3269        if ( this.element.prop( "readOnly" ) ) {
3270          suppressKeyPress = true;
3271          suppressInput = true;
3272          suppressKeyPressRepeat = true;
3273          return;
3274        }
3275
3276        suppressKeyPress = false;
3277        suppressInput = false;
3278        suppressKeyPressRepeat = false;
3279        var keyCode = $.ui.keyCode;
3280        switch( event.keyCode ) {
3281        case keyCode.PAGE_UP:
3282          suppressKeyPress = true;
3283          this._move( "previousPage", event );
3284          break;
3285        case keyCode.PAGE_DOWN:
3286          suppressKeyPress = true;
3287          this._move( "nextPage", event );
3288          break;
3289        case keyCode.UP:
3290          suppressKeyPress = true;
3291          this._keyEvent( "previous", event );
3292          break;
3293        case keyCode.DOWN:
3294          suppressKeyPress = true;
3295          this._keyEvent( "next", event );
3296          break;
3297        case keyCode.ENTER:
3298        case keyCode.NUMPAD_ENTER:
3299          // when menu is open and has focus
3300          if ( this.menu.active ) {
3301            // #6055 - Opera still allows the keypress to occur
3302            // which causes forms to submit
3303            suppressKeyPress = true;
3304            event.preventDefault();
3305            this.menu.select( event );
3306          }
3307          break;
3308        case keyCode.TAB:
3309          if ( this.menu.active ) {
3310            this.menu.select( event );
3311          }
3312          break;
3313        case keyCode.ESCAPE:
3314          if ( this.menu.element.is( ":visible" ) ) {
3315            this._value( this.term );
3316            this.close( event );
3317            // Different browsers have different default behavior for escape
3318            // Single press can mean undo or clear
3319            // Double press in IE means clear the whole form
3320            event.preventDefault();
3321          }
3322          break;
3323        default:
3324          suppressKeyPressRepeat = true;
3325          // search timeout should be triggered before the input value is changed
3326          this._searchTimeout( event );
3327          break;
3328        }
3329      },
3330      keypress: function( event ) {
3331        if ( suppressKeyPress ) {
3332          suppressKeyPress = false;
3333          if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
3334            event.preventDefault();
3335          }
3336          return;
3337        }
3338        if ( suppressKeyPressRepeat ) {
3339          return;
3340        }
3341
3342        // replicate some key handlers to allow them to repeat in Firefox and Opera
3343        var keyCode = $.ui.keyCode;
3344        switch( event.keyCode ) {
3345        case keyCode.PAGE_UP:
3346          this._move( "previousPage", event );
3347          break;
3348        case keyCode.PAGE_DOWN:
3349          this._move( "nextPage", event );
3350          break;
3351        case keyCode.UP:
3352          this._keyEvent( "previous", event );
3353          break;
3354        case keyCode.DOWN:
3355          this._keyEvent( "next", event );
3356          break;
3357        }
3358      },
3359      input: function( event ) {
3360        if ( suppressInput ) {
3361          suppressInput = false;
3362          event.preventDefault();
3363          return;
3364        }
3365        this._searchTimeout( event );
3366      },
3367      focus: function() {
3368        this.selectedItem = null;
3369        this.previous = this._value();
3370      },
3371      blur: function( event ) {
3372        if ( this.cancelBlur ) {
3373          delete this.cancelBlur;
3374          return;
3375        }
3376
3377        clearTimeout( this.searching );
3378        this.close( event );
3379        this._change( event );
3380      }
3381    });
3382
3383    this._initSource();
3384    this.menu = $( "<ul>" )
3385      .addClass( "ui-autocomplete ui-front" )
3386      .appendTo( this._appendTo() )
3387      .menu({
3388        // disable ARIA support, the live region takes care of that
3389        role: null
3390      })
3391      .hide()
3392      .data( "ui-menu" );
3393
3394    this._on( this.menu.element, {
3395      mousedown: function( event ) {
3396        // prevent moving focus out of the text field
3397        event.preventDefault();
3398
3399        // IE doesn't prevent moving focus even with event.preventDefault()
3400        // so we set a flag to know when we should ignore the blur event
3401        this.cancelBlur = true;
3402        this._delay(function() {
3403          delete this.cancelBlur;
3404        });
3405
3406        // clicking on the scrollbar causes focus to shift to the body
3407        // but we can't detect a mouseup or a click immediately afterward
3408        // so we have to track the next mousedown and close the menu if
3409        // the user clicks somewhere outside of the autocomplete
3410        var menuElement = this.menu.element[ 0 ];
3411        if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
3412          this._delay(function() {
3413            var that = this;
3414            this.document.one( "mousedown", function( event ) {
3415              if ( event.target !== that.element[ 0 ] &&
3416                  event.target !== menuElement &&
3417                  !$.contains( menuElement, event.target ) ) {
3418                that.close();
3419              }
3420            });
3421          });
3422        }
3423      },
3424      menufocus: function( event, ui ) {
3425        // support: Firefox
3426        // Prevent accidental activation of menu items in Firefox (#7024 #9118)
3427        if ( this.isNewMenu ) {
3428          this.isNewMenu = false;
3429          if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
3430            this.menu.blur();
3431
3432            this.document.one( "mousemove", function() {
3433              $( event.target ).trigger( event.originalEvent );
3434            });
3435
3436            return;
3437          }
3438        }
3439
3440        var item = ui.item.data( "ui-autocomplete-item" );
3441        if ( false !== this._trigger( "focus", event, { item: item } ) ) {
3442          // use value to match what will end up in the input, if it was a key event
3443          if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
3444            this._value( item.value );
3445          }
3446        } else {
3447          // Normally the input is populated with the item's value as the
3448          // menu is navigated, causing screen readers to notice a change and
3449          // announce the item. Since the focus event was canceled, this doesn't
3450          // happen, so we update the live region so that screen readers can
3451          // still notice the change and announce it.
3452          this.liveRegion.text( item.value );
3453        }
3454      },
3455      menuselect: function( event, ui ) {
3456        var item = ui.item.data( "ui-autocomplete-item" ),
3457          previous = this.previous;
3458
3459        // only trigger when focus was lost (click on menu)
3460        if ( this.element[0] !== this.document[0].activeElement ) {
3461          this.element.focus();
3462          this.previous = previous;
3463          // #6109 - IE triggers two focus events and the second
3464          // is asynchronous, so we need to reset the previous
3465          // term synchronously and asynchronously :-(
3466          this._delay(function() {
3467            this.previous = previous;
3468            this.selectedItem = item;
3469          });
3470        }
3471
3472        if ( false !== this._trigger( "select", event, { item: item } ) ) {
3473          this._value( item.value );
3474        }
3475        // reset the term after the select event
3476        // this allows custom select handling to work properly
3477        this.term = this._value();
3478
3479        this.close( event );
3480        this.selectedItem = item;
3481      }
3482    });
3483
3484    this.liveRegion = $( "<span>", {
3485        role: "status",
3486        "aria-live": "polite"
3487      })
3488      .addClass( "ui-helper-hidden-accessible" )
3489      .insertBefore( this.element );
3490
3491    // turning off autocomplete prevents the browser from remembering the
3492    // value when navigating through history, so we re-enable autocomplete
3493    // if the page is unloaded before the widget is destroyed. #7790
3494    this._on( this.window, {
3495      beforeunload: function() {
3496        this.element.removeAttr( "autocomplete" );
3497      }
3498    });
3499  },
3500
3501  _destroy: function() {
3502    clearTimeout( this.searching );
3503    this.element
3504      .removeClass( "ui-autocomplete-input" )
3505      .removeAttr( "autocomplete" );
3506    this.menu.element.remove();
3507    this.liveRegion.remove();
3508  },
3509
3510  _setOption: function( key, value ) {
3511    this._super( key, value );
3512    if ( key === "source" ) {
3513      this._initSource();
3514    }
3515    if ( key === "appendTo" ) {
3516      this.menu.element.appendTo( this._appendTo() );
3517    }
3518    if ( key === "disabled" && value && this.xhr ) {
3519      this.xhr.abort();
3520    }
3521  },
3522
3523  _appendTo: function() {
3524    var element = this.options.appendTo;
3525
3526    if ( element ) {
3527      element = element.jquery || element.nodeType ?
3528        $( element ) :
3529        this.document.find( element ).eq( 0 );
3530    }
3531
3532    if ( !element ) {
3533      element = this.element.closest( ".ui-front" );
3534    }
3535
3536    if ( !element.length ) {
3537      element = this.document[0].body;
3538    }
3539
3540    return element;
3541  },
3542
3543  _initSource: function() {
3544    var array, url,
3545      that = this;
3546    if ( $.isArray(this.options.source) ) {
3547      array = this.options.source;
3548      this.source = function( request, response ) {
3549        response( $.ui.autocomplete.filter( array, request.term ) );
3550      };
3551    } else if ( typeof this.options.source === "string" ) {
3552      url = this.options.source;
3553      this.source = function( request, response ) {
3554        if ( that.xhr ) {
3555          that.xhr.abort();
3556        }
3557        that.xhr = $.ajax({
3558          url: url,
3559          data: request,
3560          dataType: "json",
3561          success: function( data ) {
3562            response( data );
3563          },
3564          error: function() {
3565            response( [] );
3566          }
3567        });
3568      };
3569    } else {
3570      this.source = this.options.source;
3571    }
3572  },
3573
3574  _searchTimeout: function( event ) {
3575    clearTimeout( this.searching );
3576    this.searching = this._delay(function() {
3577      // only search if the value has changed
3578      if ( this.term !== this._value() ) {
3579        this.selectedItem = null;
3580        this.search( null, event );
3581      }
3582    }, this.options.delay );
3583  },
3584
3585  search: function( value, event ) {
3586    value = value != null ? value : this._value();
3587
3588    // always save the actual value, not the one passed as an argument
3589    this.term = this._value();
3590
3591    if ( value.length < this.options.minLength ) {
3592      return this.close( event );
3593    }
3594
3595    if ( this._trigger( "search", event ) === false ) {
3596      return;
3597    }
3598
3599    return this._search( value );
3600  },
3601
3602  _search: function( value ) {
3603    this.pending++;
3604    this.element.addClass( "ui-autocomplete-loading" );
3605    this.cancelSearch = false;
3606
3607    this.source( { term: value }, this._response() );
3608  },
3609
3610  _response: function() {
3611    var index = ++this.requestIndex;
3612
3613    return $.proxy(function( content ) {
3614      if ( index === this.requestIndex ) {
3615        this.__response( content );
3616      }
3617
3618      this.pending--;
3619      if ( !this.pending ) {
3620        this.element.removeClass( "ui-autocomplete-loading" );
3621      }
3622    }, this );
3623  },
3624
3625  __response: function( content ) {
3626    if ( content ) {
3627      content = this._normalize( content );
3628    }
3629    this._trigger( "response", null, { content: content } );
3630    if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
3631      this._suggest( content );
3632      this._trigger( "open" );
3633    } else {
3634      // use ._close() instead of .close() so we don't cancel future searches
3635      this._close();
3636    }
3637  },
3638
3639  close: function( event ) {
3640    this.cancelSearch = true;
3641    this._close( event );
3642  },
3643
3644  _close: function( event ) {
3645    if ( this.menu.element.is( ":visible" ) ) {
3646      this.menu.element.hide();
3647      this.menu.blur();
3648      this.isNewMenu = true;
3649      this._trigger( "close", event );
3650    }
3651  },
3652
3653  _change: function( event ) {
3654    if ( this.previous !== this._value() ) {
3655      this._trigger( "change", event, { item: this.selectedItem } );
3656    }
3657  },
3658
3659  _normalize: function( items ) {
3660    // assume all items have the right format when the first item is complete
3661    if ( items.length && items[0].label && items[0].value ) {
3662      return items;
3663    }
3664    return $.map( items, function( item ) {
3665      if ( typeof item === "string" ) {
3666        return {
3667          label: item,
3668          value: item
3669        };
3670      }
3671      return $.extend({
3672        label: item.label || item.value,
3673        value: item.value || item.label
3674      }, item );
3675    });
3676  },
3677
3678  _suggest: function( items ) {
3679    var ul = this.menu.element.empty();
3680    this._renderMenu( ul, items );
3681    this.isNewMenu = true;
3682    this.menu.refresh();
3683
3684    // size and position menu
3685    ul.show();
3686    this._resizeMenu();
3687    ul.position( $.extend({
3688      of: this.element
3689    }, this.options.position ));
3690
3691    if ( this.options.autoFocus ) {
3692      this.menu.next();
3693    }
3694  },
3695
3696  _resizeMenu: function() {
3697    var ul = this.menu.element;
3698    ul.outerWidth( Math.max(
3699      // Firefox wraps long text (possibly a rounding bug)
3700      // so we add 1px to avoid the wrapping (#7513)
3701      ul.width( "" ).outerWidth() + 1,
3702      this.element.outerWidth()
3703    ) );
3704  },
3705
3706  _renderMenu: function( ul, items ) {
3707    var that = this;
3708    $.each( items, function( index, item ) {
3709      that._renderItemData( ul, item );
3710    });
3711  },
3712
3713  _renderItemData: function( ul, item ) {
3714    return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
3715  },
3716
3717  _renderItem: function( ul, item ) {
3718    return $( "<li>" )
3719      .append( $( "<a>" ).text( item.label ) )
3720      .appendTo( ul );
3721  },
3722
3723  _move: function( direction, event ) {
3724    if ( !this.menu.element.is( ":visible" ) ) {
3725      this.search( null, event );
3726      return;
3727    }
3728    if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
3729        this.menu.isLastItem() && /^next/.test( direction ) ) {
3730      this._value( this.term );
3731      this.menu.blur();
3732      return;
3733    }
3734    this.menu[ direction ]( event );
3735  },
3736
3737  widget: function() {
3738    return this.menu.element;
3739  },
3740
3741  _value: function() {
3742    return this.valueMethod.apply( this.element, arguments );
3743  },
3744
3745  _keyEvent: function( keyEvent, event ) {
3746    if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
3747      this._move( keyEvent, event );
3748
3749      // prevents moving cursor to beginning/end of the text field in some browsers
3750      event.preventDefault();
3751    }
3752  }
3753});
3754
3755$.extend( $.ui.autocomplete, {
3756  escapeRegex: function( value ) {
3757    return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
3758  },
3759  filter: function(array, term) {
3760    var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
3761    return $.grep( array, function(value) {
3762      return matcher.test( value.label || value.value || value );
3763    });
3764  }
3765});
3766
3767
3768// live region extension, adding a `messages` option
3769// NOTE: This is an experimental API. We are still investigating
3770// a full solution for string manipulation and internationalization.
3771$.widget( "ui.autocomplete", $.ui.autocomplete, {
3772  options: {
3773    messages: {
3774      noResults: "No search results.",
3775      results: function( amount ) {
3776        return amount + ( amount > 1 ? " results are" : " result is" ) +
3777          " available, use up and down arrow keys to navigate.";
3778      }
3779    }
3780  },
3781
3782  __response: function( content ) {
3783    var message;
3784    this._superApply( arguments );
3785    if ( this.options.disabled || this.cancelSearch ) {
3786      return;
3787    }
3788    if ( content && content.length ) {
3789      message = this.options.messages.results( content.length );
3790    } else {
3791      message = this.options.messages.noResults;
3792    }
3793    this.liveRegion.text( message );
3794  }
3795});
3796
3797}( _4ORMAT.$ ));
3798(function( $, undefined ) {
3799
3800var lastActive,
3801  baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
3802  typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
3803  formResetHandler = function() {
3804    var form = $( this );
3805    setTimeout(function() {
3806      form.find( ":ui-button" ).button( "refresh" );
3807    }, 1 );
3808  },
3809  radioGroup = function( radio ) {
3810    var name = radio.name,
3811      form = radio.form,
3812      radios = $( [] );
3813    if ( name ) {
3814      name = name.replace( /'/g, "\\'" );
3815      if ( form ) {
3816        radios = $( form ).find( "[name='" + name + "']" );
3817      } else {
3818        radios = $( "[name='" + name + "']", radio.ownerDocument )
3819          .filter(function() {
3820            return !this.form;
3821          });
3822      }
3823    }
3824    return radios;
3825  };
3826
3827$.widget( "ui.button", {
3828  version: "1.10.4",
3829  defaultElement: "<button>",
3830  options: {
3831    disabled: null,
3832    text: true,
3833    label: null,
3834    icons: {
3835      primary: null,
3836      secondary: null
3837    }
3838  },
3839  _create: function() {
3840    this.element.closest( "form" )
3841      .unbind( "reset" + this.eventNamespace )
3842      .bind( "reset" + this.eventNamespace, formResetHandler );
3843
3844    if ( typeof this.options.disabled !== "boolean" ) {
3845      this.options.disabled = !!this.element.prop( "disabled" );
3846    } else {
3847      this.element.prop( "disabled", this.options.disabled );
3848    }
3849
3850    this._determineButtonType();
3851    this.hasTitle = !!this.buttonElement.attr( "title" );
3852
3853    var that = this,
3854      options = this.options,
3855      toggleButton = this.type === "checkbox" || this.type === "radio",
3856      activeClass = !toggleButton ? "ui-state-active" : "";
3857
3858    if ( options.label === null ) {
3859      options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
3860    }
3861
3862    this._hoverable( this.buttonElement );
3863
3864    this.buttonElement
3865      .addClass( baseClasses )
3866      .attr( "role", "button" )
3867      .bind( "mouseenter" + this.eventNamespace, function() {
3868        if ( options.disabled ) {
3869          return;
3870        }
3871        if ( this === lastActive ) {
3872          $( this ).addClass( "ui-state-active" );
3873        }
3874      })
3875      .bind( "mouseleave" + this.eventNamespace, function() {
3876        if ( options.disabled ) {
3877          return;
3878        }
3879        $( this ).removeClass( activeClass );
3880      })
3881      .bind( "click" + this.eventNamespace, function( event ) {
3882        if ( options.disabled ) {
3883          event.preventDefault();
3884          event.stopImmediatePropagation();
3885        }
3886      });
3887
3888    // Can't use _focusable() because the element that receives focus
3889    // and the element that gets the ui-state-focus class are different
3890    this._on({
3891      focus: function() {
3892        this.buttonElement.addClass( "ui-state-focus" );
3893      },
3894      blur: function() {
3895        this.buttonElement.removeClass( "ui-state-focus" );
3896      }
3897    });
3898
3899    if ( toggleButton ) {
3900      this.element.bind( "change" + this.eventNamespace, function() {
3901        that.refresh();
3902      });
3903    }
3904
3905    if ( this.type === "checkbox" ) {
3906      this.buttonElement.bind( "click" + this.eventNamespace, function() {
3907        if ( options.disabled ) {
3908          return false;
3909        }
3910      });
3911    } else if ( this.type === "radio" ) {
3912      this.buttonElement.bind( "click" + this.eventNamespace, function() {
3913        if ( options.disabled ) {
3914          return false;
3915        }
3916        $( this ).addClass( "ui-state-active" );
3917        that.buttonElement.attr( "aria-pressed", "true" );
3918
3919        var radio = that.element[ 0 ];
3920        radioGroup( radio )
3921          .not( radio )
3922          .map(function() {
3923            return $( this ).button( "widget" )[ 0 ];
3924          })
3925          .removeClass( "ui-state-active" )
3926          .attr( "aria-pressed", "false" );
3927      });
3928    } else {
3929      this.buttonElement
3930        .bind( "mousedown" + this.eventNamespace, function() {
3931          if ( options.disabled ) {
3932            return false;
3933          }
3934          $( this ).addClass( "ui-state-active" );
3935          lastActive = this;
3936          that.document.one( "mouseup", function() {
3937            lastActive = null;
3938          });
3939        })
3940        .bind( "mouseup" + this.eventNamespace, function() {
3941          if ( options.disabled ) {
3942            return false;
3943          }
3944          $( this ).removeClass( "ui-state-active" );
3945        })
3946        .bind( "keydown" + this.eventNamespace, function(event) {
3947          if ( options.disabled ) {
3948            return false;
3949          }
3950          if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
3951            $( this ).addClass( "ui-state-active" );
3952          }
3953        })
3954        // see #8559, we bind to blur here in case the button element loses
3955        // focus between keydown and keyup, it would be left in an "active" state
3956        .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
3957          $( this ).removeClass( "ui-state-active" );
3958        });
3959
3960      if ( this.buttonElement.is("a") ) {
3961        this.buttonElement.keyup(function(event) {
3962          if ( event.keyCode === $.ui.keyCode.SPACE ) {
3963            // TODO pass through original event correctly (just as 2nd argument doesn't work)
3964            $( this ).click();
3965          }
3966        });
3967      }
3968    }
3969
3970    // TODO: pull out $.Widget's handling for the disabled option into
3971    // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
3972    // be overridden by individual plugins
3973    this._setOption( "disabled", options.disabled );
3974    this._resetButton();
3975  },
3976
3977  _determineButtonType: function() {
3978    var ancestor, labelSelector, checked;
3979
3980    if ( this.element.is("[type=checkbox]") ) {
3981      this.type = "checkbox";
3982    } else if ( this.element.is("[type=radio]") ) {
3983      this.type = "radio";
3984    } else if ( this.element.is("input") ) {
3985      this.type = "input";
3986    } else {
3987      this.type = "button";
3988    }
3989
3990    if ( this.type === "checkbox" || this.type === "radio" ) {
3991      // we don't search against the document in case the element
3992      // is disconnected from the DOM
vendor: 8,776 bytes, lines 3993-4227
3993      ancestor = this.element.parents().last();
3994      labelSelector = "label[for='" + this.element.attr("id") + "']";
3995      this.buttonElement = ancestor.find( labelSelector );
3996      if ( !this.buttonElement.length ) {
3997        ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
3998        this.buttonElement = ancestor.filter( labelSelector );
3999        if ( !this.buttonElement.length ) {
4000          this.buttonElement = ancestor.find( labelSelector );
4001        }
4002      }
4003      this.element.addClass( "ui-helper-hidden-accessible" );
4004
4005      checked = this.element.is( ":checked" );
4006      if ( checked ) {
4007        this.buttonElement.addClass( "ui-state-active" );
4008      }
4009      this.buttonElement.prop( "aria-pressed", checked );
4010    } else {
4011      this.buttonElement = this.element;
4012    }
4013  },
4014
4015  widget: function() {
4016    return this.buttonElement;
4017  },
4018
4019  _destroy: function() {
4020    this.element
4021      .removeClass( "ui-helper-hidden-accessible" );
4022    this.buttonElement
4023      .removeClass( baseClasses + " ui-state-active " + typeClasses )
4024      .removeAttr( "role" )
4025      .removeAttr( "aria-pressed" )
4026      .html( this.buttonElement.find(".ui-button-text").html() );
4027
4028    if ( !this.hasTitle ) {
4029      this.buttonElement.removeAttr( "title" );
4030    }
4031  },
4032
4033  _setOption: function( key, value ) {
4034    this._super( key, value );
4035    if ( key === "disabled" ) {
4036      this.element.prop( "disabled", !!value );
4037      if ( value ) {
4038        this.buttonElement.removeClass( "ui-state-focus" );
4039      }
4040      return;
4041    }
4042    this._resetButton();
4043  },
4044
4045  refresh: function() {
4046    //See #8237 & #8828
4047    var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
4048
4049    if ( isDisabled !== this.options.disabled ) {
4050      this._setOption( "disabled", isDisabled );
4051    }
4052    if ( this.type === "radio" ) {
4053      radioGroup( this.element[0] ).each(function() {
4054        if ( $( this ).is( ":checked" ) ) {
4055          $( this ).button( "widget" )
4056            .addClass( "ui-state-active" )
4057            .attr( "aria-pressed", "true" );
4058        } else {
4059          $( this ).button( "widget" )
4060            .removeClass( "ui-state-active" )
4061            .attr( "aria-pressed", "false" );
4062        }
4063      });
4064    } else if ( this.type === "checkbox" ) {
4065      if ( this.element.is( ":checked" ) ) {
4066        this.buttonElement
4067          .addClass( "ui-state-active" )
4068          .attr( "aria-pressed", "true" );
4069      } else {
4070        this.buttonElement
4071          .removeClass( "ui-state-active" )
4072          .attr( "aria-pressed", "false" );
4073      }
4074    }
4075  },
4076
4077  _resetButton: function() {
4078    if ( this.type === "input" ) {
4079      if ( this.options.label ) {
4080        this.element.val( this.options.label );
4081      }
4082      return;
4083    }
4084    var buttonElement = this.buttonElement.removeClass( typeClasses ),
4085      buttonText = $( "<span></span>", this.document[0] )
4086        .addClass( "ui-button-text" )
4087        .html( this.options.label )
4088        .appendTo( buttonElement.empty() )
4089        .text(),
4090      icons = this.options.icons,
4091      multipleIcons = icons.primary && icons.secondary,
4092      buttonClasses = [];
4093
4094    if ( icons.primary || icons.secondary ) {
4095      if ( this.options.text ) {
4096        buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
4097      }
4098
4099      if ( icons.primary ) {
4100        buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
4101      }
4102
4103      if ( icons.secondary ) {
4104        buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
4105      }
4106
4107      if ( !this.options.text ) {
4108        buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
4109
4110        if ( !this.hasTitle ) {
4111          buttonElement.attr( "title", $.trim( buttonText ) );
4112        }
4113      }
4114    } else {
4115      buttonClasses.push( "ui-button-text-only" );
4116    }
4117    buttonElement.addClass( buttonClasses.join( " " ) );
4118  }
4119});
4120
4121$.widget( "ui.buttonset", {
4122  version: "1.10.4",
4123  options: {
4124    items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
4125  },
4126
4127  _create: function() {
4128    this.element.addClass( "ui-buttonset" );
4129  },
4130
4131  _init: function() {
4132    this.refresh();
4133  },
4134
4135  _setOption: function( key, value ) {
4136    if ( key === "disabled" ) {
4137      this.buttons.button( "option", key, value );
4138    }
4139
4140    this._super( key, value );
4141  },
4142
4143  refresh: function() {
4144    var rtl = this.element.css( "direction" ) === "rtl";
4145
4146    this.buttons = this.element.find( this.options.items )
4147      .filter( ":ui-button" )
4148        .button( "refresh" )
4149      .end()
4150      .not( ":ui-button" )
4151        .button()
4152      .end()
4153      .map(function() {
4154        return $( this ).button( "widget" )[ 0 ];
4155      })
4156        .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
4157        .filter( ":first" )
4158          .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
4159        .end()
4160        .filter( ":last" )
4161          .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
4162        .end()
4163      .end();
4164  },
4165
4166  _destroy: function() {
4167    this.element.removeClass( "ui-buttonset" );
4168    this.buttons
4169      .map(function() {
4170        return $( this ).button( "widget" )[ 0 ];
4171      })
4172        .removeClass( "ui-corner-left ui-corner-right" )
4173      .end()
4174      .button( "destroy" );
4175  }
4176});
4177
4178}( _4ORMAT.$ ) );
4179(function( $, undefined ) {
4180
4181$.extend($.ui, { datepicker: { version: "1.10.4" } });
4182
4183var PROP_NAME = "datepicker",
4184  instActive;
4185
4186/* Date picker manager.
4187   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
4188   Settings for (groups of) date pickers are maintained in an instance object,
4189   allowing multiple different settings on the same page. */
4190
4191function Datepicker() {
4192  this._curInst = null; // The current instance in use
4193  this._keyEvent = false; // If the last event was a key event
4194  this._disabledInputs = []; // List of date picker inputs that have been disabled
4195  this._datepickerShowing = false; // True if the popup picker is showing , false if not
4196  this._inDialog = false; // True if showing within a "dialog", false if not
4197  this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
4198  this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
4199  this._appendClass = "ui-datepicker-append"; // The name of the append marker class
4200  this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
4201  this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
4202  this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
4203  this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
4204  this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
4205  this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
4206  this.regional = []; // Available regional settings, indexed by language code
4207  this.regional[""] = { // Default regional settings
4208    closeText: "Done", // Display text for close link
4209    prevText: "Prev", // Display text for previous month link
4210    nextText: "Next", // Display text for next month link
4211    currentText: "Today", // Display text for current month link
4212    monthNames: ["January","February","March","April","May","June",
4213      "July","August","September","October","November","December"], // Names of months for drop-down and formatting
4214    monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
4215    dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
4216    dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
4217    dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
4218    weekHeader: "Wk", // Column header for week of the year
4219    dateFormat: "mm/dd/yy", // See format options on parseDate
4220    firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
4221    isRTL: false, // True if right-to-left language, false if left-to-right
4222    showMonthAfterYear: false, // True if the year select precedes month, false for month then year
4223    yearSuffix: "" // Additional text to append to the year in the month headers
4224  };
4225  this._defaults = { // Global defaults for all the date picker instances
4226    showOn: "focus", // "focus" for popup on focus,
4227      // "button" for trigger button, or "both" for either
vendor: 5,736 bytes, lines 4228-4332
4228    showAnim: "fadeIn", // Name of jQuery animation for popup
4229    showOptions: {}, // Options for enhanced animations
4230    defaultDate: null, // Used when field is blank: actual date,
4231      // +/-number for offset from today, null for today
4232    appendText: "", // Display text following the input box, e.g. showing the format
4233    buttonText: "...", // Text for trigger button
4234    buttonImage: "", // URL for trigger button image
4235    buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
4236    hideIfNoPrevNext: false, // True to hide next/previous month links
4237      // if not applicable, false to just disable them
4238    navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
4239    gotoCurrent: false, // True if today link goes back to current selection instead
4240    changeMonth: false, // True if month can be selected directly, false if only prev/next
4241    changeYear: false, // True if year can be selected directly, false if only prev/next
4242    yearRange: "c-10:c+10", // Range of years to display in drop-down,
4243      // either relative to today's year (-nn:+nn), relative to currently displayed year
4244      // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
4245    showOtherMonths: false, // True to show dates in other months, false to leave blank
4246    selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
4247    showWeek: false, // True to show week of the year, false to not show it
4248    calculateWeek: this.iso8601Week, // How to calculate the week of the year,
4249      // takes a Date and returns the number of the week for it
4250    shortYearCutoff: "+10", // Short year values < this are in the current century,
4251      // > this are in the previous century,
4252      // string value starting with "+" for current year + value
4253    minDate: null, // The earliest selectable date, or null for no limit
4254    maxDate: null, // The latest selectable date, or null for no limit
4255    duration: "fast", // Duration of display/closure
4256    beforeShowDay: null, // Function that takes a date and returns an array with
4257      // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
4258      // [2] = cell title (optional), e.g. $.datepicker.noWeekends
4259    beforeShow: null, // Function that takes an input field and
4260      // returns a set of custom settings for the date picker
4261    onSelect: null, // Define a callback function when a date is selected
4262    onChangeMonthYear: null, // Define a callback function when the month or year is changed
4263    onClose: null, // Define a callback function when the datepicker is closed
4264    numberOfMonths: 1, // Number of months to show at a time
4265    showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
4266    stepMonths: 1, // Number of months to step back/forward
4267    stepBigMonths: 12, // Number of months to step back/forward for the big links
4268    altField: "", // Selector for an alternate field to store selected dates into
4269    altFormat: "", // The date format to use for the alternate field
4270    constrainInput: true, // The input is constrained by the current date format
4271    showButtonPanel: false, // True to show button panel, false to not show it
4272    autoSize: false, // True to size the input for the date format, false to leave as is
4273    disabled: false // The initial disabled state
4274  };
4275  $.extend(this._defaults, this.regional[""]);
4276  this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
4277}
4278
4279$.extend(Datepicker.prototype, {
4280  /* Class name added to elements to indicate already configured with a date picker. */
4281  markerClassName: "hasDatepicker",
4282
4283  //Keep track of the maximum number of rows displayed (see #7043)
4284  maxRows: 4,
4285
4286  // TODO rename to "widget" when switching to widget factory
4287  _widgetDatepicker: function() {
4288    return this.dpDiv;
4289  },
4290
4291  /* Override the default settings for all instances of the date picker.
4292   * @param  settings  object - the new settings to use as defaults (anonymous object)
4293   * @return the manager object
4294   */
4295  setDefaults: function(settings) {
4296    extendRemove(this._defaults, settings || {});
4297    return this;
4298  },
4299
4300  /* Attach the date picker to a jQuery selection.
4301   * @param  target element - the target input field or division or span
4302   * @param  settings  object - the new settings to use for this date picker instance (anonymous)
4303   */
4304  _attachDatepicker: function(target, settings) {
4305    var nodeName, inline, inst;
4306    nodeName = target.nodeName.toLowerCase();
4307    inline = (nodeName === "div" || nodeName === "span");
4308    if (!target.id) {
4309      this.uuid += 1;
4310      target.id = "dp" + this.uuid;
4311    }
4312    inst = this._newInst($(target), inline);
4313    inst.settings = $.extend({}, settings || {});
4314    if (nodeName === "input") {
4315      this._connectDatepicker(target, inst);
4316    } else if (inline) {
4317      this._inlineDatepicker(target, inst);
4318    }
4319  },
4320
4321  /* Create a new instance object. */
4322  _newInst: function(target, inline) {
4323    var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
4324    return {id: id, input: target, // associated target
4325      selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
4326      drawMonth: 0, drawYear: 0, // month being drawn
4327      inline: inline, // is datepicker inline or not
4328      dpDiv: (!inline ? this.dpDiv : // presentation div
4329      bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
4330  },
4331
4332  /* Attach the date picker to an input field. */
vendor: 7,031 bytes, lines 4333-4513
4333  _connectDatepicker: function(target, inst) {
4334    var input = $(target);
4335    inst.append = $([]);
4336    inst.trigger = $([]);
4337    if (input.hasClass(this.markerClassName)) {
4338      return;
4339    }
4340    this._attachments(input, inst);
4341    input.addClass(this.markerClassName).keydown(this._doKeyDown).
4342      keypress(this._doKeyPress).keyup(this._doKeyUp);
4343    this._autoSize(inst);
4344    $.data(target, PROP_NAME, inst);
4345    //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
4346    if( inst.settings.disabled ) {
4347      this._disableDatepicker( target );
4348    }
4349  },
4350
4351  /* Make attachments based on settings. */
4352  _attachments: function(input, inst) {
4353    var showOn, buttonText, buttonImage,
4354      appendText = this._get(inst, "appendText"),
4355      isRTL = this._get(inst, "isRTL");
4356
4357    if (inst.append) {
4358      inst.append.remove();
4359    }
4360    if (appendText) {
4361      inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
4362      input[isRTL ? "before" : "after"](inst.append);
4363    }
4364
4365    input.unbind("focus", this._showDatepicker);
4366
4367    if (inst.trigger) {
4368      inst.trigger.remove();
4369    }
4370
4371    showOn = this._get(inst, "showOn");
4372    if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
4373      input.focus(this._showDatepicker);
4374    }
4375    if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
4376      buttonText = this._get(inst, "buttonText");
4377      buttonImage = this._get(inst, "buttonImage");
4378      inst.trigger = $(this._get(inst, "buttonImageOnly") ?
4379        $("<img/>").addClass(this._triggerClass).
4380          attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
4381        $("<button type='button'></button>").addClass(this._triggerClass).
4382          html(!buttonImage ? buttonText : $("<img/>").attr(
4383          { src:buttonImage, alt:buttonText, title:buttonText })));
4384      input[isRTL ? "before" : "after"](inst.trigger);
4385      inst.trigger.click(function() {
4386        if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
4387          $.datepicker._hideDatepicker();
4388        } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
4389          $.datepicker._hideDatepicker();
4390          $.datepicker._showDatepicker(input[0]);
4391        } else {
4392          $.datepicker._showDatepicker(input[0]);
4393        }
4394        return false;
4395      });
4396    }
4397  },
4398
4399  /* Apply the maximum length for the date format. */
4400  _autoSize: function(inst) {
4401    if (this._get(inst, "autoSize") && !inst.inline) {
4402      var findMax, max, maxI, i,
4403        date = new Date(2009, 12 - 1, 20), // Ensure double digits
4404        dateFormat = this._get(inst, "dateFormat");
4405
4406      if (dateFormat.match(/[DM]/)) {
4407        findMax = function(names) {
4408          max = 0;
4409          maxI = 0;
4410          for (i = 0; i < names.length; i++) {
4411            if (names[i].length > max) {
4412              max = names[i].length;
4413              maxI = i;
4414            }
4415          }
4416          return maxI;
4417        };
4418        date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
4419          "monthNames" : "monthNamesShort"))));
4420        date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
4421          "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
4422      }
4423      inst.input.attr("size", this._formatDate(inst, date).length);
4424    }
4425  },
4426
4427  /* Attach an inline date picker to a div. */
4428  _inlineDatepicker: function(target, inst) {
4429    var divSpan = $(target);
4430    if (divSpan.hasClass(this.markerClassName)) {
4431      return;
4432    }
4433    divSpan.addClass(this.markerClassName).append(inst.dpDiv);
4434    $.data(target, PROP_NAME, inst);
4435    this._setDate(inst, this._getDefaultDate(inst), true);
4436    this._updateDatepicker(inst);
4437    this._updateAlternate(inst);
4438    //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
4439    if( inst.settings.disabled ) {
4440      this._disableDatepicker( target );
4441    }
4442    // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
4443    // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
4444    inst.dpDiv.css( "display", "block" );
4445  },
4446
4447  /* Pop-up the date picker in a "dialog" box.
4448   * @param  input element - ignored
4449   * @param  date string or Date - the initial date to display
4450   * @param  onSelect  function - the function to call when a date is selected
4451   * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
4452   * @param  pos int[2] - coordinates for the dialog's position within the screen or
4453   *          event - with x/y coordinates or
4454   *          leave empty for default (screen centre)
4455   * @return the manager object
4456   */
4457  _dialogDatepicker: function(input, date, onSelect, settings, pos) {
4458    var id, browserWidth, browserHeight, scrollX, scrollY,
4459      inst = this._dialogInst; // internal instance
4460
4461    if (!inst) {
4462      this.uuid += 1;
4463      id = "dp" + this.uuid;
4464      this._dialogInput = $("<input type='text' id='" + id +
4465        "' style='position: absolute; top: -100px; width: 0px;'/>");
4466      this._dialogInput.keydown(this._doKeyDown);
4467      $("body").append(this._dialogInput);
4468      inst = this._dialogInst = this._newInst(this._dialogInput, false);
4469      inst.settings = {};
4470      $.data(this._dialogInput[0], PROP_NAME, inst);
4471    }
4472    extendRemove(inst.settings, settings || {});
4473    date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
4474    this._dialogInput.val(date);
4475
4476    this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
4477    if (!this._pos) {
4478      browserWidth = document.documentElement.clientWidth;
4479      browserHeight = document.documentElement.clientHeight;
4480      scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
4481      scrollY = document.documentElement.scrollTop || document.body.scrollTop;
4482      this._pos = // should use actual width/height below
4483        [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
4484    }
4485
4486    // move input on screen for focus, but hidden behind dialog
4487    this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
4488    inst.settings.onSelect = onSelect;
4489    this._inDialog = true;
4490    this.dpDiv.addClass(this._dialogClass);
4491    this._showDatepicker(this._dialogInput[0]);
4492    if ($.blockUI) {
4493      $.blockUI(this.dpDiv);
4494    }
4495    $.data(this._dialogInput[0], PROP_NAME, inst);
4496    return this;
4497  },
4498
4499  /* Detach a datepicker from its control.
4500   * @param  target element - the target input field or division or span
4501   */
4502  _destroyDatepicker: function(target) {
4503    var nodeName,
4504      $target = $(target),
4505      inst = $.data(target, PROP_NAME);
4506
4507    if (!$target.hasClass(this.markerClassName)) {
4508      return;
4509    }
4510
4511    nodeName = target.nodeName.toLowerCase();
4512    $.removeData(target, PROP_NAME);
4513    if (nodeName === "input") {
vendor: 11,673 bytes, lines 4514-4825
4514      inst.append.remove();
4515      inst.trigger.remove();
4516      $target.removeClass(this.markerClassName).
4517        unbind("focus", this._showDatepicker).
4518        unbind("keydown", this._doKeyDown).
4519        unbind("keypress", this._doKeyPress).
4520        unbind("keyup", this._doKeyUp);
4521    } else if (nodeName === "div" || nodeName === "span") {
4522      $target.removeClass(this.markerClassName).empty();
4523    }
4524  },
4525
4526  /* Enable the date picker to a jQuery selection.
4527   * @param  target element - the target input field or division or span
4528   */
4529  _enableDatepicker: function(target) {
4530    var nodeName, inline,
4531      $target = $(target),
4532      inst = $.data(target, PROP_NAME);
4533
4534    if (!$target.hasClass(this.markerClassName)) {
4535      return;
4536    }
4537
4538    nodeName = target.nodeName.toLowerCase();
4539    if (nodeName === "input") {
4540      target.disabled = false;
4541      inst.trigger.filter("button").
4542        each(function() { this.disabled = false; }).end().
4543        filter("img").css({opacity: "1.0", cursor: ""});
4544    } else if (nodeName === "div" || nodeName === "span") {
4545      inline = $target.children("." + this._inlineClass);
4546      inline.children().removeClass("ui-state-disabled");
4547      inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
4548        prop("disabled", false);
4549    }
4550    this._disabledInputs = $.map(this._disabledInputs,
4551      function(value) { return (value === target ? null : value); }); // delete entry
4552  },
4553
4554  /* Disable the date picker to a jQuery selection.
4555   * @param  target element - the target input field or division or span
4556   */
4557  _disableDatepicker: function(target) {
4558    var nodeName, inline,
4559      $target = $(target),
4560      inst = $.data(target, PROP_NAME);
4561
4562    if (!$target.hasClass(this.markerClassName)) {
4563      return;
4564    }
4565
4566    nodeName = target.nodeName.toLowerCase();
4567    if (nodeName === "input") {
4568      target.disabled = true;
4569      inst.trigger.filter("button").
4570        each(function() { this.disabled = true; }).end().
4571        filter("img").css({opacity: "0.5", cursor: "default"});
4572    } else if (nodeName === "div" || nodeName === "span") {
4573      inline = $target.children("." + this._inlineClass);
4574      inline.children().addClass("ui-state-disabled");
4575      inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
4576        prop("disabled", true);
4577    }
4578    this._disabledInputs = $.map(this._disabledInputs,
4579      function(value) { return (value === target ? null : value); }); // delete entry
4580    this._disabledInputs[this._disabledInputs.length] = target;
4581  },
4582
4583  /* Is the first field in a jQuery collection disabled as a datepicker?
4584   * @param  target element - the target input field or division or span
4585   * @return boolean - true if disabled, false if enabled
4586   */
4587  _isDisabledDatepicker: function(target) {
4588    if (!target) {
4589      return false;
4590    }
4591    for (var i = 0; i < this._disabledInputs.length; i++) {
4592      if (this._disabledInputs[i] === target) {
4593        return true;
4594      }
4595    }
4596    return false;
4597  },
4598
4599  /* Retrieve the instance data for the target control.
4600   * @param  target  element - the target input field or division or span
4601   * @return  object - the associated instance data
4602   * @throws  error if a jQuery problem getting data
4603   */
4604  _getInst: function(target) {
4605    try {
4606      return $.data(target, PROP_NAME);
4607    }
4608    catch (err) {
4609      throw "Missing instance data for this datepicker";
4610    }
4611  },
4612
4613  /* Update or retrieve the settings for a date picker attached to an input field or division.
4614   * @param  target  element - the target input field or division or span
4615   * @param  name object - the new settings to update or
4616   *        string - the name of the setting to change or retrieve,
4617   *        when retrieving also "all" for all instance settings or
4618   *        "defaults" for all global defaults
4619   * @param  value   any - the new value for the setting
4620   *        (omit if above is an object or to retrieve a value)
4621   */
4622  _optionDatepicker: function(target, name, value) {
4623    var settings, date, minDate, maxDate,
4624      inst = this._getInst(target);
4625
4626    if (arguments.length === 2 && typeof name === "string") {
4627      return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
4628        (inst ? (name === "all" ? $.extend({}, inst.settings) :
4629        this._get(inst, name)) : null));
4630    }
4631
4632    settings = name || {};
4633    if (typeof name === "string") {
4634      settings = {};
4635      settings[name] = value;
4636    }
4637
4638    if (inst) {
4639      if (this._curInst === inst) {
4640        this._hideDatepicker();
4641      }
4642
4643      date = this._getDateDatepicker(target, true);
4644      minDate = this._getMinMaxDate(inst, "min");
4645      maxDate = this._getMinMaxDate(inst, "max");
4646      extendRemove(inst.settings, settings);
4647      // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
4648      if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
4649        inst.settings.minDate = this._formatDate(inst, minDate);
4650      }
4651      if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
4652        inst.settings.maxDate = this._formatDate(inst, maxDate);
4653      }
4654      if ( "disabled" in settings ) {
4655        if ( settings.disabled ) {
4656          this._disableDatepicker(target);
4657        } else {
4658          this._enableDatepicker(target);
4659        }
4660      }
4661      this._attachments($(target), inst);
4662      this._autoSize(inst);
4663      this._setDate(inst, date);
4664      this._updateAlternate(inst);
4665      this._updateDatepicker(inst);
4666    }
4667  },
4668
4669  // change method deprecated
4670  _changeDatepicker: function(target, name, value) {
4671    this._optionDatepicker(target, name, value);
4672  },
4673
4674  /* Redraw the date picker attached to an input field or division.
4675   * @param  target  element - the target input field or division or span
4676   */
4677  _refreshDatepicker: function(target) {
4678    var inst = this._getInst(target);
4679    if (inst) {
4680      this._updateDatepicker(inst);
4681    }
4682  },
4683
4684  /* Set the dates for a jQuery selection.
4685   * @param  target element - the target input field or division or span
4686   * @param  date Date - the new date
4687   */
4688  _setDateDatepicker: function(target, date) {
4689    var inst = this._getInst(target);
4690    if (inst) {
4691      this._setDate(inst, date);
4692      this._updateDatepicker(inst);
4693      this._updateAlternate(inst);
4694    }
4695  },
4696
4697  /* Get the date(s) for the first entry in a jQuery selection.
4698   * @param  target element - the target input field or division or span
4699   * @param  noDefault boolean - true if no default date is to be used
4700   * @return Date - the current date
4701   */
4702  _getDateDatepicker: function(target, noDefault) {
4703    var inst = this._getInst(target);
4704    if (inst && !inst.inline) {
4705      this._setDateFromField(inst, noDefault);
4706    }
4707    return (inst ? this._getDate(inst) : null);
4708  },
4709
4710  /* Handle keystrokes. */
4711  _doKeyDown: function(event) {
4712    var onSelect, dateStr, sel,
4713      inst = $.datepicker._getInst(event.target),
4714      handled = true,
4715      isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
4716
4717    inst._keyEvent = true;
4718    if ($.datepicker._datepickerShowing) {
4719      switch (event.keyCode) {
4720        case 9: $.datepicker._hideDatepicker();
4721            handled = false;
4722            break; // hide on tab out
4723        case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
4724                  $.datepicker._currentClass + ")", inst.dpDiv);
4725            if (sel[0]) {
4726              $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
4727            }
4728
4729            onSelect = $.datepicker._get(inst, "onSelect");
4730            if (onSelect) {
4731              dateStr = $.datepicker._formatDate(inst);
4732
4733              // trigger custom callback
4734              onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
4735            } else {
4736              $.datepicker._hideDatepicker();
4737            }
4738
4739            return false; // don't submit the form
4740        case 27: $.datepicker._hideDatepicker();
4741            break; // hide on escape
4742        case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4743              -$.datepicker._get(inst, "stepBigMonths") :
4744              -$.datepicker._get(inst, "stepMonths")), "M");
4745            break; // previous month/year on page up/+ ctrl
4746        case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4747              +$.datepicker._get(inst, "stepBigMonths") :
4748              +$.datepicker._get(inst, "stepMonths")), "M");
4749            break; // next month/year on page down/+ ctrl
4750        case 35: if (event.ctrlKey || event.metaKey) {
4751              $.datepicker._clearDate(event.target);
4752            }
4753            handled = event.ctrlKey || event.metaKey;
4754            break; // clear on ctrl or command +end
4755        case 36: if (event.ctrlKey || event.metaKey) {
4756              $.datepicker._gotoToday(event.target);
4757            }
4758            handled = event.ctrlKey || event.metaKey;
4759            break; // current on ctrl or command +home
4760        case 37: if (event.ctrlKey || event.metaKey) {
4761              $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
4762            }
4763            handled = event.ctrlKey || event.metaKey;
4764            // -1 day on ctrl or command +left
4765            if (event.originalEvent.altKey) {
4766              $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4767                -$.datepicker._get(inst, "stepBigMonths") :
4768                -$.datepicker._get(inst, "stepMonths")), "M");
4769            }
4770            // next month/year on alt +left on Mac
4771            break;
4772        case 38: if (event.ctrlKey || event.metaKey) {
4773              $.datepicker._adjustDate(event.target, -7, "D");
4774            }
4775            handled = event.ctrlKey || event.metaKey;
4776            break; // -1 week on ctrl or command +up
4777        case 39: if (event.ctrlKey || event.metaKey) {
4778              $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
4779            }
4780            handled = event.ctrlKey || event.metaKey;
4781            // +1 day on ctrl or command +right
4782            if (event.originalEvent.altKey) {
4783              $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4784                +$.datepicker._get(inst, "stepBigMonths") :
4785                +$.datepicker._get(inst, "stepMonths")), "M");
4786            }
4787            // next month/year on alt +right
4788            break;
4789        case 40: if (event.ctrlKey || event.metaKey) {
4790              $.datepicker._adjustDate(event.target, +7, "D");
4791            }
4792            handled = event.ctrlKey || event.metaKey;
4793            break; // +1 week on ctrl or command +down
4794        default: handled = false;
4795      }
4796    } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
4797      $.datepicker._showDatepicker(this);
4798    } else {
4799      handled = false;
4800    }
4801
4802    if (handled) {
4803      event.preventDefault();
4804      event.stopPropagation();
4805    }
4806  },
4807
4808  /* Filter entered characters - based on date format. */
4809  _doKeyPress: function(event) {
4810    var chars, chr,
4811      inst = $.datepicker._getInst(event.target);
4812
4813    if ($.datepicker._get(inst, "constrainInput")) {
4814      chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
4815      chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
4816      return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
4817    }
4818  },
4819
4820  /* Synchronise manual entry and field/alternate field. */
4821  _doKeyUp: function(event) {
4822    var date,
4823      inst = $.datepicker._getInst(event.target);
4824
4825    if (inst.input.val() !== inst.lastVal) {
vendor: 9,399 bytes, lines 4826-5082
4826      try {
4827        date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
4828          (inst.input ? inst.input.val() : null),
4829          $.datepicker._getFormatConfig(inst));
4830
4831        if (date) { // only if valid
4832          $.datepicker._setDateFromField(inst);
4833          $.datepicker._updateAlternate(inst);
4834          $.datepicker._updateDatepicker(inst);
4835        }
4836      }
4837      catch (err) {
4838      }
4839    }
4840    return true;
4841  },
4842
4843  /* Pop-up the date picker for a given input field.
4844   * If false returned from beforeShow event handler do not show.
4845   * @param  input  element - the input field attached to the date picker or
4846   *          event - if triggered by focus
4847   */
4848  _showDatepicker: function(input) {
4849    input = input.target || input;
4850    if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
4851      input = $("input", input.parentNode)[0];
4852    }
4853
4854    if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
4855      return;
4856    }
4857
4858    var inst, beforeShow, beforeShowSettings, isFixed,
4859      offset, showAnim, duration;
4860
4861    inst = $.datepicker._getInst(input);
4862    if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
4863      $.datepicker._curInst.dpDiv.stop(true, true);
4864      if ( inst && $.datepicker._datepickerShowing ) {
4865        $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
4866      }
4867    }
4868
4869    beforeShow = $.datepicker._get(inst, "beforeShow");
4870    beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
4871    if(beforeShowSettings === false){
4872      return;
4873    }
4874    extendRemove(inst.settings, beforeShowSettings);
4875
4876    inst.lastVal = null;
4877    $.datepicker._lastInput = input;
4878    $.datepicker._setDateFromField(inst);
4879
4880    if ($.datepicker._inDialog) { // hide cursor
4881      input.value = "";
4882    }
4883    if (!$.datepicker._pos) { // position below input
4884      $.datepicker._pos = $.datepicker._findPos(input);
4885      $.datepicker._pos[1] += input.offsetHeight; // add the height
4886    }
4887
4888    isFixed = false;
4889    $(input).parents().each(function() {
4890      isFixed |= $(this).css("position") === "fixed";
4891      return !isFixed;
4892    });
4893
4894    offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
4895    $.datepicker._pos = null;
4896    //to avoid flashes on Firefox
4897    inst.dpDiv.empty();
4898    // determine sizing offscreen
4899    inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
4900    $.datepicker._updateDatepicker(inst);
4901    // fix width for dynamic number of date pickers
4902    // and adjust position before showing
4903    offset = $.datepicker._checkOffset(inst, offset, isFixed);
4904    inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
4905      "static" : (isFixed ? "fixed" : "absolute")), display: "none",
4906      left: offset.left + "px", top: offset.top + "px"});
4907
4908    if (!inst.inline) {
4909      showAnim = $.datepicker._get(inst, "showAnim");
4910      duration = $.datepicker._get(inst, "duration");
4911      inst.dpDiv.zIndex($(input).zIndex()+1);
4912      $.datepicker._datepickerShowing = true;
4913
4914      if ( $.effects && $.effects.effect[ showAnim ] ) {
4915        inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
4916      } else {
4917        inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
4918      }
4919
4920      if ( $.datepicker._shouldFocusInput( inst ) ) {
4921        inst.input.focus();
4922      }
4923
4924      $.datepicker._curInst = inst;
4925    }
4926  },
4927
4928  /* Generate the date picker content. */
4929  _updateDatepicker: function(inst) {
4930    this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
4931    instActive = inst; // for delegate hover events
4932    inst.dpDiv.empty().append(this._generateHTML(inst));
4933    this._attachHandlers(inst);
4934    inst.dpDiv.find("." + this._dayOverClass + " a").mouseover();
4935
4936    var origyearshtml,
4937      numMonths = this._getNumberOfMonths(inst),
4938      cols = numMonths[1],
4939      width = 17;
4940
4941    inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
4942    if (cols > 1) {
4943      inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
4944    }
4945    inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
4946      "Class"]("ui-datepicker-multi");
4947    inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
4948      "Class"]("ui-datepicker-rtl");
4949
4950    if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
4951      inst.input.focus();
4952    }
4953
4954    // deffered render of the years select (to avoid flashes on Firefox)
4955    if( inst.yearshtml ){
4956      origyearshtml = inst.yearshtml;
4957      setTimeout(function(){
4958        //assure that inst.yearshtml didn't change.
4959        if( origyearshtml === inst.yearshtml && inst.yearshtml ){
4960          inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
4961        }
4962        origyearshtml = inst.yearshtml = null;
4963      }, 0);
4964    }
4965  },
4966
4967  // #6694 - don't focus the input if it's already focused
4968  // this breaks the change event in IE
4969  // Support: IE and jQuery <1.9
4970  _shouldFocusInput: function( inst ) {
4971    return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
4972  },
4973
4974  /* Check positioning to remain on screen. */
4975  _checkOffset: function(inst, offset, isFixed) {
4976    var dpWidth = inst.dpDiv.outerWidth(),
4977      dpHeight = inst.dpDiv.outerHeight(),
4978      inputWidth = inst.input ? inst.input.outerWidth() : 0,
4979      inputHeight = inst.input ? inst.input.outerHeight() : 0,
4980      viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
4981      viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
4982
4983    offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
4984    offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
4985    offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
4986
4987    // now check if datepicker is showing outside window viewport - move to a better place if so.
4988    offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
4989      Math.abs(offset.left + dpWidth - viewWidth) : 0);
4990    offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
4991      Math.abs(dpHeight + inputHeight) : 0);
4992
4993    return offset;
4994  },
4995
4996  /* Find an object's position on the screen. */
4997  _findPos: function(obj) {
4998    var position,
4999      inst = this._getInst(obj),
5000      isRTL = this._get(inst, "isRTL");
5001
5002    while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
5003      obj = obj[isRTL ? "previousSibling" : "nextSibling"];
5004    }
5005
5006    position = $(obj).offset();
5007    return [position.left, position.top];
5008  },
5009
5010  /* Hide the date picker from view.
5011   * @param  input  element - the input field attached to the date picker
5012   */
5013  _hideDatepicker: function(input) {
5014    var showAnim, duration, postProcess, onClose,
5015      inst = this._curInst;
5016
5017    if (!inst || (input && inst !== $.data(input, PROP_NAME))) {
5018      return;
5019    }
5020
5021    if (this._datepickerShowing) {
5022      showAnim = this._get(inst, "showAnim");
5023      duration = this._get(inst, "duration");
5024      postProcess = function() {
5025        $.datepicker._tidyDialog(inst);
5026      };
5027
5028      // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
5029      if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
5030        inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
5031      } else {
5032        inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
5033          (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
5034      }
5035
5036      if (!showAnim) {
5037        postProcess();
5038      }
5039      this._datepickerShowing = false;
5040
5041      onClose = this._get(inst, "onClose");
5042      if (onClose) {
5043        onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
5044      }
5045
5046      this._lastInput = null;
5047      if (this._inDialog) {
5048        this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
5049        if ($.blockUI) {
5050          $.unblockUI();
5051          $("body").append(this.dpDiv);
5052        }
5053      }
5054      this._inDialog = false;
5055    }
5056  },
5057
5058  /* Tidy up after a dialog display. */
5059  _tidyDialog: function(inst) {
5060    inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
5061  },
5062
5063  /* Close date picker if clicked elsewhere. */
5064  _checkExternalClick: function(event) {
5065    if (!$.datepicker._curInst) {
5066      return;
5067    }
5068
5069    var $target = $(event.target),
5070      inst = $.datepicker._getInst($target[0]);
5071
5072    if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
5073        $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
5074        !$target.hasClass($.datepicker.markerClassName) &&
5075        !$target.closest("." + $.datepicker._triggerClass).length &&
5076        $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
5077      ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
5078        $.datepicker._hideDatepicker();
5079    }
5080  },
5081
5082  /* Adjust one of the date sub-fields. */
vendor: 4,555 bytes, lines 5083-5224
5083  _adjustDate: function(id, offset, period) {
5084    var target = $(id),
5085      inst = this._getInst(target[0]);
5086
5087    if (this._isDisabledDatepicker(target[0])) {
5088      return;
5089    }
5090    this._adjustInstDate(inst, offset +
5091      (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
5092      period);
5093    this._updateDatepicker(inst);
5094  },
5095
5096  /* Action for current link. */
5097  _gotoToday: function(id) {
5098    var date,
5099      target = $(id),
5100      inst = this._getInst(target[0]);
5101
5102    if (this._get(inst, "gotoCurrent") && inst.currentDay) {
5103      inst.selectedDay = inst.currentDay;
5104      inst.drawMonth = inst.selectedMonth = inst.currentMonth;
5105      inst.drawYear = inst.selectedYear = inst.currentYear;
5106    } else {
5107      date = new Date();
5108      inst.selectedDay = date.getDate();
5109      inst.drawMonth = inst.selectedMonth = date.getMonth();
5110      inst.drawYear = inst.selectedYear = date.getFullYear();
5111    }
5112    this._notifyChange(inst);
5113    this._adjustDate(target);
5114  },
5115
5116  /* Action for selecting a new month/year. */
5117  _selectMonthYear: function(id, select, period) {
5118    var target = $(id),
5119      inst = this._getInst(target[0]);
5120
5121    inst["selected" + (period === "M" ? "Month" : "Year")] =
5122    inst["draw" + (period === "M" ? "Month" : "Year")] =
5123      parseInt(select.options[select.selectedIndex].value,10);
5124
5125    this._notifyChange(inst);
5126    this._adjustDate(target);
5127  },
5128
5129  /* Action for selecting a day. */
5130  _selectDay: function(id, month, year, td) {
5131    var inst,
5132      target = $(id);
5133
5134    if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
5135      return;
5136    }
5137
5138    inst = this._getInst(target[0]);
5139    inst.selectedDay = inst.currentDay = $("a", td).html();
5140    inst.selectedMonth = inst.currentMonth = month;
5141    inst.selectedYear = inst.currentYear = year;
5142    this._selectDate(id, this._formatDate(inst,
5143      inst.currentDay, inst.currentMonth, inst.currentYear));
5144  },
5145
5146  /* Erase the input field and hide the date picker. */
5147  _clearDate: function(id) {
5148    var target = $(id);
5149    this._selectDate(target, "");
5150  },
5151
5152  /* Update the input field with the selected date. */
5153  _selectDate: function(id, dateStr) {
5154    var onSelect,
5155      target = $(id),
5156      inst = this._getInst(target[0]);
5157
5158    dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
5159    if (inst.input) {
5160      inst.input.val(dateStr);
5161    }
5162    this._updateAlternate(inst);
5163
5164    onSelect = this._get(inst, "onSelect");
5165    if (onSelect) {
5166      onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
5167    } else if (inst.input) {
5168      inst.input.trigger("change"); // fire the change event
5169    }
5170
5171    if (inst.inline){
5172      this._updateDatepicker(inst);
5173    } else {
5174      this._hideDatepicker();
5175      this._lastInput = inst.input[0];
5176      if (typeof(inst.input[0]) !== "object") {
5177        inst.input.focus(); // restore focus
5178      }
5179      this._lastInput = null;
5180    }
5181  },
5182
5183  /* Update any alternate field to synchronise with the main field. */
5184  _updateAlternate: function(inst) {
5185    var altFormat, date, dateStr,
5186      altField = this._get(inst, "altField");
5187
5188    if (altField) { // update alternate field too
5189      altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
5190      date = this._getDate(inst);
5191      dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
5192      $(altField).each(function() { $(this).val(dateStr); });
5193    }
5194  },
5195
5196  /* Set as beforeShowDay function to prevent selection of weekends.
5197   * @param  date  Date - the date to customise
5198   * @return [boolean, string] - is this date selectable?, what is its CSS class?
5199   */
5200  noWeekends: function(date) {
5201    var day = date.getDay();
5202    return [(day > 0 && day < 6), ""];
5203  },
5204
5205  /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
5206   * @param  date  Date - the date to get the week for
5207   * @return  number - the number of the week within the year that contains this date
5208   */
5209  iso8601Week: function(date) {
5210    var time,
5211      checkDate = new Date(date.getTime());
5212
5213    // Find Thursday of this week starting on Monday
5214    checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
5215
5216    time = checkDate.getTime();
5217    checkDate.setMonth(0); // Compare with Jan 1
5218    checkDate.setDate(1);
5219    return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
5220  },
5221
5222  /* Parse a string value into a date object.
5223   * See formatDate below for the possible formats.
5224   *
vendor: 4,117 bytes, lines 5225-5330
5225   * @param  format string - the expected format of the date
5226   * @param  value string - the date in the above format
5227   * @param  settings Object - attributes include:
5228   *          shortYearCutoff  number - the cutoff year for determining the century (optional)
5229   *          dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
5230   *          dayNames    string[7] - names of the days from Sunday (optional)
5231   *          monthNamesShort string[12] - abbreviated names of the months (optional)
5232   *          monthNames    string[12] - names of the months (optional)
5233   * @return  Date - the extracted date value or null if value is blank
5234   */
5235  parseDate: function (format, value, settings) {
5236    if (format == null || value == null) {
5237      throw "Invalid arguments";
5238    }
5239
5240    value = (typeof value === "object" ? value.toString() : value + "");
5241    if (value === "") {
5242      return null;
5243    }
5244
5245    var iFormat, dim, extra,
5246      iValue = 0,
5247      shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
5248      shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
5249        new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
5250      dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
5251      dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
5252      monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
5253      monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
5254      year = -1,
5255      month = -1,
5256      day = -1,
5257      doy = -1,
5258      literal = false,
5259      date,
5260      // Check whether a format character is doubled
5261      lookAhead = function(match) {
5262        var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5263        if (matches) {
5264          iFormat++;
5265        }
5266        return matches;
5267      },
5268      // Extract a number from the string value
5269      getNumber = function(match) {
5270        var isDoubled = lookAhead(match),
5271          size = (match === "@" ? 14 : (match === "!" ? 20 :
5272          (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
5273          digits = new RegExp("^\\d{1," + size + "}"),
5274          num = value.substring(iValue).match(digits);
5275        if (!num) {
5276          throw "Missing number at position " + iValue;
5277        }
5278        iValue += num[0].length;
5279        return parseInt(num[0], 10);
5280      },
5281      // Extract a name from the string value and convert to an index
5282      getName = function(match, shortNames, longNames) {
5283        var index = -1,
5284          names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
5285            return [ [k, v] ];
5286          }).sort(function (a, b) {
5287            return -(a[1].length - b[1].length);
5288          });
5289
5290        $.each(names, function (i, pair) {
5291          var name = pair[1];
5292          if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
5293            index = pair[0];
5294            iValue += name.length;
5295            return false;
5296          }
5297        });
5298        if (index !== -1) {
5299          return index + 1;
5300        } else {
5301          throw "Unknown name at position " + iValue;
5302        }
5303      },
5304      // Confirm that a literal character matches the string value
5305      checkLiteral = function() {
5306        if (value.charAt(iValue) !== format.charAt(iFormat)) {
5307          throw "Unexpected literal at position " + iValue;
5308        }
5309        iValue++;
5310      };
5311
5312    for (iFormat = 0; iFormat < format.length; iFormat++) {
5313      if (literal) {
5314        if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5315          literal = false;
5316        } else {
5317          checkLiteral();
5318        }
5319      } else {
5320        switch (format.charAt(iFormat)) {
5321          case "d":
5322            day = getNumber("d");
5323            break;
5324          case "D":
5325            getName("D", dayNamesShort, dayNames);
5326            break;
5327          case "o":
5328            doy = getNumber("o");
5329            break;
5330          case "m":
vendor: 15,219 bytes, lines 5331-5767
5331            month = getNumber("m");
5332            break;
5333          case "M":
5334            month = getName("M", monthNamesShort, monthNames);
5335            break;
5336          case "y":
5337            year = getNumber("y");
5338            break;
5339          case "@":
5340            date = new Date(getNumber("@"));
5341            year = date.getFullYear();
5342            month = date.getMonth() + 1;
5343            day = date.getDate();
5344            break;
5345          case "!":
5346            date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
5347            year = date.getFullYear();
5348            month = date.getMonth() + 1;
5349            day = date.getDate();
5350            break;
5351          case "'":
5352            if (lookAhead("'")){
5353              checkLiteral();
5354            } else {
5355              literal = true;
5356            }
5357            break;
5358          default:
5359            checkLiteral();
5360        }
5361      }
5362    }
5363
5364    if (iValue < value.length){
5365      extra = value.substr(iValue);
5366      if (!/^\s+/.test(extra)) {
5367        throw "Extra/unparsed characters found in date: " + extra;
5368      }
5369    }
5370
5371    if (year === -1) {
5372      year = new Date().getFullYear();
5373    } else if (year < 100) {
5374      year += new Date().getFullYear() - new Date().getFullYear() % 100 +
5375        (year <= shortYearCutoff ? 0 : -100);
5376    }
5377
5378    if (doy > -1) {
5379      month = 1;
5380      day = doy;
5381      do {
5382        dim = this._getDaysInMonth(year, month - 1);
5383        if (day <= dim) {
5384          break;
5385        }
5386        month++;
5387        day -= dim;
5388      } while (true);
5389    }
5390
5391    date = this._daylightSavingAdjust(new Date(year, month - 1, day));
5392    if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
5393      throw "Invalid date"; // E.g. 31/02/00
5394    }
5395    return date;
5396  },
5397
5398  /* Standard date formats. */
5399  ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
5400  COOKIE: "D, dd M yy",
5401  ISO_8601: "yy-mm-dd",
5402  RFC_822: "D, d M y",
5403  RFC_850: "DD, dd-M-y",
5404  RFC_1036: "D, d M y",
5405  RFC_1123: "D, d M yy",
5406  RFC_2822: "D, d M yy",
5407  RSS: "D, d M y", // RFC 822
5408  TICKS: "!",
5409  TIMESTAMP: "@",
5410  W3C: "yy-mm-dd", // ISO 8601
5411
5412  _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
5413    Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
5414
5415  /* Format a date object into a string value.
5416   * The format can be combinations of the following:
5417   * d  - day of month (no leading zero)
5418   * dd - day of month (two digit)
5419   * o  - day of year (no leading zeros)
5420   * oo - day of year (three digit)
5421   * D  - day name short
5422   * DD - day name long
5423   * m  - month of year (no leading zero)
5424   * mm - month of year (two digit)
5425   * M  - month name short
5426   * MM - month name long
5427   * y  - year (two digit)
5428   * yy - year (four digit)
5429   * @ - Unix timestamp (ms since 01/01/1970)
5430   * ! - Windows ticks (100ns since 01/01/0001)
5431   * "..." - literal text
5432   * '' - single quote
5433   *
5434   * @param  format string - the desired format of the date
5435   * @param  date Date - the date value to format
5436   * @param  settings Object - attributes include:
5437   *          dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
5438   *          dayNames    string[7] - names of the days from Sunday (optional)
5439   *          monthNamesShort string[12] - abbreviated names of the months (optional)
5440   *          monthNames    string[12] - names of the months (optional)
5441   * @return  string - the date in the above format
5442   */
5443  formatDate: function (format, date, settings) {
5444    if (!date) {
5445      return "";
5446    }
5447
5448    var iFormat,
5449      dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
5450      dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
5451      monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
5452      monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
5453      // Check whether a format character is doubled
5454      lookAhead = function(match) {
5455        var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5456        if (matches) {
5457          iFormat++;
5458        }
5459        return matches;
5460      },
5461      // Format a number, with leading zero if necessary
5462      formatNumber = function(match, value, len) {
5463        var num = "" + value;
5464        if (lookAhead(match)) {
5465          while (num.length < len) {
5466            num = "0" + num;
5467          }
5468        }
5469        return num;
5470      },
5471      // Format a name, short or long as requested
5472      formatName = function(match, value, shortNames, longNames) {
5473        return (lookAhead(match) ? longNames[value] : shortNames[value]);
5474      },
5475      output = "",
5476      literal = false;
5477
5478    if (date) {
5479      for (iFormat = 0; iFormat < format.length; iFormat++) {
5480        if (literal) {
5481          if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5482            literal = false;
5483          } else {
5484            output += format.charAt(iFormat);
5485          }
5486        } else {
5487          switch (format.charAt(iFormat)) {
5488            case "d":
5489              output += formatNumber("d", date.getDate(), 2);
5490              break;
5491            case "D":
5492              output += formatName("D", date.getDay(), dayNamesShort, dayNames);
5493              break;
5494            case "o":
5495              output += formatNumber("o",
5496                Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
5497              break;
5498            case "m":
5499              output += formatNumber("m", date.getMonth() + 1, 2);
5500              break;
5501            case "M":
5502              output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
5503              break;
5504            case "y":
5505              output += (lookAhead("y") ? date.getFullYear() :
5506                (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
5507              break;
5508            case "@":
5509              output += date.getTime();
5510              break;
5511            case "!":
5512              output += date.getTime() * 10000 + this._ticksTo1970;
5513              break;
5514            case "'":
5515              if (lookAhead("'")) {
5516                output += "'";
5517              } else {
5518                literal = true;
5519              }
5520              break;
5521            default:
5522              output += format.charAt(iFormat);
5523          }
5524        }
5525      }
5526    }
5527    return output;
5528  },
5529
5530  /* Extract all possible characters from the date format. */
5531  _possibleChars: function (format) {
5532    var iFormat,
5533      chars = "",
5534      literal = false,
5535      // Check whether a format character is doubled
5536      lookAhead = function(match) {
5537        var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5538        if (matches) {
5539          iFormat++;
5540        }
5541        return matches;
5542      };
5543
5544    for (iFormat = 0; iFormat < format.length; iFormat++) {
5545      if (literal) {
5546        if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5547          literal = false;
5548        } else {
5549          chars += format.charAt(iFormat);
5550        }
5551      } else {
5552        switch (format.charAt(iFormat)) {
5553          case "d": case "m": case "y": case "@":
5554            chars += "0123456789";
5555            break;
5556          case "D": case "M":
5557            return null; // Accept anything
5558          case "'":
5559            if (lookAhead("'")) {
5560              chars += "'";
5561            } else {
5562              literal = true;
5563            }
5564            break;
5565          default:
5566            chars += format.charAt(iFormat);
5567        }
5568      }
5569    }
5570    return chars;
5571  },
5572
5573  /* Get a setting value, defaulting if necessary. */
5574  _get: function(inst, name) {
5575    return inst.settings[name] !== undefined ?
5576      inst.settings[name] : this._defaults[name];
5577  },
5578
5579  /* Parse existing date and initialise date picker. */
5580  _setDateFromField: function(inst, noDefault) {
5581    if (inst.input.val() === inst.lastVal) {
5582      return;
5583    }
5584
5585    var dateFormat = this._get(inst, "dateFormat"),
5586      dates = inst.lastVal = inst.input ? inst.input.val() : null,
5587      defaultDate = this._getDefaultDate(inst),
5588      date = defaultDate,
5589      settings = this._getFormatConfig(inst);
5590
5591    try {
5592      date = this.parseDate(dateFormat, dates, settings) || defaultDate;
5593    } catch (event) {
5594      dates = (noDefault ? "" : dates);
5595    }
5596    inst.selectedDay = date.getDate();
5597    inst.drawMonth = inst.selectedMonth = date.getMonth();
5598    inst.drawYear = inst.selectedYear = date.getFullYear();
5599    inst.currentDay = (dates ? date.getDate() : 0);
5600    inst.currentMonth = (dates ? date.getMonth() : 0);
5601    inst.currentYear = (dates ? date.getFullYear() : 0);
5602    this._adjustInstDate(inst);
5603  },
5604
5605  /* Retrieve the default date shown on opening. */
5606  _getDefaultDate: function(inst) {
5607    return this._restrictMinMax(inst,
5608      this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
5609  },
5610
5611  /* A date may be specified as an exact value or a relative one. */
5612  _determineDate: function(inst, date, defaultDate) {
5613    var offsetNumeric = function(offset) {
5614        var date = new Date();
5615        date.setDate(date.getDate() + offset);
5616        return date;
5617      },
5618      offsetString = function(offset) {
5619        try {
5620          return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
5621            offset, $.datepicker._getFormatConfig(inst));
5622        }
5623        catch (e) {
5624          // Ignore
5625        }
5626
5627        var date = (offset.toLowerCase().match(/^c/) ?
5628          $.datepicker._getDate(inst) : null) || new Date(),
5629          year = date.getFullYear(),
5630          month = date.getMonth(),
5631          day = date.getDate(),
5632          pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
5633          matches = pattern.exec(offset);
5634
5635        while (matches) {
5636          switch (matches[2] || "d") {
5637            case "d" : case "D" :
5638              day += parseInt(matches[1],10); break;
5639            case "w" : case "W" :
5640              day += parseInt(matches[1],10) * 7; break;
5641            case "m" : case "M" :
5642              month += parseInt(matches[1],10);
5643              day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
5644              break;
5645            case "y": case "Y" :
5646              year += parseInt(matches[1],10);
5647              day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
5648              break;
5649          }
5650          matches = pattern.exec(offset);
5651        }
5652        return new Date(year, month, day);
5653      },
5654      newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
5655        (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
5656
5657    newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
5658    if (newDate) {
5659      newDate.setHours(0);
5660      newDate.setMinutes(0);
5661      newDate.setSeconds(0);
5662      newDate.setMilliseconds(0);
5663    }
5664    return this._daylightSavingAdjust(newDate);
5665  },
5666
5667  /* Handle switch to/from daylight saving.
5668   * Hours may be non-zero on daylight saving cut-over:
5669   * > 12 when midnight changeover, but then cannot generate
5670   * midnight datetime, so jump to 1AM, otherwise reset.
5671   * @param  date  (Date) the date to check
5672   * @return  (Date) the corrected date
5673   */
5674  _daylightSavingAdjust: function(date) {
5675    if (!date) {
5676      return null;
5677    }
5678    date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
5679    return date;
5680  },
5681
5682  /* Set the date(s) directly. */
5683  _setDate: function(inst, date, noChange) {
5684    var clear = !date,
5685      origMonth = inst.selectedMonth,
5686      origYear = inst.selectedYear,
5687      newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
5688
5689    inst.selectedDay = inst.currentDay = newDate.getDate();
5690    inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
5691    inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
5692    if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
5693      this._notifyChange(inst);
5694    }
5695    this._adjustInstDate(inst);
5696    if (inst.input) {
5697      inst.input.val(clear ? "" : this._formatDate(inst));
5698    }
5699  },
5700
5701  /* Retrieve the date(s) directly. */
5702  _getDate: function(inst) {
5703    var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
5704      this._daylightSavingAdjust(new Date(
5705      inst.currentYear, inst.currentMonth, inst.currentDay)));
5706      return startDate;
5707  },
5708
5709  /* Attach the onxxx handlers.  These are declared statically so
5710   * they work with static code transformers like Caja.
5711   */
5712  _attachHandlers: function(inst) {
5713    var stepMonths = this._get(inst, "stepMonths"),
5714      id = "#" + inst.id.replace( /\\\\/g, "\\" );
5715    inst.dpDiv.find("[data-handler]").map(function () {
5716      var handler = {
5717        prev: function () {
5718          $.datepicker._adjustDate(id, -stepMonths, "M");
5719        },
5720        next: function () {
5721          $.datepicker._adjustDate(id, +stepMonths, "M");
5722        },
5723        hide: function () {
5724          $.datepicker._hideDatepicker();
5725        },
5726        today: function () {
5727          $.datepicker._gotoToday(id);
5728        },
5729        selectDay: function () {
5730          $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
5731          return false;
5732        },
5733        selectMonth: function () {
5734          $.datepicker._selectMonthYear(id, this, "M");
5735          return false;
5736        },
5737        selectYear: function () {
5738          $.datepicker._selectMonthYear(id, this, "Y");
5739          return false;
5740        }
5741      };
5742      $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
5743    });
5744  },
5745
5746  /* Generate the HTML for the current state of the date picker. */
5747  _generateHTML: function(inst) {
5748    var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
5749      controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
5750      monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
5751      selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
5752      cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
5753      printDate, dRow, tbody, daySettings, otherMonth, unselectable,
5754      tempDate = new Date(),
5755      today = this._daylightSavingAdjust(
5756        new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
5757      isRTL = this._get(inst, "isRTL"),
5758      showButtonPanel = this._get(inst, "showButtonPanel"),
5759      hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
5760      navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
5761      numMonths = this._getNumberOfMonths(inst),
5762      showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
5763      stepMonths = this._get(inst, "stepMonths"),
5764      isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
5765      currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
5766        new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
5767      minDate = this._getMinMaxDate(inst, "min"),
vendor: 4,276 bytes, lines 5768-5848
5768      maxDate = this._getMinMaxDate(inst, "max"),
5769      drawMonth = inst.drawMonth - showCurrentAtPos,
5770      drawYear = inst.drawYear;
5771
5772    if (drawMonth < 0) {
5773      drawMonth += 12;
5774      drawYear--;
5775    }
5776    if (maxDate) {
5777      maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
5778        maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
5779      maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
5780      while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
5781        drawMonth--;
5782        if (drawMonth < 0) {
5783          drawMonth = 11;
5784          drawYear--;
5785        }
5786      }
5787    }
5788    inst.drawMonth = drawMonth;
5789    inst.drawYear = drawYear;
5790
5791    prevText = this._get(inst, "prevText");
5792    prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
5793      this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
5794      this._getFormatConfig(inst)));
5795
5796    prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
5797      "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
5798      " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
5799      (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>"));
5800
5801    nextText = this._get(inst, "nextText");
5802    nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
5803      this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
5804      this._getFormatConfig(inst)));
5805
5806    next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
5807      "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
5808      " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
5809      (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>"));
5810
5811    currentText = this._get(inst, "currentText");
5812    gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
5813    currentText = (!navigationAsDateFormat ? currentText :
5814      this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
5815
5816    controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
5817      this._get(inst, "closeText") + "</button>" : "");
5818
5819    buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
5820      (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
5821      ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
5822
5823    firstDay = parseInt(this._get(inst, "firstDay"),10);
5824    firstDay = (isNaN(firstDay) ? 0 : firstDay);
5825
5826    showWeek = this._get(inst, "showWeek");
5827    dayNames = this._get(inst, "dayNames");
5828    dayNamesMin = this._get(inst, "dayNamesMin");
5829    monthNames = this._get(inst, "monthNames");
5830    monthNamesShort = this._get(inst, "monthNamesShort");
5831    beforeShowDay = this._get(inst, "beforeShowDay");
5832    showOtherMonths = this._get(inst, "showOtherMonths");
5833    selectOtherMonths = this._get(inst, "selectOtherMonths");
5834    defaultDate = this._getDefaultDate(inst);
5835    html = "";
5836    dow;
5837    for (row = 0; row < numMonths[0]; row++) {
5838      group = "";
5839      this.maxRows = 4;
5840      for (col = 0; col < numMonths[1]; col++) {
5841        selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
5842        cornerClass = " ui-corner-all";
5843        calender = "";
5844        if (isMultiMonth) {
5845          calender += "<div class='ui-datepicker-group";
5846          if (numMonths[1] > 1) {
5847            switch (col) {
5848              case 0: calender += " ui-datepicker-group-first";
vendor: 5,473 bytes, lines 5849-5926
5849                cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
5850              case numMonths[1]-1: calender += " ui-datepicker-group-last";
5851                cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
5852              default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
5853            }
5854          }
5855          calender += "'>";
5856        }
5857        calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
5858          (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
5859          (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
5860          this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
5861          row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
5862          "</div><table class='ui-datepicker-calendar'><thead>" +
5863          "<tr>";
5864        thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
5865        for (dow = 0; dow < 7; dow++) { // days of the week
5866          day = (dow + firstDay) % 7;
5867          thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
5868            "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
5869        }
5870        calender += thead + "</tr></thead><tbody>";
5871        daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
5872        if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
5873          inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
5874        }
5875        leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
5876        curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
5877        numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
5878        this.maxRows = numRows;
5879        printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
5880        for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
5881          calender += "<tr>";
5882          tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
5883            this._get(inst, "calculateWeek")(printDate) + "</td>");
5884          for (dow = 0; dow < 7; dow++) { // create date picker days
5885            daySettings = (beforeShowDay ?
5886              beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
5887            otherMonth = (printDate.getMonth() !== drawMonth);
5888            unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
5889              (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
5890            tbody += "<td class='" +
5891              ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
5892              (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
5893              ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
5894              (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
5895              // or defaultDate is current printedDate and defaultDate is selectedDate
5896              " " + this._dayOverClass : "") + // highlight selected day
5897              (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
5898              (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
5899              (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
5900              (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
5901              ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
5902              (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
5903              (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
5904              (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
5905              (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
5906              (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
5907              (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
5908              "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
5909            printDate.setDate(printDate.getDate() + 1);
5910            printDate = this._daylightSavingAdjust(printDate);
5911          }
5912          calender += tbody + "</tr>";
5913        }
5914        drawMonth++;
5915        if (drawMonth > 11) {
5916          drawMonth = 0;
5917          drawYear++;
5918        }
5919        calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
5920              ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
5921        group += calender;
5922      }
5923      html += group;
5924    }
5925    html += buttonPanel;
5926    inst._keyEvent = false;
vendor: 4,246 bytes, lines 5927-6029
5927    return html;
5928  },
5929
5930  /* Generate the month and year header. */
5931  _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
5932      secondary, monthNames, monthNamesShort) {
5933
5934    var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
5935      changeMonth = this._get(inst, "changeMonth"),
5936      changeYear = this._get(inst, "changeYear"),
5937      showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
5938      html = "<div class='ui-datepicker-title'>",
5939      monthHtml = "";
5940
5941    // month selection
5942    if (secondary || !changeMonth) {
5943      monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
5944    } else {
5945      inMinYear = (minDate && minDate.getFullYear() === drawYear);
5946      inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
5947      monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
5948      for ( month = 0; month < 12; month++) {
5949        if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
5950          monthHtml += "<option value='" + month + "'" +
5951            (month === drawMonth ? " selected='selected'" : "") +
5952            ">" + monthNamesShort[month] + "</option>";
5953        }
5954      }
5955      monthHtml += "</select>";
5956    }
5957
5958    if (!showMonthAfterYear) {
5959      html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
5960    }
5961
5962    // year selection
5963    if ( !inst.yearshtml ) {
5964      inst.yearshtml = "";
5965      if (secondary || !changeYear) {
5966        html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
5967      } else {
5968        // determine range of years to display
5969        years = this._get(inst, "yearRange").split(":");
5970        thisYear = new Date().getFullYear();
5971        determineYear = function(value) {
5972          var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
5973            (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
5974            parseInt(value, 10)));
5975          return (isNaN(year) ? thisYear : year);
5976        };
5977        year = determineYear(years[0]);
5978        endYear = Math.max(year, determineYear(years[1] || ""));
5979        year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
5980        endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
5981        inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
5982        for (; year <= endYear; year++) {
5983          inst.yearshtml += "<option value='" + year + "'" +
5984            (year === drawYear ? " selected='selected'" : "") +
5985            ">" + year + "</option>";
5986        }
5987        inst.yearshtml += "</select>";
5988
5989        html += inst.yearshtml;
5990        inst.yearshtml = null;
5991      }
5992    }
5993
5994    html += this._get(inst, "yearSuffix");
5995    if (showMonthAfterYear) {
5996      html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
5997    }
5998    html += "</div>"; // Close datepicker_header
5999    return html;
6000  },
6001
6002  /* Adjust one of the date sub-fields. */
6003  _adjustInstDate: function(inst, offset, period) {
6004    var year = inst.drawYear + (period === "Y" ? offset : 0),
6005      month = inst.drawMonth + (period === "M" ? offset : 0),
6006      day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
6007      date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
6008
6009    inst.selectedDay = date.getDate();
6010    inst.drawMonth = inst.selectedMonth = date.getMonth();
6011    inst.drawYear = inst.selectedYear = date.getFullYear();
6012    if (period === "M" || period === "Y") {
6013      this._notifyChange(inst);
6014    }
6015  },
6016
6017  /* Ensure a date is within any min/max bounds. */
6018  _restrictMinMax: function(inst, date) {
6019    var minDate = this._getMinMaxDate(inst, "min"),
6020      maxDate = this._getMinMaxDate(inst, "max"),
6021      newDate = (minDate && date < minDate ? minDate : date);
6022    return (maxDate && newDate > maxDate ? maxDate : newDate);
6023  },
6024
6025  /* Notify change of month/year. */
6026  _notifyChange: function(inst) {
6027    var onChange = this._get(inst, "onChangeMonthYear");
6028    if (onChange) {
6029      onChange.apply((inst.input ? inst.input[0] : null),
vendor: 6,498 bytes, lines 6030-6199
6030        [inst.selectedYear, inst.selectedMonth + 1, inst]);
6031    }
6032  },
6033
6034  /* Determine the number of months to show. */
6035  _getNumberOfMonths: function(inst) {
6036    var numMonths = this._get(inst, "numberOfMonths");
6037    return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
6038  },
6039
6040  /* Determine the current maximum date - ensure no time components are set. */
6041  _getMinMaxDate: function(inst, minMax) {
6042    return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
6043  },
6044
6045  /* Find the number of days in a given month. */
6046  _getDaysInMonth: function(year, month) {
6047    return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
6048  },
6049
6050  /* Find the day of the week of the first of a month. */
6051  _getFirstDayOfMonth: function(year, month) {
6052    return new Date(year, month, 1).getDay();
6053  },
6054
6055  /* Determines if we should allow a "next/prev" month display change. */
6056  _canAdjustMonth: function(inst, offset, curYear, curMonth) {
6057    var numMonths = this._getNumberOfMonths(inst),
6058      date = this._daylightSavingAdjust(new Date(curYear,
6059      curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
6060
6061    if (offset < 0) {
6062      date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
6063    }
6064    return this._isInRange(inst, date);
6065  },
6066
6067  /* Is the given date in the accepted range? */
6068  _isInRange: function(inst, date) {
6069    var yearSplit, currentYear,
6070      minDate = this._getMinMaxDate(inst, "min"),
6071      maxDate = this._getMinMaxDate(inst, "max"),
6072      minYear = null,
6073      maxYear = null,
6074      years = this._get(inst, "yearRange");
6075      if (years){
6076        yearSplit = years.split(":");
6077        currentYear = new Date().getFullYear();
6078        minYear = parseInt(yearSplit[0], 10);
6079        maxYear = parseInt(yearSplit[1], 10);
6080        if ( yearSplit[0].match(/[+\-].*/) ) {
6081          minYear += currentYear;
6082        }
6083        if ( yearSplit[1].match(/[+\-].*/) ) {
6084          maxYear += currentYear;
6085        }
6086      }
6087
6088    return ((!minDate || date.getTime() >= minDate.getTime()) &&
6089      (!maxDate || date.getTime() <= maxDate.getTime()) &&
6090      (!minYear || date.getFullYear() >= minYear) &&
6091      (!maxYear || date.getFullYear() <= maxYear));
6092  },
6093
6094  /* Provide the configuration settings for formatting/parsing. */
6095  _getFormatConfig: function(inst) {
6096    var shortYearCutoff = this._get(inst, "shortYearCutoff");
6097    shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
6098      new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
6099    return {shortYearCutoff: shortYearCutoff,
6100      dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
6101      monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
6102  },
6103
6104  /* Format the given date for display. */
6105  _formatDate: function(inst, day, month, year) {
6106    if (!day) {
6107      inst.currentDay = inst.selectedDay;
6108      inst.currentMonth = inst.selectedMonth;
6109      inst.currentYear = inst.selectedYear;
6110    }
6111    var date = (day ? (typeof day === "object" ? day :
6112      this._daylightSavingAdjust(new Date(year, month, day))) :
6113      this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
6114    return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
6115  }
6116});
6117
6118/*
6119 * Bind hover events for datepicker elements.
6120 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
6121 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
6122 */
6123function bindHover(dpDiv) {
6124  var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
6125  return dpDiv.delegate(selector, "mouseout", function() {
6126      $(this).removeClass("ui-state-hover");
6127      if (this.className.indexOf("ui-datepicker-prev") !== -1) {
6128        $(this).removeClass("ui-datepicker-prev-hover");
6129      }
6130      if (this.className.indexOf("ui-datepicker-next") !== -1) {
6131        $(this).removeClass("ui-datepicker-next-hover");
6132      }
6133    })
6134    .delegate(selector, "mouseover", function(){
6135      if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
6136        $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
6137        $(this).addClass("ui-state-hover");
6138        if (this.className.indexOf("ui-datepicker-prev") !== -1) {
6139          $(this).addClass("ui-datepicker-prev-hover");
6140        }
6141        if (this.className.indexOf("ui-datepicker-next") !== -1) {
6142          $(this).addClass("ui-datepicker-next-hover");
6143        }
6144      }
6145    });
6146}
6147
6148/* jQuery extend now ignores nulls! */
6149function extendRemove(target, props) {
6150  $.extend(target, props);
6151  for (var name in props) {
6152    if (props[name] == null) {
6153      target[name] = props[name];
6154    }
6155  }
6156  return target;
6157}
6158
6159/* Invoke the datepicker functionality.
6160   @param  options  string - a command, optionally followed by additional parameters or
6161          Object - settings for attaching new datepicker functionality
6162   @return  jQuery object */
6163$.fn.datepicker = function(options){
6164
6165  /* Verify an empty collection wasn't passed - Fixes #6976 */
6166  if ( !this.length ) {
6167    return this;
6168  }
6169
6170  /* Initialise the date picker. */
6171  if (!$.datepicker.initialized) {
6172    $(document).mousedown($.datepicker._checkExternalClick);
6173    $.datepicker.initialized = true;
6174  }
6175
6176  /* Append datepicker main container to body if not exist. */
6177  if ($("#"+$.datepicker._mainDivId).length === 0) {
6178    $("body").append($.datepicker.dpDiv);
6179  }
6180
6181  var otherArgs = Array.prototype.slice.call(arguments, 1);
6182  if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
6183    return $.datepicker["_" + options + "Datepicker"].
6184      apply($.datepicker, [this[0]].concat(otherArgs));
6185  }
6186  if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
6187    return $.datepicker["_" + options + "Datepicker"].
6188      apply($.datepicker, [this[0]].concat(otherArgs));
6189  }
6190  return this.each(function() {
6191    typeof options === "string" ?
6192      $.datepicker["_" + options + "Datepicker"].
6193        apply($.datepicker, [this].concat(otherArgs)) :
6194      $.datepicker._attachDatepicker(this, options);
6195  });
6196};
6197
6198$.datepicker = new Datepicker(); // singleton instance
6199$.datepicker.initialized = false;
vendor: 19,925 bytes, lines 6200-6928
6200$.datepicker.uuid = new Date().getTime();
6201$.datepicker.version = "1.10.4";
6202
6203})( _4ORMAT.$ );
6204(function( $, undefined ) {
6205
6206var sizeRelatedOptions = {
6207    buttons: true,
6208    height: true,
6209    maxHeight: true,
6210    maxWidth: true,
6211    minHeight: true,
6212    minWidth: true,
6213    width: true
6214  },
6215  resizableRelatedOptions = {
6216    maxHeight: true,
6217    maxWidth: true,
6218    minHeight: true,
6219    minWidth: true
6220  };
6221
6222$.widget( "ui.dialog", {
6223  version: "1.10.4",
6224  options: {
6225    appendTo: "body",
6226    autoOpen: true,
6227    buttons: [],
6228    closeOnEscape: true,
6229    closeText: "close",
6230    dialogClass: "",
6231    draggable: true,
6232    hide: null,
6233    height: "auto",
6234    maxHeight: null,
6235    maxWidth: null,
6236    minHeight: 150,
6237    minWidth: 150,
6238    modal: false,
6239    position: {
6240      my: "center",
6241      at: "center",
6242      of: window,
6243      collision: "fit",
6244      // Ensure the titlebar is always visible
6245      using: function( pos ) {
6246        var topOffset = $( this ).css( pos ).offset().top;
6247        if ( topOffset < 0 ) {
6248          $( this ).css( "top", pos.top - topOffset );
6249        }
6250      }
6251    },
6252    resizable: true,
6253    show: null,
6254    title: null,
6255    width: 300,
6256
6257    // callbacks
6258    beforeClose: null,
6259    close: null,
6260    drag: null,
6261    dragStart: null,
6262    dragStop: null,
6263    focus: null,
6264    open: null,
6265    resize: null,
6266    resizeStart: null,
6267    resizeStop: null
6268  },
6269
6270  _create: function() {
6271    this.originalCss = {
6272      display: this.element[0].style.display,
6273      width: this.element[0].style.width,
6274      minHeight: this.element[0].style.minHeight,
6275      maxHeight: this.element[0].style.maxHeight,
6276      height: this.element[0].style.height
6277    };
6278    this.originalPosition = {
6279      parent: this.element.parent(),
6280      index: this.element.parent().children().index( this.element )
6281    };
6282    this.originalTitle = this.element.attr("title");
6283    this.options.title = this.options.title || this.originalTitle;
6284
6285    this._createWrapper();
6286
6287    this.element
6288      .show()
6289      .removeAttr("title")
6290      .addClass("ui-dialog-content ui-widget-content")
6291      .appendTo( this.uiDialog );
6292
6293    this._createTitlebar();
6294    this._createButtonPane();
6295
6296    if ( this.options.draggable && $.fn.draggable ) {
6297      this._makeDraggable();
6298    }
6299    if ( this.options.resizable && $.fn.resizable ) {
6300      this._makeResizable();
6301    }
6302
6303    this._isOpen = false;
6304  },
6305
6306  _init: function() {
6307    if ( this.options.autoOpen ) {
6308      this.open();
6309    }
6310  },
6311
6312  _appendTo: function() {
6313    var element = this.options.appendTo;
6314    if ( element && (element.jquery || element.nodeType) ) {
6315      return $( element );
6316    }
6317    return this.document.find( element || "body" ).eq( 0 );
6318  },
6319
6320  _destroy: function() {
6321    var next,
6322      originalPosition = this.originalPosition;
6323
6324    this._destroyOverlay();
6325
6326    this.element
6327      .removeUniqueId()
6328      .removeClass("ui-dialog-content ui-widget-content")
6329      .css( this.originalCss )
6330      // Without detaching first, the following becomes really slow
6331      .detach();
6332
6333    this.uiDialog.stop( true, true ).remove();
6334
6335    if ( this.originalTitle ) {
6336      this.element.attr( "title", this.originalTitle );
6337    }
6338
6339    next = originalPosition.parent.children().eq( originalPosition.index );
6340    // Don't try to place the dialog next to itself (#8613)
6341    if ( next.length && next[0] !== this.element[0] ) {
6342      next.before( this.element );
6343    } else {
6344      originalPosition.parent.append( this.element );
6345    }
6346  },
6347
6348  widget: function() {
6349    return this.uiDialog;
6350  },
6351
6352  disable: $.noop,
6353  enable: $.noop,
6354
6355  close: function( event ) {
6356    var activeElement,
6357      that = this;
6358
6359    if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
6360      return;
6361    }
6362
6363    this._isOpen = false;
6364    this._destroyOverlay();
6365
6366    if ( !this.opener.filter(":focusable").focus().length ) {
6367
6368      // support: IE9
6369      // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
6370      try {
6371        activeElement = this.document[ 0 ].activeElement;
6372
6373        // Support: IE9, IE10
6374        // If the <body> is blurred, IE will switch windows, see #4520
6375        if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
6376
6377          // Hiding a focused element doesn't trigger blur in WebKit
6378          // so in case we have nothing to focus on, explicitly blur the active element
6379          // https://bugs.webkit.org/show_bug.cgi?id=47182
6380          $( activeElement ).blur();
6381        }
6382      } catch ( error ) {}
6383    }
6384
6385    this._hide( this.uiDialog, this.options.hide, function() {
6386      that._trigger( "close", event );
6387    });
6388  },
6389
6390  isOpen: function() {
6391    return this._isOpen;
6392  },
6393
6394  moveToTop: function() {
6395    this._moveToTop();
6396  },
6397
6398  _moveToTop: function( event, silent ) {
6399    var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length;
6400    if ( moved && !silent ) {
6401      this._trigger( "focus", event );
6402    }
6403    return moved;
6404  },
6405
6406  open: function() {
6407    var that = this;
6408    if ( this._isOpen ) {
6409      if ( this._moveToTop() ) {
6410        this._focusTabbable();
6411      }
6412      return;
6413    }
6414
6415    this._isOpen = true;
6416    this.opener = $( this.document[0].activeElement );
6417
6418    this._size();
6419    this._position();
6420    this._createOverlay();
6421    this._moveToTop( null, true );
6422    this._show( this.uiDialog, this.options.show, function() {
6423      that._focusTabbable();
6424      that._trigger("focus");
6425    });
6426
6427    this._trigger("open");
6428  },
6429
6430  _focusTabbable: function() {
6431    // Set focus to the first match:
6432    // 1. First element inside the dialog matching [autofocus]
6433    // 2. Tabbable element inside the content element
6434    // 3. Tabbable element inside the buttonpane
6435    // 4. The close button
6436    // 5. The dialog itself
6437    var hasFocus = this.element.find("[autofocus]");
6438    if ( !hasFocus.length ) {
6439      hasFocus = this.element.find(":tabbable");
6440    }
6441    if ( !hasFocus.length ) {
6442      hasFocus = this.uiDialogButtonPane.find(":tabbable");
6443    }
6444    if ( !hasFocus.length ) {
6445      hasFocus = this.uiDialogTitlebarClose.filter(":tabbable");
6446    }
6447    if ( !hasFocus.length ) {
6448      hasFocus = this.uiDialog;
6449    }
6450    hasFocus.eq( 0 ).focus();
6451  },
6452
6453  _keepFocus: function( event ) {
6454    function checkFocus() {
6455      var activeElement = this.document[0].activeElement,
6456        isActive = this.uiDialog[0] === activeElement ||
6457          $.contains( this.uiDialog[0], activeElement );
6458      if ( !isActive ) {
6459        this._focusTabbable();
6460      }
6461    }
6462    event.preventDefault();
6463    checkFocus.call( this );
6464    // support: IE
6465    // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
6466    // so we check again later
6467    this._delay( checkFocus );
6468  },
6469
6470  _createWrapper: function() {
6471    this.uiDialog = $("<div>")
6472      .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
6473        this.options.dialogClass )
6474      .hide()
6475      .attr({
6476        // Setting tabIndex makes the div focusable
6477        tabIndex: -1,
6478        role: "dialog"
6479      })
6480      .appendTo( this._appendTo() );
6481
6482    this._on( this.uiDialog, {
6483      keydown: function( event ) {
6484        if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
6485            event.keyCode === $.ui.keyCode.ESCAPE ) {
6486          event.preventDefault();
6487          this.close( event );
6488          return;
6489        }
6490
6491        // prevent tabbing out of dialogs
6492        if ( event.keyCode !== $.ui.keyCode.TAB ) {
6493          return;
6494        }
6495        var tabbables = this.uiDialog.find(":tabbable"),
6496          first = tabbables.filter(":first"),
6497          last  = tabbables.filter(":last");
6498
6499        if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
6500          first.focus( 1 );
6501          event.preventDefault();
6502        } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
6503          last.focus( 1 );
6504          event.preventDefault();
6505        }
6506      },
6507      mousedown: function( event ) {
6508        if ( this._moveToTop( event ) ) {
6509          this._focusTabbable();
6510        }
6511      }
6512    });
6513
6514    // We assume that any existing aria-describedby attribute means
6515    // that the dialog content is marked up properly
6516    // otherwise we brute force the content as the description
6517    if ( !this.element.find("[aria-describedby]").length ) {
6518      this.uiDialog.attr({
6519        "aria-describedby": this.element.uniqueId().attr("id")
6520      });
6521    }
6522  },
6523
6524  _createTitlebar: function() {
6525    var uiDialogTitle;
6526
6527    this.uiDialogTitlebar = $("<div>")
6528      .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix")
6529      .prependTo( this.uiDialog );
6530    this._on( this.uiDialogTitlebar, {
6531      mousedown: function( event ) {
6532        // Don't prevent click on close button (#8838)
6533        // Focusing a dialog that is partially scrolled out of view
6534        // causes the browser to scroll it into view, preventing the click event
6535        if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) {
6536          // Dialog isn't getting focus when dragging (#8063)
6537          this.uiDialog.focus();
6538        }
6539      }
6540    });
6541
6542    // support: IE
6543    // Use type="button" to prevent enter keypresses in textboxes from closing the
6544    // dialog in IE (#9312)
6545    this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
6546      .button({
6547        label: this.options.closeText,
6548        icons: {
6549          primary: "ui-icon-closethick"
6550        },
6551        text: false
6552      })
6553      .addClass("ui-dialog-titlebar-close")
6554      .appendTo( this.uiDialogTitlebar );
6555    this._on( this.uiDialogTitlebarClose, {
6556      click: function( event ) {
6557        event.preventDefault();
6558        this.close( event );
6559      }
6560    });
6561
6562    uiDialogTitle = $("<span>")
6563      .uniqueId()
6564      .addClass("ui-dialog-title")
6565      .prependTo( this.uiDialogTitlebar );
6566    this._title( uiDialogTitle );
6567
6568    this.uiDialog.attr({
6569      "aria-labelledby": uiDialogTitle.attr("id")
6570    });
6571  },
6572
6573  _title: function( title ) {
6574    if ( !this.options.title ) {
6575      title.html("&#160;");
6576    }
6577    title.text( this.options.title );
6578  },
6579
6580  _createButtonPane: function() {
6581    this.uiDialogButtonPane = $("<div>")
6582      .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");
6583
6584    this.uiButtonSet = $("<div>")
6585      .addClass("ui-dialog-buttonset")
6586      .appendTo( this.uiDialogButtonPane );
6587
6588    this._createButtons();
6589  },
6590
6591  _createButtons: function() {
6592    var that = this,
6593      buttons = this.options.buttons;
6594
6595    // if we already have a button pane, remove it
6596    this.uiDialogButtonPane.remove();
6597    this.uiButtonSet.empty();
6598
6599    if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
6600      this.uiDialog.removeClass("ui-dialog-buttons");
6601      return;
6602    }
6603
6604    $.each( buttons, function( name, props ) {
6605      var click, buttonOptions;
6606      props = $.isFunction( props ) ?
6607        { click: props, text: name } :
6608        props;
6609      // Default to a non-submitting button
6610      props = $.extend( { type: "button" }, props );
6611      // Change the context for the click callback to be the main element
6612      click = props.click;
6613      props.click = function() {
6614        click.apply( that.element[0], arguments );
6615      };
6616      buttonOptions = {
6617        icons: props.icons,
6618        text: props.showText
6619      };
6620      delete props.icons;
6621      delete props.showText;
6622      $( "<button></button>", props )
6623        .button( buttonOptions )
6624        .appendTo( that.uiButtonSet );
6625    });
6626    this.uiDialog.addClass("ui-dialog-buttons");
6627    this.uiDialogButtonPane.appendTo( this.uiDialog );
6628  },
6629
6630  _makeDraggable: function() {
6631    var that = this,
6632      options = this.options;
6633
6634    function filteredUi( ui ) {
6635      return {
6636        position: ui.position,
6637        offset: ui.offset
6638      };
6639    }
6640
6641    this.uiDialog.draggable({
6642      cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
6643      handle: ".ui-dialog-titlebar",
6644      containment: "document",
6645      start: function( event, ui ) {
6646        $( this ).addClass("ui-dialog-dragging");
6647        that._blockFrames();
6648        that._trigger( "dragStart", event, filteredUi( ui ) );
6649      },
6650      drag: function( event, ui ) {
6651        that._trigger( "drag", event, filteredUi( ui ) );
6652      },
6653      stop: function( event, ui ) {
6654        options.position = [
6655          ui.position.left - that.document.scrollLeft(),
6656          ui.position.top - that.document.scrollTop()
6657        ];
6658        $( this ).removeClass("ui-dialog-dragging");
6659        that._unblockFrames();
6660        that._trigger( "dragStop", event, filteredUi( ui ) );
6661      }
6662    });
6663  },
6664
6665  _makeResizable: function() {
6666    var that = this,
6667      options = this.options,
6668      handles = options.resizable,
6669      // .ui-resizable has position: relative defined in the stylesheet
6670      // but dialogs have to use absolute or fixed positioning
6671      position = this.uiDialog.css("position"),
6672      resizeHandles = typeof handles === "string" ?
6673        handles :
6674        "n,e,s,w,se,sw,ne,nw";
6675
6676    function filteredUi( ui ) {
6677      return {
6678        originalPosition: ui.originalPosition,
6679        originalSize: ui.originalSize,
6680        position: ui.position,
6681        size: ui.size
6682      };
6683    }
6684
6685    this.uiDialog.resizable({
6686      cancel: ".ui-dialog-content",
6687      containment: "document",
6688      alsoResize: this.element,
6689      maxWidth: options.maxWidth,
6690      maxHeight: options.maxHeight,
6691      minWidth: options.minWidth,
6692      minHeight: this._minHeight(),
6693      handles: resizeHandles,
6694      start: function( event, ui ) {
6695        $( this ).addClass("ui-dialog-resizing");
6696        that._blockFrames();
6697        that._trigger( "resizeStart", event, filteredUi( ui ) );
6698      },
6699      resize: function( event, ui ) {
6700        that._trigger( "resize", event, filteredUi( ui ) );
6701      },
6702      stop: function( event, ui ) {
6703        options.height = $( this ).height();
6704        options.width = $( this ).width();
6705        $( this ).removeClass("ui-dialog-resizing");
6706        that._unblockFrames();
6707        that._trigger( "resizeStop", event, filteredUi( ui ) );
6708      }
6709    })
6710    .css( "position", position );
6711  },
6712
6713  _minHeight: function() {
6714    var options = this.options;
6715
6716    return options.height === "auto" ?
6717      options.minHeight :
6718      Math.min( options.minHeight, options.height );
6719  },
6720
6721  _position: function() {
6722    // Need to show the dialog to get the actual offset in the position plugin
6723    var isVisible = this.uiDialog.is(":visible");
6724    if ( !isVisible ) {
6725      this.uiDialog.show();
6726    }
6727    this.uiDialog.position( this.options.position );
6728    if ( !isVisible ) {
6729      this.uiDialog.hide();
6730    }
6731  },
6732
6733  _setOptions: function( options ) {
6734    var that = this,
6735      resize = false,
6736      resizableOptions = {};
6737
6738    $.each( options, function( key, value ) {
6739      that._setOption( key, value );
6740
6741      if ( key in sizeRelatedOptions ) {
6742        resize = true;
6743      }
6744      if ( key in resizableRelatedOptions ) {
6745        resizableOptions[ key ] = value;
6746      }
6747    });
6748
6749    if ( resize ) {
6750      this._size();
6751      this._position();
6752    }
6753    if ( this.uiDialog.is(":data(ui-resizable)") ) {
6754      this.uiDialog.resizable( "option", resizableOptions );
6755    }
6756  },
6757
6758  _setOption: function( key, value ) {
6759    var isDraggable, isResizable,
6760      uiDialog = this.uiDialog;
6761
6762    if ( key === "dialogClass" ) {
6763      uiDialog
6764        .removeClass( this.options.dialogClass )
6765        .addClass( value );
6766    }
6767
6768    if ( key === "disabled" ) {
6769      return;
6770    }
6771
6772    this._super( key, value );
6773
6774    if ( key === "appendTo" ) {
6775      this.uiDialog.appendTo( this._appendTo() );
6776    }
6777
6778    if ( key === "buttons" ) {
6779      this._createButtons();
6780    }
6781
6782    if ( key === "closeText" ) {
6783      this.uiDialogTitlebarClose.button({
6784        // Ensure that we always pass a string
6785        label: "" + value
6786      });
6787    }
6788
6789    if ( key === "draggable" ) {
6790      isDraggable = uiDialog.is(":data(ui-draggable)");
6791      if ( isDraggable && !value ) {
6792        uiDialog.draggable("destroy");
6793      }
6794
6795      if ( !isDraggable && value ) {
6796        this._makeDraggable();
6797      }
6798    }
6799
6800    if ( key === "position" ) {
6801      this._position();
6802    }
6803
6804    if ( key === "resizable" ) {
6805      // currently resizable, becoming non-resizable
6806      isResizable = uiDialog.is(":data(ui-resizable)");
6807      if ( isResizable && !value ) {
6808        uiDialog.resizable("destroy");
6809      }
6810
6811      // currently resizable, changing handles
6812      if ( isResizable && typeof value === "string" ) {
6813        uiDialog.resizable( "option", "handles", value );
6814      }
6815
6816      // currently non-resizable, becoming resizable
6817      if ( !isResizable && value !== false ) {
6818        this._makeResizable();
6819      }
6820    }
6821
6822    if ( key === "title" ) {
6823      this._title( this.uiDialogTitlebar.find(".ui-dialog-title") );
6824    }
6825  },
6826
6827  _size: function() {
6828    // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
6829    // divs will both have width and height set, so we need to reset them
6830    var nonContentHeight, minContentHeight, maxContentHeight,
6831      options = this.options;
6832
6833    // Reset content sizing
6834    this.element.show().css({
6835      width: "auto",
6836      minHeight: 0,
6837      maxHeight: "none",
6838      height: 0
6839    });
6840
6841    if ( options.minWidth > options.width ) {
6842      options.width = options.minWidth;
6843    }
6844
6845    // reset wrapper sizing
6846    // determine the height of all the non-content elements
6847    nonContentHeight = this.uiDialog.css({
6848        height: "auto",
6849        width: options.width
6850      })
6851      .outerHeight();
6852    minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
6853    maxContentHeight = typeof options.maxHeight === "number" ?
6854      Math.max( 0, options.maxHeight - nonContentHeight ) :
6855      "none";
6856
6857    if ( options.height === "auto" ) {
6858      this.element.css({
6859        minHeight: minContentHeight,
6860        maxHeight: maxContentHeight,
6861        height: "auto"
6862      });
6863    } else {
6864      this.element.height( Math.max( 0, options.height - nonContentHeight ) );
6865    }
6866
6867    if (this.uiDialog.is(":data(ui-resizable)") ) {
6868      this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
6869    }
6870  },
6871
6872  _blockFrames: function() {
6873    this.iframeBlocks = this.document.find( "iframe" ).map(function() {
6874      var iframe = $( this );
6875
6876      return $( "<div>" )
6877        .css({
6878          position: "absolute",
6879          width: iframe.outerWidth(),
6880          height: iframe.outerHeight()
6881        })
6882        .appendTo( iframe.parent() )
6883        .offset( iframe.offset() )[0];
6884    });
6885  },
6886
6887  _unblockFrames: function() {
6888    if ( this.iframeBlocks ) {
6889      this.iframeBlocks.remove();
6890      delete this.iframeBlocks;
6891    }
6892  },
6893
6894  _allowInteraction: function( event ) {
6895    if ( $( event.target ).closest(".ui-dialog").length ) {
6896      return true;
6897    }
6898
6899    // TODO: Remove hack when datepicker implements
6900    // the .ui-front logic (#8989)
6901    return !!$( event.target ).closest(".ui-datepicker").length;
6902  },
6903
6904  _createOverlay: function() {
6905    if ( !this.options.modal ) {
6906      return;
6907    }
6908
6909    var that = this,
6910      widgetFullName = this.widgetFullName;
6911    if ( !$.ui.dialog.overlayInstances ) {
6912      // Prevent use of anchors and inputs.
6913      // We use a delay in case the overlay is created from an
6914      // event that we're going to be cancelling. (#2804)
6915      this._delay(function() {
6916        // Handle .dialog().dialog("close") (#4065)
6917        if ( $.ui.dialog.overlayInstances ) {
6918          this.document.bind( "focusin.dialog", function( event ) {
6919            if ( !that._allowInteraction( event ) ) {
6920              event.preventDefault();
6921              $(".ui-dialog:visible:last .ui-dialog-content")
6922                .data( widgetFullName )._focusTabbable();
6923            }
6924          });
6925        }
6926      });
6927    }
6928
6929    this.overlay = $("<div>")
6930      .addClass("ui-widget-overlay ui-front")
6931      .appendTo( this._appendTo() );
6932    this._on( this.overlay, {
6933      mousedown: "_keepFocus"
6934    });
6935    $.ui.dialog.overlayInstances++;
6936  },
6937
6938  _destroyOverlay: function() {
6939    if ( !this.options.modal ) {
6940      return;
6941    }
6942
6943    if ( this.overlay ) {
6944      $.ui.dialog.overlayInstances--;
6945
6946      if ( !$.ui.dialog.overlayInstances ) {
6947        this.document.unbind( "focusin.dialog" );
6948      }
6949      this.overlay.remove();
6950      this.overlay = null;
6951    }
6952  }
6953});
6954
6955$.ui.dialog.overlayInstances = 0;
6956
6957// DEPRECATED
6958if ( $.uiBackCompat !== false ) {
6959  // position option with array notation
6960  // just override with old implementation
6961  $.widget( "ui.dialog", $.ui.dialog, {
6962    _position: function() {
6963      var position = this.options.position,
6964        myAt = [],
6965        offset = [ 0, 0 ],
6966        isVisible;
6967
6968      if ( position ) {
6969        if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
6970          myAt = position.split ? position.split(" ") : [ position[0], position[1] ];
6971          if ( myAt.length === 1 ) {
6972            myAt[1] = myAt[0];
6973          }
6974
6975          $.each( [ "left", "top" ], function( i, offsetPosition ) {
6976            if ( +myAt[ i ] === myAt[ i ] ) {
6977              offset[ i ] = myAt[ i ];
6978              myAt[ i ] = offsetPosition;
6979            }
6980          });
6981
6982          position = {
6983            my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
6984              myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
6985            at: myAt.join(" ")
6986          };
6987        }
6988
6989        position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
6990      } else {
6991        position = $.ui.dialog.prototype.options.position;
6992      }
6993
6994      // need to show the dialog to get the actual offset in the position plugin
6995      isVisible = this.uiDialog.is(":visible");
6996      if ( !isVisible ) {
6997        this.uiDialog.show();
6998      }
6999      this.uiDialog.position( position );
7000      if ( !isVisible ) {
7001        this.uiDialog.hide();
7002      }
7003    }
7004  });
7005}
7006
7007}( _4ORMAT.$ ) );
7008(function( $, undefined ) {
7009
7010$.widget("ui.draggable", $.ui.mouse, {
7011  version: "1.10.4",
7012  widgetEventPrefix: "drag",
7013  options: {
7014    addClasses: true,
7015    appendTo: "parent",
7016    axis: false,
7017    connectToSortable: false,
7018    containment: false,
7019    cursor: "auto",
7020    cursorAt: false,
7021    grid: false,
7022    handle: false,
7023    helper: "original",
7024    iframeFix: false,
7025    opacity: false,
7026    refreshPositions: false,
7027    revert: false,
7028    revertDuration: 500,
7029    scope: "default",
7030    scroll: true,
7031    scrollSensitivity: 20,
7032    scrollSpeed: 20,
7033    snap: false,
7034    snapMode: "both",
7035    snapTolerance: 20,
7036    stack: false,
7037    zIndex: false,
7038
7039    // callbacks
7040    drag: null,
7041    start: null,
7042    stop: null
7043  },
7044  _create: function() {
7045
7046    if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
7047      this.element[0].style.position = "relative";
7048    }
7049    if (this.options.addClasses){
7050      this.element.addClass("ui-draggable");
7051    }
7052    if (this.options.disabled){
7053      this.element.addClass("ui-draggable-disabled");
7054    }
7055
7056    this._mouseInit();
7057
7058  },
7059
7060  _destroy: function() {
7061    this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
7062    this._mouseDestroy();
7063  },
7064
7065  _mouseCapture: function(event) {
7066
7067    var o = this.options;
7068
7069    // among others, prevent a drag on a resizable-handle
7070    if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
7071      return false;
7072    }
7073
7074    //Quit if we're not on a valid handle
7075    this.handle = this._getHandle(event);
7076    if (!this.handle) {
7077      return false;
7078    }
7079
7080    $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
7081      $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
7082      .css({
7083        width: this.offsetWidth+"px", height: this.offsetHeight+"px",
7084        position: "absolute", opacity: "0.001", zIndex: 1000
7085      })
7086      .css($(this).offset())
7087      .appendTo("body");
7088    });
7089
7090    return true;
7091
7092  },
7093
7094  _mouseStart: function(event) {
7095
7096    var o = this.options;
7097
7098    //Create and append the visible helper
7099    this.helper = this._createHelper(event);
7100
7101    this.helper.addClass("ui-draggable-dragging");
7102
7103    //Cache the helper size
7104    this._cacheHelperProportions();
7105
7106    //If ddmanager is used for droppables, set the global draggable
7107    if($.ui.ddmanager) {
7108      $.ui.ddmanager.current = this;
7109    }
7110
7111    /*
7112     * - Position generation -
7113     * This block generates everything position related - it's the core of draggables.
7114     */
7115
7116    //Cache the margins of the original element
7117    this._cacheMargins();
7118
7119    //Store the helper's css position
7120    this.cssPosition = this.helper.css( "position" );
7121    this.scrollParent = this.helper.scrollParent();
7122    this.offsetParent = this.helper.offsetParent();
7123    this.offsetParentCssPosition = this.offsetParent.css( "position" );
7124
7125    //The element's absolute position on the page minus margins
7126    this.offset = this.positionAbs = this.element.offset();
7127    this.offset = {
7128      top: this.offset.top - this.margins.top,
7129      left: this.offset.left - this.margins.left
7130    };
7131
7132    //Reset scroll cache
7133    this.offset.scroll = false;
vendor: 27,184 bytes, lines 7134-7862
7134
7135    $.extend(this.offset, {
7136      click: { //Where the click happened, relative to the element
7137        left: event.pageX - this.offset.left,
7138        top: event.pageY - this.offset.top
7139      },
7140      parent: this._getParentOffset(),
7141      relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
7142    });
7143
7144    //Generate the original position
7145    this.originalPosition = this.position = this._generatePosition(event);
7146    this.originalPageX = event.pageX;
7147    this.originalPageY = event.pageY;
7148
7149    //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
7150    (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
7151
7152    //Set a containment if given in the options
7153    this._setContainment();
7154
7155    //Trigger event + callbacks
7156    if(this._trigger("start", event) === false) {
7157      this._clear();
7158      return false;
7159    }
7160
7161    //Recache the helper size
7162    this._cacheHelperProportions();
7163
7164    //Prepare the droppable offsets
7165    if ($.ui.ddmanager && !o.dropBehaviour) {
7166      $.ui.ddmanager.prepareOffsets(this, event);
7167    }
7168
7169
7170    this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
7171
7172    //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
7173    if ( $.ui.ddmanager ) {
7174      $.ui.ddmanager.dragStart(this, event);
7175    }
7176
7177    return true;
7178  },
7179
7180  _mouseDrag: function(event, noPropagation) {
7181    // reset any necessary cached properties (see #5009)
7182    if ( this.offsetParentCssPosition === "fixed" ) {
7183      this.offset.parent = this._getParentOffset();
7184    }
7185
7186    //Compute the helpers position
7187    this.position = this._generatePosition(event);
7188    this.positionAbs = this._convertPositionTo("absolute");
7189
7190    //Call plugins and callbacks and use the resulting position if something is returned
7191    if (!noPropagation) {
7192      var ui = this._uiHash();
7193      if(this._trigger("drag", event, ui) === false) {
7194        this._mouseUp({});
7195        return false;
7196      }
7197      this.position = ui.position;
7198    }
7199
7200    if(!this.options.axis || this.options.axis !== "y") {
7201      this.helper[0].style.left = this.position.left+"px";
7202    }
7203    if(!this.options.axis || this.options.axis !== "x") {
7204      this.helper[0].style.top = this.position.top+"px";
7205    }
7206    if($.ui.ddmanager) {
7207      $.ui.ddmanager.drag(this, event);
7208    }
7209
7210    return false;
7211  },
7212
7213  _mouseStop: function(event) {
7214
7215    //If we are using droppables, inform the manager about the drop
7216    var that = this,
7217      dropped = false;
7218    if ($.ui.ddmanager && !this.options.dropBehaviour) {
7219      dropped = $.ui.ddmanager.drop(this, event);
7220    }
7221
7222    //if a drop comes from outside (a sortable)
7223    if(this.dropped) {
7224      dropped = this.dropped;
7225      this.dropped = false;
7226    }
7227
7228    //if the original element is no longer in the DOM don't bother to continue (see #8269)
7229    if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) {
7230      return false;
7231    }
7232
7233    if((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
7234      $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
7235        if(that._trigger("stop", event) !== false) {
7236          that._clear();
7237        }
7238      });
7239    } else {
7240      if(this._trigger("stop", event) !== false) {
7241        this._clear();
7242      }
7243    }
7244
7245    return false;
7246  },
7247
7248  _mouseUp: function(event) {
7249    //Remove frame helpers
7250    $("div.ui-draggable-iframeFix").each(function() {
7251      this.parentNode.removeChild(this);
7252    });
7253
7254    //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
7255    if( $.ui.ddmanager ) {
7256      $.ui.ddmanager.dragStop(this, event);
7257    }
7258
7259    return $.ui.mouse.prototype._mouseUp.call(this, event);
7260  },
7261
7262  cancel: function() {
7263
7264    if(this.helper.is(".ui-draggable-dragging")) {
7265      this._mouseUp({});
7266    } else {
7267      this._clear();
7268    }
7269
7270    return this;
7271
7272  },
7273
7274  _getHandle: function(event) {
7275    return this.options.handle ?
7276      !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
7277      true;
7278  },
7279
7280  _createHelper: function(event) {
7281
7282    var o = this.options,
7283      helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
7284
7285    if(!helper.parents("body").length) {
7286      helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
7287    }
7288
7289    if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
7290      helper.css("position", "absolute");
7291    }
7292
7293    return helper;
7294
7295  },
7296
7297  _adjustOffsetFromHelper: function(obj) {
7298    if (typeof obj === "string") {
7299      obj = obj.split(" ");
7300    }
7301    if ($.isArray(obj)) {
7302      obj = {left: +obj[0], top: +obj[1] || 0};
7303    }
7304    if ("left" in obj) {
7305      this.offset.click.left = obj.left + this.margins.left;
7306    }
7307    if ("right" in obj) {
7308      this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
7309    }
7310    if ("top" in obj) {
7311      this.offset.click.top = obj.top + this.margins.top;
7312    }
7313    if ("bottom" in obj) {
7314      this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
7315    }
7316  },
7317
7318  _getParentOffset: function() {
7319
7320    //Get the offsetParent and cache its position
7321    var po = this.offsetParent.offset();
7322
7323    // This is a special case where we need to modify a offset calculated on start, since the following happened:
7324    // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
7325    // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
7326    //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
7327    if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
7328      po.left += this.scrollParent.scrollLeft();
7329      po.top += this.scrollParent.scrollTop();
7330    }
7331
7332    //This needs to be actually done for all browsers, since pageX/pageY includes this information
7333    //Ugly IE fix
7334    if((this.offsetParent[0] === document.body) ||
7335      (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
7336      po = { top: 0, left: 0 };
7337    }
7338
7339    return {
7340      top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
7341      left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
7342    };
7343
7344  },
7345
7346  _getRelativeOffset: function() {
7347
7348    if(this.cssPosition === "relative") {
7349      var p = this.element.position();
7350      return {
7351        top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
7352        left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
7353      };
7354    } else {
7355      return { top: 0, left: 0 };
7356    }
7357
7358  },
7359
7360  _cacheMargins: function() {
7361    this.margins = {
7362      left: (parseInt(this.element.css("marginLeft"),10) || 0),
7363      top: (parseInt(this.element.css("marginTop"),10) || 0),
7364      right: (parseInt(this.element.css("marginRight"),10) || 0),
7365      bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
7366    };
7367  },
7368
7369  _cacheHelperProportions: function() {
7370    this.helperProportions = {
7371      width: this.helper.outerWidth(),
7372      height: this.helper.outerHeight()
7373    };
7374  },
7375
7376  _setContainment: function() {
7377
7378    var over, c, ce,
7379      o = this.options;
7380
7381    if ( !o.containment ) {
7382      this.containment = null;
7383      return;
7384    }
7385
7386    if ( o.containment === "window" ) {
7387      this.containment = [
7388        $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
7389        $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
7390        $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
7391        $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
7392      ];
7393      return;
7394    }
7395
7396    if ( o.containment === "document") {
7397      this.containment = [
7398        0,
7399        0,
7400        $( document ).width() - this.helperProportions.width - this.margins.left,
7401        ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
7402      ];
7403      return;
7404    }
7405
7406    if ( o.containment.constructor === Array ) {
7407      this.containment = o.containment;
7408      return;
7409    }
7410
7411    if ( o.containment === "parent" ) {
7412      o.containment = this.helper[ 0 ].parentNode;
7413    }
7414
7415    c = $( o.containment );
7416    ce = c[ 0 ];
7417
7418    if( !ce ) {
7419      return;
7420    }
7421
7422    over = c.css( "overflow" ) !== "hidden";
7423
7424    this.containment = [
7425      ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
7426      ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) ,
7427      ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right,
7428      ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top  - this.margins.bottom
7429    ];
7430    this.relative_container = c;
7431  },
7432
7433  _convertPositionTo: function(d, pos) {
7434
7435    if(!pos) {
7436      pos = this.position;
7437    }
7438
7439    var mod = d === "absolute" ? 1 : -1,
7440      scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent;
7441
7442    //Cache the scroll
7443    if (!this.offset.scroll) {
7444      this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
7445    }
7446
7447    return {
7448      top: (
7449        pos.top +                               // The absolute mouse position
7450        this.offset.relative.top * mod +                    // Only for relative positioned nodes: Relative offset from element to offset parent
7451        this.offset.parent.top * mod -                    // The offsetParent's offset without borders (offset + border)
7452        ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod )
7453      ),
7454      left: (
7455        pos.left +                                // The absolute mouse position
7456        this.offset.relative.left * mod +                   // Only for relative positioned nodes: Relative offset from element to offset parent
7457        this.offset.parent.left * mod -                   // The offsetParent's offset without borders (offset + border)
7458        ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod )
7459      )
7460    };
7461
7462  },
7463
7464  _generatePosition: function(event) {
7465
7466    var containment, co, top, left,
7467      o = this.options,
7468      scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent,
7469      pageX = event.pageX,
7470      pageY = event.pageY;
7471
7472    //Cache the scroll
7473    if (!this.offset.scroll) {
7474      this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
7475    }
7476
7477    /*
7478     * - Position constraining -
7479     * Constrain the position to a mix of grid, containment.
7480     */
7481
7482    // If we are not dragging yet, we won't check for options
7483    if ( this.originalPosition ) {
7484      if ( this.containment ) {
7485        if ( this.relative_container ){
7486          co = this.relative_container.offset();
7487          containment = [
7488            this.containment[ 0 ] + co.left,
7489            this.containment[ 1 ] + co.top,
7490            this.containment[ 2 ] + co.left,
7491            this.containment[ 3 ] + co.top
7492          ];
7493        }
7494        else {
7495          containment = this.containment;
7496        }
7497
7498        if(event.pageX - this.offset.click.left < containment[0]) {
7499          pageX = containment[0] + this.offset.click.left;
7500        }
7501        if(event.pageY - this.offset.click.top < containment[1]) {
7502          pageY = containment[1] + this.offset.click.top;
7503        }
7504        if(event.pageX - this.offset.click.left > containment[2]) {
7505          pageX = containment[2] + this.offset.click.left;
7506        }
7507        if(event.pageY - this.offset.click.top > containment[3]) {
7508          pageY = containment[3] + this.offset.click.top;
7509        }
7510      }
7511
7512      if(o.grid) {
7513        //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
7514        top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
7515        pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
7516
7517        left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
7518        pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
7519      }
7520
7521    }
7522
7523    return {
7524      top: (
7525        pageY -                                 // The absolute mouse position
7526        this.offset.click.top -                       // Click offset (relative to the element)
7527        this.offset.relative.top -                        // Only for relative positioned nodes: Relative offset from element to offset parent
7528        this.offset.parent.top +                        // The offsetParent's offset without borders (offset + border)
7529        ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top )
7530      ),
7531      left: (
7532        pageX -                                 // The absolute mouse position
7533        this.offset.click.left -                        // Click offset (relative to the element)
7534        this.offset.relative.left -                       // Only for relative positioned nodes: Relative offset from element to offset parent
7535        this.offset.parent.left +                       // The offsetParent's offset without borders (offset + border)
7536        ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left )
7537      )
7538    };
7539
7540  },
7541
7542  _clear: function() {
7543    this.helper.removeClass("ui-draggable-dragging");
7544    if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
7545      this.helper.remove();
7546    }
7547    this.helper = null;
7548    this.cancelHelperRemoval = false;
7549  },
7550
7551  // From now on bulk stuff - mainly helpers
7552
7553  _trigger: function(type, event, ui) {
7554    ui = ui || this._uiHash();
7555    $.ui.plugin.call(this, type, [event, ui]);
7556    //The absolute position has to be recalculated after plugins
7557    if(type === "drag") {
7558      this.positionAbs = this._convertPositionTo("absolute");
7559    }
7560    return $.Widget.prototype._trigger.call(this, type, event, ui);
7561  },
7562
7563  plugins: {},
7564
7565  _uiHash: function() {
7566    return {
7567      helper: this.helper,
7568      position: this.position,
7569      originalPosition: this.originalPosition,
7570      offset: this.positionAbs
7571    };
7572  }
7573
7574});
7575
7576$.ui.plugin.add("draggable", "connectToSortable", {
7577  start: function(event, ui) {
7578
7579    var inst = $(this).data("ui-draggable"), o = inst.options,
7580      uiSortable = $.extend({}, ui, { item: inst.element });
7581    inst.sortables = [];
7582    $(o.connectToSortable).each(function() {
7583      var sortable = $.data(this, "ui-sortable");
7584      if (sortable && !sortable.options.disabled) {
7585        inst.sortables.push({
7586          instance: sortable,
7587          shouldRevert: sortable.options.revert
7588        });
7589        sortable.refreshPositions();  // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
7590        sortable._trigger("activate", event, uiSortable);
7591      }
7592    });
7593
7594  },
7595  stop: function(event, ui) {
7596
7597    //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
7598    var inst = $(this).data("ui-draggable"),
7599      uiSortable = $.extend({}, ui, { item: inst.element });
7600
7601    $.each(inst.sortables, function() {
7602      if(this.instance.isOver) {
7603
7604        this.instance.isOver = 0;
7605
7606        inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
7607        this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
7608
7609        //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
7610        if(this.shouldRevert) {
7611          this.instance.options.revert = this.shouldRevert;
7612        }
7613
7614        //Trigger the stop of the sortable
7615        this.instance._mouseStop(event);
7616
7617        this.instance.options.helper = this.instance.options._helper;
7618
7619        //If the helper has been the original item, restore properties in the sortable
7620        if(inst.options.helper === "original") {
7621          this.instance.currentItem.css({ top: "auto", left: "auto" });
7622        }
7623
7624      } else {
7625        this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
7626        this.instance._trigger("deactivate", event, uiSortable);
7627      }
7628
7629    });
7630
7631  },
7632  drag: function(event, ui) {
7633
7634    var inst = $(this).data("ui-draggable"), that = this;
7635
7636    $.each(inst.sortables, function() {
7637
7638      var innermostIntersecting = false,
7639        thisSortable = this;
7640
7641      //Copy over some variables to allow calling the sortable's native _intersectsWith
7642      this.instance.positionAbs = inst.positionAbs;
7643      this.instance.helperProportions = inst.helperProportions;
7644      this.instance.offset.click = inst.offset.click;
7645
7646      if(this.instance._intersectsWith(this.instance.containerCache)) {
7647        innermostIntersecting = true;
7648        $.each(inst.sortables, function () {
7649          this.instance.positionAbs = inst.positionAbs;
7650          this.instance.helperProportions = inst.helperProportions;
7651          this.instance.offset.click = inst.offset.click;
7652          if (this !== thisSortable &&
7653            this.instance._intersectsWith(this.instance.containerCache) &&
7654            $.contains(thisSortable.instance.element[0], this.instance.element[0])
7655          ) {
7656            innermostIntersecting = false;
7657          }
7658          return innermostIntersecting;
7659        });
7660      }
7661
7662
7663      if(innermostIntersecting) {
7664        //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
7665        if(!this.instance.isOver) {
7666
7667          this.instance.isOver = 1;
7668          //Now we fake the start of dragging for the sortable instance,
7669          //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
7670          //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
7671          this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
7672          this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
7673          this.instance.options.helper = function() { return ui.helper[0]; };
7674
7675          event.target = this.instance.currentItem[0];
7676          this.instance._mouseCapture(event, true);
7677          this.instance._mouseStart(event, true, true);
7678
7679          //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
7680          this.instance.offset.click.top = inst.offset.click.top;
7681          this.instance.offset.click.left = inst.offset.click.left;
7682          this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
7683          this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
7684
7685          inst._trigger("toSortable", event);
7686          inst.dropped = this.instance.element; //draggable revert needs that
7687          //hack so receive/update callbacks work (mostly)
7688          inst.currentItem = inst.element;
7689          this.instance.fromOutside = inst;
7690
7691        }
7692
7693        //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
7694        if(this.instance.currentItem) {
7695          this.instance._mouseDrag(event);
7696        }
7697
7698      } else {
7699
7700        //If it doesn't intersect with the sortable, and it intersected before,
7701        //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
7702        if(this.instance.isOver) {
7703
7704          this.instance.isOver = 0;
7705          this.instance.cancelHelperRemoval = true;
7706
7707          //Prevent reverting on this forced stop
7708          this.instance.options.revert = false;
7709
7710          // The out event needs to be triggered independently
7711          this.instance._trigger("out", event, this.instance._uiHash(this.instance));
7712
7713          this.instance._mouseStop(event, true);
7714          this.instance.options.helper = this.instance.options._helper;
7715
7716          //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
7717          this.instance.currentItem.remove();
7718          if(this.instance.placeholder) {
7719            this.instance.placeholder.remove();
7720          }
7721
7722          inst._trigger("fromSortable", event);
7723          inst.dropped = false; //draggable revert needs that
7724        }
7725
7726      }
7727
7728    });
7729
7730  }
7731});
7732
7733$.ui.plugin.add("draggable", "cursor", {
7734  start: function() {
7735    var t = $("body"), o = $(this).data("ui-draggable").options;
7736    if (t.css("cursor")) {
7737      o._cursor = t.css("cursor");
7738    }
7739    t.css("cursor", o.cursor);
7740  },
7741  stop: function() {
7742    var o = $(this).data("ui-draggable").options;
7743    if (o._cursor) {
7744      $("body").css("cursor", o._cursor);
7745    }
7746  }
7747});
7748
7749$.ui.plugin.add("draggable", "opacity", {
7750  start: function(event, ui) {
7751    var t = $(ui.helper), o = $(this).data("ui-draggable").options;
7752    if(t.css("opacity")) {
7753      o._opacity = t.css("opacity");
7754    }
7755    t.css("opacity", o.opacity);
7756  },
7757  stop: function(event, ui) {
7758    var o = $(this).data("ui-draggable").options;
7759    if(o._opacity) {
7760      $(ui.helper).css("opacity", o._opacity);
7761    }
7762  }
7763});
7764
7765$.ui.plugin.add("draggable", "scroll", {
7766  start: function() {
7767    var i = $(this).data("ui-draggable");
7768    if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
7769      i.overflowOffset = i.scrollParent.offset();
7770    }
7771  },
7772  drag: function( event ) {
7773
7774    var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
7775
7776    if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
7777
7778      if(!o.axis || o.axis !== "x") {
7779        if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
7780          i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
7781        } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
7782          i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
7783        }
7784      }
7785
7786      if(!o.axis || o.axis !== "y") {
7787        if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
7788          i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
7789        } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
7790          i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
7791        }
7792      }
7793
7794    } else {
7795
7796      if(!o.axis || o.axis !== "x") {
7797        if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
7798          scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
7799        } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
7800          scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
7801        }
7802      }
7803
7804      if(!o.axis || o.axis !== "y") {
7805        if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
7806          scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
7807        } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
7808          scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
7809        }
7810      }
7811
7812    }
7813
7814    if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
7815      $.ui.ddmanager.prepareOffsets(i, event);
7816    }
7817
7818  }
7819});
7820
7821$.ui.plugin.add("draggable", "snap", {
7822  start: function() {
7823
7824    var i = $(this).data("ui-draggable"),
7825      o = i.options;
7826
7827    i.snapElements = [];
7828
7829    $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
7830      var $t = $(this),
7831        $o = $t.offset();
7832      if(this !== i.element[0]) {
7833        i.snapElements.push({
7834          item: this,
7835          width: $t.outerWidth(), height: $t.outerHeight(),
7836          top: $o.top, left: $o.left
7837        });
7838      }
7839    });
7840
7841  },
7842  drag: function(event, ui) {
7843
7844    var ts, bs, ls, rs, l, r, t, b, i, first,
7845      inst = $(this).data("ui-draggable"),
7846      o = inst.options,
7847      d = o.snapTolerance,
7848      x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
7849      y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
7850
7851    for (i = inst.snapElements.length - 1; i >= 0; i--){
7852
7853      l = inst.snapElements[i].left;
7854      r = l + inst.snapElements[i].width;
7855      t = inst.snapElements[i].top;
7856      b = t + inst.snapElements[i].height;
7857
7858      if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
7859        if(inst.snapElements[i].snapping) {
7860          (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
7861        }
7862        inst.snapElements[i].snapping = false;
7863        continue;
7864      }
7865
7866      if(o.snapMode !== "inner") {
7867        ts = Math.abs(t - y2) <= d;
7868        bs = Math.abs(b - y1) <= d;
7869        ls = Math.abs(l - x2) <= d;
7870        rs = Math.abs(r - x1) <= d;
7871        if(ts) {
7872          ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
7873        }
7874        if(bs) {
7875          ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
7876        }
7877        if(ls) {
7878          ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
7879        }
7880        if(rs) {
7881          ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
7882        }
7883      }
7884
7885      first = (ts || bs || ls || rs);
7886
7887      if(o.snapMode !== "outer") {
7888        ts = Math.abs(t - y1) <= d;
7889        bs = Math.abs(b - y2) <= d;
7890        ls = Math.abs(l - x1) <= d;
7891        rs = Math.abs(r - x2) <= d;
7892        if(ts) {
7893          ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
7894        }
7895        if(bs) {
7896          ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
7897        }
7898        if(ls) {
7899          ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
7900        }
7901        if(rs) {
7902          ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
7903        }
7904      }
7905
7906      if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
7907        (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
7908      }
7909      inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
7910
7911    }
7912
7913  }
7914});
7915
7916$.ui.plugin.add("draggable", "stack", {
7917  start: function() {
7918    var min,
7919      o = this.data("ui-draggable").options,
7920      group = $.makeArray($(o.stack)).sort(function(a,b) {
7921        return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
7922      });
7923
7924    if (!group.length) { return; }
7925
7926    min = parseInt($(group[0]).css("zIndex"), 10) || 0;
7927    $(group).each(function(i) {
7928      $(this).css("zIndex", min + i);
7929    });
7930    this.css("zIndex", (min + group.length));
7931  }
7932});
7933
7934$.ui.plugin.add("draggable", "zIndex", {
7935  start: function(event, ui) {
7936    var t = $(ui.helper), o = $(this).data("ui-draggable").options;
7937    if(t.css("zIndex")) {
7938      o._zIndex = t.css("zIndex");
7939    }
7940    t.css("zIndex", o.zIndex);
7941  },
7942  stop: function(event, ui) {
7943    var o = $(this).data("ui-draggable").options;
7944    if(o._zIndex) {
7945      $(ui.helper).css("zIndex", o._zIndex);
7946    }
7947  }
7948});
7949
7950})( _4ORMAT.$ );
7951(function( $, undefined ) {
7952
7953function isOverAxis( x, reference, size ) {
7954  return ( x > reference ) && ( x < ( reference + size ) );
7955}
7956
7957$.widget("ui.droppable", {
7958  version: "1.10.4",
7959  widgetEventPrefix: "drop",
7960  options: {
7961    accept: "*",
7962    activeClass: false,
7963    addClasses: true,
7964    greedy: false,
7965    hoverClass: false,
7966    scope: "default",
7967    tolerance: "intersect",
7968
7969    // callbacks
7970    activate: null,
7971    deactivate: null,
7972    drop: null,
7973    out: null,
7974    over: null
7975  },
7976  _create: function() {
7977
7978    var proportions,
7979      o = this.options,
7980      accept = o.accept;
7981
7982    this.isover = false;
7983    this.isout = true;
7984
7985    this.accept = $.isFunction(accept) ? accept : function(d) {
7986      return d.is(accept);
7987    };
7988
7989    this.proportions = function( /* valueToWrite */ ) {
7990      if ( arguments.length ) {
7991        // Store the droppable's proportions
7992        proportions = arguments[ 0 ];
7993      } else {
7994        // Retrieve or derive the droppable's proportions
7995        return proportions ?
7996          proportions :
7997          proportions = {
7998            width: this.element[ 0 ].offsetWidth,
7999            height: this.element[ 0 ].offsetHeight
8000          };
8001      }
8002    };
8003
8004    // Add the reference and positions to the manager
8005    $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
8006    $.ui.ddmanager.droppables[o.scope].push(this);
8007
8008    (o.addClasses && this.element.addClass("ui-droppable"));
8009
8010  },
8011
8012  _destroy: function() {
8013    var i = 0,
8014      drop = $.ui.ddmanager.droppables[this.options.scope];
8015
8016    for ( ; i < drop.length; i++ ) {
8017      if ( drop[i] === this ) {
8018        drop.splice(i, 1);
8019      }
8020    }
8021
8022    this.element.removeClass("ui-droppable ui-droppable-disabled");
8023  },
8024
8025  _setOption: function(key, value) {
8026
8027    if(key === "accept") {
8028      this.accept = $.isFunction(value) ? value : function(d) {
8029        return d.is(value);
8030      };
8031    }
8032    $.Widget.prototype._setOption.apply(this, arguments);
8033  },
8034
8035  _activate: function(event) {
8036    var draggable = $.ui.ddmanager.current;
8037    if(this.options.activeClass) {
8038      this.element.addClass(this.options.activeClass);
8039    }
8040    if(draggable){
8041      this._trigger("activate", event, this.ui(draggable));
8042    }
8043  },
8044
8045  _deactivate: function(event) {
8046    var draggable = $.ui.ddmanager.current;
8047    if(this.options.activeClass) {
8048      this.element.removeClass(this.options.activeClass);
8049    }
8050    if(draggable){
8051      this._trigger("deactivate", event, this.ui(draggable));
8052    }
8053  },
8054
8055  _over: function(event) {
8056
8057    var draggable = $.ui.ddmanager.current;
8058
8059    // Bail if draggable and droppable are same element
8060    if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
8061      return;
8062    }
8063
8064    if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
8065      if(this.options.hoverClass) {
8066        this.element.addClass(this.options.hoverClass);
8067      }
8068      this._trigger("over", event, this.ui(draggable));
8069    }
8070
8071  },
8072
8073  _out: function(event) {
8074
8075    var draggable = $.ui.ddmanager.current;
8076
8077    // Bail if draggable and droppable are same element
8078    if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
8079      return;
8080    }
8081
8082    if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
8083      if(this.options.hoverClass) {
8084        this.element.removeClass(this.options.hoverClass);
8085      }
8086      this._trigger("out", event, this.ui(draggable));
8087    }
8088
8089  },
8090
8091  _drop: function(event,custom) {
8092
8093    var draggable = custom || $.ui.ddmanager.current,
8094      childrenIntersection = false;
vendor: 67,515 bytes, lines 8095-10558
8095
8096    // Bail if draggable and droppable are same element
8097    if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
8098      return false;
8099    }
8100
8101    this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
8102      var inst = $.data(this, "ui-droppable");
8103      if(
8104        inst.options.greedy &&
8105        !inst.options.disabled &&
8106        inst.options.scope === draggable.options.scope &&
8107        inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
8108        $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
8109      ) { childrenIntersection = true; return false; }
8110    });
8111    if(childrenIntersection) {
8112      return false;
8113    }
8114
8115    if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
8116      if(this.options.activeClass) {
8117        this.element.removeClass(this.options.activeClass);
8118      }
8119      if(this.options.hoverClass) {
8120        this.element.removeClass(this.options.hoverClass);
8121      }
8122      this._trigger("drop", event, this.ui(draggable));
8123      return this.element;
8124    }
8125
8126    return false;
8127
8128  },
8129
8130  ui: function(c) {
8131    return {
8132      draggable: (c.currentItem || c.element),
8133      helper: c.helper,
8134      position: c.position,
8135      offset: c.positionAbs
8136    };
8137  }
8138
8139});
8140
8141$.ui.intersect = function(draggable, droppable, toleranceMode) {
8142
8143  if (!droppable.offset) {
8144    return false;
8145  }
8146
8147  var draggableLeft, draggableTop,
8148    x1 = (draggable.positionAbs || draggable.position.absolute).left,
8149    y1 = (draggable.positionAbs || draggable.position.absolute).top,
8150    x2 = x1 + draggable.helperProportions.width,
8151    y2 = y1 + draggable.helperProportions.height,
8152    l = droppable.offset.left,
8153    t = droppable.offset.top,
8154    r = l + droppable.proportions().width,
8155    b = t + droppable.proportions().height;
8156
8157  switch (toleranceMode) {
8158    case "fit":
8159      return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
8160    case "intersect":
8161      return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
8162        x2 - (draggable.helperProportions.width / 2) < r && // Left Half
8163        t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
8164        y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
8165    case "pointer":
8166      draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
8167      draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
8168      return isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width );
8169    case "touch":
8170      return (
8171        (y1 >= t && y1 <= b) || // Top edge touching
8172        (y2 >= t && y2 <= b) || // Bottom edge touching
8173        (y1 < t && y2 > b)    // Surrounded vertically
8174      ) && (
8175        (x1 >= l && x1 <= r) || // Left edge touching
8176        (x2 >= l && x2 <= r) || // Right edge touching
8177        (x1 < l && x2 > r)    // Surrounded horizontally
8178      );
8179    default:
8180      return false;
8181    }
8182
8183};
8184
8185/*
8186  This manager tracks offsets of draggables and droppables
8187*/
8188$.ui.ddmanager = {
8189  current: null,
8190  droppables: { "default": [] },
8191  prepareOffsets: function(t, event) {
8192
8193    var i, j,
8194      m = $.ui.ddmanager.droppables[t.options.scope] || [],
8195      type = event ? event.type : null, // workaround for #2317
8196      list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
8197
8198    droppablesLoop: for (i = 0; i < m.length; i++) {
8199
8200      //No disabled and non-accepted
8201      if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
8202        continue;
8203      }
8204
8205      // Filter out elements in the current dragged item
8206      for (j=0; j < list.length; j++) {
8207        if(list[j] === m[i].element[0]) {
8208          m[i].proportions().height = 0;
8209          continue droppablesLoop;
8210        }
8211      }
8212
8213      m[i].visible = m[i].element.css("display") !== "none";
8214      if(!m[i].visible) {
8215        continue;
8216      }
8217
8218      //Activate the droppable if used directly from draggables
8219      if(type === "mousedown") {
8220        m[i]._activate.call(m[i], event);
8221      }
8222
8223      m[ i ].offset = m[ i ].element.offset();
8224      m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
8225
8226    }
8227
8228  },
8229  drop: function(draggable, event) {
8230
8231    var dropped = false;
8232    // Create a copy of the droppables in case the list changes during the drop (#9116)
8233    $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
8234
8235      if(!this.options) {
8236        return;
8237      }
8238      if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
8239        dropped = this._drop.call(this, event) || dropped;
8240      }
8241
8242      if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
8243        this.isout = true;
8244        this.isover = false;
8245        this._deactivate.call(this, event);
8246      }
8247
8248    });
8249    return dropped;
8250
8251  },
8252  dragStart: function( draggable, event ) {
8253    //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
8254    draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
8255      if( !draggable.options.refreshPositions ) {
8256        $.ui.ddmanager.prepareOffsets( draggable, event );
8257      }
8258    });
8259  },
8260  drag: function(draggable, event) {
8261
8262    //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
8263    if(draggable.options.refreshPositions) {
8264      $.ui.ddmanager.prepareOffsets(draggable, event);
8265    }
8266
8267    //Run through all droppables and check their positions based on specific tolerance options
8268    $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
8269
8270      if(this.options.disabled || this.greedyChild || !this.visible) {
8271        return;
8272      }
8273
8274      var parentInstance, scope, parent,
8275        intersects = $.ui.intersect(draggable, this, this.options.tolerance),
8276        c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
8277      if(!c) {
8278        return;
8279      }
8280
8281      if (this.options.greedy) {
8282        // find droppable parents with same scope
8283        scope = this.options.scope;
8284        parent = this.element.parents(":data(ui-droppable)").filter(function () {
8285          return $.data(this, "ui-droppable").options.scope === scope;
8286        });
8287
8288        if (parent.length) {
8289          parentInstance = $.data(parent[0], "ui-droppable");
8290          parentInstance.greedyChild = (c === "isover");
8291        }
8292      }
8293
8294      // we just moved into a greedy child
8295      if (parentInstance && c === "isover") {
8296        parentInstance.isover = false;
8297        parentInstance.isout = true;
8298        parentInstance._out.call(parentInstance, event);
8299      }
8300
8301      this[c] = true;
8302      this[c === "isout" ? "isover" : "isout"] = false;
8303      this[c === "isover" ? "_over" : "_out"].call(this, event);
8304
8305      // we just moved out of a greedy child
8306      if (parentInstance && c === "isout") {
8307        parentInstance.isout = false;
8308        parentInstance.isover = true;
8309        parentInstance._over.call(parentInstance, event);
8310      }
8311    });
8312
8313  },
8314  dragStop: function( draggable, event ) {
8315    draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
8316    //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
8317    if( !draggable.options.refreshPositions ) {
8318      $.ui.ddmanager.prepareOffsets( draggable, event );
8319    }
8320  }
8321};
8322
8323})( _4ORMAT.$ );
8324(function($, undefined) {
8325
8326var dataSpace = "ui-effects-";
8327
8328$.effects = {
8329  effect: {}
8330};
8331
8332/*!
8333 * jQuery Color Animations v2.1.2
8334 * https://github.com/jquery/jquery-color
8335 *
8336 * Copyright 2013 jQuery Foundation and other contributors
8337 * Released under the MIT license.
8338 * http://jquery.org/license
8339 *
8340 * Date: Wed Jan 16 08:47:09 2013 -0600
8341 */
8342(function( jQuery, undefined ) {
8343
8344  var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
8345
8346  // plusequals test for += 100 -= 100
8347  rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
8348  // a set of RE's that can match strings and generate color tuples.
8349  stringParsers = [{
8350      re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
8351      parse: function( execResult ) {
8352        return [
8353          execResult[ 1 ],
8354          execResult[ 2 ],
8355          execResult[ 3 ],
8356          execResult[ 4 ]
8357        ];
8358      }
8359    }, {
8360      re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
8361      parse: function( execResult ) {
8362        return [
8363          execResult[ 1 ] * 2.55,
8364          execResult[ 2 ] * 2.55,
8365          execResult[ 3 ] * 2.55,
8366          execResult[ 4 ]
8367        ];
8368      }
8369    }, {
8370      // this regex ignores A-F because it's compared against an already lowercased string
8371      re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
8372      parse: function( execResult ) {
8373        return [
8374          parseInt( execResult[ 1 ], 16 ),
8375          parseInt( execResult[ 2 ], 16 ),
8376          parseInt( execResult[ 3 ], 16 )
8377        ];
8378      }
8379    }, {
8380      // this regex ignores A-F because it's compared against an already lowercased string
8381      re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
8382      parse: function( execResult ) {
8383        return [
8384          parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
8385          parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
8386          parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
8387        ];
8388      }
8389    }, {
8390      re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
8391      space: "hsla",
8392      parse: function( execResult ) {
8393        return [
8394          execResult[ 1 ],
8395          execResult[ 2 ] / 100,
8396          execResult[ 3 ] / 100,
8397          execResult[ 4 ]
8398        ];
8399      }
8400    }],
8401
8402  // jQuery.Color( )
8403  color = jQuery.Color = function( color, green, blue, alpha ) {
8404    return new jQuery.Color.fn.parse( color, green, blue, alpha );
8405  },
8406  spaces = {
8407    rgba: {
8408      props: {
8409        red: {
8410          idx: 0,
8411          type: "byte"
8412        },
8413        green: {
8414          idx: 1,
8415          type: "byte"
8416        },
8417        blue: {
8418          idx: 2,
8419          type: "byte"
8420        }
8421      }
8422    },
8423
8424    hsla: {
8425      props: {
8426        hue: {
8427          idx: 0,
8428          type: "degrees"
8429        },
8430        saturation: {
8431          idx: 1,
8432          type: "percent"
8433        },
8434        lightness: {
8435          idx: 2,
8436          type: "percent"
8437        }
8438      }
8439    }
8440  },
8441  propTypes = {
8442    "byte": {
8443      floor: true,
8444      max: 255
8445    },
8446    "percent": {
8447      max: 1
8448    },
8449    "degrees": {
8450      mod: 360,
8451      floor: true
8452    }
8453  },
8454  support = color.support = {},
8455
8456  // element for support tests
8457  supportElem = jQuery( "<p>" )[ 0 ],
8458
8459  // colors = jQuery.Color.names
8460  colors,
8461
8462  // local aliases of functions called often
8463  each = jQuery.each;
8464
8465// determine rgba support immediately
8466supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
8467support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
8468
8469// define cache name and alpha properties
8470// for rgba and hsla spaces
8471each( spaces, function( spaceName, space ) {
8472  space.cache = "_" + spaceName;
8473  space.props.alpha = {
8474    idx: 3,
8475    type: "percent",
8476    def: 1
8477  };
8478});
8479
8480function clamp( value, prop, allowEmpty ) {
8481  var type = propTypes[ prop.type ] || {};
8482
8483  if ( value == null ) {
8484    return (allowEmpty || !prop.def) ? null : prop.def;
8485  }
8486
8487  // ~~ is an short way of doing floor for positive numbers
8488  value = type.floor ? ~~value : parseFloat( value );
8489
8490  // IE will pass in empty strings as value for alpha,
8491  // which will hit this case
8492  if ( isNaN( value ) ) {
8493    return prop.def;
8494  }
8495
8496  if ( type.mod ) {
8497    // we add mod before modding to make sure that negatives values
8498    // get converted properly: -10 -> 350
8499    return (value + type.mod) % type.mod;
8500  }
8501
8502  // for now all property types without mod have min and max
8503  return 0 > value ? 0 : type.max < value ? type.max : value;
8504}
8505
8506function stringParse( string ) {
8507  var inst = color(),
8508    rgba = inst._rgba = [];
8509
8510  string = string.toLowerCase();
8511
8512  each( stringParsers, function( i, parser ) {
8513    var parsed,
8514      match = parser.re.exec( string ),
8515      values = match && parser.parse( match ),
8516      spaceName = parser.space || "rgba";
8517
8518    if ( values ) {
8519      parsed = inst[ spaceName ]( values );
8520
8521      // if this was an rgba parse the assignment might happen twice
8522      // oh well....
8523      inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
8524      rgba = inst._rgba = parsed._rgba;
8525
8526      // exit each( stringParsers ) here because we matched
8527      return false;
8528    }
8529  });
8530
8531  // Found a stringParser that handled it
8532  if ( rgba.length ) {
8533
8534    // if this came from a parsed string, force "transparent" when alpha is 0
8535    // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
8536    if ( rgba.join() === "0,0,0,0" ) {
8537      jQuery.extend( rgba, colors.transparent );
8538    }
8539    return inst;
8540  }
8541
8542  // named colors
8543  return colors[ string ];
8544}
8545
8546color.fn = jQuery.extend( color.prototype, {
8547  parse: function( red, green, blue, alpha ) {
8548    if ( red === undefined ) {
8549      this._rgba = [ null, null, null, null ];
8550      return this;
8551    }
8552    if ( red.jquery || red.nodeType ) {
8553      red = jQuery( red ).css( green );
8554      green = undefined;
8555    }
8556
8557    var inst = this,
8558      type = jQuery.type( red ),
8559      rgba = this._rgba = [];
8560
8561    // more than 1 argument specified - assume ( red, green, blue, alpha )
8562    if ( green !== undefined ) {
8563      red = [ red, green, blue, alpha ];
8564      type = "array";
8565    }
8566
8567    if ( type === "string" ) {
8568      return this.parse( stringParse( red ) || colors._default );
8569    }
8570
8571    if ( type === "array" ) {
8572      each( spaces.rgba.props, function( key, prop ) {
8573        rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
8574      });
8575      return this;
8576    }
8577
8578    if ( type === "object" ) {
8579      if ( red instanceof color ) {
8580        each( spaces, function( spaceName, space ) {
8581          if ( red[ space.cache ] ) {
8582            inst[ space.cache ] = red[ space.cache ].slice();
8583          }
8584        });
8585      } else {
8586        each( spaces, function( spaceName, space ) {
8587          var cache = space.cache;
8588          each( space.props, function( key, prop ) {
8589
8590            // if the cache doesn't exist, and we know how to convert
8591            if ( !inst[ cache ] && space.to ) {
8592
8593              // if the value was null, we don't need to copy it
8594              // if the key was alpha, we don't need to copy it either
8595              if ( key === "alpha" || red[ key ] == null ) {
8596                return;
8597              }
8598              inst[ cache ] = space.to( inst._rgba );
8599            }
8600
8601            // this is the only case where we allow nulls for ALL properties.
8602            // call clamp with alwaysAllowEmpty
8603            inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
8604          });
8605
8606          // everything defined but alpha?
8607          if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
8608            // use the default of 1
8609            inst[ cache ][ 3 ] = 1;
8610            if ( space.from ) {
8611              inst._rgba = space.from( inst[ cache ] );
8612            }
8613          }
8614        });
8615      }
8616      return this;
8617    }
8618  },
8619  is: function( compare ) {
8620    var is = color( compare ),
8621      same = true,
8622      inst = this;
8623
8624    each( spaces, function( _, space ) {
8625      var localCache,
8626        isCache = is[ space.cache ];
8627      if (isCache) {
8628        localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
8629        each( space.props, function( _, prop ) {
8630          if ( isCache[ prop.idx ] != null ) {
8631            same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
8632            return same;
8633          }
8634        });
8635      }
8636      return same;
8637    });
8638    return same;
8639  },
8640  _space: function() {
8641    var used = [],
8642      inst = this;
8643    each( spaces, function( spaceName, space ) {
8644      if ( inst[ space.cache ] ) {
8645        used.push( spaceName );
8646      }
8647    });
8648    return used.pop();
8649  },
8650  transition: function( other, distance ) {
8651    var end = color( other ),
8652      spaceName = end._space(),
8653      space = spaces[ spaceName ],
8654      startColor = this.alpha() === 0 ? color( "transparent" ) : this,
8655      start = startColor[ space.cache ] || space.to( startColor._rgba ),
8656      result = start.slice();
8657
8658    end = end[ space.cache ];
8659    each( space.props, function( key, prop ) {
8660      var index = prop.idx,
8661        startValue = start[ index ],
8662        endValue = end[ index ],
8663        type = propTypes[ prop.type ] || {};
8664
8665      // if null, don't override start value
8666      if ( endValue === null ) {
8667        return;
8668      }
8669      // if null - use end
8670      if ( startValue === null ) {
8671        result[ index ] = endValue;
8672      } else {
8673        if ( type.mod ) {
8674          if ( endValue - startValue > type.mod / 2 ) {
8675            startValue += type.mod;
8676          } else if ( startValue - endValue > type.mod / 2 ) {
8677            startValue -= type.mod;
8678          }
8679        }
8680        result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
8681      }
8682    });
8683    return this[ spaceName ]( result );
8684  },
8685  blend: function( opaque ) {
8686    // if we are already opaque - return ourself
8687    if ( this._rgba[ 3 ] === 1 ) {
8688      return this;
8689    }
8690
8691    var rgb = this._rgba.slice(),
8692      a = rgb.pop(),
8693      blend = color( opaque )._rgba;
8694
8695    return color( jQuery.map( rgb, function( v, i ) {
8696      return ( 1 - a ) * blend[ i ] + a * v;
8697    }));
8698  },
8699  toRgbaString: function() {
8700    var prefix = "rgba(",
8701      rgba = jQuery.map( this._rgba, function( v, i ) {
8702        return v == null ? ( i > 2 ? 1 : 0 ) : v;
8703      });
8704
8705    if ( rgba[ 3 ] === 1 ) {
8706      rgba.pop();
8707      prefix = "rgb(";
8708    }
8709
8710    return prefix + rgba.join() + ")";
8711  },
8712  toHslaString: function() {
8713    var prefix = "hsla(",
8714      hsla = jQuery.map( this.hsla(), function( v, i ) {
8715        if ( v == null ) {
8716          v = i > 2 ? 1 : 0;
8717        }
8718
8719        // catch 1 and 2
8720        if ( i && i < 3 ) {
8721          v = Math.round( v * 100 ) + "%";
8722        }
8723        return v;
8724      });
8725
8726    if ( hsla[ 3 ] === 1 ) {
8727      hsla.pop();
8728      prefix = "hsl(";
8729    }
8730    return prefix + hsla.join() + ")";
8731  },
8732  toHexString: function( includeAlpha ) {
8733    var rgba = this._rgba.slice(),
8734      alpha = rgba.pop();
8735
8736    if ( includeAlpha ) {
8737      rgba.push( ~~( alpha * 255 ) );
8738    }
8739
8740    return "#" + jQuery.map( rgba, function( v ) {
8741
8742      // default to 0 when nulls exist
8743      v = ( v || 0 ).toString( 16 );
8744      return v.length === 1 ? "0" + v : v;
8745    }).join("");
8746  },
8747  toString: function() {
8748    return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
8749  }
8750});
8751color.fn.parse.prototype = color.fn;
8752
8753// hsla conversions adapted from:
8754// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
8755
8756function hue2rgb( p, q, h ) {
8757  h = ( h + 1 ) % 1;
8758  if ( h * 6 < 1 ) {
8759    return p + (q - p) * h * 6;
8760  }
8761  if ( h * 2 < 1) {
8762    return q;
8763  }
8764  if ( h * 3 < 2 ) {
8765    return p + (q - p) * ((2/3) - h) * 6;
8766  }
8767  return p;
8768}
8769
8770spaces.hsla.to = function ( rgba ) {
8771  if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
8772    return [ null, null, null, rgba[ 3 ] ];
8773  }
8774  var r = rgba[ 0 ] / 255,
8775    g = rgba[ 1 ] / 255,
8776    b = rgba[ 2 ] / 255,
8777    a = rgba[ 3 ],
8778    max = Math.max( r, g, b ),
8779    min = Math.min( r, g, b ),
8780    diff = max - min,
8781    add = max + min,
8782    l = add * 0.5,
8783    h, s;
8784
8785  if ( min === max ) {
8786    h = 0;
8787  } else if ( r === max ) {
8788    h = ( 60 * ( g - b ) / diff ) + 360;
8789  } else if ( g === max ) {
8790    h = ( 60 * ( b - r ) / diff ) + 120;
8791  } else {
8792    h = ( 60 * ( r - g ) / diff ) + 240;
8793  }
8794
8795  // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
8796  // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
8797  if ( diff === 0 ) {
8798    s = 0;
8799  } else if ( l <= 0.5 ) {
8800    s = diff / add;
8801  } else {
8802    s = diff / ( 2 - add );
8803  }
8804  return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
8805};
8806
8807spaces.hsla.from = function ( hsla ) {
8808  if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
8809    return [ null, null, null, hsla[ 3 ] ];
8810  }
8811  var h = hsla[ 0 ] / 360,
8812    s = hsla[ 1 ],
8813    l = hsla[ 2 ],
8814    a = hsla[ 3 ],
8815    q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
8816    p = 2 * l - q;
8817
8818  return [
8819    Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
8820    Math.round( hue2rgb( p, q, h ) * 255 ),
8821    Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
8822    a
8823  ];
8824};
8825
8826
8827each( spaces, function( spaceName, space ) {
8828  var props = space.props,
8829    cache = space.cache,
8830    to = space.to,
8831    from = space.from;
8832
8833  // makes rgba() and hsla()
8834  color.fn[ spaceName ] = function( value ) {
8835
8836    // generate a cache for this space if it doesn't exist
8837    if ( to && !this[ cache ] ) {
8838      this[ cache ] = to( this._rgba );
8839    }
8840    if ( value === undefined ) {
8841      return this[ cache ].slice();
8842    }
8843
8844    var ret,
8845      type = jQuery.type( value ),
8846      arr = ( type === "array" || type === "object" ) ? value : arguments,
8847      local = this[ cache ].slice();
8848
8849    each( props, function( key, prop ) {
8850      var val = arr[ type === "object" ? key : prop.idx ];
8851      if ( val == null ) {
8852        val = local[ prop.idx ];
8853      }
8854      local[ prop.idx ] = clamp( val, prop );
8855    });
8856
8857    if ( from ) {
8858      ret = color( from( local ) );
8859      ret[ cache ] = local;
8860      return ret;
8861    } else {
8862      return color( local );
8863    }
8864  };
8865
8866  // makes red() green() blue() alpha() hue() saturation() lightness()
8867  each( props, function( key, prop ) {
8868    // alpha is included in more than one space
8869    if ( color.fn[ key ] ) {
8870      return;
8871    }
8872    color.fn[ key ] = function( value ) {
8873      var vtype = jQuery.type( value ),
8874        fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
8875        local = this[ fn ](),
8876        cur = local[ prop.idx ],
8877        match;
8878
8879      if ( vtype === "undefined" ) {
8880        return cur;
8881      }
8882
8883      if ( vtype === "function" ) {
8884        value = value.call( this, cur );
8885        vtype = jQuery.type( value );
8886      }
8887      if ( value == null && prop.empty ) {
8888        return this;
8889      }
8890      if ( vtype === "string" ) {
8891        match = rplusequals.exec( value );
8892        if ( match ) {
8893          value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
8894        }
8895      }
8896      local[ prop.idx ] = value;
8897      return this[ fn ]( local );
8898    };
8899  });
8900});
8901
8902// add cssHook and .fx.step function for each named hook.
8903// accept a space separated string of properties
8904color.hook = function( hook ) {
8905  var hooks = hook.split( " " );
8906  each( hooks, function( i, hook ) {
8907    jQuery.cssHooks[ hook ] = {
8908      set: function( elem, value ) {
8909        var parsed, curElem,
8910          backgroundColor = "";
8911
8912        if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
8913          value = color( parsed || value );
8914          if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
8915            curElem = hook === "backgroundColor" ? elem.parentNode : elem;
8916            while (
8917              (backgroundColor === "" || backgroundColor === "transparent") &&
8918              curElem && curElem.style
8919            ) {
8920              try {
8921                backgroundColor = jQuery.css( curElem, "backgroundColor" );
8922                curElem = curElem.parentNode;
8923              } catch ( e ) {
8924              }
8925            }
8926
8927            value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
8928              backgroundColor :
8929              "_default" );
8930          }
8931
8932          value = value.toRgbaString();
8933        }
8934        try {
8935          elem.style[ hook ] = value;
8936        } catch( e ) {
8937          // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
8938        }
8939      }
8940    };
8941    jQuery.fx.step[ hook ] = function( fx ) {
8942      if ( !fx.colorInit ) {
8943        fx.start = color( fx.elem, hook );
8944        fx.end = color( fx.end );
8945        fx.colorInit = true;
8946      }
8947      jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
8948    };
8949  });
8950
8951};
8952
8953color.hook( stepHooks );
8954
8955jQuery.cssHooks.borderColor = {
8956  expand: function( value ) {
8957    var expanded = {};
8958
8959    each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
8960      expanded[ "border" + part + "Color" ] = value;
8961    });
8962    return expanded;
8963  }
8964};
8965
8966// Basic color names only.
8967// Usage of any of the other color names requires adding yourself or including
8968// jquery.color.svg-names.js.
8969colors = jQuery.Color.names = {
8970  // 4.1. Basic color keywords
8971  aqua: "#00ffff",
8972  black: "#000000",
8973  blue: "#0000ff",
8974  fuchsia: "#ff00ff",
8975  gray: "#808080",
8976  green: "#008000",
8977  lime: "#00ff00",
8978  maroon: "#800000",
8979  navy: "#000080",
8980  olive: "#808000",
8981  purple: "#800080",
8982  red: "#ff0000",
8983  silver: "#c0c0c0",
8984  teal: "#008080",
8985  white: "#ffffff",
8986  yellow: "#ffff00",
8987
8988  // 4.2.3. "transparent" color keyword
8989  transparent: [ null, null, null, 0 ],
8990
8991  _default: "#ffffff"
8992};
8993
8994})( _4ORMAT.$ );
8995
8996
8997/******************************************************************************/
8998/****************************** CLASS ANIMATIONS ******************************/
8999/******************************************************************************/
9000(function() {
9001
9002var classAnimationActions = [ "add", "remove", "toggle" ],
9003  shorthandStyles = {
9004    border: 1,
9005    borderBottom: 1,
9006    borderColor: 1,
9007    borderLeft: 1,
9008    borderRight: 1,
9009    borderTop: 1,
9010    borderWidth: 1,
9011    margin: 1,
9012    padding: 1
9013  };
9014
9015$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
9016  $.fx.step[ prop ] = function( fx ) {
9017    if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
9018      jQuery.style( fx.elem, prop, fx.end );
9019      fx.setAttr = true;
9020    }
9021  };
9022});
9023
9024function getElementStyles( elem ) {
9025  var key, len,
9026    style = elem.ownerDocument.defaultView ?
9027      elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
9028      elem.currentStyle,
9029    styles = {};
9030
9031  if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
9032    len = style.length;
9033    while ( len-- ) {
9034      key = style[ len ];
9035      if ( typeof style[ key ] === "string" ) {
9036        styles[ $.camelCase( key ) ] = style[ key ];
9037      }
9038    }
9039  // support: Opera, IE <9
9040  } else {
9041    for ( key in style ) {
9042      if ( typeof style[ key ] === "string" ) {
9043        styles[ key ] = style[ key ];
9044      }
9045    }
9046  }
9047
9048  return styles;
9049}
9050
9051
9052function styleDifference( oldStyle, newStyle ) {
9053  var diff = {},
9054    name, value;
9055
9056  for ( name in newStyle ) {
9057    value = newStyle[ name ];
9058    if ( oldStyle[ name ] !== value ) {
9059      if ( !shorthandStyles[ name ] ) {
9060        if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
9061          diff[ name ] = value;
9062        }
9063      }
9064    }
9065  }
9066
9067  return diff;
9068}
9069
9070// support: jQuery <1.8
9071if ( !$.fn.addBack ) {
9072  $.fn.addBack = function( selector ) {
9073    return this.add( selector == null ?
9074      this.prevObject : this.prevObject.filter( selector )
9075    );
9076  };
9077}
9078
9079$.effects.animateClass = function( value, duration, easing, callback ) {
9080  var o = $.speed( duration, easing, callback );
9081
9082  return this.queue( function() {
9083    var animated = $( this ),
9084      baseClass = animated.attr( "class" ) || "",
9085      applyClassChange,
9086      allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
9087
9088    // map the animated objects to store the original styles.
9089    allAnimations = allAnimations.map(function() {
9090      var el = $( this );
9091      return {
9092        el: el,
9093        start: getElementStyles( this )
9094      };
9095    });
9096
9097    // apply class change
9098    applyClassChange = function() {
9099      $.each( classAnimationActions, function(i, action) {
9100        if ( value[ action ] ) {
9101          animated[ action + "Class" ]( value[ action ] );
9102        }
9103      });
9104    };
9105    applyClassChange();
9106
9107    // map all animated objects again - calculate new styles and diff
9108    allAnimations = allAnimations.map(function() {
9109      this.end = getElementStyles( this.el[ 0 ] );
9110      this.diff = styleDifference( this.start, this.end );
9111      return this;
9112    });
9113
9114    // apply original class
9115    animated.attr( "class", baseClass );
9116
9117    // map all animated objects again - this time collecting a promise
9118    allAnimations = allAnimations.map(function() {
9119      var styleInfo = this,
9120        dfd = $.Deferred(),
9121        opts = $.extend({}, o, {
9122          queue: false,
9123          complete: function() {
9124            dfd.resolve( styleInfo );
9125          }
9126        });
9127
9128      this.el.animate( this.diff, opts );
9129      return dfd.promise();
9130    });
9131
9132    // once all animations have completed:
9133    $.when.apply( $, allAnimations.get() ).done(function() {
9134
9135      // set the final class
9136      applyClassChange();
9137
9138      // for each animated element,
9139      // clear all css properties that were animated
9140      $.each( arguments, function() {
9141        var el = this.el;
9142        $.each( this.diff, function(key) {
9143          el.css( key, "" );
9144        });
9145      });
9146
9147      // this is guarnteed to be there if you use jQuery.speed()
9148      // it also handles dequeuing the next anim...
9149      o.complete.call( animated[ 0 ] );
9150    });
9151  });
9152};
9153
9154$.fn.extend({
9155  addClass: (function( orig ) {
9156    return function( classNames, speed, easing, callback ) {
9157      return speed ?
9158        $.effects.animateClass.call( this,
9159          { add: classNames }, speed, easing, callback ) :
9160        orig.apply( this, arguments );
9161    };
9162  })( $.fn.addClass ),
9163
9164  removeClass: (function( orig ) {
9165    return function( classNames, speed, easing, callback ) {
9166      return arguments.length > 1 ?
9167        $.effects.animateClass.call( this,
9168          { remove: classNames }, speed, easing, callback ) :
9169        orig.apply( this, arguments );
9170    };
9171  })( $.fn.removeClass ),
9172
9173  toggleClass: (function( orig ) {
9174    return function( classNames, force, speed, easing, callback ) {
9175      if ( typeof force === "boolean" || force === undefined ) {
9176        if ( !speed ) {
9177          // without speed parameter
9178          return orig.apply( this, arguments );
9179        } else {
9180          return $.effects.animateClass.call( this,
9181            (force ? { add: classNames } : { remove: classNames }),
9182            speed, easing, callback );
9183        }
9184      } else {
9185        // without force parameter
9186        return $.effects.animateClass.call( this,
9187          { toggle: classNames }, force, speed, easing );
9188      }
9189    };
9190  })( $.fn.toggleClass ),
9191
9192  switchClass: function( remove, add, speed, easing, callback) {
9193    return $.effects.animateClass.call( this, {
9194      add: add,
9195      remove: remove
9196    }, speed, easing, callback );
9197  }
9198});
9199
9200})();
9201
9202/******************************************************************************/
9203/*********************************** EFFECTS **********************************/
9204/******************************************************************************/
9205
9206(function() {
9207
9208$.extend( $.effects, {
9209  version: "1.10.4",
9210
9211  // Saves a set of properties in a data storage
9212  save: function( element, set ) {
9213    for( var i=0; i < set.length; i++ ) {
9214      if ( set[ i ] !== null ) {
9215        element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
9216      }
9217    }
9218  },
9219
9220  // Restores a set of previously saved properties from a data storage
9221  restore: function( element, set ) {
9222    var val, i;
9223    for( i=0; i < set.length; i++ ) {
9224      if ( set[ i ] !== null ) {
9225        val = element.data( dataSpace + set[ i ] );
9226        // support: jQuery 1.6.2
9227        // http://bugs.jquery.com/ticket/9917
9228        // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
9229        // We can't differentiate between "" and 0 here, so we just assume
9230        // empty string since it's likely to be a more common value...
9231        if ( val === undefined ) {
9232          val = "";
9233        }
9234        element.css( set[ i ], val );
9235      }
9236    }
9237  },
9238
9239  setMode: function( el, mode ) {
9240    if (mode === "toggle") {
9241      mode = el.is( ":hidden" ) ? "show" : "hide";
9242    }
9243    return mode;
9244  },
9245
9246  // Translates a [top,left] array into a baseline value
9247  // this should be a little more flexible in the future to handle a string & hash
9248  getBaseline: function( origin, original ) {
9249    var y, x;
9250    switch ( origin[ 0 ] ) {
9251      case "top": y = 0; break;
9252      case "middle": y = 0.5; break;
9253      case "bottom": y = 1; break;
9254      default: y = origin[ 0 ] / original.height;
9255    }
9256    switch ( origin[ 1 ] ) {
9257      case "left": x = 0; break;
9258      case "center": x = 0.5; break;
9259      case "right": x = 1; break;
9260      default: x = origin[ 1 ] / original.width;
9261    }
9262    return {
9263      x: x,
9264      y: y
9265    };
9266  },
9267
9268  // Wraps the element around a wrapper that copies position properties
9269  createWrapper: function( element ) {
9270
9271    // if the element is already wrapped, return it
9272    if ( element.parent().is( ".ui-effects-wrapper" )) {
9273      return element.parent();
9274    }
9275
9276    // wrap the element
9277    var props = {
9278        width: element.outerWidth(true),
9279        height: element.outerHeight(true),
9280        "float": element.css( "float" )
9281      },
9282      wrapper = $( "<div></div>" )
9283        .addClass( "ui-effects-wrapper" )
9284        .css({
9285          fontSize: "100%",
9286          background: "transparent",
9287          border: "none",
9288          margin: 0,
9289          padding: 0
9290        }),
9291      // Store the size in case width/height are defined in % - Fixes #5245
9292      size = {
9293        width: element.width(),
9294        height: element.height()
9295      },
9296      active = document.activeElement;
9297
9298    // support: Firefox
9299    // Firefox incorrectly exposes anonymous content
9300    // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
9301    try {
9302      active.id;
9303    } catch( e ) {
9304      active = document.body;
9305    }
9306
9307    element.wrap( wrapper );
9308
9309    // Fixes #7595 - Elements lose focus when wrapped.
9310    if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
9311      $( active ).focus();
9312    }
9313
9314    wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
9315
9316    // transfer positioning properties to the wrapper
9317    if ( element.css( "position" ) === "static" ) {
9318      wrapper.css({ position: "relative" });
9319      element.css({ position: "relative" });
9320    } else {
9321      $.extend( props, {
9322        position: element.css( "position" ),
9323        zIndex: element.css( "z-index" )
9324      });
9325      $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
9326        props[ pos ] = element.css( pos );
9327        if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
9328          props[ pos ] = "auto";
9329        }
9330      });
9331      element.css({
9332        position: "relative",
9333        top: 0,
9334        left: 0,
9335        right: "auto",
9336        bottom: "auto"
9337      });
9338    }
9339    element.css(size);
9340
9341    return wrapper.css( props ).show();
9342  },
9343
9344  removeWrapper: function( element ) {
9345    var active = document.activeElement;
9346
9347    if ( element.parent().is( ".ui-effects-wrapper" ) ) {
9348      element.parent().replaceWith( element );
9349
9350      // Fixes #7595 - Elements lose focus when wrapped.
9351      if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
9352        $( active ).focus();
9353      }
9354    }
9355
9356
9357    return element;
9358  },
9359
9360  setTransition: function( element, list, factor, value ) {
9361    value = value || {};
9362    $.each( list, function( i, x ) {
9363      var unit = element.cssUnit( x );
9364      if ( unit[ 0 ] > 0 ) {
9365        value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
9366      }
9367    });
9368    return value;
9369  }
9370});
9371
9372// return an effect options object for the given parameters:
9373function _normalizeArguments( effect, options, speed, callback ) {
9374
9375  // allow passing all options as the first parameter
9376  if ( $.isPlainObject( effect ) ) {
9377    options = effect;
9378    effect = effect.effect;
9379  }
9380
9381  // convert to an object
9382  effect = { effect: effect };
9383
9384  // catch (effect, null, ...)
9385  if ( options == null ) {
9386    options = {};
9387  }
9388
9389  // catch (effect, callback)
9390  if ( $.isFunction( options ) ) {
9391    callback = options;
9392    speed = null;
9393    options = {};
9394  }
9395
9396  // catch (effect, speed, ?)
9397  if ( typeof options === "number" || $.fx.speeds[ options ] ) {
9398    callback = speed;
9399    speed = options;
9400    options = {};
9401  }
9402
9403  // catch (effect, options, callback)
9404  if ( $.isFunction( speed ) ) {
9405    callback = speed;
9406    speed = null;
9407  }
9408
9409  // add options to effect
9410  if ( options ) {
9411    $.extend( effect, options );
9412  }
9413
9414  speed = speed || options.duration;
9415  effect.duration = $.fx.off ? 0 :
9416    typeof speed === "number" ? speed :
9417    speed in $.fx.speeds ? $.fx.speeds[ speed ] :
9418    $.fx.speeds._default;
9419
9420  effect.complete = callback || options.complete;
9421
9422  return effect;
9423}
9424
9425function standardAnimationOption( option ) {
9426  // Valid standard speeds (nothing, number, named speed)
9427  if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
9428    return true;
9429  }
9430
9431  // Invalid strings - treat as "normal" speed
9432  if ( typeof option === "string" && !$.effects.effect[ option ] ) {
9433    return true;
9434  }
9435
9436  // Complete callback
9437  if ( $.isFunction( option ) ) {
9438    return true;
9439  }
9440
9441  // Options hash (but not naming an effect)
9442  if ( typeof option === "object" && !option.effect ) {
9443    return true;
9444  }
9445
9446  // Didn't match any standard API
9447  return false;
9448}
9449
9450$.fn.extend({
9451  effect: function( /* effect, options, speed, callback */ ) {
9452    var args = _normalizeArguments.apply( this, arguments ),
9453      mode = args.mode,
9454      queue = args.queue,
9455      effectMethod = $.effects.effect[ args.effect ];
9456
9457    if ( $.fx.off || !effectMethod ) {
9458      // delegate to the original method (e.g., .show()) if possible
9459      if ( mode ) {
9460        return this[ mode ]( args.duration, args.complete );
9461      } else {
9462        return this.each( function() {
9463          if ( args.complete ) {
9464            args.complete.call( this );
9465          }
9466        });
9467      }
9468    }
9469
9470    function run( next ) {
9471      var elem = $( this ),
9472        complete = args.complete,
9473        mode = args.mode;
9474
9475      function done() {
9476        if ( $.isFunction( complete ) ) {
9477          complete.call( elem[0] );
9478        }
9479        if ( $.isFunction( next ) ) {
9480          next();
9481        }
9482      }
9483
9484      // If the element already has the correct final state, delegate to
9485      // the core methods so the internal tracking of "olddisplay" works.
9486      if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
9487        elem[ mode ]();
9488        done();
9489      } else {
9490        effectMethod.call( elem[0], args, done );
9491      }
9492    }
9493
9494    return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
9495  },
9496
9497  show: (function( orig ) {
9498    return function( option ) {
9499      if ( standardAnimationOption( option ) ) {
9500        return orig.apply( this, arguments );
9501      } else {
9502        var args = _normalizeArguments.apply( this, arguments );
9503        args.mode = "show";
9504        return this.effect.call( this, args );
9505      }
9506    };
9507  })( $.fn.show ),
9508
9509  hide: (function( orig ) {
9510    return function( option ) {
9511      if ( standardAnimationOption( option ) ) {
9512        return orig.apply( this, arguments );
9513      } else {
9514        var args = _normalizeArguments.apply( this, arguments );
9515        args.mode = "hide";
9516        return this.effect.call( this, args );
9517      }
9518    };
9519  })( $.fn.hide ),
9520
9521  toggle: (function( orig ) {
9522    return function( option ) {
9523      if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
9524        return orig.apply( this, arguments );
9525      } else {
9526        var args = _normalizeArguments.apply( this, arguments );
9527        args.mode = "toggle";
9528        return this.effect.call( this, args );
9529      }
9530    };
9531  })( $.fn.toggle ),
9532
9533  // helper functions
9534  cssUnit: function(key) {
9535    var style = this.css( key ),
9536      val = [];
9537
9538    $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
9539      if ( style.indexOf( unit ) > 0 ) {
9540        val = [ parseFloat( style ), unit ];
9541      }
9542    });
9543    return val;
9544  }
9545});
9546
9547})();
9548
9549/******************************************************************************/
9550/*********************************** EASING ***********************************/
9551/******************************************************************************/
9552
9553(function() {
9554
9555// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
9556
9557var baseEasings = {};
9558
9559$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
9560  baseEasings[ name ] = function( p ) {
9561    return Math.pow( p, i + 2 );
9562  };
9563});
9564
9565$.extend( baseEasings, {
9566  Sine: function ( p ) {
9567    return 1 - Math.cos( p * Math.PI / 2 );
9568  },
9569  Circ: function ( p ) {
9570    return 1 - Math.sqrt( 1 - p * p );
9571  },
9572  Elastic: function( p ) {
9573    return p === 0 || p === 1 ? p :
9574      -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
9575  },
9576  Back: function( p ) {
9577    return p * p * ( 3 * p - 2 );
9578  },
9579  Bounce: function ( p ) {
9580    var pow2,
9581      bounce = 4;
9582
9583    while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
9584    return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
9585  }
9586});
9587
9588$.each( baseEasings, function( name, easeIn ) {
9589  $.easing[ "easeIn" + name ] = easeIn;
9590  $.easing[ "easeOut" + name ] = function( p ) {
9591    return 1 - easeIn( 1 - p );
9592  };
9593  $.easing[ "easeInOut" + name ] = function( p ) {
9594    return p < 0.5 ?
9595      easeIn( p * 2 ) / 2 :
9596      1 - easeIn( p * -2 + 2 ) / 2;
9597  };
9598});
9599
9600})();
9601
9602})( _4ORMAT.$ );
9603(function( $, undefined ) {
9604
9605var rvertical = /up|down|vertical/,
9606  rpositivemotion = /up|left|vertical|horizontal/;
9607
9608$.effects.effect.blind = function( o, done ) {
9609  // Create element
9610  var el = $( this ),
9611    props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
9612    mode = $.effects.setMode( el, o.mode || "hide" ),
9613    direction = o.direction || "up",
9614    vertical = rvertical.test( direction ),
9615    ref = vertical ? "height" : "width",
9616    ref2 = vertical ? "top" : "left",
9617    motion = rpositivemotion.test( direction ),
9618    animation = {},
9619    show = mode === "show",
9620    wrapper, distance, margin;
9621
9622  // if already wrapped, the wrapper's properties are my property. #6245
9623  if ( el.parent().is( ".ui-effects-wrapper" ) ) {
9624    $.effects.save( el.parent(), props );
9625  } else {
9626    $.effects.save( el, props );
9627  }
9628  el.show();
9629  wrapper = $.effects.createWrapper( el ).css({
9630    overflow: "hidden"
9631  });
9632
9633  distance = wrapper[ ref ]();
9634  margin = parseFloat( wrapper.css( ref2 ) ) || 0;
9635
9636  animation[ ref ] = show ? distance : 0;
9637  if ( !motion ) {
9638    el
9639      .css( vertical ? "bottom" : "right", 0 )
9640      .css( vertical ? "top" : "left", "auto" )
9641      .css({ position: "absolute" });
9642
9643    animation[ ref2 ] = show ? margin : distance + margin;
9644  }
9645
9646  // start at 0 if we are showing
9647  if ( show ) {
9648    wrapper.css( ref, 0 );
9649    if ( ! motion ) {
9650      wrapper.css( ref2, margin + distance );
9651    }
9652  }
9653
9654  // Animate
9655  wrapper.animate( animation, {
9656    duration: o.duration,
9657    easing: o.easing,
9658    queue: false,
9659    complete: function() {
9660      if ( mode === "hide" ) {
9661        el.hide();
9662      }
9663      $.effects.restore( el, props );
9664      $.effects.removeWrapper( el );
9665      done();
9666    }
9667  });
9668
9669};
9670
9671})( _4ORMAT.$ );
9672(function( $, undefined ) {
9673
9674$.effects.effect.bounce = function( o, done ) {
9675  var el = $( this ),
9676    props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
9677
9678    // defaults:
9679    mode = $.effects.setMode( el, o.mode || "effect" ),
9680    hide = mode === "hide",
9681    show = mode === "show",
9682    direction = o.direction || "up",
9683    distance = o.distance,
9684    times = o.times || 5,
9685
9686    // number of internal animations
9687    anims = times * 2 + ( show || hide ? 1 : 0 ),
9688    speed = o.duration / anims,
9689    easing = o.easing,
9690
9691    // utility:
9692    ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
9693    motion = ( direction === "up" || direction === "left" ),
9694    i,
9695    upAnim,
9696    downAnim,
9697
9698    // we will need to re-assemble the queue to stack our animations in place
9699    queue = el.queue(),
9700    queuelen = queue.length;
9701
9702  // Avoid touching opacity to prevent clearType and PNG issues in IE
9703  if ( show || hide ) {
9704    props.push( "opacity" );
9705  }
9706
9707  $.effects.save( el, props );
9708  el.show();
9709  $.effects.createWrapper( el ); // Create Wrapper
9710
9711  // default distance for the BIGGEST bounce is the outer Distance / 3
9712  if ( !distance ) {
9713    distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
9714  }
9715
9716  if ( show ) {
9717    downAnim = { opacity: 1 };
9718    downAnim[ ref ] = 0;
9719
9720    // if we are showing, force opacity 0 and set the initial position
9721    // then do the "first" animation
9722    el.css( "opacity", 0 )
9723      .css( ref, motion ? -distance * 2 : distance * 2 )
9724      .animate( downAnim, speed, easing );
9725  }
9726
9727  // start at the smallest distance if we are hiding
9728  if ( hide ) {
9729    distance = distance / Math.pow( 2, times - 1 );
9730  }
9731
9732  downAnim = {};
9733  downAnim[ ref ] = 0;
9734  // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
9735  for ( i = 0; i < times; i++ ) {
9736    upAnim = {};
9737    upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
9738
9739    el.animate( upAnim, speed, easing )
9740      .animate( downAnim, speed, easing );
9741
9742    distance = hide ? distance * 2 : distance / 2;
9743  }
9744
9745  // Last Bounce when Hiding
9746  if ( hide ) {
9747    upAnim = { opacity: 0 };
9748    upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
9749
9750    el.animate( upAnim, speed, easing );
9751  }
9752
9753  el.queue(function() {
9754    if ( hide ) {
9755      el.hide();
9756    }
9757    $.effects.restore( el, props );
9758    $.effects.removeWrapper( el );
9759    done();
9760  });
9761
9762  // inject all the animations we just queued to be first in line (after "inprogress")
9763  if ( queuelen > 1) {
9764    queue.splice.apply( queue,
9765      [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
9766  }
9767  el.dequeue();
9768
9769};
9770
9771})( _4ORMAT.$ );
9772(function( $, undefined ) {
9773
9774$.effects.effect.clip = function( o, done ) {
9775  // Create element
9776  var el = $( this ),
9777    props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
9778    mode = $.effects.setMode( el, o.mode || "hide" ),
9779    show = mode === "show",
9780    direction = o.direction || "vertical",
9781    vert = direction === "vertical",
9782    size = vert ? "height" : "width",
9783    position = vert ? "top" : "left",
9784    animation = {},
9785    wrapper, animate, distance;
9786
9787  // Save & Show
9788  $.effects.save( el, props );
9789  el.show();
9790
9791  // Create Wrapper
9792  wrapper = $.effects.createWrapper( el ).css({
9793    overflow: "hidden"
9794  });
9795  animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
9796  distance = animate[ size ]();
9797
9798  // Shift
9799  if ( show ) {
9800    animate.css( size, 0 );
9801    animate.css( position, distance / 2 );
9802  }
9803
9804  // Create Animation Object:
9805  animation[ size ] = show ? distance : 0;
9806  animation[ position ] = show ? 0 : distance / 2;
9807
9808  // Animate
9809  animate.animate( animation, {
9810    queue: false,
9811    duration: o.duration,
9812    easing: o.easing,
9813    complete: function() {
9814      if ( !show ) {
9815        el.hide();
9816      }
9817      $.effects.restore( el, props );
9818      $.effects.removeWrapper( el );
9819      done();
9820    }
9821  });
9822
9823};
9824
9825})( _4ORMAT.$ );
9826(function( $, undefined ) {
9827
9828$.effects.effect.drop = function( o, done ) {
9829
9830  var el = $( this ),
9831    props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
9832    mode = $.effects.setMode( el, o.mode || "hide" ),
9833    show = mode === "show",
9834    direction = o.direction || "left",
9835    ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
9836    motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
9837    animation = {
9838      opacity: show ? 1 : 0
9839    },
9840    distance;
9841
9842  // Adjust
9843  $.effects.save( el, props );
9844  el.show();
9845  $.effects.createWrapper( el );
9846
9847  distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
9848
9849  if ( show ) {
9850    el
9851      .css( "opacity", 0 )
9852      .css( ref, motion === "pos" ? -distance : distance );
9853  }
9854
9855  // Animation
9856  animation[ ref ] = ( show ?
9857    ( motion === "pos" ? "+=" : "-=" ) :
9858    ( motion === "pos" ? "-=" : "+=" ) ) +
9859    distance;
9860
9861  // Animate
9862  el.animate( animation, {
9863    queue: false,
9864    duration: o.duration,
9865    easing: o.easing,
9866    complete: function() {
9867      if ( mode === "hide" ) {
9868        el.hide();
9869      }
9870      $.effects.restore( el, props );
9871      $.effects.removeWrapper( el );
9872      done();
9873    }
9874  });
9875};
9876
9877})( _4ORMAT.$ );
9878(function( $, undefined ) {
9879
9880$.effects.effect.explode = function( o, done ) {
9881
9882  var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
9883    cells = rows,
9884    el = $( this ),
9885    mode = $.effects.setMode( el, o.mode || "hide" ),
9886    show = mode === "show",
9887
9888    // show and then visibility:hidden the element before calculating offset
9889    offset = el.show().css( "visibility", "hidden" ).offset(),
9890
9891    // width and height of a piece
9892    width = Math.ceil( el.outerWidth() / cells ),
9893    height = Math.ceil( el.outerHeight() / rows ),
9894    pieces = [],
9895
9896    // loop
9897    i, j, left, top, mx, my;
9898
9899  // children animate complete:
9900  function childComplete() {
9901    pieces.push( this );
9902    if ( pieces.length === rows * cells ) {
9903      animComplete();
9904    }
9905  }
9906
9907  // clone the element for each row and cell.
9908  for( i = 0; i < rows ; i++ ) { // ===>
9909    top = offset.top + i * height;
9910    my = i - ( rows - 1 ) / 2 ;
9911
9912    for( j = 0; j < cells ; j++ ) { // |||
9913      left = offset.left + j * width;
9914      mx = j - ( cells - 1 ) / 2 ;
9915
9916      // Create a clone of the now hidden main element that will be absolute positioned
9917      // within a wrapper div off the -left and -top equal to size of our pieces
9918      el
9919        .clone()
9920        .appendTo( "body" )
9921        .wrap( "<div></div>" )
9922        .css({
9923          position: "absolute",
9924          visibility: "visible",
9925          left: -j * width,
9926          top: -i * height
9927        })
9928
9929      // select the wrapper - make it overflow: hidden and absolute positioned based on
9930      // where the original was located +left and +top equal to the size of pieces
9931        .parent()
9932        .addClass( "ui-effects-explode" )
9933        .css({
9934          position: "absolute",
9935          overflow: "hidden",
9936          width: width,
9937          height: height,
9938          left: left + ( show ? mx * width : 0 ),
9939          top: top + ( show ? my * height : 0 ),
9940          opacity: show ? 0 : 1
9941        }).animate({
9942          left: left + ( show ? 0 : mx * width ),
9943          top: top + ( show ? 0 : my * height ),
9944          opacity: show ? 1 : 0
9945        }, o.duration || 500, o.easing, childComplete );
9946    }
9947  }
9948
9949  function animComplete() {
9950    el.css({
9951      visibility: "visible"
9952    });
9953    $( pieces ).remove();
9954    if ( !show ) {
9955      el.hide();
9956    }
9957    done();
9958  }
9959};
9960
9961})( _4ORMAT.$ );
9962(function( $, undefined ) {
9963
9964$.effects.effect.fade = function( o, done ) {
9965  var el = $( this ),
9966    mode = $.effects.setMode( el, o.mode || "toggle" );
9967
9968  el.animate({
9969    opacity: mode
9970  }, {
9971    queue: false,
9972    duration: o.duration,
9973    easing: o.easing,
9974    complete: done
9975  });
9976};
9977
9978})( _4ORMAT.$ );
9979(function( $, undefined ) {
9980
9981$.effects.effect.fold = function( o, done ) {
9982
9983  // Create element
9984  var el = $( this ),
9985    props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
9986    mode = $.effects.setMode( el, o.mode || "hide" ),
9987    show = mode === "show",
9988    hide = mode === "hide",
9989    size = o.size || 15,
9990    percent = /([0-9]+)%/.exec( size ),
9991    horizFirst = !!o.horizFirst,
9992    widthFirst = show !== horizFirst,
9993    ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
9994    duration = o.duration / 2,
9995    wrapper, distance,
9996    animation1 = {},
9997    animation2 = {};
9998
9999  $.effects.save( el, props );
10000  el.show();
10001
10002  // Create Wrapper
10003  wrapper = $.effects.createWrapper( el ).css({
10004    overflow: "hidden"
10005  });
10006  distance = widthFirst ?
10007    [ wrapper.width(), wrapper.height() ] :
10008    [ wrapper.height(), wrapper.width() ];
10009
10010  if ( percent ) {
10011    size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
10012  }
10013  if ( show ) {
10014    wrapper.css( horizFirst ? {
10015      height: 0,
10016      width: size
10017    } : {
10018      height: size,
10019      width: 0
10020    });
10021  }
10022
10023  // Animation
10024  animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
10025  animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
10026
10027  // Animate
10028  wrapper
10029    .animate( animation1, duration, o.easing )
10030    .animate( animation2, duration, o.easing, function() {
10031      if ( hide ) {
10032        el.hide();
10033      }
10034      $.effects.restore( el, props );
10035      $.effects.removeWrapper( el );
10036      done();
10037    });
10038
10039};
10040
10041})( _4ORMAT.$ );
10042(function( $, undefined ) {
10043
10044$.effects.effect.highlight = function( o, done ) {
10045  var elem = $( this ),
10046    props = [ "backgroundImage", "backgroundColor", "opacity" ],
10047    mode = $.effects.setMode( elem, o.mode || "show" ),
10048    animation = {
10049      backgroundColor: elem.css( "backgroundColor" )
10050    };
10051
10052  if (mode === "hide") {
10053    animation.opacity = 0;
10054  }
10055
10056  $.effects.save( elem, props );
10057
10058  elem
10059    .show()
10060    .css({
10061      backgroundImage: "none",
10062      backgroundColor: o.color || "#ffff99"
10063    })
10064    .animate( animation, {
10065      queue: false,
10066      duration: o.duration,
10067      easing: o.easing,
10068      complete: function() {
10069        if ( mode === "hide" ) {
10070          elem.hide();
10071        }
10072        $.effects.restore( elem, props );
10073        done();
10074      }
10075    });
10076};
10077
10078})( _4ORMAT.$ );
10079(function( $, undefined ) {
10080
10081$.effects.effect.pulsate = function( o, done ) {
10082  var elem = $( this ),
10083    mode = $.effects.setMode( elem, o.mode || "show" ),
10084    show = mode === "show",
10085    hide = mode === "hide",
10086    showhide = ( show || mode === "hide" ),
10087
10088    // showing or hiding leaves of the "last" animation
10089    anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
10090    duration = o.duration / anims,
10091    animateTo = 0,
10092    queue = elem.queue(),
10093    queuelen = queue.length,
10094    i;
10095
10096  if ( show || !elem.is(":visible")) {
10097    elem.css( "opacity", 0 ).show();
10098    animateTo = 1;
10099  }
10100
10101  // anims - 1 opacity "toggles"
10102  for ( i = 1; i < anims; i++ ) {
10103    elem.animate({
10104      opacity: animateTo
10105    }, duration, o.easing );
10106    animateTo = 1 - animateTo;
10107  }
10108
10109  elem.animate({
10110    opacity: animateTo
10111  }, duration, o.easing);
10112
10113  elem.queue(function() {
10114    if ( hide ) {
10115      elem.hide();
10116    }
10117    done();
10118  });
10119
10120  // We just queued up "anims" animations, we need to put them next in the queue
10121  if ( queuelen > 1 ) {
10122    queue.splice.apply( queue,
10123      [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10124  }
10125  elem.dequeue();
10126};
10127
10128})( _4ORMAT.$ );
10129(function( $, undefined ) {
10130
10131$.effects.effect.puff = function( o, done ) {
10132  var elem = $( this ),
10133    mode = $.effects.setMode( elem, o.mode || "hide" ),
10134    hide = mode === "hide",
10135    percent = parseInt( o.percent, 10 ) || 150,
10136    factor = percent / 100,
10137    original = {
10138      height: elem.height(),
10139      width: elem.width(),
10140      outerHeight: elem.outerHeight(),
10141      outerWidth: elem.outerWidth()
10142    };
10143
10144  $.extend( o, {
10145    effect: "scale",
10146    queue: false,
10147    fade: true,
10148    mode: mode,
10149    complete: done,
10150    percent: hide ? percent : 100,
10151    from: hide ?
10152      original :
10153      {
10154        height: original.height * factor,
10155        width: original.width * factor,
10156        outerHeight: original.outerHeight * factor,
10157        outerWidth: original.outerWidth * factor
10158      }
10159  });
10160
10161  elem.effect( o );
10162};
10163
10164$.effects.effect.scale = function( o, done ) {
10165
10166  // Create element
10167  var el = $( this ),
10168    options = $.extend( true, {}, o ),
10169    mode = $.effects.setMode( el, o.mode || "effect" ),
10170    percent = parseInt( o.percent, 10 ) ||
10171      ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
10172    direction = o.direction || "both",
10173    origin = o.origin,
10174    original = {
10175      height: el.height(),
10176      width: el.width(),
10177      outerHeight: el.outerHeight(),
10178      outerWidth: el.outerWidth()
10179    },
10180    factor = {
10181      y: direction !== "horizontal" ? (percent / 100) : 1,
10182      x: direction !== "vertical" ? (percent / 100) : 1
10183    };
10184
10185  // We are going to pass this effect to the size effect:
10186  options.effect = "size";
10187  options.queue = false;
10188  options.complete = done;
10189
10190  // Set default origin and restore for show/hide
10191  if ( mode !== "effect" ) {
10192    options.origin = origin || ["middle","center"];
10193    options.restore = true;
10194  }
10195
10196  options.from = o.from || ( mode === "show" ? {
10197    height: 0,
10198    width: 0,
10199    outerHeight: 0,
10200    outerWidth: 0
10201  } : original );
10202  options.to = {
10203    height: original.height * factor.y,
10204    width: original.width * factor.x,
10205    outerHeight: original.outerHeight * factor.y,
10206    outerWidth: original.outerWidth * factor.x
10207  };
10208
10209  // Fade option to support puff
10210  if ( options.fade ) {
10211    if ( mode === "show" ) {
10212      options.from.opacity = 0;
10213      options.to.opacity = 1;
10214    }
10215    if ( mode === "hide" ) {
10216      options.from.opacity = 1;
10217      options.to.opacity = 0;
10218    }
10219  }
10220
10221  // Animate
10222  el.effect( options );
10223
10224};
10225
10226$.effects.effect.size = function( o, done ) {
10227
10228  // Create element
10229  var original, baseline, factor,
10230    el = $( this ),
10231    props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
10232
10233    // Always restore
10234    props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
10235
10236    // Copy for children
10237    props2 = [ "width", "height", "overflow" ],
10238    cProps = [ "fontSize" ],
10239    vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
10240    hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
10241
10242    // Set options
10243    mode = $.effects.setMode( el, o.mode || "effect" ),
10244    restore = o.restore || mode !== "effect",
10245    scale = o.scale || "both",
10246    origin = o.origin || [ "middle", "center" ],
10247    position = el.css( "position" ),
10248    props = restore ? props0 : props1,
10249    zero = {
10250      height: 0,
10251      width: 0,
10252      outerHeight: 0,
10253      outerWidth: 0
10254    };
10255
10256  if ( mode === "show" ) {
10257    el.show();
10258  }
10259  original = {
10260    height: el.height(),
10261    width: el.width(),
10262    outerHeight: el.outerHeight(),
10263    outerWidth: el.outerWidth()
10264  };
10265
10266  if ( o.mode === "toggle" && mode === "show" ) {
10267    el.from = o.to || zero;
10268    el.to = o.from || original;
10269  } else {
10270    el.from = o.from || ( mode === "show" ? zero : original );
10271    el.to = o.to || ( mode === "hide" ? zero : original );
10272  }
10273
10274  // Set scaling factor
10275  factor = {
10276    from: {
10277      y: el.from.height / original.height,
10278      x: el.from.width / original.width
10279    },
10280    to: {
10281      y: el.to.height / original.height,
10282      x: el.to.width / original.width
10283    }
10284  };
10285
10286  // Scale the css box
10287  if ( scale === "box" || scale === "both" ) {
10288
10289    // Vertical props scaling
10290    if ( factor.from.y !== factor.to.y ) {
10291      props = props.concat( vProps );
10292      el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
10293      el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
10294    }
10295
10296    // Horizontal props scaling
10297    if ( factor.from.x !== factor.to.x ) {
10298      props = props.concat( hProps );
10299      el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
10300      el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
10301    }
10302  }
10303
10304  // Scale the content
10305  if ( scale === "content" || scale === "both" ) {
10306
10307    // Vertical props scaling
10308    if ( factor.from.y !== factor.to.y ) {
10309      props = props.concat( cProps ).concat( props2 );
10310      el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
10311      el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
10312    }
10313  }
10314
10315  $.effects.save( el, props );
10316  el.show();
10317  $.effects.createWrapper( el );
10318  el.css( "overflow", "hidden" ).css( el.from );
10319
10320  // Adjust
10321  if (origin) { // Calculate baseline shifts
10322    baseline = $.effects.getBaseline( origin, original );
10323    el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
10324    el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
10325    el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
10326    el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
10327  }
10328  el.css( el.from ); // set top & left
10329
10330  // Animate
10331  if ( scale === "content" || scale === "both" ) { // Scale the children
10332
10333    // Add margins/font-size
10334    vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
10335    hProps = hProps.concat([ "marginLeft", "marginRight" ]);
10336    props2 = props0.concat(vProps).concat(hProps);
10337
10338    el.find( "*[width]" ).each( function(){
10339      var child = $( this ),
10340        c_original = {
10341          height: child.height(),
10342          width: child.width(),
10343          outerHeight: child.outerHeight(),
10344          outerWidth: child.outerWidth()
10345        };
10346      if (restore) {
10347        $.effects.save(child, props2);
10348      }
10349
10350      child.from = {
10351        height: c_original.height * factor.from.y,
10352        width: c_original.width * factor.from.x,
10353        outerHeight: c_original.outerHeight * factor.from.y,
10354        outerWidth: c_original.outerWidth * factor.from.x
10355      };
10356      child.to = {
10357        height: c_original.height * factor.to.y,
10358        width: c_original.width * factor.to.x,
10359        outerHeight: c_original.height * factor.to.y,
10360        outerWidth: c_original.width * factor.to.x
10361      };
10362
10363      // Vertical props scaling
10364      if ( factor.from.y !== factor.to.y ) {
10365        child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
10366        child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
10367      }
10368
10369      // Horizontal props scaling
10370      if ( factor.from.x !== factor.to.x ) {
10371        child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
10372        child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
10373      }
10374
10375      // Animate children
10376      child.css( child.from );
10377      child.animate( child.to, o.duration, o.easing, function() {
10378
10379        // Restore children
10380        if ( restore ) {
10381          $.effects.restore( child, props2 );
10382        }
10383      });
10384    });
10385  }
10386
10387  // Animate
10388  el.animate( el.to, {
10389    queue: false,
10390    duration: o.duration,
10391    easing: o.easing,
10392    complete: function() {
10393      if ( el.to.opacity === 0 ) {
10394        el.css( "opacity", el.from.opacity );
10395      }
10396      if( mode === "hide" ) {
10397        el.hide();
10398      }
10399      $.effects.restore( el, props );
10400      if ( !restore ) {
10401
10402        // we need to calculate our new positioning based on the scaling
10403        if ( position === "static" ) {
10404          el.css({
10405            position: "relative",
10406            top: el.to.top,
10407            left: el.to.left
10408          });
10409        } else {
10410          $.each([ "top", "left" ], function( idx, pos ) {
10411            el.css( pos, function( _, str ) {
10412              var val = parseInt( str, 10 ),
10413                toRef = idx ? el.to.left : el.to.top;
10414
10415              // if original was "auto", recalculate the new value from wrapper
10416              if ( str === "auto" ) {
10417                return toRef + "px";
10418              }
10419
10420              return val + toRef + "px";
10421            });
10422          });
10423        }
10424      }
10425
10426      $.effects.removeWrapper( el );
10427      done();
10428    }
10429  });
10430
10431};
10432
10433})( _4ORMAT.$ );
10434(function( $, undefined ) {
10435
10436$.effects.effect.shake = function( o, done ) {
10437
10438  var el = $( this ),
10439    props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10440    mode = $.effects.setMode( el, o.mode || "effect" ),
10441    direction = o.direction || "left",
10442    distance = o.distance || 20,
10443    times = o.times || 3,
10444    anims = times * 2 + 1,
10445    speed = Math.round(o.duration/anims),
10446    ref = (direction === "up" || direction === "down") ? "top" : "left",
10447    positiveMotion = (direction === "up" || direction === "left"),
10448    animation = {},
10449    animation1 = {},
10450    animation2 = {},
10451    i,
10452
10453    // we will need to re-assemble the queue to stack our animations in place
10454    queue = el.queue(),
10455    queuelen = queue.length;
10456
10457  $.effects.save( el, props );
10458  el.show();
10459  $.effects.createWrapper( el );
10460
10461  // Animation
10462  animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
10463  animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
10464  animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
10465
10466  // Animate
10467  el.animate( animation, speed, o.easing );
10468
10469  // Shakes
10470  for ( i = 1; i < times; i++ ) {
10471    el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
10472  }
10473  el
10474    .animate( animation1, speed, o.easing )
10475    .animate( animation, speed / 2, o.easing )
10476    .queue(function() {
10477      if ( mode === "hide" ) {
10478        el.hide();
10479      }
10480      $.effects.restore( el, props );
10481      $.effects.removeWrapper( el );
10482      done();
10483    });
10484
10485  // inject all the animations we just queued to be first in line (after "inprogress")
10486  if ( queuelen > 1) {
10487    queue.splice.apply( queue,
10488      [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10489  }
10490  el.dequeue();
10491
10492};
10493
10494})( _4ORMAT.$ );
10495(function( $, undefined ) {
10496
10497$.effects.effect.slide = function( o, done ) {
10498
10499  // Create element
10500  var el = $( this ),
10501    props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
10502    mode = $.effects.setMode( el, o.mode || "show" ),
10503    show = mode === "show",
10504    direction = o.direction || "left",
10505    ref = (direction === "up" || direction === "down") ? "top" : "left",
10506    positiveMotion = (direction === "up" || direction === "left"),
10507    distance,
10508    animation = {};
10509
10510  // Adjust
10511  $.effects.save( el, props );
10512  el.show();
10513  distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
10514
10515  $.effects.createWrapper( el ).css({
10516    overflow: "hidden"
10517  });
10518
10519  if ( show ) {
10520    el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
10521  }
10522
10523  // Animation
10524  animation[ ref ] = ( show ?
10525    ( positiveMotion ? "+=" : "-=") :
10526    ( positiveMotion ? "-=" : "+=")) +
10527    distance;
10528
10529  // Animate
10530  el.animate( animation, {
10531    queue: false,
10532    duration: o.duration,
10533    easing: o.easing,
10534    complete: function() {
10535      if ( mode === "hide" ) {
10536        el.hide();
10537      }
10538      $.effects.restore( el, props );
10539      $.effects.removeWrapper( el );
10540      done();
10541    }
10542  });
10543};
10544
10545})( _4ORMAT.$ );
10546(function( $, undefined ) {
10547
10548$.effects.effect.transfer = function( o, done ) {
10549  var elem = $( this ),
10550    target = $( o.to ),
10551    targetFixed = target.css( "position" ) === "fixed",
10552    body = $("body"),
10553    fixTop = targetFixed ? body.scrollTop() : 0,
10554    fixLeft = targetFixed ? body.scrollLeft() : 0,
10555    endPosition = target.offset(),
10556    animation = {
10557      top: endPosition.top - fixTop ,
10558      left: endPosition.left - fixLeft ,
10559      height: target.innerHeight(),
10560      width: target.innerWidth()
10561    },
10562    startPosition = elem.offset(),
10563    transfer = $( "<div class='ui-effects-transfer'></div>" )
10564      .appendTo( document.body )
10565      .addClass( o.className )
10566      .css({
10567        top: startPosition.top - fixTop ,
10568        left: startPosition.left - fixLeft ,
10569        height: elem.innerHeight(),
10570        width: elem.innerWidth(),
10571        position: targetFixed ? "fixed" : "absolute"
10572      })
10573      .animate( animation, o.duration, o.easing, function() {
10574        transfer.remove();
10575        done();
10576      });
10577};
10578
10579})( _4ORMAT.$ );
10580(function( $, undefined ) {
10581
10582$.widget( "ui.menu", {
10583  version: "1.10.4",
10584  defaultElement: "<ul>",
10585  delay: 300,
10586  options: {
10587    icons: {
10588      submenu: "ui-icon-carat-1-e"
10589    },
10590    menus: "ul",
10591    position: {
10592      my: "left top",
10593      at: "right top"
10594    },
10595    role: "menu",
10596
10597    // callbacks
10598    blur: null,
10599    focus: null,
10600    select: null
10601  },
10602
10603  _create: function() {
10604    this.activeMenu = this.element;
10605    // flag used to prevent firing of the click handler
10606    // as the event bubbles up through nested menus
10607    this.mouseHandled = false;
10608    this.element
10609      .uniqueId()
10610      .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
10611      .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
10612      .attr({
10613        role: this.options.role,
10614        tabIndex: 0
10615      })
10616      // need to catch all clicks on disabled menu
10617      // not possible through _on
10618      .bind( "click" + this.eventNamespace, $.proxy(function( event ) {
10619        if ( this.options.disabled ) {
10620          event.preventDefault();
10621        }
10622      }, this ));
10623
10624    if ( this.options.disabled ) {
10625      this.element
10626        .addClass( "ui-state-disabled" )
10627        .attr( "aria-disabled", "true" );
10628    }
10629
10630    this._on({
10631      // Prevent focus from sticking to links inside menu after clicking
10632      // them (focus should always stay on UL during navigation).
10633      "mousedown .ui-menu-item > a": function( event ) {
10634        event.preventDefault();
10635      },
10636      "click .ui-state-disabled > a": function( event ) {
10637        event.preventDefault();
10638      },
10639      "click .ui-menu-item:has(a)": function( event ) {
10640        var target = $( event.target ).closest( ".ui-menu-item" );
10641        if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
10642          this.select( event );
10643
10644          // Only set the mouseHandled flag if the event will bubble, see #9469.
10645          if ( !event.isPropagationStopped() ) {
10646            this.mouseHandled = true;
10647          }
10648
10649          // Open submenu on click
10650          if ( target.has( ".ui-menu" ).length ) {
10651            this.expand( event );
10652          } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
10653
10654            // Redirect focus to the menu
10655            this.element.trigger( "focus", [ true ] );
10656
10657            // If the active item is on the top level, let it stay active.
10658            // Otherwise, blur the active item since it is no longer visible.
10659            if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
10660              clearTimeout( this.timer );
10661            }
10662          }
10663        }
10664      },
10665      "mouseenter .ui-menu-item": function( event ) {
10666        var target = $( event.currentTarget );
10667        // Remove ui-state-active class from siblings of the newly focused menu item
10668        // to avoid a jump caused by adjacent elements both having a class with a border
10669        target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
10670        this.focus( event, target );
10671      },
10672      mouseleave: "collapseAll",
10673      "mouseleave .ui-menu": "collapseAll",
10674      focus: function( event, keepActiveItem ) {
10675        // If there's already an active item, keep it active
10676        // If not, activate the first item
10677        var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
10678
10679        if ( !keepActiveItem ) {
10680          this.focus( event, item );
10681        }
10682      },
10683      blur: function( event ) {
10684        this._delay(function() {
10685          if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
10686            this.collapseAll( event );
10687          }
10688        });
10689      },
10690      keydown: "_keydown"
10691    });
10692
10693    this.refresh();
10694
vendor: 38,527 bytes, lines 10695-12019
10695    // Clicks outside of a menu collapse any open menus
10696    this._on( this.document, {
10697      click: function( event ) {
10698        if ( !$( event.target ).closest( ".ui-menu" ).length ) {
10699          this.collapseAll( event );
10700        }
10701
10702        // Reset the mouseHandled flag
10703        this.mouseHandled = false;
10704      }
10705    });
10706  },
10707
10708  _destroy: function() {
10709    // Destroy (sub)menus
10710    this.element
10711      .removeAttr( "aria-activedescendant" )
10712      .find( ".ui-menu" ).addBack()
10713        .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
10714        .removeAttr( "role" )
10715        .removeAttr( "tabIndex" )
10716        .removeAttr( "aria-labelledby" )
10717        .removeAttr( "aria-expanded" )
10718        .removeAttr( "aria-hidden" )
10719        .removeAttr( "aria-disabled" )
10720        .removeUniqueId()
10721        .show();
10722
10723    // Destroy menu items
10724    this.element.find( ".ui-menu-item" )
10725      .removeClass( "ui-menu-item" )
10726      .removeAttr( "role" )
10727      .removeAttr( "aria-disabled" )
10728      .children( "a" )
10729        .removeUniqueId()
10730        .removeClass( "ui-corner-all ui-state-hover" )
10731        .removeAttr( "tabIndex" )
10732        .removeAttr( "role" )
10733        .removeAttr( "aria-haspopup" )
10734        .children().each( function() {
10735          var elem = $( this );
10736          if ( elem.data( "ui-menu-submenu-carat" ) ) {
10737            elem.remove();
10738          }
10739        });
10740
10741    // Destroy menu dividers
10742    this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
10743  },
10744
10745  _keydown: function( event ) {
10746    var match, prev, character, skip, regex,
10747      preventDefault = true;
10748
10749    function escape( value ) {
10750      return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
10751    }
10752
10753    switch ( event.keyCode ) {
10754    case $.ui.keyCode.PAGE_UP:
10755      this.previousPage( event );
10756      break;
10757    case $.ui.keyCode.PAGE_DOWN:
10758      this.nextPage( event );
10759      break;
10760    case $.ui.keyCode.HOME:
10761      this._move( "first", "first", event );
10762      break;
10763    case $.ui.keyCode.END:
10764      this._move( "last", "last", event );
10765      break;
10766    case $.ui.keyCode.UP:
10767      this.previous( event );
10768      break;
10769    case $.ui.keyCode.DOWN:
10770      this.next( event );
10771      break;
10772    case $.ui.keyCode.LEFT:
10773      this.collapse( event );
10774      break;
10775    case $.ui.keyCode.RIGHT:
10776      if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
10777        this.expand( event );
10778      }
10779      break;
10780    case $.ui.keyCode.ENTER:
10781    case $.ui.keyCode.SPACE:
10782      this._activate( event );
10783      break;
10784    case $.ui.keyCode.ESCAPE:
10785      this.collapse( event );
10786      break;
10787    default:
10788      preventDefault = false;
10789      prev = this.previousFilter || "";
10790      character = String.fromCharCode( event.keyCode );
10791      skip = false;
10792
10793      clearTimeout( this.filterTimer );
10794
10795      if ( character === prev ) {
10796        skip = true;
10797      } else {
10798        character = prev + character;
10799      }
10800
10801      regex = new RegExp( "^" + escape( character ), "i" );
10802      match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
10803        return regex.test( $( this ).children( "a" ).text() );
10804      });
10805      match = skip && match.index( this.active.next() ) !== -1 ?
10806        this.active.nextAll( ".ui-menu-item" ) :
10807        match;
10808
10809      // If no matches on the current filter, reset to the last character pressed
10810      // to move down the menu to the first item that starts with that character
10811      if ( !match.length ) {
10812        character = String.fromCharCode( event.keyCode );
10813        regex = new RegExp( "^" + escape( character ), "i" );
10814        match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
10815          return regex.test( $( this ).children( "a" ).text() );
10816        });
10817      }
10818
10819      if ( match.length ) {
10820        this.focus( event, match );
10821        if ( match.length > 1 ) {
10822          this.previousFilter = character;
10823          this.filterTimer = this._delay(function() {
10824            delete this.previousFilter;
10825          }, 1000 );
10826        } else {
10827          delete this.previousFilter;
10828        }
10829      } else {
10830        delete this.previousFilter;
10831      }
10832    }
10833
10834    if ( preventDefault ) {
10835      event.preventDefault();
10836    }
10837  },
10838
10839  _activate: function( event ) {
10840    if ( !this.active.is( ".ui-state-disabled" ) ) {
10841      if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
10842        this.expand( event );
10843      } else {
10844        this.select( event );
10845      }
10846    }
10847  },
10848
10849  refresh: function() {
10850    var menus,
10851      icon = this.options.icons.submenu,
10852      submenus = this.element.find( this.options.menus );
10853
10854    this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
10855
10856    // Initialize nested menus
10857    submenus.filter( ":not(.ui-menu)" )
10858      .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
10859      .hide()
10860      .attr({
10861        role: this.options.role,
10862        "aria-hidden": "true",
10863        "aria-expanded": "false"
10864      })
10865      .each(function() {
10866        var menu = $( this ),
10867          item = menu.prev( "a" ),
10868          submenuCarat = $( "<span>" )
10869            .addClass( "ui-menu-icon ui-icon " + icon )
10870            .data( "ui-menu-submenu-carat", true );
10871
10872        item
10873          .attr( "aria-haspopup", "true" )
10874          .prepend( submenuCarat );
10875        menu.attr( "aria-labelledby", item.attr( "id" ) );
10876      });
10877
10878    menus = submenus.add( this.element );
10879
10880    // Don't refresh list items that are already adapted
10881    menus.children( ":not(.ui-menu-item):has(a)" )
10882      .addClass( "ui-menu-item" )
10883      .attr( "role", "presentation" )
10884      .children( "a" )
10885        .uniqueId()
10886        .addClass( "ui-corner-all" )
10887        .attr({
10888          tabIndex: -1,
10889          role: this._itemRole()
10890        });
10891
10892    // Initialize unlinked menu-items containing spaces and/or dashes only as dividers
10893    menus.children( ":not(.ui-menu-item)" ).each(function() {
10894      var item = $( this );
10895      // hyphen, em dash, en dash
10896      if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) {
10897        item.addClass( "ui-widget-content ui-menu-divider" );
10898      }
10899    });
10900
10901    // Add aria-disabled attribute to any disabled menu item
10902    menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
10903
10904    // If the active item has been removed, blur the menu
10905    if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
10906      this.blur();
10907    }
10908  },
10909
10910  _itemRole: function() {
10911    return {
10912      menu: "menuitem",
10913      listbox: "option"
10914    }[ this.options.role ];
10915  },
10916
10917  _setOption: function( key, value ) {
10918    if ( key === "icons" ) {
10919      this.element.find( ".ui-menu-icon" )
10920        .removeClass( this.options.icons.submenu )
10921        .addClass( value.submenu );
10922    }
10923    this._super( key, value );
10924  },
10925
10926  focus: function( event, item ) {
10927    var nested, focused;
10928    this.blur( event, event && event.type === "focus" );
10929
10930    this._scrollIntoView( item );
10931
10932    this.active = item.first();
10933    focused = this.active.children( "a" ).addClass( "ui-state-focus" );
10934    // Only update aria-activedescendant if there's a role
10935    // otherwise we assume focus is managed elsewhere
10936    if ( this.options.role ) {
10937      this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
10938    }
10939
10940    // Highlight active parent menu item, if any
10941    this.active
10942      .parent()
10943      .closest( ".ui-menu-item" )
10944      .children( "a:first" )
10945      .addClass( "ui-state-active" );
10946
10947    if ( event && event.type === "keydown" ) {
10948      this._close();
10949    } else {
10950      this.timer = this._delay(function() {
10951        this._close();
10952      }, this.delay );
10953    }
10954
10955    nested = item.children( ".ui-menu" );
10956    if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
10957      this._startOpening(nested);
10958    }
10959    this.activeMenu = item.parent();
10960
10961    this._trigger( "focus", event, { item: item } );
10962  },
10963
10964  _scrollIntoView: function( item ) {
10965    var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
10966    if ( this._hasScroll() ) {
10967      borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
10968      paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
10969      offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
10970      scroll = this.activeMenu.scrollTop();
10971      elementHeight = this.activeMenu.height();
10972      itemHeight = item.height();
10973
10974      if ( offset < 0 ) {
10975        this.activeMenu.scrollTop( scroll + offset );
10976      } else if ( offset + itemHeight > elementHeight ) {
10977        this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
10978      }
10979    }
10980  },
10981
10982  blur: function( event, fromFocus ) {
10983    if ( !fromFocus ) {
10984      clearTimeout( this.timer );
10985    }
10986
10987    if ( !this.active ) {
10988      return;
10989    }
10990
10991    this.active.children( "a" ).removeClass( "ui-state-focus" );
10992    this.active = null;
10993
10994    this._trigger( "blur", event, { item: this.active } );
10995  },
10996
10997  _startOpening: function( submenu ) {
10998    clearTimeout( this.timer );
10999
11000    // Don't open if already open fixes a Firefox bug that caused a .5 pixel
11001    // shift in the submenu position when mousing over the carat icon
11002    if ( submenu.attr( "aria-hidden" ) !== "true" ) {
11003      return;
11004    }
11005
11006    this.timer = this._delay(function() {
11007      this._close();
11008      this._open( submenu );
11009    }, this.delay );
11010  },
11011
11012  _open: function( submenu ) {
11013    var position = $.extend({
11014      of: this.active
11015    }, this.options.position );
11016
11017    clearTimeout( this.timer );
11018    this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
11019      .hide()
11020      .attr( "aria-hidden", "true" );
11021
11022    submenu
11023      .show()
11024      .removeAttr( "aria-hidden" )
11025      .attr( "aria-expanded", "true" )
11026      .position( position );
11027  },
11028
11029  collapseAll: function( event, all ) {
11030    clearTimeout( this.timer );
11031    this.timer = this._delay(function() {
11032      // If we were passed an event, look for the submenu that contains the event
11033      var currentMenu = all ? this.element :
11034        $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
11035
11036      // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
11037      if ( !currentMenu.length ) {
11038        currentMenu = this.element;
11039      }
11040
11041      this._close( currentMenu );
11042
11043      this.blur( event );
11044      this.activeMenu = currentMenu;
11045    }, this.delay );
11046  },
11047
11048  // With no arguments, closes the currently active menu - if nothing is active
11049  // it closes all menus.  If passed an argument, it will search for menus BELOW
11050  _close: function( startMenu ) {
11051    if ( !startMenu ) {
11052      startMenu = this.active ? this.active.parent() : this.element;
11053    }
11054
11055    startMenu
11056      .find( ".ui-menu" )
11057        .hide()
11058        .attr( "aria-hidden", "true" )
11059        .attr( "aria-expanded", "false" )
11060      .end()
11061      .find( "a.ui-state-active" )
11062        .removeClass( "ui-state-active" );
11063  },
11064
11065  collapse: function( event ) {
11066    var newItem = this.active &&
11067      this.active.parent().closest( ".ui-menu-item", this.element );
11068    if ( newItem && newItem.length ) {
11069      this._close();
11070      this.focus( event, newItem );
11071    }
11072  },
11073
11074  expand: function( event ) {
11075    var newItem = this.active &&
11076      this.active
11077        .children( ".ui-menu " )
11078        .children( ".ui-menu-item" )
11079        .first();
11080
11081    if ( newItem && newItem.length ) {
11082      this._open( newItem.parent() );
11083
11084      // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
11085      this._delay(function() {
11086        this.focus( event, newItem );
11087      });
11088    }
11089  },
11090
11091  next: function( event ) {
11092    this._move( "next", "first", event );
11093  },
11094
11095  previous: function( event ) {
11096    this._move( "prev", "last", event );
11097  },
11098
11099  isFirstItem: function() {
11100    return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
11101  },
11102
11103  isLastItem: function() {
11104    return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
11105  },
11106
11107  _move: function( direction, filter, event ) {
11108    var next;
11109    if ( this.active ) {
11110      if ( direction === "first" || direction === "last" ) {
11111        next = this.active
11112          [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
11113          .eq( -1 );
11114      } else {
11115        next = this.active
11116          [ direction + "All" ]( ".ui-menu-item" )
11117          .eq( 0 );
11118      }
11119    }
11120    if ( !next || !next.length || !this.active ) {
11121      next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
11122    }
11123
11124    this.focus( event, next );
11125  },
11126
11127  nextPage: function( event ) {
11128    var item, base, height;
11129
11130    if ( !this.active ) {
11131      this.next( event );
11132      return;
11133    }
11134    if ( this.isLastItem() ) {
11135      return;
11136    }
11137    if ( this._hasScroll() ) {
11138      base = this.active.offset().top;
11139      height = this.element.height();
11140      this.active.nextAll( ".ui-menu-item" ).each(function() {
11141        item = $( this );
11142        return item.offset().top - base - height < 0;
11143      });
11144
11145      this.focus( event, item );
11146    } else {
11147      this.focus( event, this.activeMenu.children( ".ui-menu-item" )
11148        [ !this.active ? "first" : "last" ]() );
11149    }
11150  },
11151
11152  previousPage: function( event ) {
11153    var item, base, height;
11154    if ( !this.active ) {
11155      this.next( event );
11156      return;
11157    }
11158    if ( this.isFirstItem() ) {
11159      return;
11160    }
11161    if ( this._hasScroll() ) {
11162      base = this.active.offset().top;
11163      height = this.element.height();
11164      this.active.prevAll( ".ui-menu-item" ).each(function() {
11165        item = $( this );
11166        return item.offset().top - base + height > 0;
11167      });
11168
11169      this.focus( event, item );
11170    } else {
11171      this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
11172    }
11173  },
11174
11175  _hasScroll: function() {
11176    return this.element.outerHeight() < this.element.prop( "scrollHeight" );
11177  },
11178
11179  select: function( event ) {
11180    // TODO: It should never be possible to not have an active item at this
11181    // point, but the tests don't trigger mouseenter before click.
11182    this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
11183    var ui = { item: this.active };
11184    if ( !this.active.has( ".ui-menu" ).length ) {
11185      this.collapseAll( event, true );
11186    }
11187    this._trigger( "select", event, ui );
11188  }
11189});
11190
11191}( _4ORMAT.$ ));
11192(function( $, undefined ) {
11193
11194$.widget( "ui.progressbar", {
11195  version: "1.10.4",
11196  options: {
11197    max: 100,
11198    value: 0,
11199
11200    change: null,
11201    complete: null
11202  },
11203
11204  min: 0,
11205
11206  _create: function() {
11207    // Constrain initial value
11208    this.oldValue = this.options.value = this._constrainedValue();
11209
11210    this.element
11211      .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
11212      .attr({
11213        // Only set static values, aria-valuenow and aria-valuemax are
11214        // set inside _refreshValue()
11215        role: "progressbar",
11216        "aria-valuemin": this.min
11217      });
11218
11219    this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
11220      .appendTo( this.element );
11221
11222    this._refreshValue();
11223  },
11224
11225  _destroy: function() {
11226    this.element
11227      .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
11228      .removeAttr( "role" )
11229      .removeAttr( "aria-valuemin" )
11230      .removeAttr( "aria-valuemax" )
11231      .removeAttr( "aria-valuenow" );
11232
11233    this.valueDiv.remove();
11234  },
11235
11236  value: function( newValue ) {
11237    if ( newValue === undefined ) {
11238      return this.options.value;
11239    }
11240
11241    this.options.value = this._constrainedValue( newValue );
11242    this._refreshValue();
11243  },
11244
11245  _constrainedValue: function( newValue ) {
11246    if ( newValue === undefined ) {
11247      newValue = this.options.value;
11248    }
11249
11250    this.indeterminate = newValue === false;
11251
11252    // sanitize value
11253    if ( typeof newValue !== "number" ) {
11254      newValue = 0;
11255    }
11256
11257    return this.indeterminate ? false :
11258      Math.min( this.options.max, Math.max( this.min, newValue ) );
11259  },
11260
11261  _setOptions: function( options ) {
11262    // Ensure "value" option is set after other values (like max)
11263    var value = options.value;
11264    delete options.value;
11265
11266    this._super( options );
11267
11268    this.options.value = this._constrainedValue( value );
11269    this._refreshValue();
11270  },
11271
11272  _setOption: function( key, value ) {
11273    if ( key === "max" ) {
11274      // Don't allow a max less than min
11275      value = Math.max( this.min, value );
11276    }
11277
11278    this._super( key, value );
11279  },
11280
11281  _percentage: function() {
11282    return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
11283  },
11284
11285  _refreshValue: function() {
11286    var value = this.options.value,
11287      percentage = this._percentage();
11288
11289    this.valueDiv
11290      .toggle( this.indeterminate || value > this.min )
11291      .toggleClass( "ui-corner-right", value === this.options.max )
11292      .width( percentage.toFixed(0) + "%" );
11293
11294    this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
11295
11296    if ( this.indeterminate ) {
11297      this.element.removeAttr( "aria-valuenow" );
11298      if ( !this.overlayDiv ) {
11299        this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
11300      }
11301    } else {
11302      this.element.attr({
11303        "aria-valuemax": this.options.max,
11304        "aria-valuenow": value
11305      });
11306      if ( this.overlayDiv ) {
11307        this.overlayDiv.remove();
11308        this.overlayDiv = null;
11309      }
11310    }
11311
11312    if ( this.oldValue !== value ) {
11313      this.oldValue = value;
11314      this._trigger( "change" );
11315    }
11316    if ( value === this.options.max ) {
11317      this._trigger( "complete" );
11318    }
11319  }
11320});
11321
11322})( _4ORMAT.$ );
11323(function( $, undefined ) {
11324
11325function num(v) {
11326  return parseInt(v, 10) || 0;
11327}
11328
11329function isNumber(value) {
11330  return !isNaN(parseInt(value, 10));
11331}
11332
11333$.widget("ui.resizable", $.ui.mouse, {
11334  version: "1.10.4",
11335  widgetEventPrefix: "resize",
11336  options: {
11337    alsoResize: false,
11338    animate: false,
11339    animateDuration: "slow",
11340    animateEasing: "swing",
11341    aspectRatio: false,
11342    autoHide: false,
11343    containment: false,
11344    ghost: false,
11345    grid: false,
11346    handles: "e,s,se",
11347    helper: false,
11348    maxHeight: null,
11349    maxWidth: null,
11350    minHeight: 10,
11351    minWidth: 10,
11352    // See #7960
11353    zIndex: 90,
11354
11355    // callbacks
11356    resize: null,
11357    start: null,
11358    stop: null
11359  },
11360  _create: function() {
11361
11362    var n, i, handle, axis, hname,
11363      that = this,
11364      o = this.options;
11365    this.element.addClass("ui-resizable");
11366
11367    $.extend(this, {
11368      _aspectRatio: !!(o.aspectRatio),
11369      aspectRatio: o.aspectRatio,
11370      originalElement: this.element,
11371      _proportionallyResizeElements: [],
11372      _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
11373    });
11374
11375    //Wrap the element if it cannot hold child nodes
11376    if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
11377
11378      //Create a wrapper element and set the wrapper to the new current internal element
11379      this.element.wrap(
11380        $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
11381          position: this.element.css("position"),
11382          width: this.element.outerWidth(),
11383          height: this.element.outerHeight(),
11384          top: this.element.css("top"),
11385          left: this.element.css("left")
11386        })
11387      );
11388
11389      //Overwrite the original this.element
11390      this.element = this.element.parent().data(
11391        "ui-resizable", this.element.data("ui-resizable")
11392      );
11393
11394      this.elementIsWrapper = true;
11395
11396      //Move margins to the wrapper
11397      this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
11398      this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
11399
11400      //Prevent Safari textarea resize
11401      this.originalResizeStyle = this.originalElement.css("resize");
11402      this.originalElement.css("resize", "none");
11403
11404      //Push the actual element to our proportionallyResize internal array
11405      this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
11406
11407      // avoid IE jump (hard set the margin)
11408      this.originalElement.css({ margin: this.originalElement.css("margin") });
11409
11410      // fix handlers offset
11411      this._proportionallyResize();
11412
11413    }
11414
11415    this.handles = o.handles || (!$(".ui-resizable-handle", this.element).length ? "e,s,se" : { n: ".ui-resizable-n", e: ".ui-resizable-e", s: ".ui-resizable-s", w: ".ui-resizable-w", se: ".ui-resizable-se", sw: ".ui-resizable-sw", ne: ".ui-resizable-ne", nw: ".ui-resizable-nw" });
11416    if(this.handles.constructor === String) {
11417
11418      if ( this.handles === "all") {
11419        this.handles = "n,e,s,w,se,sw,ne,nw";
11420      }
11421
11422      n = this.handles.split(",");
11423      this.handles = {};
11424
11425      for(i = 0; i < n.length; i++) {
11426
11427        handle = $.trim(n[i]);
11428        hname = "ui-resizable-"+handle;
11429        axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
11430
11431        // Apply zIndex to all handles - see #7960
11432        axis.css({ zIndex: o.zIndex });
11433
11434        //TODO : What's going on here?
11435        if ("se" === handle) {
11436          axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
11437        }
11438
11439        //Insert into internal handles object and append to element
11440        this.handles[handle] = ".ui-resizable-"+handle;
11441        this.element.append(axis);
11442      }
11443
11444    }
11445
11446    this._renderAxis = function(target) {
11447
11448      var i, axis, padPos, padWrapper;
11449
11450      target = target || this.element;
11451
11452      for(i in this.handles) {
11453
11454        if(this.handles[i].constructor === String) {
11455          this.handles[i] = $(this.handles[i], this.element).show();
11456        }
11457
11458        //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
11459        if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
11460
11461          axis = $(this.handles[i], this.element);
11462
11463          //Checking the correct pad and border
11464          padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
11465
11466          //The padding type i have to apply...
11467          padPos = [ "padding",
11468            /ne|nw|n/.test(i) ? "Top" :
11469            /se|sw|s/.test(i) ? "Bottom" :
11470            /^e$/.test(i) ? "Right" : "Left" ].join("");
11471
11472          target.css(padPos, padWrapper);
11473
11474          this._proportionallyResize();
11475
11476        }
11477
11478        //TODO: What's that good for? There's not anything to be executed left
11479        if(!$(this.handles[i]).length) {
11480          continue;
11481        }
11482      }
11483    };
11484
11485    //TODO: make renderAxis a prototype function
11486    this._renderAxis(this.element);
11487
11488    this._handles = $(".ui-resizable-handle", this.element)
11489      .disableSelection();
11490
11491    //Matching axis name
11492    this._handles.mouseover(function() {
11493      if (!that.resizing) {
11494        if (this.className) {
11495          axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
11496        }
11497        //Axis, default = se
11498        that.axis = axis && axis[1] ? axis[1] : "se";
11499      }
11500    });
11501
11502    //If we want to auto hide the elements
11503    if (o.autoHide) {
11504      this._handles.hide();
11505      $(this.element)
11506        .addClass("ui-resizable-autohide")
11507        .mouseenter(function() {
11508          if (o.disabled) {
11509            return;
11510          }
11511          $(this).removeClass("ui-resizable-autohide");
11512          that._handles.show();
11513        })
11514        .mouseleave(function(){
11515          if (o.disabled) {
11516            return;
11517          }
11518          if (!that.resizing) {
11519            $(this).addClass("ui-resizable-autohide");
11520            that._handles.hide();
11521          }
11522        });
11523    }
11524
11525    //Initialize the mouse interaction
11526    this._mouseInit();
11527
11528  },
11529
11530  _destroy: function() {
11531
11532    this._mouseDestroy();
11533
11534    var wrapper,
11535      _destroy = function(exp) {
11536        $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
11537          .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
11538      };
11539
11540    //TODO: Unwrap at same DOM position
11541    if (this.elementIsWrapper) {
11542      _destroy(this.element);
11543      wrapper = this.element;
11544      this.originalElement.css({
11545        position: wrapper.css("position"),
11546        width: wrapper.outerWidth(),
11547        height: wrapper.outerHeight(),
11548        top: wrapper.css("top"),
11549        left: wrapper.css("left")
11550      }).insertAfter( wrapper );
11551      wrapper.remove();
11552    }
11553
11554    this.originalElement.css("resize", this.originalResizeStyle);
11555    _destroy(this.originalElement);
11556
11557    return this;
11558  },
11559
11560  _mouseCapture: function(event) {
11561    var i, handle,
11562      capture = false;
11563
11564    for (i in this.handles) {
11565      handle = $(this.handles[i])[0];
11566      if (handle === event.target || $.contains(handle, event.target)) {
11567        capture = true;
11568      }
11569    }
11570
11571    return !this.options.disabled && capture;
11572  },
11573
11574  _mouseStart: function(event) {
11575
11576    var curleft, curtop, cursor,
11577      o = this.options,
11578      iniPos = this.element.position(),
11579      el = this.element;
11580
11581    this.resizing = true;
11582
11583    // bugfix for http://dev.jquery.com/ticket/1749
11584    if ( (/absolute/).test( el.css("position") ) ) {
11585      el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
11586    } else if (el.is(".ui-draggable")) {
11587      el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
11588    }
11589
11590    this._renderProxy();
11591
11592    curleft = num(this.helper.css("left"));
11593    curtop = num(this.helper.css("top"));
11594
11595    if (o.containment) {
11596      curleft += $(o.containment).scrollLeft() || 0;
11597      curtop += $(o.containment).scrollTop() || 0;
11598    }
11599
11600    //Store needed variables
11601    this.offset = this.helper.offset();
11602    this.position = { left: curleft, top: curtop };
11603    this.size = this._helper ? { width: this.helper.width(), height: this.helper.height() } : { width: el.width(), height: el.height() };
11604    this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
11605    this.originalPosition = { left: curleft, top: curtop };
11606    this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
11607    this.originalMousePosition = { left: event.pageX, top: event.pageY };
11608
11609    //Aspect Ratio
11610    this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
11611
11612    cursor = $(".ui-resizable-" + this.axis).css("cursor");
11613    $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
11614
11615    el.addClass("ui-resizable-resizing");
11616    this._propagate("start", event);
11617    return true;
11618  },
11619
11620  _mouseDrag: function(event) {
11621
11622    //Increase performance, avoid regex
11623    var data,
11624      el = this.helper, props = {},
11625      smp = this.originalMousePosition,
11626      a = this.axis,
11627      prevTop = this.position.top,
11628      prevLeft = this.position.left,
11629      prevWidth = this.size.width,
11630      prevHeight = this.size.height,
11631      dx = (event.pageX-smp.left)||0,
11632      dy = (event.pageY-smp.top)||0,
11633      trigger = this._change[a];
11634
11635    if (!trigger) {
11636      return false;
11637    }
11638
11639    // Calculate the attrs that will be change
11640    data = trigger.apply(this, [event, dx, dy]);
11641
11642    // Put this in the mouseDrag handler since the user can start pressing shift while resizing
11643    this._updateVirtualBoundaries(event.shiftKey);
11644    if (this._aspectRatio || event.shiftKey) {
11645      data = this._updateRatio(data, event);
11646    }
11647
11648    data = this._respectSize(data, event);
11649
11650    this._updateCache(data);
11651
11652    // plugins callbacks need to be called first
11653    this._propagate("resize", event);
11654
11655    if (this.position.top !== prevTop) {
11656      props.top = this.position.top + "px";
11657    }
11658    if (this.position.left !== prevLeft) {
11659      props.left = this.position.left + "px";
11660    }
11661    if (this.size.width !== prevWidth) {
11662      props.width = this.size.width + "px";
11663    }
11664    if (this.size.height !== prevHeight) {
11665      props.height = this.size.height + "px";
11666    }
11667    el.css(props);
11668
11669    if (!this._helper && this._proportionallyResizeElements.length) {
11670      this._proportionallyResize();
11671    }
11672
11673    // Call the user callback if the element was resized
11674    if ( ! $.isEmptyObject(props) ) {
11675      this._trigger("resize", event, this.ui());
11676    }
11677
11678    return false;
11679  },
11680
11681  _mouseStop: function(event) {
11682
11683    this.resizing = false;
11684    var pr, ista, soffseth, soffsetw, s, left, top,
11685      o = this.options, that = this;
11686
11687    if(this._helper) {
11688
11689      pr = this._proportionallyResizeElements;
11690      ista = pr.length && (/textarea/i).test(pr[0].nodeName);
11691      soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
11692      soffsetw = ista ? 0 : that.sizeDiff.width;
11693
11694      s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };
11695      left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
11696      top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
11697
11698      if (!o.animate) {
11699        this.element.css($.extend(s, { top: top, left: left }));
11700      }
11701
11702      that.helper.height(that.size.height);
11703      that.helper.width(that.size.width);
11704
11705      if (this._helper && !o.animate) {
11706        this._proportionallyResize();
11707      }
11708    }
11709
11710    $("body").css("cursor", "auto");
11711
11712    this.element.removeClass("ui-resizable-resizing");
11713
11714    this._propagate("stop", event);
11715
11716    if (this._helper) {
11717      this.helper.remove();
11718    }
11719
11720    return false;
11721
11722  },
11723
11724  _updateVirtualBoundaries: function(forceAspectRatio) {
11725    var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
11726      o = this.options;
11727
11728    b = {
11729      minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
11730      maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
11731      minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
11732      maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
11733    };
11734
11735    if(this._aspectRatio || forceAspectRatio) {
11736      // We want to create an enclosing box whose aspect ration is the requested one
11737      // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
11738      pMinWidth = b.minHeight * this.aspectRatio;
11739      pMinHeight = b.minWidth / this.aspectRatio;
11740      pMaxWidth = b.maxHeight * this.aspectRatio;
11741      pMaxHeight = b.maxWidth / this.aspectRatio;
11742
11743      if(pMinWidth > b.minWidth) {
11744        b.minWidth = pMinWidth;
11745      }
11746      if(pMinHeight > b.minHeight) {
11747        b.minHeight = pMinHeight;
11748      }
11749      if(pMaxWidth < b.maxWidth) {
11750        b.maxWidth = pMaxWidth;
11751      }
11752      if(pMaxHeight < b.maxHeight) {
11753        b.maxHeight = pMaxHeight;
11754      }
11755    }
11756    this._vBoundaries = b;
11757  },
11758
11759  _updateCache: function(data) {
11760    this.offset = this.helper.offset();
11761    if (isNumber(data.left)) {
11762      this.position.left = data.left;
11763    }
11764    if (isNumber(data.top)) {
11765      this.position.top = data.top;
11766    }
11767    if (isNumber(data.height)) {
11768      this.size.height = data.height;
11769    }
11770    if (isNumber(data.width)) {
11771      this.size.width = data.width;
11772    }
11773  },
11774
11775  _updateRatio: function( data ) {
11776
11777    var cpos = this.position,
11778      csize = this.size,
11779      a = this.axis;
11780
11781    if (isNumber(data.height)) {
11782      data.width = (data.height * this.aspectRatio);
11783    } else if (isNumber(data.width)) {
11784      data.height = (data.width / this.aspectRatio);
11785    }
11786
11787    if (a === "sw") {
11788      data.left = cpos.left + (csize.width - data.width);
11789      data.top = null;
11790    }
11791    if (a === "nw") {
11792      data.top = cpos.top + (csize.height - data.height);
11793      data.left = cpos.left + (csize.width - data.width);
11794    }
11795
11796    return data;
11797  },
11798
11799  _respectSize: function( data ) {
11800
11801    var o = this._vBoundaries,
11802      a = this.axis,
11803      ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
11804      isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
11805      dw = this.originalPosition.left + this.originalSize.width,
11806      dh = this.position.top + this.size.height,
11807      cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
11808    if (isminw) {
11809      data.width = o.minWidth;
11810    }
11811    if (isminh) {
11812      data.height = o.minHeight;
11813    }
11814    if (ismaxw) {
11815      data.width = o.maxWidth;
11816    }
11817    if (ismaxh) {
11818      data.height = o.maxHeight;
11819    }
11820
11821    if (isminw && cw) {
11822      data.left = dw - o.minWidth;
11823    }
11824    if (ismaxw && cw) {
11825      data.left = dw - o.maxWidth;
11826    }
11827    if (isminh && ch) {
11828      data.top = dh - o.minHeight;
11829    }
11830    if (ismaxh && ch) {
11831      data.top = dh - o.maxHeight;
11832    }
11833
11834    // fixing jump error on top/left - bug #2330
11835    if (!data.width && !data.height && !data.left && data.top) {
11836      data.top = null;
11837    } else if (!data.width && !data.height && !data.top && data.left) {
11838      data.left = null;
11839    }
11840
11841    return data;
11842  },
11843
11844  _proportionallyResize: function() {
11845
11846    if (!this._proportionallyResizeElements.length) {
11847      return;
11848    }
11849
11850    var i, j, borders, paddings, prel,
11851      element = this.helper || this.element;
11852
11853    for ( i=0; i < this._proportionallyResizeElements.length; i++) {
11854
11855      prel = this._proportionallyResizeElements[i];
11856
11857      if (!this.borderDif) {
11858        this.borderDif = [];
11859        borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
11860        paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
11861
11862        for ( j = 0; j < borders.length; j++ ) {
11863          this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
11864        }
11865      }
11866
11867      prel.css({
11868        height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
11869        width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
11870      });
11871
11872    }
11873
11874  },
11875
11876  _renderProxy: function() {
11877
11878    var el = this.element, o = this.options;
11879    this.elementOffset = el.offset();
11880
11881    if(this._helper) {
11882
11883      this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
11884
11885      this.helper.addClass(this._helper).css({
11886        width: this.element.outerWidth() - 1,
11887        height: this.element.outerHeight() - 1,
11888        position: "absolute",
11889        left: this.elementOffset.left +"px",
11890        top: this.elementOffset.top +"px",
11891        zIndex: ++o.zIndex //TODO: Don't modify option
11892      });
11893
11894      this.helper
11895        .appendTo("body")
11896        .disableSelection();
11897
11898    } else {
11899      this.helper = this.element;
11900    }
11901
11902  },
11903
11904  _change: {
11905    e: function(event, dx) {
11906      return { width: this.originalSize.width + dx };
11907    },
11908    w: function(event, dx) {
11909      var cs = this.originalSize, sp = this.originalPosition;
11910      return { left: sp.left + dx, width: cs.width - dx };
11911    },
11912    n: function(event, dx, dy) {
11913      var cs = this.originalSize, sp = this.originalPosition;
11914      return { top: sp.top + dy, height: cs.height - dy };
11915    },
11916    s: function(event, dx, dy) {
11917      return { height: this.originalSize.height + dy };
11918    },
11919    se: function(event, dx, dy) {
11920      return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
11921    },
11922    sw: function(event, dx, dy) {
11923      return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
11924    },
11925    ne: function(event, dx, dy) {
11926      return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
11927    },
11928    nw: function(event, dx, dy) {
11929      return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
11930    }
11931  },
11932
11933  _propagate: function(n, event) {
11934    $.ui.plugin.call(this, n, [event, this.ui()]);
11935    (n !== "resize" && this._trigger(n, event, this.ui()));
11936  },
11937
11938  plugins: {},
11939
11940  ui: function() {
11941    return {
11942      originalElement: this.originalElement,
11943      element: this.element,
11944      helper: this.helper,
11945      position: this.position,
11946      size: this.size,
11947      originalSize: this.originalSize,
11948      originalPosition: this.originalPosition
11949    };
11950  }
11951
11952});
11953
11954/*
11955 * Resizable Extensions
11956 */
11957
11958$.ui.plugin.add("resizable", "animate", {
11959
11960  stop: function( event ) {
11961    var that = $(this).data("ui-resizable"),
11962      o = that.options,
11963      pr = that._proportionallyResizeElements,
11964      ista = pr.length && (/textarea/i).test(pr[0].nodeName),
11965      soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
11966      soffsetw = ista ? 0 : that.sizeDiff.width,
11967      style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
11968      left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
11969      top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
11970
11971    that.element.animate(
11972      $.extend(style, top && left ? { top: top, left: left } : {}), {
11973        duration: o.animateDuration,
11974        easing: o.animateEasing,
11975        step: function() {
11976
11977          var data = {
11978            width: parseInt(that.element.css("width"), 10),
11979            height: parseInt(that.element.css("height"), 10),
11980            top: parseInt(that.element.css("top"), 10),
11981            left: parseInt(that.element.css("left"), 10)
11982          };
11983
11984          if (pr && pr.length) {
11985            $(pr[0]).css({ width: data.width, height: data.height });
11986          }
11987
11988          // propagating resize, and updating values for each animation step
11989          that._updateCache(data);
11990          that._propagate("resize", event);
11991
11992        }
11993      }
11994    );
11995  }
11996
11997});
11998
11999$.ui.plugin.add("resizable", "containment", {
12000
12001  start: function() {
12002    var element, p, co, ch, cw, width, height,
12003      that = $(this).data("ui-resizable"),
12004      o = that.options,
12005      el = that.element,
12006      oc = o.containment,
12007      ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
12008
12009    if (!ce) {
12010      return;
12011    }
12012
12013    that.containerElement = $(ce);
12014
12015    if (/document/.test(oc) || oc === document) {
12016      that.containerOffset = { left: 0, top: 0 };
12017      that.containerPosition = { left: 0, top: 0 };
12018
12019      that.parentData = {
12020        element: $(document), left: 0, top: 0,
12021        width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
12022      };
12023    }
12024
12025    // i'm a node, so compute top, left, right, bottom
12026    else {
12027      element = $(ce);
12028      p = [];
12029      $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
12030
12031      that.containerOffset = element.offset();
12032      that.containerPosition = element.position();
12033      that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
12034
12035      co = that.containerOffset;
12036      ch = that.containerSize.height;
12037      cw = that.containerSize.width;
12038      width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
12039      height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
12040
12041      that.parentData = {
12042        element: ce, left: co.left, top: co.top, width: width, height: height
12043      };
12044    }
12045  },
12046
12047  resize: function( event ) {
12048    var woset, hoset, isParent, isOffsetRelative,
12049      that = $(this).data("ui-resizable"),
12050      o = that.options,
12051      co = that.containerOffset, cp = that.position,
12052      pRatio = that._aspectRatio || event.shiftKey,
12053      cop = { top:0, left:0 }, ce = that.containerElement;
12054
12055    if (ce[0] !== document && (/static/).test(ce.css("position"))) {
12056      cop = co;
12057    }
12058
12059    if (cp.left < (that._helper ? co.left : 0)) {
12060      that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
12061      if (pRatio) {
12062        that.size.height = that.size.width / that.aspectRatio;
12063      }
12064      that.position.left = o.helper ? co.left : 0;
12065    }
12066
12067    if (cp.top < (that._helper ? co.top : 0)) {
12068      that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
12069      if (pRatio) {
12070        that.size.width = that.size.height * that.aspectRatio;
12071      }
12072      that.position.top = that._helper ? co.top : 0;
12073    }
12074
12075    that.offset.left = that.parentData.left+that.position.left;
12076    that.offset.top = that.parentData.top+that.position.top;
12077
12078    woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
12079    hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
12080
12081    isParent = that.containerElement.get(0) === that.element.parent().get(0);
12082    isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
12083
12084    if ( isParent && isOffsetRelative ) {
12085      woset -= Math.abs( that.parentData.left );
12086    }
12087
12088    if (woset + that.size.width >= that.parentData.width) {
12089      that.size.width = that.parentData.width - woset;
12090      if (pRatio) {
12091        that.size.height = that.size.width / that.aspectRatio;
12092      }
12093    }
12094
12095    if (hoset + that.size.height >= that.parentData.height) {
12096      that.size.height = that.parentData.height - hoset;
12097      if (pRatio) {
12098        that.size.width = that.size.height * that.aspectRatio;
12099      }
12100    }
12101  },
12102
12103  stop: function(){
12104    var that = $(this).data("ui-resizable"),
12105      o = that.options,
12106      co = that.containerOffset,
12107      cop = that.containerPosition,
12108      ce = that.containerElement,
12109      helper = $(that.helper),
12110      ho = helper.offset(),
12111      w = helper.outerWidth() - that.sizeDiff.width,
12112      h = helper.outerHeight() - that.sizeDiff.height;
12113
12114    if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
12115      $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
12116    }
12117
12118    if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
12119      $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
12120    }
12121
12122  }
12123});
12124
12125$.ui.plugin.add("resizable", "alsoResize", {
12126
12127  start: function () {
12128    var that = $(this).data("ui-resizable"),
12129      o = that.options,
12130      _store = function (exp) {
12131        $(exp).each(function() {
12132          var el = $(this);
12133          el.data("ui-resizable-alsoresize", {
12134            width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
12135            left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
12136          });
12137        });
12138      };
12139
vendor: 56,170 bytes, lines 12140-13986
12140    if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
12141      if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
12142      else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
12143    }else{
12144      _store(o.alsoResize);
12145    }
12146  },
12147
12148  resize: function (event, ui) {
12149    var that = $(this).data("ui-resizable"),
12150      o = that.options,
12151      os = that.originalSize,
12152      op = that.originalPosition,
12153      delta = {
12154        height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
12155        top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
12156      },
12157
12158      _alsoResize = function (exp, c) {
12159        $(exp).each(function() {
12160          var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
12161            css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
12162
12163          $.each(css, function (i, prop) {
12164            var sum = (start[prop]||0) + (delta[prop]||0);
12165            if (sum && sum >= 0) {
12166              style[prop] = sum || null;
12167            }
12168          });
12169
12170          el.css(style);
12171        });
12172      };
12173
12174    if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
12175      $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
12176    }else{
12177      _alsoResize(o.alsoResize);
12178    }
12179  },
12180
12181  stop: function () {
12182    $(this).removeData("resizable-alsoresize");
12183  }
12184});
12185
12186$.ui.plugin.add("resizable", "ghost", {
12187
12188  start: function() {
12189
12190    var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
12191
12192    that.ghost = that.originalElement.clone();
12193    that.ghost
12194      .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
12195      .addClass("ui-resizable-ghost")
12196      .addClass(typeof o.ghost === "string" ? o.ghost : "");
12197
12198    that.ghost.appendTo(that.helper);
12199
12200  },
12201
12202  resize: function(){
12203    var that = $(this).data("ui-resizable");
12204    if (that.ghost) {
12205      that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
12206    }
12207  },
12208
12209  stop: function() {
12210    var that = $(this).data("ui-resizable");
12211    if (that.ghost && that.helper) {
12212      that.helper.get(0).removeChild(that.ghost.get(0));
12213    }
12214  }
12215
12216});
12217
12218$.ui.plugin.add("resizable", "grid", {
12219
12220  resize: function() {
12221    var that = $(this).data("ui-resizable"),
12222      o = that.options,
12223      cs = that.size,
12224      os = that.originalSize,
12225      op = that.originalPosition,
12226      a = that.axis,
12227      grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
12228      gridX = (grid[0]||1),
12229      gridY = (grid[1]||1),
12230      ox = Math.round((cs.width - os.width) / gridX) * gridX,
12231      oy = Math.round((cs.height - os.height) / gridY) * gridY,
12232      newWidth = os.width + ox,
12233      newHeight = os.height + oy,
12234      isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
12235      isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
12236      isMinWidth = o.minWidth && (o.minWidth > newWidth),
12237      isMinHeight = o.minHeight && (o.minHeight > newHeight);
12238
12239    o.grid = grid;
12240
12241    if (isMinWidth) {
12242      newWidth = newWidth + gridX;
12243    }
12244    if (isMinHeight) {
12245      newHeight = newHeight + gridY;
12246    }
12247    if (isMaxWidth) {
12248      newWidth = newWidth - gridX;
12249    }
12250    if (isMaxHeight) {
12251      newHeight = newHeight - gridY;
12252    }
12253
12254    if (/^(se|s|e)$/.test(a)) {
12255      that.size.width = newWidth;
12256      that.size.height = newHeight;
12257    } else if (/^(ne)$/.test(a)) {
12258      that.size.width = newWidth;
12259      that.size.height = newHeight;
12260      that.position.top = op.top - oy;
12261    } else if (/^(sw)$/.test(a)) {
12262      that.size.width = newWidth;
12263      that.size.height = newHeight;
12264      that.position.left = op.left - ox;
12265    } else {
12266      if ( newHeight - gridY > 0 ) {
12267        that.size.height = newHeight;
12268        that.position.top = op.top - oy;
12269      } else {
12270        that.size.height = gridY;
12271        that.position.top = op.top + os.height - gridY;
12272      }
12273      if ( newWidth - gridX > 0 ) {
12274        that.size.width = newWidth;
12275        that.position.left = op.left - ox;
12276      } else {
12277        that.size.width = gridX;
12278        that.position.left = op.left + os.width - gridX;
12279      }
12280    }
12281  }
12282
12283});
12284
12285})( _4ORMAT.$ );
12286(function( $, undefined ) {
12287
12288$.widget("ui.selectable", $.ui.mouse, {
12289  version: "1.10.4",
12290  options: {
12291    appendTo: "body",
12292    autoRefresh: true,
12293    distance: 0,
12294    filter: "*",
12295    tolerance: "touch",
12296
12297    // callbacks
12298    selected: null,
12299    selecting: null,
12300    start: null,
12301    stop: null,
12302    unselected: null,
12303    unselecting: null
12304  },
12305  _create: function() {
12306    var selectees,
12307      that = this;
12308
12309    this.element.addClass("ui-selectable");
12310
12311    this.dragged = false;
12312
12313    // cache selectee children based on filter
12314    this.refresh = function() {
12315      selectees = $(that.options.filter, that.element[0]);
12316      selectees.addClass("ui-selectee");
12317      selectees.each(function() {
12318        var $this = $(this),
12319          pos = $this.offset();
12320        $.data(this, "selectable-item", {
12321          element: this,
12322          $element: $this,
12323          left: pos.left,
12324          top: pos.top,
12325          right: pos.left + $this.outerWidth(),
12326          bottom: pos.top + $this.outerHeight(),
12327          startselected: false,
12328          selected: $this.hasClass("ui-selected"),
12329          selecting: $this.hasClass("ui-selecting"),
12330          unselecting: $this.hasClass("ui-unselecting")
12331        });
12332      });
12333    };
12334    this.refresh();
12335
12336    this.selectees = selectees.addClass("ui-selectee");
12337
12338    this._mouseInit();
12339
12340    this.helper = $("<div class='ui-selectable-helper'></div>");
12341  },
12342
12343  _destroy: function() {
12344    this.selectees
12345      .removeClass("ui-selectee")
12346      .removeData("selectable-item");
12347    this.element
12348      .removeClass("ui-selectable ui-selectable-disabled");
12349    this._mouseDestroy();
12350  },
12351
12352  _mouseStart: function(event) {
12353    var that = this,
12354      options = this.options;
12355
12356    this.opos = [event.pageX, event.pageY];
12357
12358    if (this.options.disabled) {
12359      return;
12360    }
12361
12362    this.selectees = $(options.filter, this.element[0]);
12363
12364    this._trigger("start", event);
12365
12366    $(options.appendTo).append(this.helper);
12367    // position helper (lasso)
12368    this.helper.css({
12369      "left": event.pageX,
12370      "top": event.pageY,
12371      "width": 0,
12372      "height": 0
12373    });
12374
12375    if (options.autoRefresh) {
12376      this.refresh();
12377    }
12378
12379    this.selectees.filter(".ui-selected").each(function() {
12380      var selectee = $.data(this, "selectable-item");
12381      selectee.startselected = true;
12382      if (!event.metaKey && !event.ctrlKey) {
12383        selectee.$element.removeClass("ui-selected");
12384        selectee.selected = false;
12385        selectee.$element.addClass("ui-unselecting");
12386        selectee.unselecting = true;
12387        // selectable UNSELECTING callback
12388        that._trigger("unselecting", event, {
12389          unselecting: selectee.element
12390        });
12391      }
12392    });
12393
12394    $(event.target).parents().addBack().each(function() {
12395      var doSelect,
12396        selectee = $.data(this, "selectable-item");
12397      if (selectee) {
12398        doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
12399        selectee.$element
12400          .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
12401          .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
12402        selectee.unselecting = !doSelect;
12403        selectee.selecting = doSelect;
12404        selectee.selected = doSelect;
12405        // selectable (UN)SELECTING callback
12406        if (doSelect) {
12407          that._trigger("selecting", event, {
12408            selecting: selectee.element
12409          });
12410        } else {
12411          that._trigger("unselecting", event, {
12412            unselecting: selectee.element
12413          });
12414        }
12415        return false;
12416      }
12417    });
12418
12419  },
12420
12421  _mouseDrag: function(event) {
12422
12423    this.dragged = true;
12424
12425    if (this.options.disabled) {
12426      return;
12427    }
12428
12429    var tmp,
12430      that = this,
12431      options = this.options,
12432      x1 = this.opos[0],
12433      y1 = this.opos[1],
12434      x2 = event.pageX,
12435      y2 = event.pageY;
12436
12437    if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
12438    if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
12439    this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
12440
12441    this.selectees.each(function() {
12442      var selectee = $.data(this, "selectable-item"),
12443        hit = false;
12444
12445      //prevent helper from being selected if appendTo: selectable
12446      if (!selectee || selectee.element === that.element[0]) {
12447        return;
12448      }
12449
12450      if (options.tolerance === "touch") {
12451        hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
12452      } else if (options.tolerance === "fit") {
12453        hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
12454      }
12455
12456      if (hit) {
12457        // SELECT
12458        if (selectee.selected) {
12459          selectee.$element.removeClass("ui-selected");
12460          selectee.selected = false;
12461        }
12462        if (selectee.unselecting) {
12463          selectee.$element.removeClass("ui-unselecting");
12464          selectee.unselecting = false;
12465        }
12466        if (!selectee.selecting) {
12467          selectee.$element.addClass("ui-selecting");
12468          selectee.selecting = true;
12469          // selectable SELECTING callback
12470          that._trigger("selecting", event, {
12471            selecting: selectee.element
12472          });
12473        }
12474      } else {
12475        // UNSELECT
12476        if (selectee.selecting) {
12477          if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
12478            selectee.$element.removeClass("ui-selecting");
12479            selectee.selecting = false;
12480            selectee.$element.addClass("ui-selected");
12481            selectee.selected = true;
12482          } else {
12483            selectee.$element.removeClass("ui-selecting");
12484            selectee.selecting = false;
12485            if (selectee.startselected) {
12486              selectee.$element.addClass("ui-unselecting");
12487              selectee.unselecting = true;
12488            }
12489            // selectable UNSELECTING callback
12490            that._trigger("unselecting", event, {
12491              unselecting: selectee.element
12492            });
12493          }
12494        }
12495        if (selectee.selected) {
12496          if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
12497            selectee.$element.removeClass("ui-selected");
12498            selectee.selected = false;
12499
12500            selectee.$element.addClass("ui-unselecting");
12501            selectee.unselecting = true;
12502            // selectable UNSELECTING callback
12503            that._trigger("unselecting", event, {
12504              unselecting: selectee.element
12505            });
12506          }
12507        }
12508      }
12509    });
12510
12511    return false;
12512  },
12513
12514  _mouseStop: function(event) {
12515    var that = this;
12516
12517    this.dragged = false;
12518
12519    $(".ui-unselecting", this.element[0]).each(function() {
12520      var selectee = $.data(this, "selectable-item");
12521      selectee.$element.removeClass("ui-unselecting");
12522      selectee.unselecting = false;
12523      selectee.startselected = false;
12524      that._trigger("unselected", event, {
12525        unselected: selectee.element
12526      });
12527    });
12528    $(".ui-selecting", this.element[0]).each(function() {
12529      var selectee = $.data(this, "selectable-item");
12530      selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
12531      selectee.selecting = false;
12532      selectee.selected = true;
12533      selectee.startselected = true;
12534      that._trigger("selected", event, {
12535        selected: selectee.element
12536      });
12537    });
12538    this._trigger("stop", event);
12539
12540    this.helper.remove();
12541
12542    return false;
12543  }
12544
12545});
12546
12547})( _4ORMAT.$ );
12548(function( $, undefined ) {
12549
12550// number of pages in a slider
12551// (how many times can you page up/down to go through the whole range)
12552var numPages = 5;
12553
12554$.widget( "ui.slider", $.ui.mouse, {
12555  version: "1.10.4",
12556  widgetEventPrefix: "slide",
12557
12558  options: {
12559    animate: false,
12560    distance: 0,
12561    max: 100,
12562    min: 0,
12563    orientation: "horizontal",
12564    range: false,
12565    step: 1,
12566    value: 0,
12567    values: null,
12568
12569    // callbacks
12570    change: null,
12571    slide: null,
12572    start: null,
12573    stop: null
12574  },
12575
12576  _create: function() {
12577    this._keySliding = false;
12578    this._mouseSliding = false;
12579    this._animateOff = true;
12580    this._handleIndex = null;
12581    this._detectOrientation();
12582    this._mouseInit();
12583
12584    this.element
12585      .addClass( "ui-slider" +
12586        " ui-slider-" + this.orientation +
12587        " ui-widget" +
12588        " ui-widget-content" +
12589        " ui-corner-all");
12590
12591    this._refresh();
12592    this._setOption( "disabled", this.options.disabled );
12593
12594    this._animateOff = false;
12595  },
12596
12597  _refresh: function() {
12598    this._createRange();
12599    this._createHandles();
12600    this._setupEvents();
12601    this._refreshValue();
12602  },
12603
12604  _createHandles: function() {
12605    var i, handleCount,
12606      options = this.options,
12607      existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12608      handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
12609      handles = [];
12610
12611    handleCount = ( options.values && options.values.length ) || 1;
12612
12613    if ( existingHandles.length > handleCount ) {
12614      existingHandles.slice( handleCount ).remove();
12615      existingHandles = existingHandles.slice( 0, handleCount );
12616    }
12617
12618    for ( i = existingHandles.length; i < handleCount; i++ ) {
12619      handles.push( handle );
12620    }
12621
12622    this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12623
12624    this.handle = this.handles.eq( 0 );
12625
12626    this.handles.each(function( i ) {
12627      $( this ).data( "ui-slider-handle-index", i );
12628    });
12629  },
12630
12631  _createRange: function() {
12632    var options = this.options,
12633      classes = "";
12634
12635    if ( options.range ) {
12636      if ( options.range === true ) {
12637        if ( !options.values ) {
12638          options.values = [ this._valueMin(), this._valueMin() ];
12639        } else if ( options.values.length && options.values.length !== 2 ) {
12640          options.values = [ options.values[0], options.values[0] ];
12641        } else if ( $.isArray( options.values ) ) {
12642          options.values = options.values.slice(0);
12643        }
12644      }
12645
12646      if ( !this.range || !this.range.length ) {
12647        this.range = $( "<div></div>" )
12648          .appendTo( this.element );
12649
12650        classes = "ui-slider-range" +
12651        // note: this isn't the most fittingly semantic framework class for this element,
12652        // but worked best visually with a variety of themes
12653        " ui-widget-header ui-corner-all";
12654      } else {
12655        this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
12656          // Handle range switching from true to min/max
12657          .css({
12658            "left": "",
12659            "bottom": ""
12660          });
12661      }
12662
12663      this.range.addClass( classes +
12664        ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
12665    } else {
12666      if ( this.range ) {
12667        this.range.remove();
12668      }
12669      this.range = null;
12670    }
12671  },
12672
12673  _setupEvents: function() {
12674    var elements = this.handles.add( this.range ).filter( "a" );
12675    this._off( elements );
12676    this._on( elements, this._handleEvents );
12677    this._hoverable( elements );
12678    this._focusable( elements );
12679  },
12680
12681  _destroy: function() {
12682    this.handles.remove();
12683    if ( this.range ) {
12684      this.range.remove();
12685    }
12686
12687    this.element
12688      .removeClass( "ui-slider" +
12689        " ui-slider-horizontal" +
12690        " ui-slider-vertical" +
12691        " ui-widget" +
12692        " ui-widget-content" +
12693        " ui-corner-all" );
12694
12695    this._mouseDestroy();
12696  },
12697
12698  _mouseCapture: function( event ) {
12699    var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12700      that = this,
12701      o = this.options;
12702
12703    if ( o.disabled ) {
12704      return false;
12705    }
12706
12707    this.elementSize = {
12708      width: this.element.outerWidth(),
12709      height: this.element.outerHeight()
12710    };
12711    this.elementOffset = this.element.offset();
12712
12713    position = { x: event.pageX, y: event.pageY };
12714    normValue = this._normValueFromMouse( position );
12715    distance = this._valueMax() - this._valueMin() + 1;
12716    this.handles.each(function( i ) {
12717      var thisDistance = Math.abs( normValue - that.values(i) );
12718      if (( distance > thisDistance ) ||
12719        ( distance === thisDistance &&
12720          (i === that._lastChangedValue || that.values(i) === o.min ))) {
12721        distance = thisDistance;
12722        closestHandle = $( this );
12723        index = i;
12724      }
12725    });
12726
12727    allowed = this._start( event, index );
12728    if ( allowed === false ) {
12729      return false;
12730    }
12731    this._mouseSliding = true;
12732
12733    this._handleIndex = index;
12734
12735    closestHandle
12736      .addClass( "ui-state-active" )
12737      .focus();
12738
12739    offset = closestHandle.offset();
12740    mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
12741    this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
12742      left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
12743      top: event.pageY - offset.top -
12744        ( closestHandle.height() / 2 ) -
12745        ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
12746        ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
12747        ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
12748    };
12749
12750    if ( !this.handles.hasClass( "ui-state-hover" ) ) {
12751      this._slide( event, index, normValue );
12752    }
12753    this._animateOff = true;
12754    return true;
12755  },
12756
12757  _mouseStart: function() {
12758    return true;
12759  },
12760
12761  _mouseDrag: function( event ) {
12762    var position = { x: event.pageX, y: event.pageY },
12763      normValue = this._normValueFromMouse( position );
12764
12765    this._slide( event, this._handleIndex, normValue );
12766
12767    return false;
12768  },
12769
12770  _mouseStop: function( event ) {
12771    this.handles.removeClass( "ui-state-active" );
12772    this._mouseSliding = false;
12773
12774    this._stop( event, this._handleIndex );
12775    this._change( event, this._handleIndex );
12776
12777    this._handleIndex = null;
12778    this._clickOffset = null;
12779    this._animateOff = false;
12780
12781    return false;
12782  },
12783
12784  _detectOrientation: function() {
12785    this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
12786  },
12787
12788  _normValueFromMouse: function( position ) {
12789    var pixelTotal,
12790      pixelMouse,
12791      percentMouse,
12792      valueTotal,
12793      valueMouse;
12794
12795    if ( this.orientation === "horizontal" ) {
12796      pixelTotal = this.elementSize.width;
12797      pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
12798    } else {
12799      pixelTotal = this.elementSize.height;
12800      pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
12801    }
12802
12803    percentMouse = ( pixelMouse / pixelTotal );
12804    if ( percentMouse > 1 ) {
12805      percentMouse = 1;
12806    }
12807    if ( percentMouse < 0 ) {
12808      percentMouse = 0;
12809    }
12810    if ( this.orientation === "vertical" ) {
12811      percentMouse = 1 - percentMouse;
12812    }
12813
12814    valueTotal = this._valueMax() - this._valueMin();
12815    valueMouse = this._valueMin() + percentMouse * valueTotal;
12816
12817    return this._trimAlignValue( valueMouse );
12818  },
12819
12820  _start: function( event, index ) {
12821    var uiHash = {
12822      handle: this.handles[ index ],
12823      value: this.value()
12824    };
12825    if ( this.options.values && this.options.values.length ) {
12826      uiHash.value = this.values( index );
12827      uiHash.values = this.values();
12828    }
12829    return this._trigger( "start", event, uiHash );
12830  },
12831
12832  _slide: function( event, index, newVal ) {
12833    var otherVal,
12834      newValues,
12835      allowed;
12836
12837    if ( this.options.values && this.options.values.length ) {
12838      otherVal = this.values( index ? 0 : 1 );
12839
12840      if ( ( this.options.values.length === 2 && this.options.range === true ) &&
12841          ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
12842        ) {
12843        newVal = otherVal;
12844      }
12845
12846      if ( newVal !== this.values( index ) ) {
12847        newValues = this.values();
12848        newValues[ index ] = newVal;
12849        // A slide can be canceled by returning false from the slide callback
12850        allowed = this._trigger( "slide", event, {
12851          handle: this.handles[ index ],
12852          value: newVal,
12853          values: newValues
12854        } );
12855        otherVal = this.values( index ? 0 : 1 );
12856        if ( allowed !== false ) {
12857          this.values( index, newVal );
12858        }
12859      }
12860    } else {
12861      if ( newVal !== this.value() ) {
12862        // A slide can be canceled by returning false from the slide callback
12863        allowed = this._trigger( "slide", event, {
12864          handle: this.handles[ index ],
12865          value: newVal
12866        } );
12867        if ( allowed !== false ) {
12868          this.value( newVal );
12869        }
12870      }
12871    }
12872  },
12873
12874  _stop: function( event, index ) {
12875    var uiHash = {
12876      handle: this.handles[ index ],
12877      value: this.value()
12878    };
12879    if ( this.options.values && this.options.values.length ) {
12880      uiHash.value = this.values( index );
12881      uiHash.values = this.values();
12882    }
12883
12884    this._trigger( "stop", event, uiHash );
12885  },
12886
12887  _change: function( event, index ) {
12888    if ( !this._keySliding && !this._mouseSliding ) {
12889      var uiHash = {
12890        handle: this.handles[ index ],
12891        value: this.value()
12892      };
12893      if ( this.options.values && this.options.values.length ) {
12894        uiHash.value = this.values( index );
12895        uiHash.values = this.values();
12896      }
12897
12898      //store the last changed value index for reference when handles overlap
12899      this._lastChangedValue = index;
12900
12901      this._trigger( "change", event, uiHash );
12902    }
12903  },
12904
12905  value: function( newValue ) {
12906    if ( arguments.length ) {
12907      this.options.value = this._trimAlignValue( newValue );
12908      this._refreshValue();
12909      this._change( null, 0 );
12910      return;
12911    }
12912
12913    return this._value();
12914  },
12915
12916  values: function( index, newValue ) {
12917    var vals,
12918      newValues,
12919      i;
12920
12921    if ( arguments.length > 1 ) {
12922      this.options.values[ index ] = this._trimAlignValue( newValue );
12923      this._refreshValue();
12924      this._change( null, index );
12925      return;
12926    }
12927
12928    if ( arguments.length ) {
12929      if ( $.isArray( arguments[ 0 ] ) ) {
12930        vals = this.options.values;
12931        newValues = arguments[ 0 ];
12932        for ( i = 0; i < vals.length; i += 1 ) {
12933          vals[ i ] = this._trimAlignValue( newValues[ i ] );
12934          this._change( null, i );
12935        }
12936        this._refreshValue();
12937      } else {
12938        if ( this.options.values && this.options.values.length ) {
12939          return this._values( index );
12940        } else {
12941          return this.value();
12942        }
12943      }
12944    } else {
12945      return this._values();
12946    }
12947  },
12948
12949  _setOption: function( key, value ) {
12950    var i,
12951      valsLength = 0;
12952
12953    if ( key === "range" && this.options.range === true ) {
12954      if ( value === "min" ) {
12955        this.options.value = this._values( 0 );
12956        this.options.values = null;
12957      } else if ( value === "max" ) {
12958        this.options.value = this._values( this.options.values.length-1 );
12959        this.options.values = null;
12960      }
12961    }
12962
12963    if ( $.isArray( this.options.values ) ) {
12964      valsLength = this.options.values.length;
12965    }
12966
12967    $.Widget.prototype._setOption.apply( this, arguments );
12968
12969    switch ( key ) {
12970      case "orientation":
12971        this._detectOrientation();
12972        this.element
12973          .removeClass( "ui-slider-horizontal ui-slider-vertical" )
12974          .addClass( "ui-slider-" + this.orientation );
12975        this._refreshValue();
12976        break;
12977      case "value":
12978        this._animateOff = true;
12979        this._refreshValue();
12980        this._change( null, 0 );
12981        this._animateOff = false;
12982        break;
12983      case "values":
12984        this._animateOff = true;
12985        this._refreshValue();
12986        for ( i = 0; i < valsLength; i += 1 ) {
12987          this._change( null, i );
12988        }
12989        this._animateOff = false;
12990        break;
12991      case "min":
12992      case "max":
12993        this._animateOff = true;
12994        this._refreshValue();
12995        this._animateOff = false;
12996        break;
12997      case "range":
12998        this._animateOff = true;
12999        this._refresh();
13000        this._animateOff = false;
13001        break;
13002    }
13003  },
13004
13005  //internal value getter
13006  // _value() returns value trimmed by min and max, aligned by step
13007  _value: function() {
13008    var val = this.options.value;
13009    val = this._trimAlignValue( val );
13010
13011    return val;
13012  },
13013
13014  //internal values getter
13015  // _values() returns array of values trimmed by min and max, aligned by step
13016  // _values( index ) returns single value trimmed by min and max, aligned by step
13017  _values: function( index ) {
13018    var val,
13019      vals,
13020      i;
13021
13022    if ( arguments.length ) {
13023      val = this.options.values[ index ];
13024      val = this._trimAlignValue( val );
13025
13026      return val;
13027    } else if ( this.options.values && this.options.values.length ) {
13028      // .slice() creates a copy of the array
13029      // this copy gets trimmed by min and max and then returned
13030      vals = this.options.values.slice();
13031      for ( i = 0; i < vals.length; i+= 1) {
13032        vals[ i ] = this._trimAlignValue( vals[ i ] );
13033      }
13034
13035      return vals;
13036    } else {
13037      return [];
13038    }
13039  },
13040
13041  // returns the step-aligned value that val is closest to, between (inclusive) min and max
13042  _trimAlignValue: function( val ) {
13043    if ( val <= this._valueMin() ) {
13044      return this._valueMin();
13045    }
13046    if ( val >= this._valueMax() ) {
13047      return this._valueMax();
13048    }
13049    var step = ( this.options.step > 0 ) ? this.options.step : 1,
13050      valModStep = (val - this._valueMin()) % step,
13051      alignValue = val - valModStep;
13052
13053    if ( Math.abs(valModStep) * 2 >= step ) {
13054      alignValue += ( valModStep > 0 ) ? step : ( -step );
13055    }
13056
13057    // Since JavaScript has problems with large floats, round
13058    // the final value to 5 digits after the decimal point (see #4124)
13059    return parseFloat( alignValue.toFixed(5) );
13060  },
13061
13062  _valueMin: function() {
13063    return this.options.min;
13064  },
13065
13066  _valueMax: function() {
13067    return this.options.max;
13068  },
13069
13070  _refreshValue: function() {
13071    var lastValPercent, valPercent, value, valueMin, valueMax,
13072      oRange = this.options.range,
13073      o = this.options,
13074      that = this,
13075      animate = ( !this._animateOff ) ? o.animate : false,
13076      _set = {};
13077
13078    if ( this.options.values && this.options.values.length ) {
13079      this.handles.each(function( i ) {
13080        valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
13081        _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13082        $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13083        if ( that.options.range === true ) {
13084          if ( that.orientation === "horizontal" ) {
13085            if ( i === 0 ) {
13086              that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
13087            }
13088            if ( i === 1 ) {
13089              that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13090            }
13091          } else {
13092            if ( i === 0 ) {
13093              that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
13094            }
13095            if ( i === 1 ) {
13096              that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13097            }
13098          }
13099        }
13100        lastValPercent = valPercent;
13101      });
13102    } else {
13103      value = this.value();
13104      valueMin = this._valueMin();
13105      valueMax = this._valueMax();
13106      valPercent = ( valueMax !== valueMin ) ?
13107          ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
13108          0;
13109      _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13110      this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13111
13112      if ( oRange === "min" && this.orientation === "horizontal" ) {
13113        this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
13114      }
13115      if ( oRange === "max" && this.orientation === "horizontal" ) {
13116        this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13117      }
13118      if ( oRange === "min" && this.orientation === "vertical" ) {
13119        this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
13120      }
13121      if ( oRange === "max" && this.orientation === "vertical" ) {
13122        this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13123      }
13124    }
13125  },
13126
13127  _handleEvents: {
13128    keydown: function( event ) {
13129      var allowed, curVal, newVal, step,
13130        index = $( event.target ).data( "ui-slider-handle-index" );
13131
13132      switch ( event.keyCode ) {
13133        case $.ui.keyCode.HOME:
13134        case $.ui.keyCode.END:
13135        case $.ui.keyCode.PAGE_UP:
13136        case $.ui.keyCode.PAGE_DOWN:
13137        case $.ui.keyCode.UP:
13138        case $.ui.keyCode.RIGHT:
13139        case $.ui.keyCode.DOWN:
13140        case $.ui.keyCode.LEFT:
13141          event.preventDefault();
13142          if ( !this._keySliding ) {
13143            this._keySliding = true;
13144            $( event.target ).addClass( "ui-state-active" );
13145            allowed = this._start( event, index );
13146            if ( allowed === false ) {
13147              return;
13148            }
13149          }
13150          break;
13151      }
13152
13153      step = this.options.step;
13154      if ( this.options.values && this.options.values.length ) {
13155        curVal = newVal = this.values( index );
13156      } else {
13157        curVal = newVal = this.value();
13158      }
13159
13160      switch ( event.keyCode ) {
13161        case $.ui.keyCode.HOME:
13162          newVal = this._valueMin();
13163          break;
13164        case $.ui.keyCode.END:
13165          newVal = this._valueMax();
13166          break;
13167        case $.ui.keyCode.PAGE_UP:
13168          newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
13169          break;
13170        case $.ui.keyCode.PAGE_DOWN:
13171          newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
13172          break;
13173        case $.ui.keyCode.UP:
13174        case $.ui.keyCode.RIGHT:
13175          if ( curVal === this._valueMax() ) {
13176            return;
13177          }
13178          newVal = this._trimAlignValue( curVal + step );
13179          break;
13180        case $.ui.keyCode.DOWN:
13181        case $.ui.keyCode.LEFT:
13182          if ( curVal === this._valueMin() ) {
13183            return;
13184          }
13185          newVal = this._trimAlignValue( curVal - step );
13186          break;
13187      }
13188
13189      this._slide( event, index, newVal );
13190    },
13191    click: function( event ) {
13192      event.preventDefault();
13193    },
13194    keyup: function( event ) {
13195      var index = $( event.target ).data( "ui-slider-handle-index" );
13196
13197      if ( this._keySliding ) {
13198        this._keySliding = false;
13199        this._stop( event, index );
13200        this._change( event, index );
13201        $( event.target ).removeClass( "ui-state-active" );
13202      }
13203    }
13204  }
13205
13206});
13207
13208}( _4ORMAT.$ ));
13209(function( $, undefined ) {
13210
13211function isOverAxis( x, reference, size ) {
13212  return ( x > reference ) && ( x < ( reference + size ) );
13213}
13214
13215function isFloating(item) {
13216  return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
13217}
13218
13219$.widget("ui.sortable", $.ui.mouse, {
13220  version: "1.10.4",
13221  widgetEventPrefix: "sort",
13222  ready: false,
13223  options: {
13224    appendTo: "parent",
13225    axis: false,
13226    connectWith: false,
13227    containment: false,
13228    cursor: "auto",
13229    cursorAt: false,
13230    dropOnEmpty: true,
13231    forcePlaceholderSize: false,
13232    forceHelperSize: false,
13233    grid: false,
13234    handle: false,
13235    helper: "original",
13236    items: "> *",
13237    opacity: false,
13238    placeholder: false,
13239    revert: false,
13240    scroll: true,
13241    scrollSensitivity: 20,
13242    scrollSpeed: 20,
13243    scope: "default",
13244    tolerance: "intersect",
13245    zIndex: 1000,
13246
13247    // callbacks
13248    activate: null,
13249    beforeStop: null,
13250    change: null,
13251    deactivate: null,
13252    out: null,
13253    over: null,
13254    receive: null,
13255    remove: null,
13256    sort: null,
13257    start: null,
13258    stop: null,
13259    update: null
13260  },
13261  _create: function() {
13262
13263    var o = this.options;
13264    this.containerCache = {};
13265    this.element.addClass("ui-sortable");
13266
13267    //Get the items
13268    this.refresh();
13269
13270    //Let's determine if the items are being displayed horizontally
13271    this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
13272
13273    //Let's determine the parent's offset
13274    this.offset = this.element.offset();
13275
13276    //Initialize mouse events for interaction
13277    this._mouseInit();
13278
13279    //We're ready to go
13280    this.ready = true;
13281
13282  },
13283
13284  _destroy: function() {
13285    this.element
13286      .removeClass("ui-sortable ui-sortable-disabled");
13287    this._mouseDestroy();
13288
13289    for ( var i = this.items.length - 1; i >= 0; i-- ) {
13290      this.items[i].item.removeData(this.widgetName + "-item");
13291    }
13292
13293    return this;
13294  },
13295
13296  _setOption: function(key, value){
13297    if ( key === "disabled" ) {
13298      this.options[ key ] = value;
13299
13300      this.widget().toggleClass( "ui-sortable-disabled", !!value );
13301    } else {
13302      // Don't call widget base _setOption for disable as it adds ui-state-disabled class
13303      $.Widget.prototype._setOption.apply(this, arguments);
13304    }
13305  },
13306
13307  _mouseCapture: function(event, overrideHandle) {
13308    var currentItem = null,
13309      validHandle = false,
13310      that = this;
13311
13312    if (this.reverting) {
13313      return false;
13314    }
13315
13316    if(this.options.disabled || this.options.type === "static") {
13317      return false;
13318    }
13319
13320    //We have to refresh the items data once first
13321    this._refreshItems(event);
13322
13323    //Find out if the clicked node (or one of its parents) is a actual item in this.items
13324    $(event.target).parents().each(function() {
13325      if($.data(this, that.widgetName + "-item") === that) {
13326        currentItem = $(this);
13327        return false;
13328      }
13329    });
13330    if($.data(event.target, that.widgetName + "-item") === that) {
13331      currentItem = $(event.target);
13332    }
13333
13334    if(!currentItem) {
13335      return false;
13336    }
13337    if(this.options.handle && !overrideHandle) {
13338      $(this.options.handle, currentItem).find("*").addBack().each(function() {
13339        if(this === event.target) {
13340          validHandle = true;
13341        }
13342      });
13343      if(!validHandle) {
13344        return false;
13345      }
13346    }
13347
13348    this.currentItem = currentItem;
13349    this._removeCurrentsFromItems();
13350    return true;
13351
13352  },
13353
13354  _mouseStart: function(event, overrideHandle, noActivation) {
13355
13356    var i, body,
13357      o = this.options;
13358
13359    this.currentContainer = this;
13360
13361    //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
13362    this.refreshPositions();
13363
13364    //Create and append the visible helper
13365    this.helper = this._createHelper(event);
13366
13367    //Cache the helper size
13368    this._cacheHelperProportions();
13369
13370    /*
13371     * - Position generation -
13372     * This block generates everything position related - it's the core of draggables.
13373     */
13374
13375    //Cache the margins of the original element
13376    this._cacheMargins();
13377
13378    //Get the next scrolling parent
13379    this.scrollParent = this.helper.scrollParent();
13380
13381    //The element's absolute position on the page minus margins
13382    this.offset = this.currentItem.offset();
13383    this.offset = {
13384      top: this.offset.top - this.margins.top,
13385      left: this.offset.left - this.margins.left
13386    };
13387
13388    $.extend(this.offset, {
13389      click: { //Where the click happened, relative to the element
13390        left: event.pageX - this.offset.left,
13391        top: event.pageY - this.offset.top
13392      },
13393      parent: this._getParentOffset(),
13394      relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
13395    });
13396
13397    // Only after we got the offset, we can change the helper's position to absolute
13398    // TODO: Still need to figure out a way to make relative sorting possible
13399    this.helper.css("position", "absolute");
13400    this.cssPosition = this.helper.css("position");
13401
13402    //Generate the original position
13403    this.originalPosition = this._generatePosition(event);
13404    this.originalPageX = event.pageX;
13405    this.originalPageY = event.pageY;
13406
13407    //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
13408    (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
13409
13410    //Cache the former DOM position
13411    this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
13412
13413    //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
13414    if(this.helper[0] !== this.currentItem[0]) {
13415      this.currentItem.hide();
13416    }
13417
13418    //Create the placeholder
13419    this._createPlaceholder();
13420
13421    //Set a containment if given in the options
13422    if(o.containment) {
13423      this._setContainment();
13424    }
13425
13426    if( o.cursor && o.cursor !== "auto" ) { // cursor option
13427      body = this.document.find( "body" );
13428
13429      // support: IE
13430      this.storedCursor = body.css( "cursor" );
13431      body.css( "cursor", o.cursor );
13432
13433      this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
13434    }
13435
13436    if(o.opacity) { // opacity option
13437      if (this.helper.css("opacity")) {
13438        this._storedOpacity = this.helper.css("opacity");
13439      }
13440      this.helper.css("opacity", o.opacity);
13441    }
13442
13443    if(o.zIndex) { // zIndex option
13444      if (this.helper.css("zIndex")) {
13445        this._storedZIndex = this.helper.css("zIndex");
13446      }
13447      this.helper.css("zIndex", o.zIndex);
13448    }
13449
13450    //Prepare scrolling
13451    if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
13452      this.overflowOffset = this.scrollParent.offset();
13453    }
13454
13455    //Call callbacks
13456    this._trigger("start", event, this._uiHash());
13457
13458    //Recache the helper size
13459    if(!this._preserveHelperProportions) {
13460      this._cacheHelperProportions();
13461    }
13462
13463
13464    //Post "activate" events to possible containers
13465    if( !noActivation ) {
13466      for ( i = this.containers.length - 1; i >= 0; i-- ) {
13467        this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
13468      }
13469    }
13470
13471    //Prepare possible droppables
13472    if($.ui.ddmanager) {
13473      $.ui.ddmanager.current = this;
13474    }
13475
13476    if ($.ui.ddmanager && !o.dropBehaviour) {
13477      $.ui.ddmanager.prepareOffsets(this, event);
13478    }
13479
13480    this.dragging = true;
13481
13482    this.helper.addClass("ui-sortable-helper");
13483    this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
13484    return true;
13485
13486  },
13487
13488  _mouseDrag: function(event) {
13489    var i, item, itemElement, intersection,
13490      o = this.options,
13491      scrolled = false;
13492
13493    //Compute the helpers position
13494    this.position = this._generatePosition(event);
13495    this.positionAbs = this._convertPositionTo("absolute");
13496
13497    if (!this.lastPositionAbs) {
13498      this.lastPositionAbs = this.positionAbs;
13499    }
13500
13501    //Do scrolling
13502    if(this.options.scroll) {
13503      if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
13504
13505        if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
13506          this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
13507        } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
13508          this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
13509        }
13510
13511        if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
13512          this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
13513        } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
13514          this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
13515        }
13516
13517      } else {
13518
13519        if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
13520          scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
13521        } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
13522          scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
13523        }
13524
13525        if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
13526          scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
13527        } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
13528          scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
13529        }
13530
13531      }
13532
13533      if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
13534        $.ui.ddmanager.prepareOffsets(this, event);
13535      }
13536    }
13537
13538    //Regenerate the absolute position used for position checks
13539    this.positionAbs = this._convertPositionTo("absolute");
13540
13541    //Set the helper position
13542    if(!this.options.axis || this.options.axis !== "y") {
13543      this.helper[0].style.left = this.position.left+"px";
13544    }
13545    if(!this.options.axis || this.options.axis !== "x") {
13546      this.helper[0].style.top = this.position.top+"px";
13547    }
13548
13549    //Rearrange
13550    for (i = this.items.length - 1; i >= 0; i--) {
13551
13552      //Cache variables and intersection, continue if no intersection
13553      item = this.items[i];
13554      itemElement = item.item[0];
13555      intersection = this._intersectsWithPointer(item);
13556      if (!intersection) {
13557        continue;
13558      }
13559
13560      // Only put the placeholder inside the current Container, skip all
13561      // items from other containers. This works because when moving
13562      // an item from one container to another the
13563      // currentContainer is switched before the placeholder is moved.
13564      //
13565      // Without this, moving items in "sub-sortables" can cause
13566      // the placeholder to jitter beetween the outer and inner container.
13567      if (item.instance !== this.currentContainer) {
13568        continue;
13569      }
13570
13571      // cannot intersect with itself
13572      // no useless actions that have been done before
13573      // no action if the item moved is the parent of the item checked
13574      if (itemElement !== this.currentItem[0] &&
13575        this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
13576        !$.contains(this.placeholder[0], itemElement) &&
13577        (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
13578      ) {
13579
13580        this.direction = intersection === 1 ? "down" : "up";
13581
13582        if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
13583          this._rearrange(event, item);
13584        } else {
13585          break;
13586        }
13587
13588        this._trigger("change", event, this._uiHash());
13589        break;
13590      }
13591    }
13592
13593    //Post events to containers
13594    this._contactContainers(event);
13595
13596    //Interconnect with droppables
13597    if($.ui.ddmanager) {
13598      $.ui.ddmanager.drag(this, event);
13599    }
13600
13601    //Call callbacks
13602    this._trigger("sort", event, this._uiHash());
13603
13604    this.lastPositionAbs = this.positionAbs;
13605    return false;
13606
13607  },
13608
13609  _mouseStop: function(event, noPropagation) {
13610
13611    if(!event) {
13612      return;
13613    }
13614
13615    //If we are using droppables, inform the manager about the drop
13616    if ($.ui.ddmanager && !this.options.dropBehaviour) {
13617      $.ui.ddmanager.drop(this, event);
13618    }
13619
13620    if(this.options.revert) {
13621      var that = this,
13622        cur = this.placeholder.offset(),
13623        axis = this.options.axis,
13624        animation = {};
13625
13626      if ( !axis || axis === "x" ) {
13627        animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
13628      }
13629      if ( !axis || axis === "y" ) {
13630        animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
13631      }
13632      this.reverting = true;
13633      $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
13634        that._clear(event);
13635      });
13636    } else {
13637      this._clear(event, noPropagation);
13638    }
13639
13640    return false;
13641
13642  },
13643
13644  cancel: function() {
13645
13646    if(this.dragging) {
13647
13648      this._mouseUp({ target: null });
13649
13650      if(this.options.helper === "original") {
13651        this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
13652      } else {
13653        this.currentItem.show();
13654      }
13655
13656      //Post deactivating events to containers
13657      for (var i = this.containers.length - 1; i >= 0; i--){
13658        this.containers[i]._trigger("deactivate", null, this._uiHash(this));
13659        if(this.containers[i].containerCache.over) {
13660          this.containers[i]._trigger("out", null, this._uiHash(this));
13661          this.containers[i].containerCache.over = 0;
13662        }
13663      }
13664
13665    }
13666
13667    if (this.placeholder) {
13668      //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
13669      if(this.placeholder[0].parentNode) {
13670        this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
13671      }
13672      if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
13673        this.helper.remove();
13674      }
13675
13676      $.extend(this, {
13677        helper: null,
13678        dragging: false,
13679        reverting: false,
13680        _noFinalSort: null
13681      });
13682
13683      if(this.domPosition.prev) {
13684        $(this.domPosition.prev).after(this.currentItem);
13685      } else {
13686        $(this.domPosition.parent).prepend(this.currentItem);
13687      }
13688    }
13689
13690    return this;
13691
13692  },
13693
13694  serialize: function(o) {
13695
13696    var items = this._getItemsAsjQuery(o && o.connected),
13697      str = [];
13698    o = o || {};
13699
13700    $(items).each(function() {
13701      var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
13702      if (res) {
13703        str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
13704      }
13705    });
13706
13707    if(!str.length && o.key) {
13708      str.push(o.key + "=");
13709    }
13710
13711    return str.join("&");
13712
13713  },
13714
13715  toArray: function(o) {
13716
13717    var items = this._getItemsAsjQuery(o && o.connected),
13718      ret = [];
13719
13720    o = o || {};
13721
13722    items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
13723    return ret;
13724
13725  },
13726
13727  /* Be careful with the following core functions */
13728  _intersectsWith: function(item) {
13729
13730    var x1 = this.positionAbs.left,
13731      x2 = x1 + this.helperProportions.width,
13732      y1 = this.positionAbs.top,
13733      y2 = y1 + this.helperProportions.height,
13734      l = item.left,
13735      r = l + item.width,
13736      t = item.top,
13737      b = t + item.height,
13738      dyClick = this.offset.click.top,
13739      dxClick = this.offset.click.left,
13740      isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
13741      isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
13742      isOverElement = isOverElementHeight && isOverElementWidth;
13743
13744    if ( this.options.tolerance === "pointer" ||
13745      this.options.forcePointerForContainers ||
13746      (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
13747    ) {
13748      return isOverElement;
13749    } else {
13750
13751      return (l < x1 + (this.helperProportions.width / 2) && // Right Half
13752        x2 - (this.helperProportions.width / 2) < r && // Left Half
13753        t < y1 + (this.helperProportions.height / 2) && // Bottom Half
13754        y2 - (this.helperProportions.height / 2) < b ); // Top Half
13755
13756    }
13757  },
13758
13759  _intersectsWithPointer: function(item) {
13760
13761    var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
13762      isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
13763      isOverElement = isOverElementHeight && isOverElementWidth,
13764      verticalDirection = this._getDragVerticalDirection(),
13765      horizontalDirection = this._getDragHorizontalDirection();
13766
13767    if (!isOverElement) {
13768      return false;
13769    }
13770
13771    return this.floating ?
13772      ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
13773      : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
13774
13775  },
13776
13777  _intersectsWithSides: function(item) {
13778
13779    var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
13780      isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
13781      verticalDirection = this._getDragVerticalDirection(),
13782      horizontalDirection = this._getDragHorizontalDirection();
13783
13784    if (this.floating && horizontalDirection) {
13785      return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
13786    } else {
13787      return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
13788    }
13789
13790  },
13791
13792  _getDragVerticalDirection: function() {
13793    var delta = this.positionAbs.top - this.lastPositionAbs.top;
13794    return delta !== 0 && (delta > 0 ? "down" : "up");
13795  },
13796
13797  _getDragHorizontalDirection: function() {
13798    var delta = this.positionAbs.left - this.lastPositionAbs.left;
13799    return delta !== 0 && (delta > 0 ? "right" : "left");
13800  },
13801
13802  refresh: function(event) {
13803    this._refreshItems(event);
13804    this.refreshPositions();
13805    return this;
13806  },
13807
13808  _connectWith: function() {
13809    var options = this.options;
13810    return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
13811  },
13812
13813  _getItemsAsjQuery: function(connected) {
13814
13815    var i, j, cur, inst,
13816      items = [],
13817      queries = [],
13818      connectWith = this._connectWith();
13819
13820    if(connectWith && connected) {
13821      for (i = connectWith.length - 1; i >= 0; i--){
13822        cur = $(connectWith[i]);
13823        for ( j = cur.length - 1; j >= 0; j--){
13824          inst = $.data(cur[j], this.widgetFullName);
13825          if(inst && inst !== this && !inst.options.disabled) {
13826            queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
13827          }
13828        }
13829      }
13830    }
13831
13832    queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
13833
13834    function addItems() {
13835      items.push( this );
13836    }
13837    for (i = queries.length - 1; i >= 0; i--){
13838      queries[i][0].each( addItems );
13839    }
13840
13841    return $(items);
13842
13843  },
13844
13845  _removeCurrentsFromItems: function() {
13846
13847    var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
13848
13849    this.items = $.grep(this.items, function (item) {
13850      for (var j=0; j < list.length; j++) {
13851        if(list[j] === item.item[0]) {
13852          return false;
13853        }
13854      }
13855      return true;
13856    });
13857
13858  },
13859
13860  _refreshItems: function(event) {
13861
13862    this.items = [];
13863    this.containers = [this];
13864
13865    var i, j, cur, inst, targetData, _queries, item, queriesLength,
13866      items = this.items,
13867      queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
13868      connectWith = this._connectWith();
13869
13870    if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
13871      for (i = connectWith.length - 1; i >= 0; i--){
13872        cur = $(connectWith[i]);
13873        for (j = cur.length - 1; j >= 0; j--){
13874          inst = $.data(cur[j], this.widgetFullName);
13875          if(inst && inst !== this && !inst.options.disabled) {
13876            queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
13877            this.containers.push(inst);
13878          }
13879        }
13880      }
13881    }
13882
13883    for (i = queries.length - 1; i >= 0; i--) {
13884      targetData = queries[i][1];
13885      _queries = queries[i][0];
13886
13887      for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
13888        item = $(_queries[j]);
13889
13890        item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
13891
13892        items.push({
13893          item: item,
13894          instance: targetData,
13895          width: 0, height: 0,
13896          left: 0, top: 0
13897        });
13898      }
13899    }
13900
13901  },
13902
13903  refreshPositions: function(fast) {
13904
13905    //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
13906    if(this.offsetParent && this.helper) {
13907      this.offset.parent = this._getParentOffset();
13908    }
13909
13910    var i, item, t, p;
13911
13912    for (i = this.items.length - 1; i >= 0; i--){
13913      item = this.items[i];
13914
13915      //We ignore calculating positions of all connected containers when we're not over them
13916      if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
13917        continue;
13918      }
13919
13920      t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
13921
13922      if (!fast) {
13923        item.width = t.outerWidth();
13924        item.height = t.outerHeight();
13925      }
13926
13927      p = t.offset();
13928      item.left = p.left;
13929      item.top = p.top;
13930    }
13931
13932    if(this.options.custom && this.options.custom.refreshContainers) {
13933      this.options.custom.refreshContainers.call(this);
13934    } else {
13935      for (i = this.containers.length - 1; i >= 0; i--){
13936        p = this.containers[i].element.offset();
13937        this.containers[i].containerCache.left = p.left;
13938        this.containers[i].containerCache.top = p.top;
13939        this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
13940        this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
13941      }
13942    }
13943
13944    return this;
13945  },
13946
13947  _createPlaceholder: function(that) {
13948    that = that || this;
13949    var className,
13950      o = that.options;
13951
13952    if(!o.placeholder || o.placeholder.constructor === String) {
13953      className = o.placeholder;
13954      o.placeholder = {
13955        element: function() {
13956
13957          var nodeName = that.currentItem[0].nodeName.toLowerCase(),
13958            element = $( "<" + nodeName + ">", that.document[0] )
13959              .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
13960              .removeClass("ui-sortable-helper");
13961
13962          if ( nodeName === "tr" ) {
13963            that.currentItem.children().each(function() {
13964              $( "<td>&#160;</td>", that.document[0] )
13965                .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
13966                .appendTo( element );
13967            });
13968          } else if ( nodeName === "img" ) {
13969            element.attr( "src", that.currentItem.attr( "src" ) );
13970          }
13971
13972          if ( !className ) {
13973            element.css( "visibility", "hidden" );
13974          }
13975
13976          return element;
13977        },
13978        update: function(container, p) {
13979
13980          // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
13981          // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
13982          if(className && !o.forcePlaceholderSize) {
13983            return;
13984          }
13985
13986          //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
13987          if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
13988          if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
13989        }
13990      };
13991    }
13992
13993    //Create the placeholder
13994    that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
13995
13996    //Append it after the actual current item
13997    that.currentItem.after(that.placeholder);
13998
13999    //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
14000    o.placeholder.update(that, that.placeholder);
14001
14002  },
14003
14004  _contactContainers: function(event) {
14005    var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
14006      innermostContainer = null,
14007      innermostIndex = null;
14008
14009    // get innermost container that intersects with item
14010    for (i = this.containers.length - 1; i >= 0; i--) {
14011
14012      // never consider a container that's located within the item itself
14013      if($.contains(this.currentItem[0], this.containers[i].element[0])) {
14014        continue;
14015      }
14016
14017      if(this._intersectsWith(this.containers[i].containerCache)) {
14018
14019        // if we've already found a container and it's more "inner" than this, then continue
14020        if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
14021          continue;
14022        }
14023
14024        innermostContainer = this.containers[i];
14025        innermostIndex = i;
14026
14027      } else {
14028        // container doesn't intersect. trigger "out" event if necessary
14029        if(this.containers[i].containerCache.over) {
14030          this.containers[i]._trigger("out", event, this._uiHash(this));
14031          this.containers[i].containerCache.over = 0;
14032        }
14033      }
14034
14035    }
14036
14037    // if no intersecting containers found, return
14038    if(!innermostContainer) {
14039      return;
14040    }
14041
14042    // move the item into the container if it's not there already
14043    if(this.containers.length === 1) {
14044      if (!this.containers[innermostIndex].containerCache.over) {
14045        this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
14046        this.containers[innermostIndex].containerCache.over = 1;
14047      }
14048    } else {
14049
14050      //When entering a new container, we will find the item with the least distance and append our item near it
14051      dist = 10000;
14052      itemWithLeastDistance = null;
14053      floating = innermostContainer.floating || isFloating(this.currentItem);
14054      posProperty = floating ? "left" : "top";
14055      sizeProperty = floating ? "width" : "height";
14056      base = this.positionAbs[posProperty] + this.offset.click[posProperty];
14057      for (j = this.items.length - 1; j >= 0; j--) {
14058        if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
14059          continue;
14060        }
14061        if(this.items[j].item[0] === this.currentItem[0]) {
14062          continue;
14063        }
14064        if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
14065          continue;
14066        }
14067        cur = this.items[j].item.offset()[posProperty];
14068        nearBottom = false;
14069        if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
14070          nearBottom = true;
14071          cur += this.items[j][sizeProperty];
14072        }
14073
14074        if(Math.abs(cur - base) < dist) {
14075          dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
14076          this.direction = nearBottom ? "up": "down";
14077        }
14078      }
14079
14080      //Check if dropOnEmpty is enabled
14081      if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
14082        return;
14083      }
14084
14085      if(this.currentContainer === this.containers[innermostIndex]) {
14086        return;
14087      }
14088
14089      itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
14090      this._trigger("change", event, this._uiHash());
14091      this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
14092      this.currentContainer = this.containers[innermostIndex];
14093
14094      //Update the placeholder
14095      this.options.placeholder.update(this.currentContainer, this.placeholder);
14096
14097      this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
14098      this.containers[innermostIndex].containerCache.over = 1;
14099    }
14100
14101
14102  },
14103
14104  _createHelper: function(event) {
14105
14106    var o = this.options,
14107      helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
14108
14109    //Add the helper to the DOM if that didn't happen already
14110    if(!helper.parents("body").length) {
14111      $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
14112    }
14113
14114    if(helper[0] === this.currentItem[0]) {
14115      this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left
vendor: 23,930 bytes, lines 14115-14790
14115: this.currentItem.css("left") };
14116    }
14117
14118    if(!helper[0].style.width || o.forceHelperSize) {
14119      helper.width(this.currentItem.width());
14120    }
14121    if(!helper[0].style.height || o.forceHelperSize) {
14122      helper.height(this.currentItem.height());
14123    }
14124
14125    return helper;
14126
14127  },
14128
14129  _adjustOffsetFromHelper: function(obj) {
14130    if (typeof obj === "string") {
14131      obj = obj.split(" ");
14132    }
14133    if ($.isArray(obj)) {
14134      obj = {left: +obj[0], top: +obj[1] || 0};
14135    }
14136    if ("left" in obj) {
14137      this.offset.click.left = obj.left + this.margins.left;
14138    }
14139    if ("right" in obj) {
14140      this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
14141    }
14142    if ("top" in obj) {
14143      this.offset.click.top = obj.top + this.margins.top;
14144    }
14145    if ("bottom" in obj) {
14146      this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
14147    }
14148  },
14149
14150  _getParentOffset: function() {
14151
14152
14153    //Get the offsetParent and cache its position
14154    this.offsetParent = this.helper.offsetParent();
14155    var po = this.offsetParent.offset();
14156
14157    // This is a special case where we need to modify a offset calculated on start, since the following happened:
14158    // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
14159    // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
14160    //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
14161    if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
14162      po.left += this.scrollParent.scrollLeft();
14163      po.top += this.scrollParent.scrollTop();
14164    }
14165
14166    // This needs to be actually done for all browsers, since pageX/pageY includes this information
14167    // with an ugly IE fix
14168    if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
14169      po = { top: 0, left: 0 };
14170    }
14171
14172    return {
14173      top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
14174      left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
14175    };
14176
14177  },
14178
14179  _getRelativeOffset: function() {
14180
14181    if(this.cssPosition === "relative") {
14182      var p = this.currentItem.position();
14183      return {
14184        top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
14185        left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
14186      };
14187    } else {
14188      return { top: 0, left: 0 };
14189    }
14190
14191  },
14192
14193  _cacheMargins: function() {
14194    this.margins = {
14195      left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
14196      top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
14197    };
14198  },
14199
14200  _cacheHelperProportions: function() {
14201    this.helperProportions = {
14202      width: this.helper.outerWidth(),
14203      height: this.helper.outerHeight()
14204    };
14205  },
14206
14207  _setContainment: function() {
14208
14209    var ce, co, over,
14210      o = this.options;
14211    if(o.containment === "parent") {
14212      o.containment = this.helper[0].parentNode;
14213    }
14214    if(o.containment === "document" || o.containment === "window") {
14215      this.containment = [
14216        0 - this.offset.relative.left - this.offset.parent.left,
14217        0 - this.offset.relative.top - this.offset.parent.top,
14218        $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
14219        ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
14220      ];
14221    }
14222
14223    if(!(/^(document|window|parent)$/).test(o.containment)) {
14224      ce = $(o.containment)[0];
14225      co = $(o.containment).offset();
14226      over = ($(ce).css("overflow") !== "hidden");
14227
14228      this.containment = [
14229        co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
14230        co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
14231        co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
14232        co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
14233      ];
14234    }
14235
14236  },
14237
14238  _convertPositionTo: function(d, pos) {
14239
14240    if(!pos) {
14241      pos = this.position;
14242    }
14243    var mod = d === "absolute" ? 1 : -1,
14244      scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
14245      scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
14246
14247    return {
14248      top: (
14249        pos.top +                               // The absolute mouse position
14250        this.offset.relative.top * mod +                    // Only for relative positioned nodes: Relative offset from element to offset parent
14251        this.offset.parent.top * mod -                      // The offsetParent's offset without borders (offset + border)
14252        ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
14253      ),
14254      left: (
14255        pos.left +                                // The absolute mouse position
14256        this.offset.relative.left * mod +                   // Only for relative positioned nodes: Relative offset from element to offset parent
14257        this.offset.parent.left * mod -                   // The offsetParent's offset without borders (offset + border)
14258        ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
14259      )
14260    };
14261
14262  },
14263
14264  _generatePosition: function(event) {
14265
14266    var top, left,
14267      o = this.options,
14268      pageX = event.pageX,
14269      pageY = event.pageY,
14270      scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
14271
14272    // This is another very weird special case that only happens for relative elements:
14273    // 1. If the css position is relative
14274    // 2. and the scroll parent is the document or similar to the offset parent
14275    // we have to refresh the relative offset during the scroll so there are no jumps
14276    if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
14277      this.offset.relative = this._getRelativeOffset();
14278    }
14279
14280    /*
14281     * - Position constraining -
14282     * Constrain the position to a mix of grid, containment.
14283     */
14284
14285    if(this.originalPosition) { //If we are not dragging yet, we won't check for options
14286
14287      if(this.containment) {
14288        if(event.pageX - this.offset.click.left < this.containment[0]) {
14289          pageX = this.containment[0] + this.offset.click.left;
14290        }
14291        if(event.pageY - this.offset.click.top < this.containment[1]) {
14292          pageY = this.containment[1] + this.offset.click.top;
14293        }
14294        if(event.pageX - this.offset.click.left > this.containment[2]) {
14295          pageX = this.containment[2] + this.offset.click.left;
14296        }
14297        if(event.pageY - this.offset.click.top > this.containment[3]) {
14298          pageY = this.containment[3] + this.offset.click.top;
14299        }
14300      }
14301
14302      if(o.grid) {
14303        top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
14304        pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
14305
14306        left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
14307        pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
14308      }
14309
14310    }
14311
14312    return {
14313      top: (
14314        pageY -                               // The absolute mouse position
14315        this.offset.click.top -                         // Click offset (relative to the element)
14316        this.offset.relative.top  -                     // Only for relative positioned nodes: Relative offset from element to offset parent
14317        this.offset.parent.top +                        // The offsetParent's offset without borders (offset + border)
14318        ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
14319      ),
14320      left: (
14321        pageX -                               // The absolute mouse position
14322        this.offset.click.left -                        // Click offset (relative to the element)
14323        this.offset.relative.left -                     // Only for relative positioned nodes: Relative offset from element to offset parent
14324        this.offset.parent.left +                       // The offsetParent's offset without borders (offset + border)
14325        ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
14326      )
14327    };
14328
14329  },
14330
14331  _rearrange: function(event, i, a, hardRefresh) {
14332
14333    a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
14334
14335    //Various things done here to improve the performance:
14336    // 1. we create a setTimeout, that calls refreshPositions
14337    // 2. on the instance, we have a counter variable, that get's higher after every append
14338    // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
14339    // 4. this lets only the last addition to the timeout stack through
14340    this.counter = this.counter ? ++this.counter : 1;
14341    var counter = this.counter;
14342
14343    this._delay(function() {
14344      if(counter === this.counter) {
14345        this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
14346      }
14347    });
14348
14349  },
14350
14351  _clear: function(event, noPropagation) {
14352
14353    this.reverting = false;
14354    // We delay all events that have to be triggered to after the point where the placeholder has been removed and
14355    // everything else normalized again
14356    var i,
14357      delayedTriggers = [];
14358
14359    // We first have to update the dom position of the actual currentItem
14360    // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
14361    if(!this._noFinalSort && this.currentItem.parent().length) {
14362      this.placeholder.before(this.currentItem);
14363    }
14364    this._noFinalSort = null;
14365
14366    if(this.helper[0] === this.currentItem[0]) {
14367      for(i in this._storedCSS) {
14368        if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
14369          this._storedCSS[i] = "";
14370        }
14371      }
14372      this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
14373    } else {
14374      this.currentItem.show();
14375    }
14376
14377    if(this.fromOutside && !noPropagation) {
14378      delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
14379    }
14380    if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
14381      delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
14382    }
14383
14384    // Check if the items Container has Changed and trigger appropriate
14385    // events.
14386    if (this !== this.currentContainer) {
14387      if(!noPropagation) {
14388        delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
14389        delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
14390        delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
14391      }
14392    }
14393
14394
14395    //Post events to containers
14396    function delayEvent( type, instance, container ) {
14397      return function( event ) {
14398        container._trigger( type, event, instance._uiHash( instance ) );
14399      };
14400    }
14401    for (i = this.containers.length - 1; i >= 0; i--){
14402      if (!noPropagation) {
14403        delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
14404      }
14405      if(this.containers[i].containerCache.over) {
14406        delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
14407        this.containers[i].containerCache.over = 0;
14408      }
14409    }
14410
14411    //Do what was originally in plugins
14412    if ( this.storedCursor ) {
14413      this.document.find( "body" ).css( "cursor", this.storedCursor );
14414      this.storedStylesheet.remove();
14415    }
14416    if(this._storedOpacity) {
14417      this.helper.css("opacity", this._storedOpacity);
14418    }
14419    if(this._storedZIndex) {
14420      this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
14421    }
14422
14423    this.dragging = false;
14424    if(this.cancelHelperRemoval) {
14425      if(!noPropagation) {
14426        this._trigger("beforeStop", event, this._uiHash());
14427        for (i=0; i < delayedTriggers.length; i++) {
14428          delayedTriggers[i].call(this, event);
14429        } //Trigger all delayed events
14430        this._trigger("stop", event, this._uiHash());
14431      }
14432
14433      this.fromOutside = false;
14434      return false;
14435    }
14436
14437    if(!noPropagation) {
14438      this._trigger("beforeStop", event, this._uiHash());
14439    }
14440
14441    //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
14442    this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
14443
14444    if(this.helper[0] !== this.currentItem[0]) {
14445      this.helper.remove();
14446    }
14447    this.helper = null;
14448
14449    if(!noPropagation) {
14450      for (i=0; i < delayedTriggers.length; i++) {
14451        delayedTriggers[i].call(this, event);
14452      } //Trigger all delayed events
14453      this._trigger("stop", event, this._uiHash());
14454    }
14455
14456    this.fromOutside = false;
14457    return true;
14458
14459  },
14460
14461  _trigger: function() {
14462    if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
14463      this.cancel();
14464    }
14465  },
14466
14467  _uiHash: function(_inst) {
14468    var inst = _inst || this;
14469    return {
14470      helper: inst.helper,
14471      placeholder: inst.placeholder || $([]),
14472      position: inst.position,
14473      originalPosition: inst.originalPosition,
14474      offset: inst.positionAbs,
14475      item: inst.currentItem,
14476      sender: _inst ? _inst.element : null
14477    };
14478  }
14479
14480});
14481
14482})( _4ORMAT.$ );
14483(function( $ ) {
14484
14485function modifier( fn ) {
14486  return function() {
14487    var previous = this.element.val();
14488    fn.apply( this, arguments );
14489    this._refresh();
14490    if ( previous !== this.element.val() ) {
14491      this._trigger( "change" );
14492    }
14493  };
14494}
14495
14496$.widget( "ui.spinner", {
14497  version: "1.10.4",
14498  defaultElement: "<input>",
14499  widgetEventPrefix: "spin",
14500  options: {
14501    culture: null,
14502    icons: {
14503      down: "ui-icon-triangle-1-s",
14504      up: "ui-icon-triangle-1-n"
14505    },
14506    incremental: true,
14507    max: null,
14508    min: null,
14509    numberFormat: null,
14510    page: 10,
14511    step: 1,
14512
14513    change: null,
14514    spin: null,
14515    start: null,
14516    stop: null
14517  },
14518
14519  _create: function() {
14520    // handle string values that need to be parsed
14521    this._setOption( "max", this.options.max );
14522    this._setOption( "min", this.options.min );
14523    this._setOption( "step", this.options.step );
14524
14525    // Only format if there is a value, prevents the field from being marked
14526    // as invalid in Firefox, see #9573.
14527    if ( this.value() !== "" ) {
14528      // Format the value, but don't constrain.
14529      this._value( this.element.val(), true );
14530    }
14531
14532    this._draw();
14533    this._on( this._events );
14534    this._refresh();
14535
14536    // turning off autocomplete prevents the browser from remembering the
14537    // value when navigating through history, so we re-enable autocomplete
14538    // if the page is unloaded before the widget is destroyed. #7790
14539    this._on( this.window, {
14540      beforeunload: function() {
14541        this.element.removeAttr( "autocomplete" );
14542      }
14543    });
14544  },
14545
14546  _getCreateOptions: function() {
14547    var options = {},
14548      element = this.element;
14549
14550    $.each( [ "min", "max", "step" ], function( i, option ) {
14551      var value = element.attr( option );
14552      if ( value !== undefined && value.length ) {
14553        options[ option ] = value;
14554      }
14555    });
14556
14557    return options;
14558  },
14559
14560  _events: {
14561    keydown: function( event ) {
14562      if ( this._start( event ) && this._keydown( event ) ) {
14563        event.preventDefault();
14564      }
14565    },
14566    keyup: "_stop",
14567    focus: function() {
14568      this.previous = this.element.val();
14569    },
14570    blur: function( event ) {
14571      if ( this.cancelBlur ) {
14572        delete this.cancelBlur;
14573        return;
14574      }
14575
14576      this._stop();
14577      this._refresh();
14578      if ( this.previous !== this.element.val() ) {
14579        this._trigger( "change", event );
14580      }
14581    },
14582    mousewheel: function( event, delta ) {
14583      if ( !delta ) {
14584        return;
14585      }
14586      if ( !this.spinning && !this._start( event ) ) {
14587        return false;
14588      }
14589
14590      this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
14591      clearTimeout( this.mousewheelTimer );
14592      this.mousewheelTimer = this._delay(function() {
14593        if ( this.spinning ) {
14594          this._stop( event );
14595        }
14596      }, 100 );
14597      event.preventDefault();
14598    },
14599    "mousedown .ui-spinner-button": function( event ) {
14600      var previous;
14601
14602      // We never want the buttons to have focus; whenever the user is
14603      // interacting with the spinner, the focus should be on the input.
14604      // If the input is focused then this.previous is properly set from
14605      // when the input first received focus. If the input is not focused
14606      // then we need to set this.previous based on the value before spinning.
14607      previous = this.element[0] === this.document[0].activeElement ?
14608        this.previous : this.element.val();
14609      function checkFocus() {
14610        var isActive = this.element[0] === this.document[0].activeElement;
14611        if ( !isActive ) {
14612          this.element.focus();
14613          this.previous = previous;
14614          // support: IE
14615          // IE sets focus asynchronously, so we need to check if focus
14616          // moved off of the input because the user clicked on the button.
14617          this._delay(function() {
14618            this.previous = previous;
14619          });
14620        }
14621      }
14622
14623      // ensure focus is on (or stays on) the text field
14624      event.preventDefault();
14625      checkFocus.call( this );
14626
14627      // support: IE
14628      // IE doesn't prevent moving focus even with event.preventDefault()
14629      // so we set a flag to know when we should ignore the blur event
14630      // and check (again) if focus moved off of the input.
14631      this.cancelBlur = true;
14632      this._delay(function() {
14633        delete this.cancelBlur;
14634        checkFocus.call( this );
14635      });
14636
14637      if ( this._start( event ) === false ) {
14638        return;
14639      }
14640
14641      this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14642    },
14643    "mouseup .ui-spinner-button": "_stop",
14644    "mouseenter .ui-spinner-button": function( event ) {
14645      // button will add ui-state-active if mouse was down while mouseleave and kept down
14646      if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
14647        return;
14648      }
14649
14650      if ( this._start( event ) === false ) {
14651        return false;
14652      }
14653      this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14654    },
14655    // TODO: do we really want to consider this a stop?
14656    // shouldn't we just stop the repeater and wait until mouseup before
14657    // we trigger the stop event?
14658    "mouseleave .ui-spinner-button": "_stop"
14659  },
14660
14661  _draw: function() {
14662    var uiSpinner = this.uiSpinner = this.element
14663      .addClass( "ui-spinner-input" )
14664      .attr( "autocomplete", "off" )
14665      .wrap( this._uiSpinnerHtml() )
14666      .parent()
14667        // add buttons
14668        .append( this._buttonHtml() );
14669
14670    this.element.attr( "role", "spinbutton" );
14671
14672    // button bindings
14673    this.buttons = uiSpinner.find( ".ui-spinner-button" )
14674      .attr( "tabIndex", -1 )
14675      .button()
14676      .removeClass( "ui-corner-all" );
14677
14678    // IE 6 doesn't understand height: 50% for the buttons
14679    // unless the wrapper has an explicit height
14680    if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
14681        uiSpinner.height() > 0 ) {
14682      uiSpinner.height( uiSpinner.height() );
14683    }
14684
14685    // disable spinner if element was already disabled
14686    if ( this.options.disabled ) {
14687      this.disable();
14688    }
14689  },
14690
14691  _keydown: function( event ) {
14692    var options = this.options,
14693      keyCode = $.ui.keyCode;
14694
14695    switch ( event.keyCode ) {
14696    case keyCode.UP:
14697      this._repeat( null, 1, event );
14698      return true;
14699    case keyCode.DOWN:
14700      this._repeat( null, -1, event );
14701      return true;
14702    case keyCode.PAGE_UP:
14703      this._repeat( null, options.page, event );
14704      return true;
14705    case keyCode.PAGE_DOWN:
14706      this._repeat( null, -options.page, event );
14707      return true;
14708    }
14709
14710    return false;
14711  },
14712
14713  _uiSpinnerHtml: function() {
14714    return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
14715  },
14716
14717  _buttonHtml: function() {
14718    return "" +
14719      "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
14720        "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
14721      "</a>" +
14722      "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
14723        "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
14724      "</a>";
14725  },
14726
14727  _start: function( event ) {
14728    if ( !this.spinning && this._trigger( "start", event ) === false ) {
14729      return false;
14730    }
14731
14732    if ( !this.counter ) {
14733      this.counter = 1;
14734    }
14735    this.spinning = true;
14736    return true;
14737  },
14738
14739  _repeat: function( i, steps, event ) {
14740    i = i || 500;
14741
14742    clearTimeout( this.timer );
14743    this.timer = this._delay(function() {
14744      this._repeat( 40, steps, event );
14745    }, i );
14746
14747    this._spin( steps * this.options.step, event );
14748  },
14749
14750  _spin: function( step, event ) {
14751    var value = this.value() || 0;
14752
14753    if ( !this.counter ) {
14754      this.counter = 1;
14755    }
14756
14757    value = this._adjustValue( value + step * this._increment( this.counter ) );
14758
14759    if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
14760      this._value( value );
14761      this.counter++;
14762    }
14763  },
14764
14765  _increment: function( i ) {
14766    var incremental = this.options.incremental;
14767
14768    if ( incremental ) {
14769      return $.isFunction( incremental ) ?
14770        incremental( i ) :
14771        Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
14772    }
14773
14774    return 1;
14775  },
14776
14777  _precision: function() {
14778    var precision = this._precisionOf( this.options.step );
14779    if ( this.options.min !== null ) {
14780      precision = Math.max( precision, this._precisionOf( this.options.min ) );
14781    }
14782    return precision;
14783  },
14784
14785  _precisionOf: function( num ) {
14786    var str = num.toString(),
14787      decimal = str.indexOf( "." );
14788    return decimal === -1 ? 0 : str.length - decimal - 1;
14789  },
14790
14791  _adjustValue: function( value ) {
14792    var base, aboveMin,
14793      options = this.options;
14794
14795    // make sure we're at a valid step
14796    // - find out where we are relative to the base (min or 0)
14797    base = options.min !== null ? options.min : 0;
14798    aboveMin = value - base;
14799    // - round to the nearest step
14800    aboveMin = Math.round(aboveMin / options.step) * options.step;
14801    // - rounding is based on 0, so adjust back to our base
14802    value = base + aboveMin;
14803
14804    // fix precision from bad JS floating point math
14805    value = parseFloat( value.toFixed( this._precision() ) );
14806
14807    // clamp the value
14808    if ( options.max !== null && value > options.max) {
14809      return options.max;
14810    }
14811    if ( options.min !== null && value < options.min ) {
14812      return options.min;
14813    }
14814
14815    return value;
14816  },
14817
14818  _stop: function( event ) {
14819    if ( !this.spinning ) {
14820      return;
14821    }
14822
14823    clearTimeout( this.timer );
14824    clearTimeout( this.mousewheelTimer );
14825    this.counter = 0;
14826    this.spinning = false;
14827    this._trigger( "stop", event );
14828  },
14829
14830  _setOption: function( key, value ) {
14831    if ( key === "culture" || key === "numberFormat" ) {
14832      var prevValue = this._parse( this.element.val() );
14833      this.options[ key ] = value;
14834      this.element.val( this._format( prevValue ) );
14835      return;
14836    }
14837
14838    if ( key === "max" || key === "min" || key === "step" ) {
14839      if ( typeof value === "string" ) {
14840        value = this._parse( value );
14841      }
14842    }
14843    if ( key === "icons" ) {
14844      this.buttons.first().find( ".ui-icon" )
14845        .removeClass( this.options.icons.up )
14846        .addClass( value.up );
14847      this.buttons.last().find( ".ui-icon" )
14848        .removeClass( this.options.icons.down )
14849        .addClass( value.down );
14850    }
14851
14852    this._super( key, value );
14853
14854    if ( key === "disabled" ) {
14855      if ( value ) {
14856        this.element.prop( "disabled", true );
14857        this.buttons.button( "disable" );
14858      } else {
14859        this.element.prop( "disabled", false );
14860        this.buttons.button( "enable" );
14861      }
14862    }
14863  },
14864
14865  _setOptions: modifier(function( options ) {
14866    this._super( options );
14867    this._value( this.element.val() );
14868  }),
14869
14870  _parse: function( val ) {
14871    if ( typeof val === "string" && val !== "" ) {
14872      val = window.Globalize && this.options.numberFormat ?
14873        Globalize.parseFloat( val, 10, this.options.culture ) : +val;
14874    }
14875    return val === "" || isNaN( val ) ? null : val;
14876  },
14877
14878  _format: function( value ) {
14879    if ( value === "" ) {
14880      return "";
14881    }
14882    return window.Globalize && this.options.numberFormat ?
14883      Globalize.format( value, this.options.numberFormat, this.options.culture ) :
14884      value;
14885  },
14886
14887  _refresh: function() {
14888    this.element.attr({
14889      "aria-valuemin": this.options.min,
14890      "aria-valuemax": this.options.max,
14891      // TODO: what should we do with values that can't be parsed?
14892      "aria-valuenow": this._parse( this.element.val() )
14893    });
14894  },
14895
14896  // update the value without triggering change
14897  _value: function( value, allowAny ) {
14898    var parsed;
14899    if ( value !== "" ) {
14900      parsed = this._parse( value );
14901      if ( parsed !== null ) {
14902        if ( !allowAny ) {
14903          parsed = this._adjustValue( parsed );
14904        }
14905        value = this._format( parsed );
14906      }
14907    }
14908    this.element.val( value );
14909    this._refresh();
14910  },
14911
14912  _destroy: function() {
14913    this.element
14914      .removeClass( "ui-spinner-input" )
14915      .prop( "disabled", false )
14916      .removeAttr( "autocomplete" )
14917      .removeAttr( "role" )
14918      .removeAttr( "aria-valuemin" )
14919      .removeAttr( "aria-valuemax" )
14920      .removeAttr( "aria-valuenow" );
14921    this.uiSpinner.replaceWith( this.element );
14922  },
14923
14924  stepUp: modifier(function( steps ) {
14925    this._stepUp( steps );
14926  }),
14927  _stepUp: function( steps ) {
14928    if ( this._start() ) {
14929      this._spin( (steps || 1) * this.options.step );
14930      this._stop();
14931    }
14932  },
14933
14934  stepDown: modifier(function( steps ) {
14935    this._stepDown( steps );
14936  }),
14937  _stepDown: function( steps ) {
14938    if ( this._start() ) {
14939      this._spin( (steps || 1) * -this.options.step );
14940      this._stop();
14941    }
14942  },
14943
14944  pageUp: modifier(function( pages ) {
14945    this._stepUp( (pages || 1) * this.options.page );
14946  }),
14947
14948  pageDown: modifier(function( pages ) {
14949    this._stepDown( (pages || 1) * this.options.page );
14950  }),
14951
14952  value: function( newVal ) {
14953    if ( !arguments.length ) {
14954      return this._parse( this.element.val() );
14955    }
14956    modifier( this._value ).call( this, newVal );
14957  },
14958
14959  widget: function() {
14960    return this.uiSpinner;
14961  }
14962});
14963
14964}( _4ORMAT.$ ) );
14965(function( $, undefined ) {
14966
14967var tabId = 0,
14968  rhash = /#.*$/;
14969
14970function getNextTabId() {
14971  return ++tabId;
14972}
14973
14974function isLocal( anchor ) {
14975  // support: IE7
14976  // IE7 doesn't normalize the href property when set via script (#9317)
14977  anchor = anchor.cloneNode( false );
14978
14979  return anchor.hash.length > 1 &&
14980    decodeURIComponent( anchor.href.replace( rhash, "" ) ) ===
14981      decodeURIComponent( location.href.replace( rhash, "" ) );
14982}
14983
14984$.widget( "ui.tabs", {
14985  version: "1.10.4",
14986  delay: 300,
14987  options: {
14988    active: null,
14989    collapsible: false,
14990    event: "click",
14991    heightStyle: "content",
14992    hide: null,
14993    show: null,
14994
14995    // callbacks
14996    activate: null,
14997    beforeActivate: null,
14998    beforeLoad: null,
14999    load: null
15000  },
15001
15002  _create: function() {
15003    var that = this,
15004      options = this.options;
15005
15006    this.running = false;
vendor: 29,620 bytes, lines 15007-16024
15007
15008    this.element
15009      .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
15010      .toggleClass( "ui-tabs-collapsible", options.collapsible )
15011      // Prevent users from focusing disabled tabs via click
15012      .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
15013        if ( $( this ).is( ".ui-state-disabled" ) ) {
15014          event.preventDefault();
15015        }
15016      })
15017      // support: IE <9
15018      // Preventing the default action in mousedown doesn't prevent IE
15019      // from focusing the element, so if the anchor gets focused, blur.
15020      // We don't have to worry about focusing the previously focused
15021      // element since clicking on a non-focusable element should focus
15022      // the body anyway.
15023      .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
15024        if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
15025          this.blur();
15026        }
15027      });
15028
15029    this._processTabs();
15030    options.active = this._initialActive();
15031
15032    // Take disabling tabs via class attribute from HTML
15033    // into account and update option properly.
15034    if ( $.isArray( options.disabled ) ) {
15035      options.disabled = $.unique( options.disabled.concat(
15036        $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
15037          return that.tabs.index( li );
15038        })
15039      ) ).sort();
15040    }
15041
15042    // check for length avoids error when initializing empty list
15043    if ( this.options.active !== false && this.anchors.length ) {
15044      this.active = this._findActive( options.active );
15045    } else {
15046      this.active = $();
15047    }
15048
15049    this._refresh();
15050
15051    if ( this.active.length ) {
15052      this.load( options.active );
15053    }
15054  },
15055
15056  _initialActive: function() {
15057    var active = this.options.active,
15058      collapsible = this.options.collapsible,
15059      locationHash = location.hash.substring( 1 );
15060
15061    if ( active === null ) {
15062      // check the fragment identifier in the URL
15063      if ( locationHash ) {
15064        this.tabs.each(function( i, tab ) {
15065          if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
15066            active = i;
15067            return false;
15068          }
15069        });
15070      }
15071
15072      // check for a tab marked active via a class
15073      if ( active === null ) {
15074        active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
15075      }
15076
15077      // no active tab, set to false
15078      if ( active === null || active === -1 ) {
15079        active = this.tabs.length ? 0 : false;
15080      }
15081    }
15082
15083    // handle numbers: negative, out of range
15084    if ( active !== false ) {
15085      active = this.tabs.index( this.tabs.eq( active ) );
15086      if ( active === -1 ) {
15087        active = collapsible ? false : 0;
15088      }
15089    }
15090
15091    // don't allow collapsible: false and active: false
15092    if ( !collapsible && active === false && this.anchors.length ) {
15093      active = 0;
15094    }
15095
15096    return active;
15097  },
15098
15099  _getCreateEventData: function() {
15100    return {
15101      tab: this.active,
15102      panel: !this.active.length ? $() : this._getPanelForTab( this.active )
15103    };
15104  },
15105
15106  _tabKeydown: function( event ) {
15107    var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
15108      selectedIndex = this.tabs.index( focusedTab ),
15109      goingForward = true;
15110
15111    if ( this._handlePageNav( event ) ) {
15112      return;
15113    }
15114
15115    switch ( event.keyCode ) {
15116      case $.ui.keyCode.RIGHT:
15117      case $.ui.keyCode.DOWN:
15118        selectedIndex++;
15119        break;
15120      case $.ui.keyCode.UP:
15121      case $.ui.keyCode.LEFT:
15122        goingForward = false;
15123        selectedIndex--;
15124        break;
15125      case $.ui.keyCode.END:
15126        selectedIndex = this.anchors.length - 1;
15127        break;
15128      case $.ui.keyCode.HOME:
15129        selectedIndex = 0;
15130        break;
15131      case $.ui.keyCode.SPACE:
15132        // Activate only, no collapsing
15133        event.preventDefault();
15134        clearTimeout( this.activating );
15135        this._activate( selectedIndex );
15136        return;
15137      case $.ui.keyCode.ENTER:
15138        // Toggle (cancel delayed activation, allow collapsing)
15139        event.preventDefault();
15140        clearTimeout( this.activating );
15141        // Determine if we should collapse or activate
15142        this._activate( selectedIndex === this.options.active ? false : selectedIndex );
15143        return;
15144      default:
15145        return;
15146    }
15147
15148    // Focus the appropriate tab, based on which key was pressed
15149    event.preventDefault();
15150    clearTimeout( this.activating );
15151    selectedIndex = this._focusNextTab( selectedIndex, goingForward );
15152
15153    // Navigating with control key will prevent automatic activation
15154    if ( !event.ctrlKey ) {
15155      // Update aria-selected immediately so that AT think the tab is already selected.
15156      // Otherwise AT may confuse the user by stating that they need to activate the tab,
15157      // but the tab will already be activated by the time the announcement finishes.
15158      focusedTab.attr( "aria-selected", "false" );
15159      this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
15160
15161      this.activating = this._delay(function() {
15162        this.option( "active", selectedIndex );
15163      }, this.delay );
15164    }
15165  },
15166
15167  _panelKeydown: function( event ) {
15168    if ( this._handlePageNav( event ) ) {
15169      return;
15170    }
15171
15172    // Ctrl+up moves focus to the current tab
15173    if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
15174      event.preventDefault();
15175      this.active.focus();
15176    }
15177  },
15178
15179  // Alt+page up/down moves focus to the previous/next tab (and activates)
15180  _handlePageNav: function( event ) {
15181    if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
15182      this._activate( this._focusNextTab( this.options.active - 1, false ) );
15183      return true;
15184    }
15185    if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
15186      this._activate( this._focusNextTab( this.options.active + 1, true ) );
15187      return true;
15188    }
15189  },
15190
15191  _findNextTab: function( index, goingForward ) {
15192    var lastTabIndex = this.tabs.length - 1;
15193
15194    function constrain() {
15195      if ( index > lastTabIndex ) {
15196        index = 0;
15197      }
15198      if ( index < 0 ) {
15199        index = lastTabIndex;
15200      }
15201      return index;
15202    }
15203
15204    while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
15205      index = goingForward ? index + 1 : index - 1;
15206    }
15207
15208    return index;
15209  },
15210
15211  _focusNextTab: function( index, goingForward ) {
15212    index = this._findNextTab( index, goingForward );
15213    this.tabs.eq( index ).focus();
15214    return index;
15215  },
15216
15217  _setOption: function( key, value ) {
15218    if ( key === "active" ) {
15219      // _activate() will handle invalid values and update this.options
15220      this._activate( value );
15221      return;
15222    }
15223
15224    if ( key === "disabled" ) {
15225      // don't use the widget factory's disabled handling
15226      this._setupDisabled( value );
15227      return;
15228    }
15229
15230    this._super( key, value);
15231
15232    if ( key === "collapsible" ) {
15233      this.element.toggleClass( "ui-tabs-collapsible", value );
15234      // Setting collapsible: false while collapsed; open first panel
15235      if ( !value && this.options.active === false ) {
15236        this._activate( 0 );
15237      }
15238    }
15239
15240    if ( key === "event" ) {
15241      this._setupEvents( value );
15242    }
15243
15244    if ( key === "heightStyle" ) {
15245      this._setupHeightStyle( value );
15246    }
15247  },
15248
15249  _tabId: function( tab ) {
15250    return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
15251  },
15252
15253  _sanitizeSelector: function( hash ) {
15254    return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
15255  },
15256
15257  refresh: function() {
15258    var options = this.options,
15259      lis = this.tablist.children( ":has(a[href])" );
15260
15261    // get disabled tabs from class attribute from HTML
15262    // this will get converted to a boolean if needed in _refresh()
15263    options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
15264      return lis.index( tab );
15265    });
15266
15267    this._processTabs();
15268
15269    // was collapsed or no tabs
15270    if ( options.active === false || !this.anchors.length ) {
15271      options.active = false;
15272      this.active = $();
15273    // was active, but active tab is gone
15274    } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
15275      // all remaining tabs are disabled
15276      if ( this.tabs.length === options.disabled.length ) {
15277        options.active = false;
15278        this.active = $();
15279      // activate previous tab
15280      } else {
15281        this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
15282      }
15283    // was active, active tab still exists
15284    } else {
15285      // make sure active index is correct
15286      options.active = this.tabs.index( this.active );
15287    }
15288
15289    this._refresh();
15290  },
15291
15292  _refresh: function() {
15293    this._setupDisabled( this.options.disabled );
15294    this._setupEvents( this.options.event );
15295    this._setupHeightStyle( this.options.heightStyle );
15296
15297    this.tabs.not( this.active ).attr({
15298      "aria-selected": "false",
15299      tabIndex: -1
15300    });
15301    this.panels.not( this._getPanelForTab( this.active ) )
15302      .hide()
15303      .attr({
15304        "aria-expanded": "false",
15305        "aria-hidden": "true"
15306      });
15307
15308    // Make sure one tab is in the tab order
15309    if ( !this.active.length ) {
15310      this.tabs.eq( 0 ).attr( "tabIndex", 0 );
15311    } else {
15312      this.active
15313        .addClass( "ui-tabs-active ui-state-active" )
15314        .attr({
15315          "aria-selected": "true",
15316          tabIndex: 0
15317        });
15318      this._getPanelForTab( this.active )
15319        .show()
15320        .attr({
15321          "aria-expanded": "true",
15322          "aria-hidden": "false"
15323        });
15324    }
15325  },
15326
15327  _processTabs: function() {
15328    var that = this;
15329
15330    this.tablist = this._getList()
15331      .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
15332      .attr( "role", "tablist" );
15333
15334    this.tabs = this.tablist.find( "> li:has(a[href])" )
15335      .addClass( "ui-state-default ui-corner-top" )
15336      .attr({
15337        role: "tab",
15338        tabIndex: -1
15339      });
15340
15341    this.anchors = this.tabs.map(function() {
15342        return $( "a", this )[ 0 ];
15343      })
15344      .addClass( "ui-tabs-anchor" )
15345      .attr({
15346        role: "presentation",
15347        tabIndex: -1
15348      });
15349
15350    this.panels = $();
15351
15352    this.anchors.each(function( i, anchor ) {
15353      var selector, panel, panelId,
15354        anchorId = $( anchor ).uniqueId().attr( "id" ),
15355        tab = $( anchor ).closest( "li" ),
15356        originalAriaControls = tab.attr( "aria-controls" );
15357
15358      // inline tab
15359      if ( isLocal( anchor ) ) {
15360        selector = anchor.hash;
15361        panel = that.element.find( that._sanitizeSelector( selector ) );
15362      // remote tab
15363      } else {
15364        panelId = that._tabId( tab );
15365        selector = "#" + panelId;
15366        panel = that.element.find( selector );
15367        if ( !panel.length ) {
15368          panel = that._createPanel( panelId );
15369          panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
15370        }
15371        panel.attr( "aria-live", "polite" );
15372      }
15373
15374      if ( panel.length) {
15375        that.panels = that.panels.add( panel );
15376      }
15377      if ( originalAriaControls ) {
15378        tab.data( "ui-tabs-aria-controls", originalAriaControls );
15379      }
15380      tab.attr({
15381        "aria-controls": selector.substring( 1 ),
15382        "aria-labelledby": anchorId
15383      });
15384      panel.attr( "aria-labelledby", anchorId );
15385    });
15386
15387    this.panels
15388      .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
15389      .attr( "role", "tabpanel" );
15390  },
15391
15392  // allow overriding how to find the list for rare usage scenarios (#7715)
15393  _getList: function() {
15394    return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
15395  },
15396
15397  _createPanel: function( id ) {
15398    return $( "<div>" )
15399      .attr( "id", id )
15400      .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
15401      .data( "ui-tabs-destroy", true );
15402  },
15403
15404  _setupDisabled: function( disabled ) {
15405    if ( $.isArray( disabled ) ) {
15406      if ( !disabled.length ) {
15407        disabled = false;
15408      } else if ( disabled.length === this.anchors.length ) {
15409        disabled = true;
15410      }
15411    }
15412
15413    // disable tabs
15414    for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
15415      if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
15416        $( li )
15417          .addClass( "ui-state-disabled" )
15418          .attr( "aria-disabled", "true" );
15419      } else {
15420        $( li )
15421          .removeClass( "ui-state-disabled" )
15422          .removeAttr( "aria-disabled" );
15423      }
15424    }
15425
15426    this.options.disabled = disabled;
15427  },
15428
15429  _setupEvents: function( event ) {
15430    var events = {
15431      click: function( event ) {
15432        event.preventDefault();
15433      }
15434    };
15435    if ( event ) {
15436      $.each( event.split(" "), function( index, eventName ) {
15437        events[ eventName ] = "_eventHandler";
15438      });
15439    }
15440
15441    this._off( this.anchors.add( this.tabs ).add( this.panels ) );
15442    this._on( this.anchors, events );
15443    this._on( this.tabs, { keydown: "_tabKeydown" } );
15444    this._on( this.panels, { keydown: "_panelKeydown" } );
15445
15446    this._focusable( this.tabs );
15447    this._hoverable( this.tabs );
15448  },
15449
15450  _setupHeightStyle: function( heightStyle ) {
15451    var maxHeight,
15452      parent = this.element.parent();
15453
15454    if ( heightStyle === "fill" ) {
15455      maxHeight = parent.height();
15456      maxHeight -= this.element.outerHeight() - this.element.height();
15457
15458      this.element.siblings( ":visible" ).each(function() {
15459        var elem = $( this ),
15460          position = elem.css( "position" );
15461
15462        if ( position === "absolute" || position === "fixed" ) {
15463          return;
15464        }
15465        maxHeight -= elem.outerHeight( true );
15466      });
15467
15468      this.element.children().not( this.panels ).each(function() {
15469        maxHeight -= $( this ).outerHeight( true );
15470      });
15471
15472      this.panels.each(function() {
15473        $( this ).height( Math.max( 0, maxHeight -
15474          $( this ).innerHeight() + $( this ).height() ) );
15475      })
15476      .css( "overflow", "auto" );
15477    } else if ( heightStyle === "auto" ) {
15478      maxHeight = 0;
15479      this.panels.each(function() {
15480        maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
15481      }).height( maxHeight );
15482    }
15483  },
15484
15485  _eventHandler: function( event ) {
15486    var options = this.options,
15487      active = this.active,
15488      anchor = $( event.currentTarget ),
15489      tab = anchor.closest( "li" ),
15490      clickedIsActive = tab[ 0 ] === active[ 0 ],
15491      collapsing = clickedIsActive && options.collapsible,
15492      toShow = collapsing ? $() : this._getPanelForTab( tab ),
15493      toHide = !active.length ? $() : this._getPanelForTab( active ),
15494      eventData = {
15495        oldTab: active,
15496        oldPanel: toHide,
15497        newTab: collapsing ? $() : tab,
15498        newPanel: toShow
15499      };
15500
15501    event.preventDefault();
15502
15503    if ( tab.hasClass( "ui-state-disabled" ) ||
15504        // tab is already loading
15505        tab.hasClass( "ui-tabs-loading" ) ||
15506        // can't switch durning an animation
15507        this.running ||
15508        // click on active header, but not collapsible
15509        ( clickedIsActive && !options.collapsible ) ||
15510        // allow canceling activation
15511        ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
15512      return;
15513    }
15514
15515    options.active = collapsing ? false : this.tabs.index( tab );
15516
15517    this.active = clickedIsActive ? $() : tab;
15518    if ( this.xhr ) {
15519      this.xhr.abort();
15520    }
15521
15522    if ( !toHide.length && !toShow.length ) {
15523      $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
15524    }
15525
15526    if ( toShow.length ) {
15527      this.load( this.tabs.index( tab ), event );
15528    }
15529    this._toggle( event, eventData );
15530  },
15531
15532  // handles show/hide for selecting tabs
15533  _toggle: function( event, eventData ) {
15534    var that = this,
15535      toShow = eventData.newPanel,
15536      toHide = eventData.oldPanel;
15537
15538    this.running = true;
15539
15540    function complete() {
15541      that.running = false;
15542      that._trigger( "activate", event, eventData );
15543    }
15544
15545    function show() {
15546      eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
15547
15548      if ( toShow.length && that.options.show ) {
15549        that._show( toShow, that.options.show, complete );
15550      } else {
15551        toShow.show();
15552        complete();
15553      }
15554    }
15555
15556    // start out by hiding, then showing, then completing
15557    if ( toHide.length && this.options.hide ) {
15558      this._hide( toHide, this.options.hide, function() {
15559        eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
15560        show();
15561      });
15562    } else {
15563      eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
15564      toHide.hide();
15565      show();
15566    }
15567
15568    toHide.attr({
15569      "aria-expanded": "false",
15570      "aria-hidden": "true"
15571    });
15572    eventData.oldTab.attr( "aria-selected", "false" );
15573    // If we're switching tabs, remove the old tab from the tab order.
15574    // If we're opening from collapsed state, remove the previous tab from the tab order.
15575    // If we're collapsing, then keep the collapsing tab in the tab order.
15576    if ( toShow.length && toHide.length ) {
15577      eventData.oldTab.attr( "tabIndex", -1 );
15578    } else if ( toShow.length ) {
15579      this.tabs.filter(function() {
15580        return $( this ).attr( "tabIndex" ) === 0;
15581      })
15582      .attr( "tabIndex", -1 );
15583    }
15584
15585    toShow.attr({
15586      "aria-expanded": "true",
15587      "aria-hidden": "false"
15588    });
15589    eventData.newTab.attr({
15590      "aria-selected": "true",
15591      tabIndex: 0
15592    });
15593  },
15594
15595  _activate: function( index ) {
15596    var anchor,
15597      active = this._findActive( index );
15598
15599    // trying to activate the already active panel
15600    if ( active[ 0 ] === this.active[ 0 ] ) {
15601      return;
15602    }
15603
15604    // trying to collapse, simulate a click on the current active header
15605    if ( !active.length ) {
15606      active = this.active;
15607    }
15608
15609    anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
15610    this._eventHandler({
15611      target: anchor,
15612      currentTarget: anchor,
15613      preventDefault: $.noop
15614    });
15615  },
15616
15617  _findActive: function( index ) {
15618    return index === false ? $() : this.tabs.eq( index );
15619  },
15620
15621  _getIndex: function( index ) {
15622    // meta-function to give users option to provide a href string instead of a numerical index.
15623    if ( typeof index === "string" ) {
15624      index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
15625    }
15626
15627    return index;
15628  },
15629
15630  _destroy: function() {
15631    if ( this.xhr ) {
15632      this.xhr.abort();
15633    }
15634
15635    this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
15636
15637    this.tablist
15638      .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
15639      .removeAttr( "role" );
15640
15641    this.anchors
15642      .removeClass( "ui-tabs-anchor" )
15643      .removeAttr( "role" )
15644      .removeAttr( "tabIndex" )
15645      .removeUniqueId();
15646
15647    this.tabs.add( this.panels ).each(function() {
15648      if ( $.data( this, "ui-tabs-destroy" ) ) {
15649        $( this ).remove();
15650      } else {
15651        $( this )
15652          .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
15653            "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
15654          .removeAttr( "tabIndex" )
15655          .removeAttr( "aria-live" )
15656          .removeAttr( "aria-busy" )
15657          .removeAttr( "aria-selected" )
15658          .removeAttr( "aria-labelledby" )
15659          .removeAttr( "aria-hidden" )
15660          .removeAttr( "aria-expanded" )
15661          .removeAttr( "role" );
15662      }
15663    });
15664
15665    this.tabs.each(function() {
15666      var li = $( this ),
15667        prev = li.data( "ui-tabs-aria-controls" );
15668      if ( prev ) {
15669        li
15670          .attr( "aria-controls", prev )
15671          .removeData( "ui-tabs-aria-controls" );
15672      } else {
15673        li.removeAttr( "aria-controls" );
15674      }
15675    });
15676
15677    this.panels.show();
15678
15679    if ( this.options.heightStyle !== "content" ) {
15680      this.panels.css( "height", "" );
15681    }
15682  },
15683
15684  enable: function( index ) {
15685    var disabled = this.options.disabled;
15686    if ( disabled === false ) {
15687      return;
15688    }
15689
15690    if ( index === undefined ) {
15691      disabled = false;
15692    } else {
15693      index = this._getIndex( index );
15694      if ( $.isArray( disabled ) ) {
15695        disabled = $.map( disabled, function( num ) {
15696          return num !== index ? num : null;
15697        });
15698      } else {
15699        disabled = $.map( this.tabs, function( li, num ) {
15700          return num !== index ? num : null;
15701        });
15702      }
15703    }
15704    this._setupDisabled( disabled );
15705  },
15706
15707  disable: function( index ) {
15708    var disabled = this.options.disabled;
15709    if ( disabled === true ) {
15710      return;
15711    }
15712
15713    if ( index === undefined ) {
15714      disabled = true;
15715    } else {
15716      index = this._getIndex( index );
15717      if ( $.inArray( index, disabled ) !== -1 ) {
15718        return;
15719      }
15720      if ( $.isArray( disabled ) ) {
15721        disabled = $.merge( [ index ], disabled ).sort();
15722      } else {
15723        disabled = [ index ];
15724      }
15725    }
15726    this._setupDisabled( disabled );
15727  },
15728
15729  load: function( index, event ) {
15730    index = this._getIndex( index );
15731    var that = this,
15732      tab = this.tabs.eq( index ),
15733      anchor = tab.find( ".ui-tabs-anchor" ),
15734      panel = this._getPanelForTab( tab ),
15735      eventData = {
15736        tab: tab,
15737        panel: panel
15738      };
15739
15740    // not remote
15741    if ( isLocal( anchor[ 0 ] ) ) {
15742      return;
15743    }
15744
15745    this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
15746
15747    // support: jQuery <1.8
15748    // jQuery <1.8 returns false if the request is canceled in beforeSend,
15749    // but as of 1.8, $.ajax() always returns a jqXHR object.
15750    if ( this.xhr && this.xhr.statusText !== "canceled" ) {
15751      tab.addClass( "ui-tabs-loading" );
15752      panel.attr( "aria-busy", "true" );
15753
15754      this.xhr
15755        .success(function( response ) {
15756          // support: jQuery <1.8
15757          // http://bugs.jquery.com/ticket/11778
15758          setTimeout(function() {
15759            panel.html( response );
15760            that._trigger( "load", event, eventData );
15761          }, 1 );
15762        })
15763        .complete(function( jqXHR, status ) {
15764          // support: jQuery <1.8
15765          // http://bugs.jquery.com/ticket/11778
15766          setTimeout(function() {
15767            if ( status === "abort" ) {
15768              that.panels.stop( false, true );
15769            }
15770
15771            tab.removeClass( "ui-tabs-loading" );
15772            panel.removeAttr( "aria-busy" );
15773
15774            if ( jqXHR === that.xhr ) {
15775              delete that.xhr;
15776            }
15777          }, 1 );
15778        });
15779    }
15780  },
15781
15782  _ajaxSettings: function( anchor, event, eventData ) {
15783    var that = this;
15784    return {
15785      url: anchor.attr( "href" ),
15786      beforeSend: function( jqXHR, settings ) {
15787        return that._trigger( "beforeLoad", event,
15788          $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
15789      }
15790    };
15791  },
15792
15793  _getPanelForTab: function( tab ) {
15794    var id = $( tab ).attr( "aria-controls" );
15795    return this.element.find( this._sanitizeSelector( "#" + id ) );
15796  }
15797});
15798
15799})( _4ORMAT.$ );
15800(function( $ ) {
15801
15802var increments = 0;
15803
15804function addDescribedBy( elem, id ) {
15805  var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
15806  describedby.push( id );
15807  elem
15808    .data( "ui-tooltip-id", id )
15809    .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
15810}
15811
15812function removeDescribedBy( elem ) {
15813  var id = elem.data( "ui-tooltip-id" ),
15814    describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
15815    index = $.inArray( id, describedby );
15816  if ( index !== -1 ) {
15817    describedby.splice( index, 1 );
15818  }
15819
15820  elem.removeData( "ui-tooltip-id" );
15821  describedby = $.trim( describedby.join( " " ) );
15822  if ( describedby ) {
15823    elem.attr( "aria-describedby", describedby );
15824  } else {
15825    elem.removeAttr( "aria-describedby" );
15826  }
15827}
15828
15829$.widget( "ui.tooltip", {
15830  version: "1.10.4",
15831  options: {
15832    content: function() {
15833      // support: IE<9, Opera in jQuery <1.7
15834      // .text() can't accept undefined, so coerce to a string
15835      var title = $( this ).attr( "title" ) || "";
15836      // Escape title, since we're going from an attribute to raw HTML
15837      return $( "<a>" ).text( title ).html();
15838    },
15839    hide: true,
15840    // Disabled elements have inconsistent behavior across browsers (#8661)
15841    items: "[title]:not([disabled])",
15842    position: {
15843      my: "left top+15",
15844      at: "left bottom",
15845      collision: "flipfit flip"
15846    },
15847    show: true,
15848    tooltipClass: null,
15849    track: false,
15850
15851    // callbacks
15852    close: null,
15853    open: null
15854  },
15855
15856  _create: function() {
15857    this._on({
15858      mouseover: "open",
15859      focusin: "open"
15860    });
15861
15862    // IDs of generated tooltips, needed for destroy
15863    this.tooltips = {};
15864    // IDs of parent tooltips where we removed the title attribute
15865    this.parents = {};
15866
15867    if ( this.options.disabled ) {
15868      this._disable();
15869    }
15870  },
15871
15872  _setOption: function( key, value ) {
15873    var that = this;
15874
15875    if ( key === "disabled" ) {
15876      this[ value ? "_disable" : "_enable" ]();
15877      this.options[ key ] = value;
15878      // disable element style changes
15879      return;
15880    }
15881
15882    this._super( key, value );
15883
15884    if ( key === "content" ) {
15885      $.each( this.tooltips, function( id, element ) {
15886        that._updateContent( element );
15887      });
15888    }
15889  },
15890
15891  _disable: function() {
15892    var that = this;
15893
15894    // close open tooltips
15895    $.each( this.tooltips, function( id, element ) {
15896      var event = $.Event( "blur" );
15897      event.target = event.currentTarget = element[0];
15898      that.close( event, true );
15899    });
15900
15901    // remove title attributes to prevent native tooltips
15902    this.element.find( this.options.items ).addBack().each(function() {
15903      var element = $( this );
15904      if ( element.is( "[title]" ) ) {
15905        element
15906          .data( "ui-tooltip-title", element.attr( "title" ) )
15907          .attr( "title", "" );
15908      }
15909    });
15910  },
15911
15912  _enable: function() {
15913    // restore title attributes
15914    this.element.find( this.options.items ).addBack().each(function() {
15915      var element = $( this );
15916      if ( element.data( "ui-tooltip-title" ) ) {
15917        element.attr( "title", element.data( "ui-tooltip-title" ) );
15918      }
15919    });
15920  },
15921
15922  open: function( event ) {
15923    var that = this,
15924      target = $( event ? event.target : this.element )
15925        // we need closest here due to mouseover bubbling,
15926        // but always pointing at the same event target
15927        .closest( this.options.items );
15928
15929    // No element to show a tooltip for or the tooltip is already open
15930    if ( !target.length || target.data( "ui-tooltip-id" ) ) {
15931      return;
15932    }
15933
15934    if ( target.attr( "title" ) ) {
15935      target.data( "ui-tooltip-title", target.attr( "title" ) );
15936    }
15937
15938    target.data( "ui-tooltip-open", true );
15939
15940    // kill parent tooltips, custom or native, for hover
15941    if ( event && event.type === "mouseover" ) {
15942      target.parents().each(function() {
15943        var parent = $( this ),
15944          blurEvent;
15945        if ( parent.data( "ui-tooltip-open" ) ) {
15946          blurEvent = $.Event( "blur" );
15947          blurEvent.target = blurEvent.currentTarget = this;
15948          that.close( blurEvent, true );
15949        }
15950        if ( parent.attr( "title" ) ) {
15951          parent.uniqueId();
15952          that.parents[ this.id ] = {
15953            element: this,
15954            title: parent.attr( "title" )
15955          };
15956          parent.attr( "title", "" );
15957        }
15958      });
15959    }
15960
15961    this._updateContent( target, event );
15962  },
15963
15964  _updateContent: function( target, event ) {
15965    var content,
15966      contentOption = this.options.content,
15967      that = this,
15968      eventType = event ? event.type : null;
15969
15970    if ( typeof contentOption === "string" ) {
15971      return this._open( event, target, contentOption );
15972    }
15973
15974    content = contentOption.call( target[0], function( response ) {
15975      // ignore async response if tooltip was closed already
15976      if ( !target.data( "ui-tooltip-open" ) ) {
15977        return;
15978      }
15979      // IE may instantly serve a cached response for ajax requests
15980      // delay this call to _open so the other call to _open runs first
15981      that._delay(function() {
15982        // jQuery creates a special event for focusin when it doesn't
15983        // exist natively. To improve performance, the native event
15984        // object is reused and the type is changed. Therefore, we can't
15985        // rely on the type being correct after the event finished
15986        // bubbling, so we set it back to the previous value. (#8740)
15987        if ( event ) {
15988          event.type = eventType;
15989        }
15990        this._open( event, target, response );
15991      });
15992    });
15993    if ( content ) {
15994      this._open( event, target, content );
15995    }
15996  },
15997
15998  _open: function( event, target, content ) {
15999    var tooltip, events, delayedShow,
16000      positionOption = $.extend( {}, this.options.position );
16001
16002    if ( !content ) {
16003      return;
16004    }
16005
16006    // Content can be updated multiple times. If the tooltip already
16007    // exists, then just update the content and bail.
16008    tooltip = this._find( target );
16009    if ( tooltip.length ) {
16010      tooltip.find( ".ui-tooltip-content" ).html( content );
16011      return;
16012    }
16013
16014    // if we have a title, clear it to prevent the native tooltip
16015    // we have to check first to avoid defining a title if none exists
16016    // (we don't want to cause an element to start matching [title])
16017    //
16018    // We use removeAttr only for key events, to allow IE to export the correct
16019    // accessible attributes. For mouse events, set to empty string to avoid
16020    // native tooltip showing up (happens only when removing inside mouseover).
16021    if ( target.is( "[title]" ) ) {
16022      if ( event && event.type === "mouseover" ) {
16023        target.attr( "title", "" );
16024      } else {
16025        target.removeAttr( "title" );
16026      }
16027    }
16028
16029    tooltip = this._tooltip( target );
16030    addDescribedBy( target, tooltip.attr( "id" ) );
16031    tooltip.find( ".ui-tooltip-content" ).html( content );
16032
16033    function position( event ) {
16034      positionOption.of = event;
16035      if ( tooltip.is( ":hidden" ) ) {
16036        return;
16037      }
16038      tooltip.position( positionOption );
16039    }
16040    if ( this.options.track && event && /^mouse/.test( event.type ) ) {
16041      this._on( this.document, {
16042        mousemove: position
16043      });
16044      // trigger once to override element-relative positioning
16045      position( event );
16046    } else {
16047      tooltip.position( $.extend({
16048        of: target
16049      }, this.options.position ) );
16050    }
16051
16052    tooltip.hide();
16053
16054    this._show( tooltip, this.options.show );
16055    // Handle tracking tooltips that are shown with a delay (#8644). As soon
16056    // as the tooltip is visible, position the tooltip using the most recent
16057    // event.
16058    if ( this.options.show && this.options.show.delay ) {
16059      delayedShow = this.delayedShow = setInterval(function() {
16060        if ( tooltip.is( ":visible" ) ) {
16061          position( positionOption.of );
16062          clearInterval( delayedShow );
16063        }
16064      }, $.fx.interval );
16065    }
16066
16067    this._trigger( "open", event, { tooltip: tooltip } );
16068
16069    events = {
16070      keyup: function( event ) {
16071        if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
16072          var fakeEvent = $.Event(event);
16073          fakeEvent.currentTarget = target[0];
16074          this.close( fakeEvent, true );
16075        }
16076      },
16077      remove: function() {
16078        this._removeTooltip( tooltip );
16079      }
16080    };
16081    if ( !event || event.type === "mouseover" ) {
16082      events.mouseleave = "close";
16083    }
16084    if ( !event || event.type === "focusin" ) {
16085      events.focusout = "close";
16086    }
16087    this._on( true, target, events );
16088  },
16089
16090  close: function( event ) {
16091    var that = this,
16092      target = $( event ? event.currentTarget : this.element ),
16093      tooltip = this._find( target );
16094
16095    // disabling closes the tooltip, so we need to track when we're closing
16096    // to avoid an infinite loop in case the tooltip becomes disabled on close
16097    if ( this.closing ) {
16098      return;
16099    }
16100
16101    // Clear the interval for delayed tracking tooltips
16102    clearInterval( this.delayedShow );
16103
16104    // only set title if we had one before (see comment in _open())
16105    if ( target.data( "ui-tooltip-title" ) ) {
16106      target.attr( "title", target.data( "ui-tooltip-title" ) );
16107    }
16108
16109    removeDescribedBy( target );
16110
16111    tooltip.stop( true );
16112    this._hide( tooltip, this.options.hide, function() {
16113      that._removeTooltip( $( this ) );
16114    });
16115
16116    target.removeData( "ui-tooltip-open" );
16117    this._off( target, "mouseleave focusout keyup" );
16118    // Remove 'remove' binding only on delegated targets
16119    if ( target[0] !== this.element[0] ) {
16120      this._off( target, "remove" );
16121    }
16122    this._off( this.document, "mousemove" );
16123
16124    if ( event && event.type === "mouseleave" ) {
16125      $.each( this.parents, function( id, parent ) {
16126        $( parent.element ).attr( "title", parent.title );
16127        delete that.parents[ id ];
16128      });
16129    }
16130
16131    this.closing = true;
16132    this._trigger( "close", event, { tooltip: tooltip } );
16133    this.closing = false;
16134  },
16135
16136  _tooltip: function( element ) {
16137    var id = "ui-tooltip-" + increments++,
16138      tooltip = $( "<div>" )
16139        .attr({
16140          id: id,
16141          role: "tooltip"
16142        })
16143        .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
16144          ( this.options.tooltipClass || "" ) );
16145    $( "<div>" )
16146      .addClass( "ui-tooltip-content" )
16147      .appendTo( tooltip );
16148    tooltip.appendTo( this.document[0].body );
16149    this.tooltips[ id ] = element;
16150    return tooltip;
16151  },
16152
16153  _find: function( target ) {
16154    var id = target.data( "ui-tooltip-id" );
16155    return id ? $( "#" + id ) : $();
16156  },
16157
16158  _removeTooltip: function( tooltip ) {
16159    tooltip.remove();
16160    delete this.tooltips[ tooltip.attr( "id" ) ];
16161  },
16162
16163  _destroy: function() {
16164    var that = this;
16165
16166    // close open tooltips
16167    $.each( this.tooltips, function( id, element ) {
16168      // Delegate to close method to handle common cleanup
16169      var event = $.Event( "blur" );
16170      event.target = event.currentTarget = element[0];
16171      that.close( event, true );
16172
16173      // Remove immediately; destroying an open tooltip doesn't use the
16174      // hide animation
16175      $( "#" + id ).remove();
16176
16177      // Restore the title
16178      if ( element.data( "ui-tooltip-title" ) ) {
16179        element.attr( "title", element.data( "ui-tooltip-title" ) );
16180        element.removeData( "ui-tooltip-title" );
16181      }
16182    });
16183  }
16184});
16185
16186}( _4ORMAT.$ ) );
16187/* ===========================================================
16188 * bootstrap-tooltip.js v2.1.1
16189 * http://twitter.github.com/bootstrap/javascript.html#tooltips
16190 * Inspired by the original jQuery.tipsy by Jason Frame
16191 * ===========================================================
16192 * Copyright 2012 Twitter, Inc.
16193 *
16194 * Licensed under the Apache License, Version 2.0 (the "License");
16195 * you may not use this file except in compliance with the License.
16196 * You may obtain a copy of the License at
16197 *
16198 * http://www.apache.org/licenses/LICENSE-2.0
16199 *
16200 * Unless required by applicable law or agreed to in writing, software
16201 * distributed under the License is distributed on an "AS IS" BASIS,
16202 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16203 * See the License for the specific language governing permissions and
16204 * limitations under the License.
16205 * ========================================================== */
16206
16207
16208
16209!function ($) {
16210
16211  "use strict"; // jshint ;_;
16212
16213
16214 /* TOOLTIP PUBLIC CLASS DEFINITION
16215  * =============================== */
16216
16217  var Tooltip = function (element, options) {
16218    this.init('tooltip', element, options)
16219  }
16220
16221  Tooltip.prototype = {
16222
16223    constructor: Tooltip
16224
16225  , init: function (type, element, options) {
16226      var eventIn
16227        , eventOut
16228
16229      this.type = type
16230      this.$element = $(element)
16231      this.options = this.getOptions(options)
16232      this.enabled = true
16233
16234      if (this.options.trigger == 'click') {
16235        this.$element.live('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
16236      } else if (this.options.trigger != 'manual') {
16237        eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
16238        eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
16239        this.$element.live(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
16240        this.$element.live(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
16241      }
16242
16243      this.options.selector ?
16244        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
16245        this.fixTitle()
16246    }
16247
16248  , getOptions: function (options) {
16249      options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
16250
16251      if (options.delay && typeof options.delay == 'number') {
16252        options.delay = {
16253          show: options.delay
16254        , hide: options.delay
16255        }
16256      }
16257
16258      return options
16259    }
16260
16261  , enter: function (e) {
16262      var self = $(e.currentTarget)[this.type](this._options).data(this.type)
16263
16264      if (!self.options.delay || !self.options.delay.show) return self.show()
16265
16266      clearTimeout(this.timeout)
16267      self.hoverState = 'in'
16268      this.timeout = setTimeout(function() {
16269        if (self.hoverState == 'in') self.show()
16270      }, self.options.delay.show)
16271    }
16272
16273  , leave: function (e) {
16274      var self = $(e.currentTarget)[this.type](this._options).data(this.type)
16275
16276      if (this.timeout) clearTimeout(this.timeout)
16277      if (!self.options.delay || !self.options.delay.hide) return self.hide()
16278
16279      self.hoverState = 'out'
16280      this.timeout = setTimeout(function() {
16281        if (self.hoverState == 'out') self.hide()
16282      }, self.options.delay.hide)
16283    }
16284
16285  , show: function () {
16286      var $tip
16287        , inside
16288        , pos
16289        , actualWidth
16290        , actualHeight
16291        , placement
16292        , tp
16293
16294      if (this.hasContent() && this.enabled) {
16295        $tip = this.tip()
16296        this.setContent()
16297
16298        if (this.options.animation) {
16299          $tip.addClass('fade')
16300        }
16301
16302        placement = typeof this.options.placement == 'function' ?
16303          this.options.placement.call(this, $tip[0], this.$element[0]) :
16304          this.options.placement
16305
16306        inside = /in/.test(placement)
16307
16308        $tip
16309          .remove()
16310          .css({ top: 0, left: 0, display: 'block' })
16311          .appendTo(inside ? this.$element : document.body)
16312
16313        pos = this.getPosition(inside)
16314
16315        actualWidth = $tip[0].offsetWidth
16316        actualHeight = $tip[0].offsetHeight
16317
16318        switch (inside ? placement.split(' ')[1] : placement) {
16319          case 'bottom':
16320            tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
16321            break
16322          case 'top':
16323            tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
16324            break
16325          case 'left':
16326            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
16327            break
16328          case 'right':
16329            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
16330            break
16331        }
16332
16333        $tip
16334          .css(tp)
16335          .addClass(placement)
16336          .addClass('in')
16337      }
16338    }
16339
16340  , setContent: function () {
16341      var $tip = this.tip()
16342        , title = this.getTitle()
16343
16344      $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
16345      $tip.removeClass('fade in top bottom left right')
16346    }
16347
16348  , hide: function () {
16349      var that = this
16350        , $tip = this.tip()
16351
16352      $tip.removeClass('in')
16353
16354      function removeWithAnimation() {
16355        var timeout = setTimeout(function () {
16356          $tip.unbind($.support.transition.end).remove()
16357        }, 500)
16358
16359        $tip.one($.support.transition.end, function () {
16360          clearTimeout(timeout)
16361          $tip.remove()
16362        })
16363      }
16364
16365      $.support.transition && this.$tip.hasClass('fade') ?
16366        removeWithAnimation() :
16367        $tip.remove()
16368
16369      return this
16370    }
16371
16372  , fixTitle: function () {
16373      var $e = this.$element
16374      if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
16375        $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
16376      }
16377    }
16378
16379  , hasContent: function () {
16380      return this.getTitle()
16381    }
16382
16383  , getPosition: function (inside) {
16384      return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
16385        width: this.$element[0].offsetWidth
16386      , height: this.$element[0].offsetHeight
16387      })
16388    }
16389
16390  , getTitle: function () {
16391      var title
16392        , $e = this.$element
16393        , o = this.options
16394
16395      title = $e.attr('data-original-title')
16396        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
16397
16398      return title
16399    }
16400
16401  , tip: function () {
16402      return this.$tip = this.$tip || $(this.options.template)
16403    }
16404
16405  , validate: function () {
16406      if (!this.$element[0].parentNode) {
16407        this.hide()
16408        this.$element = null
16409        this.options = null
16410      }
16411    }
16412
16413  , enable: function () {
16414      this.enabled = true
16415    }
16416
16417  , disable: function () {
16418      this.enabled = false
16419    }
16420
16421  , toggleEnabled: function () {
16422      this.enabled = !this.enabled
16423    }
16424
16425  , toggle: function () {
16426      this[this.tip().hasClass('in') ? 'hide' : 'show']()
16427    }
16428
16429  , destroy: function () {
16430      this.hide().$element.unbind('.' + this.type).removeData(this.type)
16431    }
16432
16433  }
16434
16435
16436 /* TOOLTIP PLUGIN DEFINITION
16437  * ========================= */
16438
16439  $.fn.tooltip = function ( option ) {
16440    return this.each(function () {
16441      var $this = $(this)
16442        , data = $this.data('tooltip')
16443        , options = typeof option == 'object' && option
16444      if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
16445      if (typeof option == 'string') data[option]()
16446    })
16447  }
16448
16449  $.fn.tooltip.Constructor = Tooltip
16450
16451  $.fn.tooltip.defaults = {
16452    animation: true
16453  , placement: 'top'
16454  , selector: false
16455  , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
16456  , trigger: 'hover'
16457  , title: ''
16458  , delay: 0
16459  , html: true
16460  }
16461
16462}(typeof(_4ORMAT) === 'object' ? _4ORMAT.jQuery : window.jQuery);
16463(function(){
16464  var $ = this.jQuery,
16465      that =  null;
16466
16467  /**
16468   * Create and show a new modal message.
16469   * @constructor
16470   * @param {(string|Object)} options - Either a string that will be the modal message text or an options object.
16471   * @param {Object} options.target_el - jQuery collection of the element in which the modal message will be placed.
16472   * For example:
16473   *   $('body')
16474   * @param {string} options.title - The text shown as the modal message's title.
16475   * For example:
16476   *   "My Title"
16477   */
16478  this.ModalMessage = function(options) {
16479
16480    // Options can take just a string or an object of values
16481
16482    // Object accepts following values:
16483    // {
16484    //   target_el : $('body'),
16485    //   title : "My Title",
16486    //   html : "<p>String of html.</p>",
16487    //   text : "String of text.",
16488    //   modal_class : 'small/medium/large',
16489    //   prevent_close : true,
16490    //   enter_button : 'button',
16491    //   buttons : {
16492    //     'button' : {
16493    //       text : 'My Button',
16494    //       classes : 'class1 class2 class3',
16495    //       icon : 'check',
16496    //       action : function() {
16497    //         alert('callback');
16498    //       }
16499    //     },
16500    //     'close' : { text : 'Close' }
16501    //   },
16502    //   on_create_callback : function() {} // called after modal is appended to DOM
16503    //   before_close_callback : function(modal) {} // called before modal is closed (via 'X' button or modal.close_modal)
16504    //   after_close_callback : function(modal) {} // called after modal is closed (via 'X' button or modal.close_modal)
16505    // }
16506
16507    // Instantiation syntax:
16508    // var modal = new ModalMessage({ options });
16509
16510    // Notes:
16511
16512    // - Accepts an object passed to target to append the modal.
16513    // - If html and text is passed as args the text will not show.
16514    // - Creating a button 'close' automatically gets the close event bound.
16515    // - If no buttons are created a close button will be added, if at least one
16516    //   button is created then close will not automatically be added.
16517    // - Button icons pull from ss-icon library.
16518    // - Buttons can be assigned functions through the action option callback.
16519    // - Specify 'prevent_close' as true if user shouldn't be able to close the modal.
16520    // - enter_button determines which button gets a click invoked when users presses enter button
16521
16522
16523    var html = '',
16524        modal_class = 'small',
16525        target_el = $('body');
16526
16527    that = this;
16528
16529    this.anim_speed = 300;
16530    this.options = options;
16531
16532    if(options.modal_class) { modal_class = options.modal_class; }
16533
16534    if (typeof(options) === 'string') { options = {text: options}; }
16535
16536    if (options.buttons === undefined && options.prevent_close !== true) {
16537      options.buttons = {
16538        close: {
16539          text: 'Close',
16540          classes: 'btn_default'
16541        }
16542      };
16543    }
16544
16545    // Wrapper and Overlay for popup
16546
16547    html += '<div class="_4ORMAT_overlay"></div><div class="ModalMessage generated ' + modal_class + '">';
16548
16549    // Body content gets inserted here. If html isn't provided we assume that
16550    // title and/or text is provided and populate the popup with this instead.
16551
16552    if(options.title) {
16553      html += '<div id="modalMessage_header">';
16554
16555      if(options.prevent_close !== true) {
16556        html += '<a href="javascript:void(0)" class="ss-icon close">close</a>';
16557      }
16558
16559      html += '<div id="modalMessage_header_title">' + options.title + '</div>';
16560      html += '</div>';
16561    } else {
16562      if(options.prevent_close !== true) {
16563        html += '<a href="javascript:void(0)" class="ss-icon close">close</a>';
16564      }
16565    }
16566
16567    html += '<div class="msg">';
16568
16569    if(options.html) {
16570      html += options.html;
16571    } else if(options.text) {
16572      html += '<p>' + options.text + '</p>';
16573    }
16574
16575    html += '</div>';
16576
16577    // Construct buttons
16578
16579    if(options.buttons) {
16580      html += '<p class="center">';
16581
16582      // for each button add it with the classes and names
16583
16584      $.each(options.buttons, function(i, v) {
16585        var text = '',
16586            classes = '';
16587
16588        if(v.text) { text = v.text; }
16589        if(v.classes) { classes = ' ' + v.classes; }
16590
16591        html += '<a href="javascript:void(0)" class="' + i + classes +'">';
16592
16593        if(v.icon) {
16594          html += '<span class="ss-icon">' + v.icon + '</span> ';
16595        }
16596
16597        html += text + '</a>';
16598      });
16599
16600      html += '</p>';
16601    }
16602
16603    html += '</div>';
16604
16605    // Append html to dom.
16606
16607    if(typeof(options.target_el) === 'object') {
16608      target_el = options.target_el;
16609    }
16610
16611    target_el.append(html);
16612
16613    if(typeof(options.on_create_callback) === 'function') {
16614      options.on_create_callback();
16615    }
16616
16617    // Animate after appended.
16618
16619    setTimeout(function() {
16620      $('.ModalMessage').addClass('show');
16621      $('._4ORMAT_overlay').addClass('show');
16622    }, 1);
16623
16624    // Bind button actions
16625
16626    if(options.buttons) {
16627      $.each(options.buttons, function(i, v) {
16628        if(typeof(v.action) === 'function') {
16629          $('.ModalMessage').delegate('.' + i, 'click.modal', v.action);
16630        }
16631      });
16632    }
16633
16634    $(document).unbind('keydown.modal').bind('keydown.modal', function(e) {
16635      if(e.which == 13) {
16636        if(! options.enter_button) { options.enter_button = 'close'; }
16637        $('.ModalMessage .' + options.enter_button).trigger('click');
16638      }
16639    });
16640
16641    // Bind close event
16642
16643    if(options.prevent_close !== true) {
16644      $('html').delegate('.ModalMessage .close, ._4ORMAT_overlay', 'click.modal_close', this.close_modal);
16645    }
16646  };
16647
16648  // helper functions
16649
16650  this.ModalMessage.prototype.close_modal = function() {
16651    if (typeof(that.options.before_close_callback) === 'function') {
16652      that.options.before_close_callback(that);
16653    }
16654
16655    $('.ModalMessage').removeClass('show');
16656    $('._4ORMAT_overlay').removeClass('show');
16657
16658    if(that.options.prevent_close !== true) {
16659      $('html').undelegate('.ModalMessage .close, ._4ORMAT_overlay', 'click.modal_close');
16660    }
16661
16662    if(that.options.buttons) {
16663      $.each(that.options.buttons, function(i, v) {
16664        if(typeof(v.action) === 'function') {
16665          $('.ModalMessage').undelegate('.' + i, 'click.modal');
16666        }
16667      });
16668    }
16669
16670    $(document).unbind('keydown.modal');
16671
16672    setTimeout(function() {
16673      $('.ModalMessage.generated').remove();
16674      $('._4ORMAT_overlay').remove();
16675      if (typeof(that.options.after_close_callback) === 'function') {
16676        that.options.after_close_callback(that);
16677      }
16678    }, that.anim_speed);
16679  };
16680}).call(typeof(_4ORMAT) === 'object' ? _4ORMAT : window);
16681
16682
16683
16684
16685
16686// Public facing javascript for content pages
16687// It's included in the content iframe when the page is flagged to be
16688// rendered in 'edit mode'
16689(function() {
16690  var $ = this.$;
16691  var ModalMessage = _4ORMAT.ModalMessage;
16692
16693  var ContactForm = {};
16694  this.ContactForm = ContactForm;
16695
16696  var formSubmitTextValues = {};
16697
16698  function beginFormInit() {
16699    if (typeof _4ORMAT.contact_forms === "object") {
16700      $(".email_form[data-editable-type='contact-form']").each(function(_i, form) {
16701        var $form = $(form);
16702
16703        if ($form.data("contactFormType") !== "mailing-list") {
16704          ContactForm.initForm($form);
16705        }
16706      });
16707    }
16708  }
16709
16710  ContactForm.initForm = function(form) {
16711    if (_4ORMAT_DATA && !_4ORMAT_DATA.page.content_editable && !_4ORMAT_DATA.preview) {
16712      $.ajax("/public_heartbeat").fail(function() {
16713        form.find("input, textarea").prop("disabled", true);
16714        form.find("input[type=submit]").attr("originalValue", form.find("input[type=submit]").val());
16715        form.find("input[type=submit]").val("Form is unavailable, please try again later");
16716      });
16717    }
16718
16719    ContactForm.addValidations(form);
16720
16721    // fixme - $(window).resize doesnt work but window.onresize does
16722    window.onresize = function() {
16723      $("div.tooltip").remove();
16724    };
16725  };
16726
16727  // validation rules by data-validate type
16728  ContactForm.validationRules = {
16729    email: { email: true, required: true },
16730    name: { maxlength: 255 },
16731    body: { required: true, maxlength: 65535 },
16732  };
16733
16734  // messages to display to the user when validating
16735  ContactForm.validationMessages = {
16736    email: {
16737      required: "Email address is required.",
16738      email: "Email address is not valid.",
16739    },
16740    name: {
16741      maxlength: "Field length must not exceed 255 characters.",
16742    },
16743    body: {
16744      required: "Message must not be blank.",
16745      maxlength: "Message length must not exceed 65,535 characters.",
16746    },
16747  };
16748
16749  // add validations to the form
16750  ContactForm.addValidations = function(form) {
16751    var rules = {};
16752    var messages = {};
16753    var name;
16754    var type;
16755
16756    // A simple system that is specifically not the HTML5 validation spec so
16757    // that we don't have two validations going on.
16758    //
16759    // <input> - no validation
16760    // <input data-validate='required'> - validated presence
16761    // <input data-validate='email'> - validates presence and email format
16762    form.find("*[data-validate]").each(function(i, node) {
16763      node = $(node);
16764      type = node.data("validate");
16765      name = node.attr("name");
16766
16767      rules[name] = ContactForm.validationRules[type];
16768      messages[name] = ContactForm.validationMessages[type];
16769    });
16770
16771    // Validations currently disabled in editor mode. Rendering the tooltips is
16772    // broken because of the page position of the iframe.
16773    if (!_4ORMAT_DATA.page.content_editable) {
16774      form.validate({
16775        rules: rules,
16776        messages: messages,
16777        errorElement: "p",
16778        errorClass: "invalid",
16779        errorPlacement: ContactForm.errorPlacement,
16780        unhighlight: ContactForm.unhighlight,
16781        submitHandler: ContactForm.submitHandler,
16782      });
16783    }
16784  };
16785
16786  // callback that places validation error on the page
16787  ContactForm.errorPlacement = function(error, element) {
16788    $(element)
16789      .tooltip("destroy")
16790      .attr("title", $(error).text());
16791    $(element)
16792      .tooltip({
16793        html: false,
16794        placement: "bottom",
16795        trigger: "manual",
16796      })
16797      .tooltip("show");
16798  };
16799
16800  // callback that unhighlights a previously highlighted field
16801  ContactForm.unhighlight = function(element) {
16802    $(element).tooltip("destroy");
16803  };
16804  ContactForm.submitHandler = function(form) {
16805    if (_4ORMAT_DATA.page.content_editable) {
16806      ContactForm.previewSubmit();
16807    } else {
16808      ContactForm.saveSubmitValue(form);
16809      ContactForm.disableSubmit(form);
16810      $.ajax({
16811        url: $(form).attr("action"),
16812        data: $(form).serialize(),
16813        type: "POST",
16814        context: form,
16815      })
16816        .done(ContactForm.sendSuccess)
16817        .done(function() {
16818          $(this)
16819            .find("textarea")
16820            .val("");
16821        })
16822        .fail(ContactForm.sendError);
16823    }
16824    return false; // required to prevent the form from submitting?
16825  };
16826
16827  ContactForm.disableSubmit = function(form) {
16828    $(form)
16829      .find("input[type=submit]")
16830      .attr("disabled", "disabled")
16831      .val("Sending...");
16832  };
16833
16834  ContactForm.saveSubmitValue = function(form) {
16835    var formSubmitValue = $(form)
16836      .find("input[type=submit]")
16837      .val();
16838    formSubmitTextValues[$(form).attr("id")] = formSubmitValue;
16839  };
16840
16841  ContactForm.previewSubmit = function() {
16842    new ModalMessage({
16843      title: "Note",
16844      text: "When this button is clicked by visitors to your site, it will send you this form in an email.",
16845    });
16846  };
16847
16848  ContactForm.sendSuccess = function() {
16849    var formId = $(this).attr("id");
16850
16851    $(this).trigger("reset");
16852
16853    $(this)
16854      .find("input[type=submit]")
16855      .attr("disabled", "disabled")
16856      .addClass("f_form_send_success")
16857      .val("Message Sent");
16858
16859    var that = this;
16860    var resetFormTimeout = 2000;
16861    setTimeout(function() {
16862      $(that)
16863        .find("input[type=submit]")
16864        .removeAttr("disabled")
16865        .val(formSubmitTextValues[formId]);
16866    }, resetFormTimeout);
16867
16868    $(this)
16869      .find("fieldset")
16870      .removeClass("_4ORMAT_module_input_active");
16871  };
16872
16873  ContactForm.sendError = function() {
16874    var formId = $(this).attr("id");
16875    $(this)
16876      .find("input[type=submit]")
16877      .removeAttr("disabled")
16878      .val(formSubmitTextValues[formId]);
16879
16880    new ModalMessage({
16881      title: "Warning",
16882      text: "We could not deliver your message. Please try again later.",
16883      modal_class: "warning small",
16884    });
16885  };
16886
16887  beginFormInit();
16888}.call(_4ORMAT));

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.