PageSourceSearch

https://delavciindelodajalci.com/Scripts/AllStartScripts.js

js delavciindelodajalci.com collected 2026-10-05 07:54:47 UTC 1,185,538 bytes, 33,222 lines download raw bytes

1/*  Prototype JavaScript framework, version 1.7.2
2*  (c) 2005-2010 Sam Stephenson
3*
4*  Prototype is freely distributable under the terms of an MIT-style license.
5*  For details, see the Prototype web site: http://www.prototypejs.org/
6*
7*--------------------------------------------------------------------------*/
8
9var Prototype = {
10
11Version: '1.7.2',
12
13Browser: (function(){
14	var ua = navigator.userAgent;
15	var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
16	return {
17	IE:             !!window.attachEvent && !isOpera,
18	Opera:          isOpera,
19	WebKit:         ua.indexOf('AppleWebKit/') > -1,
20	Gecko:          ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
21	MobileSafari:   /Apple.*Mobile/.test(ua)
22	}
23})(),
24
25BrowserFeatures: {
26	XPath: !!document.evaluate,
27
28	SelectorsAPI: !!document.querySelector,
29
30	ElementExtensions: (function() {
31	var constructor = window.Element || window.HTMLElement;
32	return !!(constructor && constructor.prototype);
33	})(),
34	SpecificElementExtensions: (function() {
35	if (typeof window.HTMLDivElement !== 'undefined')
36		return true;
37
38	var div = document.createElement('div'),
39		form = document.createElement('form'),
40		isSupported = false;
41
42	if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
43		isSupported = true;
44	}
45
46	div = form = null;
47
48	return isSupported;
49	})()
50},
51
52ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script\\s*>',
53JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
54
55emptyFunction: function() { },
56
57K: function(x) { return x }
58};
59
60if (Prototype.Browser.MobileSafari)
61Prototype.BrowserFeatures.SpecificElementExtensions = false;
62/* Based on Alex Arnell's inheritance implementation. */
63
64var Class = (function() {
65
66var IS_DONTENUM_BUGGY = (function(){
67	for (var p in { toString: 1 }) {
68	if (p === 'toString') return false;
69	}
70	return true;
71})();
72
73function subclass() {};
74function create() {
75	var parent = null, properties = $A(arguments);
76	if (Object.isFunction(properties[0]))
77	parent = properties.shift();
78
79	function klass() {
80	this.initialize.apply(this, arguments);
81	}
82
83	Object.extend(klass, Class.Methods);
84	klass.superclass = parent;
85	klass.subclasses = [];
86
87	if (parent) {
88	subclass.prototype = parent.prototype;
89	klass.prototype = new subclass;
90	parent.subclasses.push(klass);
91	}
92
93	for (var i = 0, length = properties.length; i < length; i++)
94	klass.addMethods(properties[i]);
95
96	if (!klass.prototype.initialize)
97	klass.prototype.initialize = Prototype.emptyFunction;
98
99	klass.prototype.constructor = klass;
100	return klass;
101}
102
103function addMethods(source) {
104	var ancestor   = this.superclass && this.superclass.prototype,
105		properties = Object.keys(source);
106
107	if (IS_DONTENUM_BUGGY) {
108	if (source.toString != Object.prototype.toString)
109		properties.push("toString");
110	if (source.valueOf != Object.prototype.valueOf)
111		properties.push("valueOf");
112	}
113
114	for (var i = 0, length = properties.length; i < length; i++) {
115	var property = properties[i], value = source[property];
116	if (ancestor && Object.isFunction(value) &&
117		value.argumentNames()[0] == "$super") {
118		var method = value;
119		value = (function(m) {
120		return function() { return ancestor[m].apply(this, arguments); };
121		})(property).wrap(method);
122
123		value.valueOf = (function(method) {
124		return function() { return method.valueOf.call(method); };
125		})(method);
126
127		value.toString = (function(method) {
128		return function() { return method.toString.call(method); };
129		})(method);
130	}
131	this.prototype[property] = value;
132	}
133
134	return this;
135}
136
137return {
138	create: create,
139	Methods: {
140	addMethods: addMethods
141	}
142};
143})();
144(function() {
145
146var _toString = Object.prototype.toString,
147	_hasOwnProperty = Object.prototype.hasOwnProperty,
148	NULL_TYPE = 'Null',
149	UNDEFINED_TYPE = 'Undefined',
150	BOOLEAN_TYPE = 'Boolean',
151	NUMBER_TYPE = 'Number',
152	STRING_TYPE = 'String',
153	OBJECT_TYPE = 'Object',
154	FUNCTION_CLASS = '[object Function]',
155	BOOLEAN_CLASS = '[object Boolean]',
156	NUMBER_CLASS = '[object Number]',
157	STRING_CLASS = '[object String]',
158	ARRAY_CLASS = '[object Array]',
159	DATE_CLASS = '[object Date]',
160	NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
161		typeof JSON.stringify === 'function' &&
162		JSON.stringify(0) === '0' &&
163		typeof JSON.stringify(Prototype.K) === 'undefined';
164
165
166
167var DONT_ENUMS = ['toString', 'toLocaleString', 'valueOf',
168'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor'];
169
170var IS_DONTENUM_BUGGY = (function(){
171	for (var p in { toString: 1 }) {
172	if (p === 'toString') return false;
173	}
174	return true;
175})();
176
177function Type(o) {
178	switch(o) {
179	case null: return NULL_TYPE;
180	case (void 0): return UNDEFINED_TYPE;
181	}
182	var type = typeof o;
183	switch(type) {
184	case 'boolean': return BOOLEAN_TYPE;
185	case 'number':  return NUMBER_TYPE;
186	case 'string':  return STRING_TYPE;
187	}
188	return OBJECT_TYPE;
189}
190
191function extend(destination, source) {
192	for (var property in source)
193	destination[property] = source[property];
194	return destination;
195}
196
197function inspect(object) {
198	try {
199	if (isUndefined(object)) return 'undefined';
200	if (object === null) return 'null';
201	return object.inspect ? object.inspect() : String(object);
202	} catch (e) {
203	if (e instanceof RangeError) return '...';
204	throw e;
205	}
206}
207
208function toJSON(value) {
209	return Str('', { '': value }, []);
210}
211
212function Str(key, holder, stack) {
213	var value = holder[key];
214	if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
215	value = value.toJSON(key);
216	}
217
218	var _class = _toString.call(value);
219
220	switch (_class) {
221	case NUMBER_CLASS:
222	case BOOLEAN_CLASS:
223	case STRING_CLASS:
224		value = value.valueOf();
225	}
226
227	switch (value) {
228	case null: return 'null';
229	case true: return 'true';
230	case false: return 'false';
231	}
232
233	var type = typeof value;
234	switch (type) {
235	case 'string':
236		return value.inspect(true);
237	case 'number':
238		return isFinite(value) ? String(value) : 'null';
239	case 'object':
240
241		for (var i = 0, length = stack.length; i < length; i++) {
242		if (stack[i] === value) {
243			throw new TypeError("Cyclic reference to '" + value + "' in object");
244		}
245		}
246		stack.push(value);
247
248		var partial = [];
249		if (_class === ARRAY_CLASS) {
250		for (var i = 0, length = value.length; i < length; i++) {
251			var str = Str(i, value, stack);
252			partial.push(typeof str === 'undefined' ? 'null' : str);
253		}
254		partial = '[' + partial.join(',') + ']';
255		} else {
256		var keys = Object.keys(value);
257		for (var i = 0, length = keys.length; i < length; i++) {
258			var key = keys[i], str = Str(key, value, stack);
259			if (typeof str !== "undefined") {
260			partial.push(key.inspect(true)+ ':' + str);
261			}
262		}
263		partial = '{' + partial.join(',') + '}';
264		}
265		stack.pop();
266		return partial;
267	}
268}
269
270function stringify(object) {
271	return JSON.stringify(object);
272}
273
274function toQueryString(object) {
275	return $H(object).toQueryString();
276}
277
278function toHTML(object) {
279	return object && object.toHTML ? object.toHTML() : String.interpret(object);
280}
281
282function keys(object) {
283	if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
284	var results = [];
285	for (var property in object) {
286	if (_hasOwnProperty.call(object, property))
287		results.push(property);
288	}
289
290	if (IS_DONTENUM_BUGGY) {
291	for (var i = 0; property = DONT_ENUMS[i]; i++) {
292		if (_hasOwnProperty.call(object, property))
293		results.push(property);
294	}
295	}
296
297	return results;
298}
299
300function values(object) {
301	var results = [];
302	for (var property in object)
303	results.push(object[property]);
304	return results;
305}
306
307function clone(object) {
308	return extend({ }, object);
309}
310
311function isElement(object) {
312	return !!(object && object.nodeType == 1);
313}
314
315function isArray(object) {
316	return _toString.call(object) === ARRAY_CLASS;
317}
318
319var hasNativeIsArray = (typeof Array.isArray == 'function')
320	&& Array.isArray([]) && !Array.isArray({});
321
322if (hasNativeIsArray) {
323	isArray = Array.isArray;
324}
325
326function isHash(object) {
327	return object instanceof Hash;
328}
329
330function isFunction(object) {
331	return _toString.call(object) === FUNCTION_CLASS;
332}
333
334function isString(object) {
335	return _toString.call(object) === STRING_CLASS;
336}
337
338function isNumber(object) {
339	return _toString.call(object) === NUMBER_CLASS;
340}
341
342function isDate(object) {
343	return _toString.call(object) === DATE_CLASS;
344}
345
346function isUndefined(object) {
347	return typeof object === "undefined";
348}
349
350extend(Object, {
351	extend:        extend,
352	inspect:       inspect,
353	toJSON:        NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
354	toQueryString: toQueryString,
355	toHTML:        toHTML,
356	keys:          Object.keys || keys,
357	values:        values,
358	clone:         clone,
359	isElement:     isElement,
360	isArray:       isArray,
361	isHash:        isHash,
362	isFunction:    isFunction,
363	isString:      isString,
364	isNumber:      isNumber,
365	isDate:        isDate,
366	isUndefined:   isUndefined
367});
368})();
369Object.extend(Function.prototype, (function() {
370var slice = Array.prototype.slice;
371
372function update(array, args) {
373	var arrayLength = array.length, length = args.length;
374	while (length--) array[arrayLength + length] = args[length];
375	return array;
376}
377
378function merge(array, args) {
379	array = slice.call(array, 0);
380	return update(array, args);
381}
382
383function argumentNames() {
384	var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
385	.replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
386	.replace(/\s+/g, '').split(',');
387	return names.length == 1 && !names[0] ? [] : names;
388}
389
390
391function bind(context) {
392	if (arguments.length < 2 && Object.isUndefined(arguments[0]))
393	return this;
394
395	if (!Object.isFunction(this))
396	throw new TypeError("The object is not callable.");
397
398	var nop = function() {};
399	var __method = this, args = slice.call(arguments, 1);
400
401	var bound = function() {
402	var a = merge(args, arguments);
403	var c = this instanceof bound ? this : context;
404	return __method.apply(c, a);
405	};
406
407	nop.prototype   = this.prototype;
408	bound.prototype = new nop();
409
410	return bound;
411}
412
413function bindAsEventListener(context) {
414	var __method = this, args = slice.call(arguments, 1);
415	return function(event) {
416	var a = update([event || window.event], args);
417	return __method.apply(context, a);
418	}
419}
420
421function curry() {
422	if (!arguments.length) return this;
423	var __method = this, args = slice.call(arguments, 0);
424	return function() {
425	var a = merge(args, arguments);
426	return __method.apply(this, a);
427	}
428}
429
430function delay(timeout) {
431	var __method = this, args = slice.call(arguments, 1);
432	timeout = timeout * 1000;
433	return window.setTimeout(function() {
434	return __method.apply(__method, args);
435	}, timeout);
436}
437
438function defer() {
439	var args = update([0.01], arguments);
440	return this.delay.apply(this, args);
441}
442
443function wrap(wrapper) {
444	var __method = this;
445	return function() {
446	var a = update([__method.bind(this)], arguments);
447	return wrapper.apply(this, a);
448	}
449}
450
451function methodize() {
452	if (this._methodized) return this._methodized;
453	var __method = this;
454	return this._methodized = function() {
455	var a = update([this], arguments);
456	return __method.apply(null, a);
457	};
458}
459
460var extensions = {
461	argumentNames:       argumentNames,
462	bindAsEventListener: bindAsEventListener,
463	curry:               curry,
464	delay:               delay,
465	defer:               defer,
466	wrap:                wrap,
467	methodize:           methodize
468};
469
470if (!Function.prototype.bind)
471	extensions.bind = bind;
472
473return extensions;
474})());
475
476
477
478(function(proto) {
479
480
481function toISOString() {
482	return this.getUTCFullYear() + '-' +
483	(this.getUTCMonth() + 1).toPaddedString(2) + '-' +
484	this.getUTCDate().toPaddedString(2) + 'T' +
485	this.getUTCHours().toPaddedString(2) + ':' +
486	this.getUTCMinutes().toPaddedString(2) + ':' +
487	this.getUTCSeconds().toPaddedString(2) + 'Z';
488}
489
490
491function toJSON() {
492	return this.toISOString();
493}
494
495if (!proto.toISOString) proto.toISOString = toISOString;
496if (!proto.toJSON) proto.toJSON = toJSON;
497
498})(Date.prototype);
499
500
501RegExp.prototype.match = RegExp.prototype.test;
502
503RegExp.escape = function(str) {
504return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
505};
506var PeriodicalExecuter = Class.create({
507initialize: function(callback, frequency) {
508	this.callback = callback;
509	this.frequency = frequency;
510	this.currentlyExecuting = false;
511
512	this.registerCallback();
513},
514
515registerCallback: function() {
516	this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
517},
518
519execute: function() {
520	this.callback(this);
521},
522
523stop: function() {
524	if (!this.timer) return;
525	clearInterval(this.timer);
526	this.timer = null;
527},
528
529onTimerEvent: function() {
530	if (!this.currentlyExecuting) {
531	try {
532		this.currentlyExecuting = true;
533		this.execute();
534		this.currentlyExecuting = false;
535	} catch(e) {
536		this.currentlyExecuting = false;
537		throw e;
538	}
539	}
540}
541});
542Object.extend(String, {
543interpret: function(value) {
544	return value == null ? '' : String(value);
545},
546specialChar: {
547	'\b': '\\b',
548	'\t': '\\t',
549	'\n': '\\n',
550	'\f': '\\f',
551	'\r': '\\r',
552	'\\': '\\\\'
553}
554});
555
556Object.extend(String.prototype, (function() {
557var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
558	typeof JSON.parse === 'function' &&
559	JSON.parse('{"test": true}').test;
560
561function prepareReplacement(replacement) {
562	if (Object.isFunction(replacement)) return replacement;
563	var template = new Template(replacement);
564	return function(match) { return template.evaluate(match) };
565}
566
567function isNonEmptyRegExp(regexp) {
568	return regexp.source && regexp.source !== '(?:)';
569}
570
571
572function gsub(pattern, replacement) {
573	var result = '', source = this, match;
574	replacement = prepareReplacement(replacement);
575
576	if (Object.isString(pattern))
577	pattern = RegExp.escape(pattern);
578
579	if (!(pattern.length || isNonEmptyRegExp(pattern))) {
580	replacement = replacement('');
581	return replacement + source.split('').join(replacement) + replacement;
582	}
583
584	while (source.length > 0) {
585	match = source.match(pattern)
586	if (match && match[0].length > 0) {
587		result += source.slice(0, match.index);
588		result += String.interpret(replacement(match));
589		source  = source.slice(match.index + match[0].length);
590	} else {
591		result += source, source = '';
592	}
593	}
594	return result;
595}
596
597function sub(pattern, replacement, count) {
598	replacement = prepareReplacement(replacement);
599	count = Object.isUndefined(count) ? 1 : count;
600
601	return this.gsub(pattern, function(match) {
602	if (--count < 0) return match[0];
603	return replacement(match);
604	});
605}
606
607function scan(pattern, iterator) {
608	this.gsub(pattern, iterator);
609	return String(this);
610}
611
612function truncate(length, truncation) {
613	length = length || 30;
614	truncation = Object.isUndefined(truncation) ? '...' : truncation;
615	return this.length > length ?
616	this.slice(0, length - truncation.length) + truncation : String(this);
617}
618
619function strip() {
620	return this.replace(/^\s+/, '').replace(/\s+$/, '');
621}
622
623function stripTags() {
624	return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
625}
626
627function stripScripts() {
628	return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
629}
630
631function extractScripts() {
632	var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
633		matchOne = new RegExp(Prototype.ScriptFragment, 'im');
634	return (this.match(matchAll) || []).map(function(scriptTag) {
635	return (scriptTag.match(matchOne) || ['', ''])[1];
636	});
637}
638
639function evalScripts() {
640	return this.extractScripts().map(function(script) { return eval(script); });
641}
642
643function escapeHTML() {
644	return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
645}
646
647function unescapeHTML() {
648	return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
649}
650
651
652function toQueryParams(separator) {
653	var match = this.strip().match(/([^?#]*)(#.*)?$/);
654	if (!match) return { };
655
656	return match[1].split(separator || '&').inject({ }, function(hash, pair) {
657	if ((pair = pair.split('='))[0]) {
658		var key = decodeURIComponent(pair.shift()),
659			value = pair.length > 1 ? pair.join('=') : pair[0];
660
661		if (value != undefined) {
662		value = value.gsub('+', ' ');
663		value = decodeURIComponent(value);
664		}
665
666		if (key in hash) {
667		if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
668		hash[key].push(value);
669		}
670		else hash[key] = value;
671	}
672	return hash;
673	});
674}
675
676function toArray() {
677	return this.split('');
678}
679
680function succ() {
681	return this.slice(0, this.length - 1) +
682	String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
683}
684
685function times(count) {
686	return count < 1 ? '' : new Array(count + 1).join(this);
687}
688
689function camelize() {
690	return this.replace(/-+(.)?/g, function(match, chr) {
691	return chr ? chr.toUpperCase() : '';
692	});
693}
694
695function capitalize() {
696	return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
697}
698
699function underscore() {
700	return this.replace(/::/g, '/')
701			.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
702			.replace(/([a-z\d])([A-Z])/g, '$1_$2')
703			.replace(/-/g, '_')
704			.toLowerCase();
705}
706
707function dasherize() {
708	return this.replace(/_/g, '-');
709}
710
711function inspect(useDoubleQuotes) {
712	var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
713	if (character in String.specialChar) {
714		return String.specialChar[character];
715	}
716	return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
717	});
718	if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
719	return "'" + escapedString.replace(/'/g, '\\\'') + "'";
720}
721
722function unfilterJSON(filter) {
723	return this.replace(filter || Prototype.JSONFilter, '$1');
724}
725
726function isJSON() {
727	var str = this;
728	if (str.blank()) return false;
729	str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
730	str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
731	str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
732	return (/^[\],:{}\s]*$/).test(str);
733}
734
735function evalJSON(sanitize) {
736	var json = this.unfilterJSON(),
737		cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
738	if (cx.test(json)) {
739	json = json.replace(cx, function (a) {
740		return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
741	});
742	}
743	try {
744	if (!sanitize || json.isJSON()) return eval('(' + json + ')');
745	} catch (e) { }
746	throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
747}
748
749function parseJSON() {
750	var json = this.unfilterJSON();
751	return JSON.parse(json);
752}
753
754function include(pattern) {
755	return this.indexOf(pattern) > -1;
756}
757
758function startsWith(pattern, position) {
759	position = Object.isNumber(position) ? position : 0;
760	return this.lastIndexOf(pattern, position) === position;
761}
762
763function endsWith(pattern, position) {
764	pattern = String(pattern);
765	position = Object.isNumber(position) ? position : this.length;
766	if (position < 0) position = 0;
767	if (position > this.length) position = this.length;
768	var d = position - pattern.length;
769	return d >= 0 && this.indexOf(pattern, d) === d;
770}
771
772function empty() {
773	return this == '';
774}
775
776function blank() {
777	return /^\s*$/.test(this);
778}
779
780function interpolate(object, pattern) {
781	return new Template(this, pattern).evaluate(object);
782}
783
784return {
785	gsub:           gsub,
786	sub:            sub,
787	scan:           scan,
788	truncate:       truncate,
789	strip:          String.prototype.trim || strip,
790	stripTags:      stripTags,
791	stripScripts:   stripScripts,
792	extractScripts: extractScripts,
793	evalScripts:    evalScripts,
794	escapeHTML:     escapeHTML,
795	unescapeHTML:   unescapeHTML,
796	toQueryParams:  toQueryParams,
797	parseQuery:     toQueryParams,
798	toArray:        toArray,
799	succ:           succ,
800	times:          times,
801	camelize:       camelize,
802	capitalize:     capitalize,
803	underscore:     underscore,
804	dasherize:      dasherize,
805	inspect:        inspect,
806	unfilterJSON:   unfilterJSON,
807	isJSON:         isJSON,
808	evalJSON:       NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
809	include:        include,
810	startsWith:     String.prototype.startsWith || startsWith,
811	endsWith:       String.prototype.endsWith || endsWith,
812	empty:          empty,
813	blank:          blank,
814	interpolate:    interpolate
815};
816})());
817
818var Template = Class.create({
819initialize: function(template, pattern) {
820	this.template = template.toString();
821	this.pattern = pattern || Template.Pattern;
822},
823
824evaluate: function(object) {
825	if (object && Object.isFunction(object.toTemplateReplacements))
826	object = object.toTemplateReplacements();
827
828	return this.template.gsub(this.pattern, function(match) {
829	if (object == null) return (match[1] + '');
830
831	var before = match[1] || '';
832	if (before == '\\') return match[2];
833
834	var ctx = object, expr = match[3],
835		pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
836
837	match = pattern.exec(expr);
838	if (match == null) return before;
839
840	while (match != null) {
841		var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
842		ctx = ctx[comp];
843		if (null == ctx || '' == match[3]) break;
844		expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
845		match = pattern.exec(expr);
846	}
847
848	return before + String.interpret(ctx);
849	});
850}
851});
852Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
853
854var $break = { };
855
856var Enumerable = (function() {
857function each(iterator, context) {
858	try {
859	this._each(iterator, context);
860	} catch (e) {
861	if (e != $break) throw e;
862	}
863	return this;
864}
865
866function eachSlice(number, iterator, context) {
867	var index = -number, slices = [], array = this.toArray();
868	if (number < 1) return array;
869	while ((index += number) < array.length)
870	slices.push(array.slice(index, index+number));
871	return slices.collect(iterator, context);
872}
873
874function all(iterator, context) {
875	iterator = iterator || Prototype.K;
876	var result = true;
877	this.each(function(value, index) {
878	result = result && !!iterator.call(context, value, index, this);
879	if (!result) throw $break;
880	}, this);
881	return result;
882}
883
884function any(iterator, context) {
885	iterator = iterator || Prototype.K;
886	var result = false;
887	this.each(function(value, index) {
888	if (result = !!iterator.call(context, value, index, this))
889		throw $break;
890	}, this);
891	return result;
892}
893
894function collect(iterator, context) {
895	iterator = iterator || Prototype.K;
896	var results = [];
897	this.each(function(value, index) {
898	results.push(iterator.call(context, value, index, this));
899	}, this);
900	return results;
901}
902
903function detect(iterator, context) {
904	var result;
905	this.each(function(value, index) {
906	if (iterator.call(context, value, index, this)) {
907		result = value;
908		throw $break;
909	}
910	}, this);
911	return result;
912}
913
914function findAll(iterator, context) {
915	var results = [];
916	this.each(function(value, index) {
917	if (iterator.call(context, value, index, this))
918		results.push(value);
919	}, this);
920	return results;
921}
922
923function grep(filter, iterator, context) {
924	iterator = iterator || Prototype.K;
925	var results = [];
926
927	if (Object.isString(filter))
928	filter = new RegExp(RegExp.escape(filter));
929
930	this.each(function(value, index) {
931	if (filter.match(value))
932		results.push(iterator.call(context, value, index, this));
933	}, this);
934	return results;
935}
936
937function include(object) {
938	if (Object.isFunction(this.indexOf) && this.indexOf(object) != -1)
939	return true;
940
941	var found = false;
942	this.each(function(value) {
943	if (value == object) {
944		found = true;
945		throw $break;
946	}
947	});
948	return found;
949}
950
951function inGroupsOf(number, fillWith) {
952	fillWith = Object.isUndefined(fillWith) ? null : fillWith;
953	return this.eachSlice(number, function(slice) {
954	while(slice.length < number) slice.push(fillWith);
955	return slice;
956	});
957}
958
959function inject(memo, iterator, context) {
960	this.each(function(value, index) {
961	memo = iterator.call(context, memo, value, index, this);
962	}, this);
963	return memo;
964}
965
966function invoke(method) {
967	var args = $A(arguments).slice(1);
968	return this.map(function(value) {
969	return value[method].apply(value, args);
970	});
971}
972
973function max(iterator, context) {
974	iterator = iterator || Prototype.K;
975	var result;
976	this.each(function(value, index) {
977	value = iterator.call(context, value, index, this);
978	if (result == null || value >= result)
979		result = value;
980	}, this);
981	return result;
982}
983
984function min(iterator, context) {
985	iterator = iterator || Prototype.K;
986	var result;
987	this.each(function(value, index) {
988	value = iterator.call(context, value, index, this);
989	if (result == null || value < result)
990		result = value;
991	}, this);
992	return result;
993}
994
995function partition(iterator, context) {
996	iterator = iterator || Prototype.K;
997	var trues = [], falses = [];
998	this.each(function(value, index) {
999	(iterator.call(context, value, index, this) ?
1000		trues : falses).push(value);
1001	}, this);
1002	return [trues, falses];
1003}
1004
1005function pluck(property) {
1006	var results = [];
1007	this.each(function(value) {
1008	results.push(value[property]);
1009	});
1010	return results;
1011}
1012
1013function reject(iterator, context) {
1014	var results = [];
1015	this.each(function(value, index) {
1016	if (!iterator.call(context, value, index, this))
1017		results.push(value);
1018	}, this);
1019	return results;
1020}
1021
1022function sortBy(iterator, context) {
1023	return this.map(function(value, index) {
1024	return {
1025		value: value,
1026		criteria: iterator.call(context, value, index, this)
1027	};
1028	}, this).sort(function(left, right) {
1029	var a = left.criteria, b = right.criteria;
1030	return a < b ? -1 : a > b ? 1 : 0;
1031	}
1031).pluck('value');
1032}
1033
1034function toArray() {
1035	return this.map();
1036}
1037
1038function zip() {
1039	var iterator = Prototype.K, args = $A(arguments);
1040	if (Object.isFunction(args.last()))
1041	iterator = args.pop();
1042
1043	var collections = [this].concat(args).map($A);
1044	return this.map(function(value, index) {
1045	return iterator(collections.pluck(index));
1046	});
1047}
1048
1049function size() {
1050	return this.toArray().length;
1051}
1052
1053function inspect() {
1054	return '#<Enumerable:' + this.toArray().inspect() + '>';
1055}
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065return {
1066	each:       each,
1067	eachSlice:  eachSlice,
1068	all:        all,
1069	every:      all,
1070	any:        any,
1071	some:       any,
1072	collect:    collect,
1073	map:        collect,
1074	detect:     detect,
1075	findAll:    findAll,
1076	select:     findAll,
1077	filter:     findAll,
1078	grep:       grep,
1079	include:    include,
1080	member:     include,
1081	inGroupsOf: inGroupsOf,
1082	inject:     inject,
1083	invoke:     invoke,
1084	max:        max,
1085	min:        min,
1086	partition:  partition,
1087	pluck:      pluck,
1088	reject:     reject,
1089	sortBy:     sortBy,
1090	toArray:    toArray,
1091	entries:    toArray,
1092	zip:        zip,
1093	size:       size,
1094	inspect:    inspect,
1095	find:       detect
1096};
1097})();
1098
1099function $A(iterable) {
1100if (!iterable) return [];
1101if ('toArray' in Object(iterable)) return iterable.toArray();
1102var length = iterable.length || 0, results = new Array(length);
1103while (length--) results[length] = iterable[length];
1104return results;
1105}
1106
1107
1108function $w(string) {
1109if (!Object.isString(string)) return [];
1110string = string.strip();
1111return string ? string.split(/\s+/) : [];
1112}
1113
1114// Boogie 2023-08-18 - Hack za uporabo v GoogleMaps
1115Array.from_old = Array.from ;
1116Array.from = $A;
1117
1118
1119(function() {
1120var arrayProto = Array.prototype,
1121	slice = arrayProto.slice,
1122	_each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
1123
1124function each(iterator, context) {
1125	for (var i = 0, length = this.length >>> 0; i < length; i++) {
1126	if (i in this) iterator.call(context, this[i], i, this);
1127	}
1128}
1129if (!_each) _each = each;
1130
1131function clear() {
1132	this.length = 0;
1133	return this;
1134}
1135
1136function first() {
1137	return this[0];
1138}
1139
1140function last() {
1141	return this[this.length - 1];
1142}
1143
1144function compact() {
1145	return this.select(function(value) {
1146	return value != null;
1147	});
1148}
1149
1150function flatten() {
1151	return this.inject([], function(array, value) {
1152	if (Object.isArray(value))
1153		return array.concat(value.flatten());
1154	array.push(value);
1155	return array;
1156	});
1157}
1158
1159function without() {
1160	var values = slice.call(arguments, 0);
1161	return this.select(function(value) {
1162	return !values.include(value);
1163	});
1164}
1165
1166function reverse(inline) {
1167	return (inline === false ? this.toArray() : this)._reverse();
1168}
1169
1170function uniq(sorted) {
1171	return this.inject([], function(array, value, index) {
1172	if (0 == index || (sorted ? array.last() != value : !array.include(value)))
1173		array.push(value);
1174	return array;
1175	});
1176}
1177
1178function intersect(array) {
1179	return this.uniq().findAll(function(item) {
1180	return array.indexOf(item) !== -1;
1181	});
1182}
1183
1184
1185function clone() {
1186	return slice.call(this, 0);
1187}
1188
1189function size() {
1190	return this.length;
1191}
1192
1193function inspect() {
1194	return '[' + this.map(Object.inspect).join(', ') + ']';
1195}
1196
1197function indexOf(item, i) {
1198	if (this == null) throw new TypeError();
1199
1200	var array = Object(this), length = array.length >>> 0;
1201	if (length === 0) return -1;
1202
1203	i = Number(i);
1204	if (isNaN(i)) {
1205	i = 0;
1206	} else if (i !== 0 && isFinite(i)) {
1207	i = (i > 0 ? 1 : -1) * Math.floor(Math.abs(i));
1208	}
1209
1210	if (i > length) return -1;
1211
1212	var k = i >= 0 ? i : Math.max(length - Math.abs(i), 0);
1213	for (; k < length; k++)
1214	if (k in array && array[k] === item) return k;
1215	return -1;
1216}
1217
1218
1219function lastIndexOf(item, i) {
1220	if (this == null) throw new TypeError();
1221
1222	var array = Object(this), length = array.length >>> 0;
1223	if (length === 0) return -1;
1224
1225	if (!Object.isUndefined(i)) {
1226	i = Number(i);
1227	if (isNaN(i)) {
1228		i = 0;
1229	} else if (i !== 0 && isFinite(i)) {
1230		i = (i > 0 ? 1 : -1) * Math.floor(Math.abs(i));
1231	}
1232	} else {
1233	i = length;
1234	}
1235
1236	var k = i >= 0 ? Math.min(i, length - 1) :
1237	length - Math.abs(i);
1238
1239	for (; k >= 0; k--)
1240	if (k in array && array[k] === item) return k;
1241	return -1;
1242}
1243
1244function concat(_) {
1245	var array = [], items = slice.call(arguments, 0), item, n = 0;
1246	items.unshift(this);
1247	for (var i = 0, length = items.length; i < length; i++) {
1248	item = items[i];
1249	if (Object.isArray(item) && !('callee' in item)) {
1250		for (var j = 0, arrayLength = item.length; j < arrayLength; j++) {
1251		if (j in item) array[n] = item[j];
1252		n++;
1253		}
1254	} else {
1255		array[n++] = item;
1256	}
1257	}
1258	array.length = n;
1259	return array;
1260}
1261
1262
1263function wrapNative(method) {
1264	return function() {
1265	if (arguments.length === 0) {
1266		return method.call(this, Prototype.K);
1267	} else if (arguments[0] === undefined) {
1268		var args = slice.call(arguments, 1);
1269		args.unshift(Prototype.K);
1270		return method.apply(this, args);
1271	} else {
1272		return method.apply(this, arguments);
1273	}
1274	};
1275}
1276
1277
1278function map(iterator) {
1279	if (this == null) throw new TypeError();
1280	iterator = iterator || Prototype.K;
1281
1282	var object = Object(this);
1283	var results = [], context = arguments[1], n = 0;
1284
1285	for (var i = 0, length = object.length >>> 0; i < length; i++) {
1286	if (i in object) {
1287		results[n] = iterator.call(context, object[i], i, object);
1288	}
1289	n++;
1290	}
1291	results.length = n;
1292	return results;
1293}
1294
1295if (arrayProto.map) {
1296	map = wrapNative(Array.prototype.map);
1297}
1298
1299function filter(iterator) {
1300	if (this == null || !Object.isFunction(iterator))
1301	throw new TypeError();
1302
1303	var object = Object(this);
1304	var results = [], context = arguments[1], value;
1305
1306	for (var i = 0, length = object.length >>> 0; i < length; i++) {
1307	if (i in object) {
1308		value = object[i];
1309		if (iterator.call(context, value, i, object)) {
1310		results.push(value);
1311		}
1312	}
1313	}
1314	return results;
1315}
1316
1317if (arrayProto.filter) {
1318	filter = Array.prototype.filter;
1319}
1320
1321function some(iterator) {
1322	if (this == null) throw new TypeError();
1323	iterator = iterator || Prototype.K;
1324	var context = arguments[1];
1325
1326	var object = Object(this);
1327	for (var i = 0, length = object.length >>> 0; i < length; i++) {
1328	if (i in object && iterator.call(context, object[i], i, object)) {
1329		return true;
1330	}
1331	}
1332
1333	return false;
1334}
1335
1336if (arrayProto.some) {
1337	var some = wrapNative(Array.prototype.some);
1338}
1339
1340
1341function every(iterator) {
1342	if (this == null) throw new TypeError();
1343	iterator = iterator || Prototype.K;
1344	var context = arguments[1];
1345
1346	var object = Object(this);
1347	for (var i = 0, length = object.length >>> 0; i < length; i++) {
1348	if (i in object && !iterator.call(context, object[i], i, object)) {
1349		return false;
1350	}
1351	}
1352
1353	return true;
1354}
1355
1356if (arrayProto.every) {
1357	var every = wrapNative(Array.prototype.every);
1358}
1359
1360var _reduce = arrayProto.reduce;
1361function inject(memo, iterator) {
1362	iterator = iterator || Prototype.K;
1363	var context = arguments[2];
1364	return _reduce.call(this, iterator.bind(context), memo);
1365}
1366
1367if (!arrayProto.reduce) {
1368	var inject = Enumerable.inject;
1369}
1370
1371Object.extend(arrayProto, Enumerable);
1372
1373if (!arrayProto._reverse)
1374	arrayProto._reverse = arrayProto.reverse;
1375
1376Object.extend(arrayProto, {
1377	_each:     _each,
1378
1379	map:       map,
1380	collect:   map,
1381	select:    filter,
1382	filter:    filter,
1383	findAll:   filter,
1384	some:      some,
1385	any:       some,
1386	every:     every,
1387	all:       every,
1388	inject:    inject,
1389
1390	clear:     clear,
1391	first:     first,
1392	last:      last,
1393	compact:   compact,
1394	flatten:   flatten,
1395	without:   without,
1396	reverse:   reverse,
1397	uniq:      uniq,
1398	intersect: intersect,
1399	clone:     clone,
1400	toArray:   clone,
1401	size:      size,
1402	inspect:   inspect
1403});
1404
1405var CONCAT_ARGUMENTS_BUGGY = (function() {
1406	return [].concat(arguments)[0][0] !== 1;
1407})(1,2);
1408
1409if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
1410
1411if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
1412if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
1413})();
1414function $H(object) {
1415return new Hash(object);
1416};
1417
1418var Hash = Class.create(Enumerable, (function() {
1419function initialize(object) {
1420	this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
1421}
1422
1423
1424function _each(iterator, context) {
1425	var i = 0;
1426	for (var key in this._object) {
1427	var value = this._object[key], pair = [key, value];
1428	pair.key = key;
1429	pair.value = value;
1430	iterator.call(context, pair, i);
1431	i++;
1432	}
1433}
1434
1435function set(key, value) {
1436	return this._object[key] = value;
1437}
1438
1439function get(key) {
1440	if (this._object[key] !== Object.prototype[key])
1441	return this._object[key];
1442}
1443
1444function unset(key) {
1445	var value = this._object[key];
1446	delete this._object[key];
1447	return value;
1448}
1449
1450function toObject() {
1451	return Object.clone(this._object);
1452}
1453
1454
1455
1456function keys() {
1457	return this.pluck('key');
1458}
1459
1460function values() {
1461	return this.pluck('value');
1462}
1463
1464function index(value) {
1465	var match = this.detect(function(pair) {
1466	return pair.value === value;
1467	});
1468	return match && match.key;
1469}
1470
1471function merge(object) {
1472	return this.clone().update(object);
1473}
1474
1475function update(object) {
1476	return new Hash(object).inject(this, function(result, pair) {
1477	result.set(pair.key, pair.value);
1478	return result;
1479	});
1480}
1481
1482function toQueryPair(key, value) {
1483	if (Object.isUndefined(value)) return key;
1484
1485	value = String.interpret(value);
1486
1487	value = value.gsub(/(\r)?\n/, '\r\n');
1488	value = encodeURIComponent(value);
1489	value = value.gsub(/%20/, '+');
1490	return key + '=' + value;
1491}
1492
1493function toQueryString() {
1494	return this.inject([], function(results, pair) {
1495	var key = encodeURIComponent(pair.key), values = pair.value;
1496
1497	if (values && typeof values == 'object') {
1498		if (Object.isArray(values)) {
1499		var queryValues = [];
1500		for (var i = 0, len = values.length, value; i < len; i++) {
1501			value = values[i];
1502			queryValues.push(toQueryPair(key, value));
1503		}
1504		return results.concat(queryValues);
1505		}
1506	} else results.push(toQueryPair(key, values));
1507	return results;
1508	}).join('&');
1509}
1510
1511function inspect() {
1512	return '#<Hash:{' + this.map(function(pair) {
1513	return pair.map(Object.inspect).join(': ');
1514	}).join(', ') + '}>';
1515}
1516
1517function clone() {
1518	return new Hash(this);
1519}
1520
1521return {
1522	initialize:             initialize,
1523	_each:                  _each,
1524	set:                    set,
1525	get:                    get,
1526	unset:                  unset,
1527	toObject:               toObject,
1528	toTemplateReplacements: toObject,
1529	keys:                   keys,
1530	values:                 values,
1531	index:                  index,
1532	merge:                  merge,
1533	update:                 update,
1534	toQueryString:          toQueryString,
1535	inspect:                inspect,
1536	toJSON:                 toObject,
1537	clone:                  clone
1538};
1539})());
1540
1541Hash.from = $H;
1542Object.extend(Number.prototype, (function() {
1543function toColorPart() {
1544	return this.toPaddedString(2, 16);
1545}
1546
1547function succ() {
1548	return this + 1;
1549}
1550
1551function times(iterator, context) {
1552	$R(0, this, true).each(iterator, context);
1553	return this;
1554}
1555
1556function toPaddedString(length, radix) {
1557	var string = this.toString(radix || 10);
1558	return '0'.times(length - string.length) + string;
1559}
1560
1561function abs() {
1562	return Math.abs(this);
1563}
1564
1565function round() {
1566	return Math.round(this);
1567}
1568
1569function ceil() {
1570	return Math.ceil(this);
1571}
1572
1573function floor() {
1574	return Math.floor(this);
1575}
1576
1577return {
1578	toColorPart:    toColorPart,
1579	succ:           succ,
1580	times:          times,
1581	toPaddedString: toPaddedString,
1582	abs:            abs,
1583	round:          round,
1584	ceil:           ceil,
1585	floor:          floor
1586};
1587})());
1588
1589function $R(start, end, exclusive) {
1590return new ObjectRange(start, end, exclusive);
1591}
1592
1593var ObjectRange = Class.create(Enumerable, (function() {
1594function initialize(start, end, exclusive) {
1595	this.start = start;
1596	this.end = end;
1597	this.exclusive = exclusive;
1598}
1599
1600function _each(iterator, context) {
1601	var value = this.start, i;
1602	for (i = 0; this.include(value); i++) {
1603	iterator.call(context, value, i);
1604	value = value.succ();
1605	}
1606}
1607
1608function include(value) {
1609	if (value < this.start)
1610	return false;
1611	if (this.exclusive)
1612	return value < this.end;
1613	return value <= this.end;
1614}
1615
1616return {
1617	initialize: initialize,
1618	_each:      _each,
1619	include:    include
1620};
1621})());
1622
1623
1624
1625var Abstract = { };
1626
1627
1628var Try = {
1629these: function() {
1630	var returnValue;
1631
1632	for (var i = 0, length = arguments.length; i < length; i++) {
1633	var lambda = arguments[i];
1634	try {
1635		returnValue = lambda();
1636		break;
1637	} catch (e) { }
1638	}
1639
1640	return returnValue;
1641}
1642};
1643
1644var Ajax = {
1645getTransport: function() {
1646	return Try.these(
1647	function() {return new XMLHttpRequest()},
1648	function() {return new ActiveXObject('Msxml2.XMLHTTP')},
1649	function() {return new ActiveXObject('Microsoft.XMLHTTP')}
1650	) || false;
1651},
1652
1653activeRequestCount: 0
1654};
1655
1656Ajax.Responders = {
1657responders: [],
1658
1659_each: function(iterator, context) {
1660	this.responders._each(iterator, context);
1661},
1662
1663register: function(responder) {
1664	if (!this.include(responder))
1665	this.responders.push(responder);
1666},
1667
1668unregister: function(responder) {
1669	this.responders = this.responders.without(responder);
1670},
1671
1672dispatch: function(callback, request, transport, json) {
1673	this.each(function(responder) {
1674	if (Object.isFunction(responder[callback])) {
1675		try {
1676		responder[callback].apply(responder, [request, transport, json]);
1677		} catch (e) { }
1678	}
1679	});
1680}
1681};
1682
1683Object.extend(Ajax.Responders, Enumerable);
1684
1685Ajax.Responders.register({
1686onCreate:   function() { Ajax.activeRequestCount++ },
1687onComplete: function() { Ajax.activeRequestCount-- }
1688});
1689Ajax.Base = Class.create({
1690initialize: function(options) {
1691	this.options = {
1692	method:       'post',
1693	asynchronous: true,
1694	contentType:  'application/x-www-form-urlencoded',
1695	encoding:     'UTF-8',
1696	parameters:   '',
1697	evalJSON:     true,
1698	evalJS:       true
1699	};
1700	Object.extend(this.options, options || { });
1701
1702	this.options.method = this.options.method.toLowerCase();
1703
1704	if (Object.isHash(this.options.parameters))
1705	this.options.parameters = this.options.parameters.toObject();
1706}
1707});
1708Ajax.Request = Class.create(Ajax.Base, {
1709_complete: false,
1710
1711initialize: function($super, url, options) {
1712	$super(options);
1713	this.transport = Ajax.getTransport();
1714	this.request(url);
1715},
1716
1717request: function(url) {
1718	this.url = url;
1719	this.method = this.options.method;
1720	var params = Object.isString(this.options.parameters) ?
1721		this.options.parameters :
1722		Object.toQueryString(this.options.parameters);
1723
1724	if (!['get', 'post'].include(this.method)) {
1725	params += (params ? '&' : '') + "_method=" + this.method;
1726	this.method = 'post';
1727	}
1728
1729	if (params && this.method === 'get') {
1730	this.url += (this.url.include('?') ? '&' : '?') + params;
1731	}
1732
1733	this.parameters = params.toQueryParams();
1734
1735	try {
1736	var response = new Ajax.Response(this);
1737	if (this.options.onCreate) this.options.onCreate(response);
1738	Ajax.Responders.dispatch('onCreate', this, response);
1739
1740	this.transport.open(this.method.toUpperCase(), this.url,
1741		this.options.asynchronous);
1742
1743	if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
1744
1745	this.transport.onreadystatechange = this.onStateChange.bind(this);
1746	this.setRequestHeaders();
1747
1748	this.body = this.method == 'post' ? (this.options.postBody || params) : null;
1749	this.transport.send(this.body);
1750
1751	/* Force Firefox to handle ready state 4 for synchronous requests */
1752	if (!this.options.asynchronous && this.transport.overrideMimeType)
1753		this.onStateChange();
1754
1755	}
1756	catch (e) {
1757	this.dispatchException(e);
1758	}
1759},
1760
1761onStateChange: function() {
1762	var readyState = this.transport.readyState;
1763	if (readyState > 1 && !((readyState == 4) && this._complete))
1764	this.respondToReadyState(this.transport.readyState);
1765},
1766
1767setRequestHeaders: function() {
1768	var headers = {
1769	'X-Requested-With': 'XMLHttpRequest',
1770	'X-Prototype-Version': Prototype.Version,
1771	'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
1772	};
1773
1774	if (this.method == 'post') {
1775	headers['Content-type'] = this.options.contentType +
1776		(this.options.encoding ? '; charset=' + this.options.encoding : '');
1777
1778	/* Force "Connection: close" for older Mozilla browsers to work
1779	* around a bug where XMLHttpRequest sends an incorrect
1780	* Content-length header. See Mozilla Bugzilla #246651.
1781	*/
1782	if (this.transport.overrideMimeType &&
1783		(navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
1784			headers['Connection'] = 'close';
1785	}
1786
1787	if (typeof this.options.requestHeaders == 'object') {
1788	var extras = this.options.requestHeaders;
1789
1790	if (Object.isFunction(extras.push))
1791		for (var i = 0, length = extras.length; i < length; i += 2)
1792		headers[extras[i]] = extras[i+1];
1793	else
1794		$H(extras).each(function(pair) { headers[pair.key] = pair.value });
1795	}
1796
1797	for (var name in headers)
1798	if (headers[name] != null)
1799		this.transport.setRequestHeader(name, headers[name]);
1800},
1801
1802success: function() {
1803	var status = this.getStatus();
1804	return !status || (status >= 200 && status < 300) || status == 304;
1805},
1806
1807getStatus: function() {
1808	try {
1809	if (this.transport.status === 1223) return 204;
1810	return this.transport.status || 0;
1811	} catch (e) { return 0 }
1812},
1813
1814respondToReadyState: function(readyState) {
1815	var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
1816
1817	if (state == 'Complete') {
1818	try {
1819		this._complete = true;
1820		(this.options['on' + response.status]
1821		|| this.options['on' + (this.success() ? 'Success' : 'Failure')]
1822		|| Prototype.emptyFunction)(response, response.headerJSON);
1823	} catch (e) {
1824		this.dispatchException(e);
1825	}
1826
1827	var contentType = response.getHeader('Content-type');
1828	if (this.options.evalJS == 'force'
1829		|| (this.options.evalJS && this.isSameOrigin() && contentType
1830		&& contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
1831		this.evalResponse();
1832	}
1833
1834	try {
1835	(this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
1836	Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
1837	} catch (e) {
1838	this.dispatchException(e);
1839	}
1840
1841	if (state == 'Complete') {
1842	this.transport.onreadystatechange = Prototype.emptyFunction;
1843	}
1844},
1845
1846isSameOrigin: function() {
1847	var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
1848	return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
1849	protocol: location.protocol,
1850	domain: document.domain,
1851	port: location.port ? ':' + location.port : ''
1852	}));
1853},
1854
1855getHeader: function(name) {
1856	try {
1857	return this.transport.getResponseHeader(name) || null;
1858	} catch (e) { return null; }
1859},
1860
1861evalResponse: function() {
1862	try {
1863	return eval((this.transport.responseText || '').unfilterJSON());
1864	} catch (e) {
1865	this.dispatchException(e);
1866	}
1867},
1868
1869dispatchException: function(exception) {
1870	(this.options.onException || Prototype.emptyFunction)(this, exception);
1871	Ajax.Responders.dispatch('onException', this, exception);
1872}
1873});
1874
1875Ajax.Request.Events =
1876['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
1877
1878
1879
1880
1881
1882
1883
1884
1885Ajax.Response = Class.create({
1886initialize: function(request){
1887	this.request = request;
1888	var transport  = this.transport  = request.transport,
1889		readyState = this.readyState = transport.readyState;
1890
1891	if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
1892	this.status       = this.getStatus();
1893	this.statusText   = this.getStatusText();
1894	this.responseText = String.interpret(transport.responseText);
1895	this.headerJSON   = this._getHeaderJSON();
1896	}
1897
1898	if (readyState == 4) {
1899	var xml = transport.responseXML;
1900	this.responseXML  = Object.isUndefined(xml) ? null : xml;
1901	this.responseJSON = this._getResponseJSON();
1902	}
1903},
1904
1905status:      0,
1906
1907statusText: '',
1908
1909getStatus: Ajax.Request.prototype.getStatus,
1910
1911getStatusText: function() {
1912	try {
1913	return this.transport.statusText || '';
1914	} catch (e) { return '' }
1915},
1916
1917getHeader: Ajax.Request.prototype.getHeader,
1918
1919getAllHeaders: function() {
1920	try {
1921	return this.getAllResponseHeaders();
1922	} catch (e) { return null }
1923},
1924
1925getResponseHeader: function(name) {
1926	return this.transport.getResponseHeader(name);
1927},
1928
1929getAllResponseHeaders: function() {
1930	return this.transport.getAllResponseHeaders();
1931},
1932
1933_getHeaderJSON: function() {
1934	var json = this.getHeader('X-JSON');
1935	if (!json) return null;
1936
1937	try {
1938	json = decodeURIComponent(escape(json));
1939	} catch(e) {
1940	}
1941
1942	try {
1943	return json.evalJSON(this.request.options.sanitizeJSON ||
1944		!this.request.isSameOrigin());
1945	} catch (e) {
1946	this.request.dispatchException(e);
1947	}
1948},
1949
1950_getResponseJSON: function() {
1951	var options = this.request.options;
1952	if (!options.evalJSON || (options.evalJSON != 'force' &&
1953	!(this.getHeader('Content-type') || '').include('application/json')) ||
1954		this.responseText.blank())
1955		return null;
1956	try {
1957	return this.responseText.evalJSON(options.sanitizeJSON ||
1958		!this.request.isSameOrigin());
1959	} catch (e) {
1960	this.request.dispatchException(e);
1961	}
1962}
1963});
1964
1965Ajax.Updater = Class.create(Ajax.Request, {
1966initialize: function($super, container, url, options) {
1967	this.container = {
1968	success: (container.success || container),
1969	failure: (container.failure || (container.success ? null : container))
1970	};
1971
1972	options = Object.clone(options);
1973	var onComplete = options.onComplete;
1974	options.onComplete = (function(response, json) {
1975	this.updateContent(response.responseText);
1976	if (Object.isFunction(onComplete)) onComplete(response, json);
1977	}).bind(this);
1978
1979	$super(url, options);
1980},
1981
1982updateContent: function(responseText) {
1983	var receiver = this.container[this.success() ? 'success' : 'failure'],
1984		options = this.options;
1985
1986	if (!options.evalScripts) responseText = responseText.stripScripts();
1987
1988	if (receiver = $(receiver)) {
1989	if (options.insertion) {
1990		if (Object.isString(options.insertion)) {
1991		var insertion = { }; insertion[options.insertion] = responseText;
1992		receiver.insert(insertion);
1993		}
1994		else options.insertion(receiver, responseText);
1995	}
1996	else receiver.update(responseText);
1997	}
1998}
1999});
2000
2001Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
2002initialize: function($super, container, url, options) {
2003	$super(options);
2004	this.onComplete = this.options.onComplete;
2005
2006	this.frequency = (this.options.frequency || 2);
2007	this.decay = (this.options.decay || 1);
2008
2009	this.updater = { };
2010	this.container = container;
2011	this.url = url;
2012
2013	this.start();
2014},
2015
2016start: function() {
2017	this.options.onComplete = this.updateComplete.bind(this);
2018	this.onTimerEvent();
2019},
2020
2021stop: function() {
2022	this.updater.options.onComplete = undefined;
2023	clearTimeout(this.timer);
2024	(this.onComplete || Prototype.emptyFunction).apply(this, arguments);
2025},
2026
2027updateComplete: function(response) {
2028	if (this.options.decay) {
2029	this.decay = (response.responseText == this.lastText ?
2030		this.decay * this.options.decay : 1);
2031
2032	this.lastText = response.responseText;
2033	}
2034	this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
2035},
2036
2037onTimerEvent: function() {
2038	this.updater = new Ajax.Updater(this.container, this.url, this.options);
2039}
2040});
2041
2042(function(GLOBAL) {
2043
2044var UNDEFINED;
2045var SLICE = Array.prototype.slice;
2046
2047var DIV = document.createElement('div');
2048
2049exception_log = function (log_txt) {
2050	if (window.console != undefined) {
2051		console.log(log_txt);
2052	}
2053}
2054
2055function $(element) {
2056	if (arguments.length > 1) {
2057		for (var i = 0, elements = [], length = arguments.length; i < length; i++)
2058			elements.push($(arguments[i]));
2059		return elements;
2060	}
2061
2062	if (Object.isString(element)) {
2063		if (document.getElementById(element)) {
2064			element = document.getElementById(element) ;
2065		} else {
2066			exception_log("Element "+element+" not found ! -> "+arguments.callee.caller) ;
2067			element = document.getElementById(element) ;
2068		}
2069	}
2070	return Element.extend(element);
2071}
2072
2073GLOBAL.$ = $;
2074
2075
2076if (!GLOBAL.Node) GLOBAL.Node = {};
2077
2078if (!GLOBAL.Node.ELEMENT_NODE) {
2079	Object.extend(GLOBAL.Node, {
2080	ELEMENT_NODE:                1,
2081	ATTRIBUTE_NODE:              2,
2082	TEXT_NODE:                   3,
2083	CDATA_SECTION_NODE:          4,
2084	ENTITY_REFERENCE_NODE:       5,
2085	ENTITY_NODE:                 6,
2086	PROCESSING_INSTRUCTION_NODE: 7,
2087	COMMENT_NODE:                8,
2088	DOCUMENT_NODE:               9,
2089	DOCUMENT_TYPE_NODE:         10,
2090	DOCUMENT_FRAGMENT_NODE:     11,
2091	NOTATION_NODE:              12
2092	});
2093}
2094
2095var ELEMENT_CACHE = {};
2096
2097function shouldUseCreationCache(tagName, attributes) {
2098	if (tagName === 'select') return false;
2099	if ('type' in attributes) return false;
2100	return true;
2101}
2102
2103var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
2104	try {
2105	var el = document.createElement('<input name="x">');
2106	return el.tagName.toLowerCase() === 'input' && el.name === 'x';
2107	}
2108	catch(err) {
2109	return false;
2110	}
2111})();
2112
2113
2114var oldElement = GLOBAL.Element;
2115function Element(tagName, attributes) {
2116	attributes = attributes || {};
2117	tagName = tagName.toLowerCase();
2118
2119	if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
2120	tagName = '<' + tagName + ' name="' + attributes.name + '">';
2121	delete attributes.name;
2122	return Element.writeAttribute(document.createElement(tagName), attributes);
2123	}
2124
2125	if (!ELEMENT_CACHE[tagName])
2126	ELEMENT_CACHE[tagName] = Element.extend(document.createElement(tagName));
2127
2128	var node = shouldUseCreationCache(tagName, attributes) ?
2129	ELEMENT_CACHE[tagName].cloneNode(false) : document.createElement(tagName);
2130
2131	return Element.writeAttribute(node, attributes);
2132}
2133
2134GLOBAL.Element = Element;
2135
2136Object.extend(GLOBAL.Element, oldElement || {});
2137if (oldElement) GLOBAL.Element.prototype = oldElement.prototype;
2138
2139Element.Methods = { ByTag: {}, Simulated: {} };
2140
2141var methods = {};
2142
2143var INSPECT_ATTRIBUTES = { id: 'id', className: 'class' };
2144function inspect(element) {
2145	element = $(element);
2146	var result = '<' + element.tagName.toLowerCase();
2147
2148	var attribute, value;
2149	for (var property in INSPECT_ATTRIBUTES) {
2150	attribute = INSPECT_ATTRIBUTES[property];
2151	value = (element[property] || '').toString();
2152	if (value) result += ' ' + attribute + '=' + value.inspect(true);
2153	}
2154
2155	return result + '>';
2156}
2157
2158methods.inspect = inspect;
2159
2160
2161function visible(element) {
2162	return $(element).style.display !== 'none';
2163}
2164
2165function toggle(element, bool) {
2166	element = $(element);
2167	if (Object.isUndefined(bool))
2168	bool = !Element.visible(element);
2169	Element[bool ? 'show' : 'hide'](element);
2170
2171	return element;
2172}
2173
2174function hide(element) {
2175	element = ($D(element)) ? $(element) : null;
2176	if (element != null)
2177		element.style.display = 'none';
2178	return element;
2179}
2180
2181function show(element) {
2182	element = $(element);
2183	element.style.display = '';
2184	return element;
2185}
2186
2187
2188Object.extend(methods, {
2189	visible: visible,
2190	toggle:  toggle,
2191	hide:    hide,
2192	show:    show
2193});
2194
2195
2196function remove(element) {
2197	element = $(element);
2198	if (element.parentNode != null)
2199		element.parentNode.removeChild(element);
2200	return element;
2201}
2202
2203var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
2204	var el = document.createElement("select"),
2205		isBuggy = true;
2206	el.innerHTML = "<option value=\"test\">test</option>";
2207	if (el.options && el.options[0]) {
2208	isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
2209	}
2210	el = null;
2211	return isBuggy;
2212})();
2213
2214var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
2215	try {
2216	var el = document.createElement("table");
2217	if (el && el.tBodies) {
2218		el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
2219		var isBuggy = typeof el.tBodies[0] == "undefined";
2220		el = null;
2221		return isBuggy;
2222	}
2223	} catch (e) {
2224	return true;
2225	}
2226})();
2227
2228var LINK_ELEMENT_INNERHTML_BUGGY = (function() {
2229	try {
2230	var el = document.createElement('div');
2231	el.innerHTML = "<link />";
2232	var isBuggy = (el.childNodes.length === 0);
2233	el = null;
2234	return isBuggy;
2235	} catch(e) {
2236	return true;
2237	}
2238})();
2239
2240var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY ||
2241TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY;
2242
2243var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
2244	var s = document.createElement("script"),
2245		isBuggy = false;
2246	try {
2247	s.appendChild(document.createTextNode(""));
2248	isBuggy = !s.firstChild ||
2249		s.firstChild && s.firstChild.nodeType !== 3;
2250	} catch (e) {
2251	isBuggy = true;
2252	}
2253	s = null;
2254	return isBuggy;
2255})();
2256
2257function update(element, content) {
2258	element = $(element);
2259
2260	var descendants = element.getElementsByTagName('*'),
2261	i = descendants.length;
2262	while (i--) purgeElement(descendants[i]);
2263
2264	if (content && content.toElement)
2265	content = content.toElement();
2266
2267	if (Object.isElement(content))
2268	return element.update().insert(content);
2269
2270
2271	content = Object.toHTML(content);
2272	var tagName = element.tagName.toUpperCase();
2273
2274	if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
2275	element.text = content;
2276	return element;
2277	}
2278
2279	if (ANY_INNERHTML_BUGGY) {
2280	if (tagName in INSERTION_TRANSLATIONS.tags) {
2281		while (element.firstChild)
2282		element.removeChild(element.firstChild);
2283
2284		var nodes = getContentFromAnonymousElement(tagName, content.stripScripts());
2285		for (var i = 0, node; node = nodes[i]; i++)
2286		element.appendChild(node);
2287
2288	} else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf('<link') > -1) {
2289		while (element.firstChild)
2290		element.removeChild(element.firstChild);
2291
2292		var nodes = getContentFromAnonymousElement(tagName,
2293		content.stripScripts(), true);
2294
2295		for (var i = 0, node; node = nodes[i]; i++)
2296		element.appendChild(node);
2297	} else {
2298		element.innerHTML = content.stripScripts();
2299	}
2300	} else {
2301	element.innerHTML = content.stripScripts();
2302	}
2303
2304	content.evalScripts.bind(content).defer();
2305	return element;
2306}
2307
2308function replace(element, content) {
2309	element = $(element);
2310
2311	if (content && content.toElement) {
2312	content = content.toElement();
2313	} else if (!Object.isElement(content)) {
2314	content = Object.toHTML(content);
2315	var range = element.ownerDocument.createRange();
2316	range.selectNode(element);
2317	content.evalScripts.bind(content).defer();
2318	content = range.createContextualFragment(content.stripScripts());
2319	}
2320
2321	element.parentNode.replaceChild(content, element);
2322	return element;
2323}
2324
2325var INSERTION_TRANSLATIONS = {
2326	before: function(element, node) {
2327	element.parentNode.insertBefore(node, element);
2328	},
2329	top: function(element, node) {
2330	element.insertBefore(node, element.firstChild);
2331	},
2332	bottom: function(element, node) {
2333	element.appendChild(node);
2334	},
2335	after: function(element, node) {
2336	element.parentNode.insertBefore(node, element.nextSibling);
2337	},
2338
2339	tags: {
2340	TABLE:  ['<table>',                '</table>',                   1],
2341	TBODY:  ['<table><tbody>',         '</tbody></table>',           2],
2342	TR:     ['<table><tbody><tr>',     '</tr></tbody></table>',      3],
2343	TD:     ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
2344	SELECT: ['<select>',               '</select>',                  1]
2345	}
2346};
2347
2348var tags = INSERTION_TRANSLATIONS.tags;
2349
2350Object.extend(tags, {
2351	THEAD: tags.TBODY,
2352	TFOOT: tags.TBODY,
2353	TH:    tags.TD
2354});
2355
2356function replace_IE(element, content) {
2357	element = $(element);
2358	if (content && content.toElement)
2359	content = content.toElement();
2360	if (Object.isElement(content)) {
2361	element.parentNode.replaceChild(content, element);
2362	return element;
2363	}
2364
2365	content = Object.toHTML(content);
2366	var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
2367
2368	if (tagName in INSERTION_TRANSLATIONS.tags) {
2369	var nextSibling = Element.next(element);
2370	var fragments = getContentFromAnonymousElement(
2371	tagName, content.stripScripts());
2372
2373	parent.removeChild(element);
2374
2375	var iterator;
2376	if (nextSibling)
2377		iterator = function(node) { parent.insertBefore(node, nextSibling) };
2378	else
2379		iterator = function(node) { parent.appendChild(node); }
2380
2381	fragments.each(iterator);
2382	} else {
2383	element.outerHTML = content.stripScripts();
2384	}
2385
2386	content.evalScripts.bind(content).defer();
2387	return element;
2388}
2389
2390if ('outerHTML' in document.documentElement)
2391	replace = replace_IE;
2392
2393function isContent(content) {
2394	if (Object.isUndefined(content) || content === null) return false;
2395
2396	if (Object.isString(content) || Object.isNumber(content)) return true;
2397	if (Object.isElement(content)) return true;
2398	if (content.toElement || content.toHTML) return true;
2399
2400	return false;
2401}
2402
2403function insertContentAt(element, content, position) {
2404	position   = position.toLowerCase();
2405	var method = INSERTION_TRANSLATIONS[position];
2406
2407	if (content && content.toElement) content = content.toElement();
2408	if (Object.isElement(content)) {
2409	method(element, content);
2410	return element;
2411	}
2412
2413	content = Object.toHTML(content);
2414	var tagName = ((position === 'before' || position === 'after') ?
2415	element.parentNode : element).tagName.toUpperCase();
2416
2417	var childNodes = getContentFromAnonymousElement(tagName, content.stripScripts());
2418
2419	if (position === 'top' || position === 'after') childNodes.reverse();
2420
2421	for (var i = 0, node; node = childNodes[i]; i++)
2422	method(element, node);
2423
2424	content.evalScripts.bind(content).defer();
2425}
2426
2427function insert(element, insertions) {
2428	element = $(element);
2429
2430	if (isContent(insertions))
2431	insertions = { bottom: insertions };
2432
2433	for (var position in insertions)
2434	insertContentAt(element, insertions[position], position);
2435
2436	return element;
2437}
2438
2439function wrap(element, wrapper, attributes) {
2440	element = $(element);
2441
2442	if (Object.isElement(wrapper)) {
2443	$(wrapper).writeAttribute(attributes || {});
2444	} else if (Object.isString(wrapper)) {
2445	wrapper = new Element(wrapper, attributes);
2446	} else {
2447	wrapper = new Element('div', wrapper);
2448	}
2449
2450	if (element.parentNode)
2451	element.parentNode.replaceChild(wrapper, element);
2452
2453	wrapper.appendChild(element);
2454
2455	return wrapper;
2456}
2457
2458function cleanWhitespace(element) {
2459	element = $(element);
2460	var node = element.firstChild;
2461
2462	while (node) {
2463	var nextNode = node.nextSibling;
2464	if (node.nodeType === Node.TEXT_NODE && !/\S/.test(node.nodeValue))
2465		element.removeChild(node);
2466	node = nextNode;
2467	}
2468	return element;
2469}
2470
2471function empty(element) {
2472	return $(element).innerHTML.blank();
2473}
2474
2475function getContentFromAnonymousElement(tagName, html, force) {
2476	var t = INSERTION_TRANSLATIONS.tags[tagName], div = DIV;
2477
2478	var workaround = !!t;
2479	if (!workaround && force) {
2480	workaround = true;
2481	t = ['', '', 0];
2482	}
2483
2484	if (workaround) {
2485	div.innerHTML = '&#160;' + t[0] + html + t[1];
2486	div.removeChild(div.firstChild);
2487	for (var i = t[2]; i--; )
2488		div = div.firstChild;
2489	} else {
2490	div.innerHTML = html;
2491	}
2492
2493	return $A(div.childNodes);
2494}
2495
2496function clone(element, deep) {
2497	if (!(element = $(element))) return;
2498	var clone = element.cloneNode(deep);
2499	if (!HAS_UNIQUE_ID_PROPERTY) {
2500	clone._prototypeUID = UNDEFINED;
2501	if (deep) {
2502		var descendants = Element.select(clone, '*'),
2503		i = descendants.length;
2504		while (i--)
2505		descendants[i]._prototypeUID = UNDEFINED;
2506	}
2507	}
2508	return Element.extend(clone);
2509}
2510
2511function purgeElement(element) {
2512	var uid = getUniqueElementID(element);
2513	if (uid) {
2514	Element.stopObserving(element);
2515	if (!HAS_UNIQUE_ID_PROPERTY)
2516		element._prototypeUID = UNDEFINED;
2517	delete Element.Storage[uid];
2518	}
2519}
2520
2521function purgeCollection(elements) {
2522	var i = elements.length;
2523	while (i--)
2524	purgeElement(elements[i]);
2525}
2526
2527function purgeCollection_IE(elements) {
2528	var i = elements.length, element, uid;
2529	while (i--) {
2530	element = elements[i];
2531	uid = getUniqueElementID(element);
2532	delete Element.Storage[uid];
2533	delete Event.cache[uid];
2534	}
2535}
2536
2537if (HAS_UNIQUE_ID_PROPERTY) {
2538	purgeCollection = purgeCollection_IE;
2539}
2540
2541
2542function purge(element) {
2543	if (!(element = $(element))) return;
2544	purgeElement(element);
2545
2546	var descendants = element.getElementsByTagName('*'),
2547	i = descendants.length;
2548
2549	while (i--) purgeElement(descendants[i]);
2550
2551	return null;
2552}
2553
2554Object.extend(methods, {
2555	remove:  remove,
2556	update:  update,
2557	replace: replace,
2558	insert:  insert,
2559	wrap:    wrap,
2560	cleanWhitespace: cleanWhitespace,
2561	empty:   empty,
2562	clone:   clone,
2563	purge:   purge
2564});
2565
2566
2567
2568function recursivelyCollect(element, property, maximumLength) {
2569	element = $(element);
2570	maximumLength = maximumLength || -1;
2571	var elements = [];
2572
2573	while (element = element[property]) {
2574	if (element.nodeType === Node.ELEMENT_NODE)
2575		elements.push(Element.extend(element));
2576
2577	if (elements.length === maximumLength) break;
2578	}
2579
2580	return elements;
2581}
2582
2583
2584function ancestors(element) {
2585	return recursivelyCollect(element, 'parentNode');
2586}
2587
2588function descendants(element) {
2589	return Element.select(element, '*');
2590}
2591
2592function firstDescendant(element) {
2593	element = $(element).firstChild;
2594	while (element && element.nodeType !== Node.ELEMENT_NODE)
2595	element = element.nextSibling;
2596
2597	return $(element);
2598}
2599
2600function immediateDescendants(element) {
2601	var results = [], child = $(element).firstChild;
2602
2603	while (child) {
2604	if (child.nodeType === Node.ELEMENT_NODE)
2605		results.push(Element.extend(child));
2606
2607	child = child.nextSibling;
2608	}
2609
2610	return results;
2611}
2612
2613function previousSiblings(element) {
2614	return recursivelyCollect(element, 'previousSibling');
2615}
2616
2617function nextSiblings(element) {
2618	return recursivelyCollect(element, 'nextSibling');
2619}
2620
2621function siblings(element) {
2622	element = $(element);
2623	var previous = previousSiblings(element),
2624	next = nextSiblings(element);
2625	return previous.reverse().concat(next);
2626}
2627
2628function match(element, selector) {
2629	element = $(element);
2630
2631	if (Object.isString(selector))
2632	return Prototype.Selector.match(element, selector);
2633
2634	return selector.match(element);
2635}
2636
2637
2638function _recursivelyFind(element, property, expression, index) {
2639	element = $(element), expression = expression || 0, index = index || 0;
2640	if (Object.isNumber(expression)) {
2641	index = expression, expression = null;
2642	}
2643
2644	while (element = element[property]) {
2645	if (element.nodeType !== 1) continue;
2646	if (expression && !Prototype.Selector.match(element, expression))
2647		continue;
2648	if (--index >= 0) continue;
2649
2650	return Element.extend(element);
2651	}
2652}
2653
2654
2655function up(element, expression, index) {
2656	element = $(element);
2657
2658	if (arguments.length === 1) return $(element.parentNode);
2659	return _recursivelyFind(element, 'parentNode', expression, index);
2660}
2661
2662function down(element, expression, index) {
2663	if (arguments.length === 1) return firstDescendant(element);
2664	element = $(element), expression = expression || 0, index = index || 0;
2665
2666	if (Object.isNumber(expression))
2667	index = expression, expression = '*';
2668
2669	var node = Prototype.Selector.select(expression, element)[index];
2670	return Element.extend(node);
2671}
2672
2673function previous(element, expression, index) {
2674	return _recursivelyFind(element, 'previousSibling', expression, index);
2675}
2676
2677function next(element, expression, index) {
2678	return _recursivelyFind(element, 'nextSibling', expression, index);
2679}
2680
2681function select(element) {
2682	element = $(element);
2683	var expressions = SLICE.call(arguments, 1).join(', ');
2684	return Prototype.Selector.select(expressions, element);
2685}
2686
2687function adjacent(element) {
2688	element = $(element);
2689	var expressions = SLICE.call(arguments, 1).join(', ');
2690	var siblings = Element.siblings(element), results = [];
2691	for (var i = 0, sibling; sibling = siblings[i]; i++) {
2692	if (Prototype.Selector.match(sibling, expressions))
2693		results.push(sibling);
2694	}
2695
2696	return results;
2697}
2698
2699function descendantOf_DOM(element, ancestor) {
2700	element = $(element), ancestor = $(ancestor);
2701	while (element = element.parentNode)
2702	if (element === ancestor) return true;
2703	return false;
2704}
2705
2706function descendantOf_contains(element, ancestor) {
2707	element = $(element), ancestor = $(ancestor);
2708	if (!ancestor.contains) return descendantOf_DOM(element, ancestor);
2709	return ancestor.contains(element) && ancestor !== element;
2710}
2711
2712function descendantOf_compareDocumentPosition(element, ancestor) {
2713	element = $(element), ancestor = $(ancestor);
2714	return (element.compareDocumentPosition(ancestor) & 8) === 8;
2715}
2716
2717var descendantOf;
2718if (DIV.compareDocumentPosition) {
2719	descendantOf = descendantOf_compareDocumentPosition;
2720} else if (DIV.contains) {
2721	descendantOf = descendantOf_contains;
2722} else {
2723	descendantOf = descendantOf_DOM;
2724}
2725
2726
2727Object.extend(methods, {
2728	recursivelyCollect:   recursivelyCollect,
2729	ancestors:            ancestors,
2730	descendants:          descendants,
2731	firstDescendant:      firstDescendant,
2732	immediateDescendants: immediateDescendants,
2733	previousSiblings:     previousSiblings,
2734	nextSiblings:         nextSiblings,
2735	siblings:             siblings,
2736	match:                match,
2737	up:                   up,
2738	down:                 down,
2739	previous:             previous,
2740	next:                 next,
2741	select:               select,
2742	adjacent:             adjacent,
2743	descendantOf:         descendantOf,
2744
2745	getElementsBySelector: select,
2746
2747	childElements:         immediateDescendants
2748});
2749
2750
2751var idCounter = 1;
2752function identify(element) {
2753	element = $(element);
2754	var id = Element.readAttribute(element, 'id');
2755	if (id) return id;
2756
2757	do { id = 'anonymous_element_' + idCounter++ } while ($(id));
2758
2759	Element.writeAttribute(element, 'id', id);
2760	return id;
2761}
2762
2763
2764function readAttribute(element, name) {
2765	return $(element).getAttribute(name);
2766}
2767
2768function readAttribute_IE(element, name) {
2769	element = $(element);
2770
2771	var table = ATTRIBUTE_TRANSLATIONS.read;
2772	if (table.values[name])
2773	return table.values[name](element, name);
2774
2775	if (table.names[name]) name = table.names[name];
2776
2777	if (name.include(':')) {
2778	if (!element.attributes || !element.attributes[name]) return null;
2779	return element.attributes[name].value;
2780	}
2781
2782	return element.getAttribute(name);
2783}
2784
2785function readAttribute_Opera(element, name) {
2786	if (name === 'title') return element.title;
2787	return element.getAttribute(name);
2788}
2789
2790var PROBLEMATIC_ATTRIBUTE_READING = (function() {
2791	DIV.setAttribute('onclick', []);
2792	var value = DIV.getAttribute('onclick');
2793	var isFunction = Object.isArray(value);
2794	DIV.removeAttribute('onclick');
2795	return isFunction;
2796})();
2797
2798if (PROBLEMATIC_ATTRIBUTE_READING) {
2799	readAttribute = readAttribute_IE;
2800} else if (Prototype.Browser.Opera) {
2801	readAttribute = readAttribute_Opera;
2802}
2803
2804
2805function writeAttribute(element, name, value) {
2806	element = $(element);
2807	var attributes = {}, table = ATTRIBUTE_TRANSLATIONS.write;
2808
2809	if (typeof name === 'object') {
2810	attributes = name;
2811	} else {
2812	attributes[name] = Object.isUndefined(value) ? true : value;
2813	}
2814
2815	for (var attr in attributes) {
2816	name = table.names[attr] || attr;
2817	value = attributes[attr];
2818	if (table.values[attr])
2819		name = table.values[attr](element, value) || name;
2820	if (value === false || value === null)
2821		element.removeAttribute(name);
2822	else if (value === true)
2823		element.setAttribute(name, name);
2824	else element.setAttribute(name, value);
2825	}
2826
2827	return element;
2828}
2829
2830var PROBLEMATIC_HAS_ATTRIBUTE_WITH_CHECKBOXES = (function () {
2831	if (!HAS_EXTENDED_CREATE_ELEMENT_SYNTAX) {
2832	return false;
2833	}
2834	var checkbox = document.createElement('<input type="checkbox">');
2835	checkbox.checked = true;
2836	var node = checkbox.getAttributeNode('checked');
2837	return !node || !node.specified;
2838})();
2839
2840function hasAttribute(element, attribute) {
2841	attribute = ATTRIBUTE_TRANSLATIONS.has[attribute] || attribute;
2842	var node = $(element).getAttributeNode(attribute);
2843	return !!(node && node.specified);
2844}
2845
2846function hasAttribute_IE(element, attribute) {
2847	if (attribute === 'checked') {
2848	return element.checked;
2849	}
2850	return hasAttribute(element, attribute);
2851}
2852
2853GLOBAL.Element.Methods.Simulated.hasAttribute =
2854PROBLEMATIC_HAS_ATTRIBUTE_WITH_CHECKBOXES ?
2855hasAttribute_IE : hasAttribute;
2856
2857function classNames(element) {
2858	return new Element.ClassNames(element);
2859}
2860
2861var regExpCache = {};
2862function getRegExpForClassName(className) {
2863	if (regExpCache[className]) return regExpCache[className];
2864
2865	var re = new RegExp("(^|\\s+)" + className + "(\\s+|$)");
2866	regExpCache[className] = re;
2867	return re;
2868}
2869
2870function hasClassName(element, className) {
2871	if (!(element = $(element))) return;
2872
2873	var elementClassName = element.className;
2874
2875	if (elementClassName.length === 0) return false;
2876	if (elementClassName === className) return true;
2877
2878	return getRegExpForClassName(className).test(elementClassName);
2879}
2880
2881function addClassName(element, className) {
2882	if (!(element = $(element))) return;
2883
2884	if (!hasClassName(element, className))
2885	element.className += (element.className ? ' ' : '') + className;
2886
2887	return element;
2888}
2889
2890function removeClassName(element, className) {
2891	if (!(element = $(element))) return;
2892
2893	element.className = element.className.replace(
2894	getRegExpForClassName(className), ' ').strip();
2895
2896	return element;
2897}
2898
2899function toggleClassName(element, className, bool) {
2900	if (!(element = $(element))) return;
2901
2902	if (Object.isUndefined(bool))
2903	bool = !hasClassName(element, className);
2904
2905	var method = Element[bool ? 'addClassName' : 'removeClassName'];
2906	return method(element, className);
2907}
2908
2909var ATTRIBUTE_TRANSLATIONS = {};
2910
2911var classProp = 'className', forProp = 'for';
2912
2913DIV.setAttribute(classProp, 'x');
2914if (DIV.className !== 'x') {
2915	DIV.setAttribute('class', 'x');
2916	if (DIV.className === 'x')
2917	classProp = 'class';
2918}
2919
2920var LABEL = document.createElement('label');
2921LABEL.setAttribute(forProp, 'x');
2922if (LABEL.htmlFor !== 'x') {
2923	LABEL.setAttribute('htmlFor', 'x');
2924	if (LABEL.htmlFor === 'x')
2925	forProp = 'htmlFor';
2926}
2927LABEL = null;
2928
2929function _getAttr(element, attribute) {
2930	return element.getAttribute(attribute);
2931}
2932
2933function _getAttr2(element, attribute) {
2934	return element.getAttribute(attribute, 2);
2935}
2936
2937function _getAttrNode(element, attribute) {
2938	var node = element.getAttributeNode(attribute);
2939	return node ? node.value : '';
2940}
2941
2942function _getFlag(element, attribute) {
2943	return $(element).hasAttribute(attribute) ? attribute : null;
2944}
2945
2946DIV.onclick = Prototype.emptyFunction;
2947var onclickValue = DIV.getAttribute('onclick');
2948
2949var _getEv;
2950
2951if (String(onclickValue).indexOf('{') > -1) {
2952	_getEv = function(element, attribute) {
2953	var value = element.getAttribute(attribute);
2954	if (!value) return null;
2955	value = value.toString();
2956	value = value.split('{')[1];
2957	value = value.split('}')[0];
2958	return value.strip();
2959	};
2960}
2961else if (onclickValue === '') {
2962	_getEv = function(element, attribute) {
2963	var value = element.getAttribute(attribute);
2964	if (!value) return null;
2965	return value.strip();
2966	};
2967}
2968
2969ATTRIBUTE_TRANSLATIONS.read = {
2970	names: {
2971	'class':     classProp,
2972	'className': classProp,
2973	'for':       forProp,
2974	'htmlFor':   forProp
2975	},
2976
2977	values: {
2978	style: function(element) {
2979		return element.style.cssText.toLowerCase();
2980	},
2981	title: function(element) {
2982		return element.title;
2983	}
2984	}
2985};
2986
2987ATTRIBUTE_TRANSLATIONS.write = {
2988	names: {
2989	className:   'class',
2990	htmlFor:     'for',
2991	cellpadding: 'cellPadding',
2992	cellspacing: 'cellSpacing'
2993	},
2994
2995	values: {
2996	checked: function(element, value) {
2997		element.checked = !!value;
2998	},
2999
3000	style: function(element, value) {
3001		element.style.cssText = value ? value : '';
3002	}
3003	}
3004};
3005
3006ATTRIBUTE_TRANSLATIONS.has = { names: {} };
3007
3008Object.extend(ATTRIBUTE_TRANSLATIONS.write.names,
3009ATTRIBUTE_TRANSLATIONS.read.names);
3010
3011var CAMEL_CASED_ATTRIBUTE_NAMES = $w('colSpan rowSpan vAlign dateTime ' +
3012'accessKey tabIndex encType maxLength readOnly longDesc frameBorder');
3013
3014for (var i = 0, attr; attr = CAMEL_CASED_ATTRIBUTE_NAMES[i]; i++) {
3015	ATTRIBUTE_TRANSLATIONS.write.names[attr.toLowerCase()] = attr;
3016	ATTRIBUTE_TRANSLATIONS.has.names[attr.toLowerCase()]   = attr;
3017}
3018
3019Object.extend(ATTRIBUTE_TRANSLATIONS.read.values, {
3020	href:        _getAttr2,
3021	src:         _getAttr2,
3022	type:        _getAttr,
3023	action:      _getAttrNode,
3024	disabled:    _getFlag,
3025	checked:     _getFlag,
3026	readonly:    _getFlag,
3027	multiple:    _getFlag,
3028	onload:      _getEv,
3029	onunload:    _getEv,
3030	onclick:     _getEv,
3031	ondblclick:  _getEv,
3032	onmousedown: _getEv,
3033	onmouseup:   _getEv,
3034	onmouseover: _getEv,
3035	onmousemove: _getEv,
3036	onmouseout:  _getEv,
3037	onfocus:     _getEv,
3038	onblur:      _getEv,
3039	onkeypress:  _getEv,
3040	onkeydown:   _getEv,
3041	onkeyup:     _getEv,
3042	onsubmit:    _getEv,
3043	onreset:     _getEv,
3044	onselect:    _getEv,
3045	onchange:    _getEv
3046});
3047
3048
3049Object.extend(methods, {
3050	identify:        identify,
3051	readAttribute:   readAttribute,
3052	writeAttribute:  writeAttribute,
3053	classNames:      classNames,
3054	hasClassName:    hasClassName,
3055	addClassName:    addClassName,
3056	removeClassName: removeClassName,
3057	toggleClassName: toggleClassName
3058});
3059
3060
3061function normalizeStyleName(style) {
3062	if (style === 'float' || style === 'styleFloat')
3063	return 'cssFloat';
3064	return style.camelize();
3065}
3066
3067function normalizeStyleName_IE(style) {
3068	if (style === 'float' || style === 'cssFloat')
3069	return 'styleFloat';
3070	return style.camelize();
3071}
3072
3073function setStyle(element, styles) {
3074	element = $(element);
3075	var elementStyle = element.style, match;
3076
3077	if (Object.isString(styles)) {
3078	elementStyle.cssText += ';' + styles;
3079	if (styles.include('opacity')) {
3080		var opacity = styles.match(/opacity:\s*(\d?\.?\d*)/)[1];
3081		Element.setOpacity(element, opacity);
3082	}
3083	return element;
3084	}
3085
3086	for (var property in styles) {
3087	if (property === 'opacity') {
3088		Element.setOpacity(element, styles[property]);
3089	} else {
3090		var value = styles[property];
3091		if (property === 'float' || property === 'cssFloat') {
3092		property = Object.isUndefined(elementStyle.styleFloat) ?
3093		'cssFloat' : 'styleFloat';
3094		}
3095		elementStyle[property] = value;
3096	}
3097	}
3098
3099	return element;
3100}
3101
3102
3103function getStyle(element, style) {
3104	element = $(element);
3105	style = normalizeStyleName(style);
3106
3107	var value = element.style[style];
3108	if (!value || value === 'auto') {
3109	var css = document.defaultView.getComputedStyle(element, null);
3110	value = css ? css[style] : null;
3111	}
3112	
3113	// NOTE Dodal Tomaž - pridobimo z-index elementa
3114	if(style == "z-index" || style == "zIndex") {
3115		if (window.getComputedStyle) {
3116			css = document.defaultView.getComputedStyle(element,null).getPropertyValue("z-index");
3117			value = css;
3118			if(value == null || value == "auto")
3119				value = 1;
3120		} else if (element.currentStyle) {
3121			css = element.currentStyle["z-index"];
3122			value = css;
3123			if(value == null || value == "auto")
3124				value = 1;
3125		}
3126	}
3127
3128	if (style === 'opacity') return value ? parseFloat(value) : 1.0;
3129	return value === 'auto' ? null : value;
3130}
3131
3132function getStyle_Opera(element, style) {
3133	switch (style) {
3134	case 'height': case 'width':
3135		if (!Element.visible(element)) return null;
3136
3137		var dim = parseInt(getStyle(element, style), 10);
3138
3139		if (dim !== element['offset' + style.capitalize()])
3140		return dim + 'px';
3141
3142		return Element.measure(element, style);
3143
3144	default: return getStyle(element, style);
3145	}
3146}
3147
3148function getStyle_IE(element, style) {
3149	element = $(element);
3150	style = normalizeStyleName_IE(style);
3151
3152	var value = element.style[style];
3153	if (!value && element.currentStyle) {
3154	value = element.currentStyle[style];
3155	}
3156
3157	if (style === 'opacity' && !STANDARD_CSS_OPACITY_SUPPORTED)
3158	return getOpacity_IE(element);
3159
3160	if (value === 'auto') {
3161	if ((style === 'width' || style === 'height') && Element.visible(element))
3162		return Element.measure(element, style) + 'px';
3163	return null;
3164	}
3165
3166	return value;
3167}
3168
3169function stripAlphaFromFilter_IE(filter) {
3170	return (filter || '').replace(/alpha\([^\)]*\)/gi, '');
3171}
3172
3173function hasLayout_IE(element) {
3174	if (!element.currentStyle || !element.currentStyle.hasLayout)
3175	element.style.zoom = 1;
3176	return element;
3177}
3178
3179var STANDARD_CSS_OPACITY_SUPPORTED = (function() {
3180	DIV.style.cssText = "opacity:.55";
3181	return /^0.55/.test(DIV.style.opacity);
3182})();
3183
3184function setOpacity(element, value) {
3185	element = $(element);
3186	if (value == 1 || value === '') value = '';
3187	else if (value < 0.00001) value = 0;
3188	element.style.opacity = value;
3189	return element;
3190}
3191
3192function setOpacity_IE(element, value) {
3193	if (STANDARD_CSS_OPACITY_SUPPORTED)
3194	return setOpacity(element, value);
3195
3196	element = hasLayout_IE($(element));
3197	var filter = Element.getStyle(element, 'filter'),
3198	style = element.style;
3199
3200	if (value == 1 || value === '') {
3201	filter = stripAlphaFromFilter_IE(filter);
3202	if (filter) style.filter = filter;
3203	else style.removeAttribute('filter');
3204	return element;
3205	}
3206
3207	if (value < 0.00001) value = 0;
3208
3209	style.filter = stripAlphaFromFilter_IE(filter) +
3210	'alpha(opacity=' + (value * 100) + ')';
3211
3212	return element;
3213}
3214
3215
3216function getOpacity(element) {
3217	return Element.getStyle(element, 'opacity');
3218}
3219
3220function getOpacity_IE(element) {
3221	if (STANDARD_CSS_OPACITY_SUPPORTED)
3222	return getOpacity(element);
3223
3224	var filter = Element.getStyle(element, 'filter');
3225	if (filter.length === 0) return 1.0;
3226	var match = (filter || '').match(/alpha\(opacity=(.*)\)/);
3227	if (match && match[1]) return parseFloat(match[1]) / 100;
3228	return 1.0;
3229}
3230
3231
3232Object.extend(methods, {
3233	setStyle:   setStyle,
3234	getStyle:   getStyle,
3235	setOpacity: setOpacity,
3236	getOpacity: getOpacity
3237});
3238
3239if ('styleFloat' in DIV.style) {
3240	methods.getStyle = getStyle_IE;
3241	methods.setOpacity = setOpacity_IE;
3242	methods.getOpacity = getOpacity_IE;
3243}
3244
3245var UID = 0;
3246
3247GLOBAL.Element.Storage = { UID: 1 };
3248
3249function getUniqueElementID(element) {
3250	if (element === window) return 0;
3251
3252	if (typeof element._prototypeUID === 'undefined')
3253	element._prototypeUID = Element.Storage.UID++;
3254	return element._prototypeUID;
3255}
3256
3257function getUniqueElementID_IE(element) {
3258	if (element === window) return 0;
3259	if (element == document) return 1;
3260	return element.uniqueID;
3261}
3262
3263var HAS_UNIQUE_ID_PROPERTY = ('uniqueID' in DIV);
3264if (HAS_UNIQUE_ID_PROPERTY)
3265	getUniqueElementID = getUniqueElementID_IE;
3266
3267function getStorage(element) {
3268	if (!(element = $(element))) return;
3269
3270	var uid = getUniqueElementID(element);
3271
3272	if (!Element.Storage[uid])
3273	Element.Storage[uid] = $H();
3274
3275	return Element.Storage[uid];
3276}
3277
3278function store(element, key, value) {
3279	if (!(element = $(element))) return;
3280	var storage = getStorage(element);
3281	if (arguments.length === 2) {
3282	storage.update(key);
3283	} else {
3284	storage.set(key, value);
3285	}
3286	return element;
3287}
3288
3289function retrieve(element, key, defaultValue) {
3290	if (!(element = $(element))) return;
3291	var storage = getStorage(element), value = storage.get(key);
3292
3293	if (Object.isUndefined(value)) {
3294	storage.set(key, defaultValue);
3295	value = defaultValue;
3296	}
3297
3298	return value;
3299}
3300
3301
3302Object.extend(methods, {
3303	getStorage: getStorage,
3304	store:      store,
3305	retrieve:   retrieve
3306});
3307
3308
3309var Methods = {}, ByTag = Element.Methods.ByTag,
3310F = Prototype.BrowserFeatures;
3311
3312if (!F.ElementExtensions && ('__proto__' in DIV)) {
3313	GLOBAL.HTMLElement = {};
3314	GLOBAL.HTMLElement.prototype = DIV['__proto__'];
3315	F.ElementExtensions = true;
3316}
3317
3318function checkElementPrototypeDeficiency(tagName) {
3319	if (typeof window.Element === 'undefined') return false;
3320	if (!HAS_EXTENDED_CREATE_ELEMENT_SYNTAX) return false;
3321	var proto = window.Element.prototype;
3322	if (proto) {
3323	var id = '_' + (Math.random() + '').slice(2),
3324	el = document.createElement(tagName);
3325	proto[id] = 'x';
3326	var isBuggy = (el[id] !== 'x');
3327	delete proto[id];
3328	el = null;
3329	return isBuggy;
3330	}
3331
3332	return false;
3333}
3334
3335var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY =
3336checkElementPrototypeDeficiency('object');
3337
3338function extendElementWith(element, methods) {
3339	for (var property in methods) {
3340	var value = methods[property];
3341	if (Object.isFunction(value) && !(property in element))
3342		element[property] = value.methodize();
3343	}
3344}
3345
3346var EXTENDED = {};
3347function elementIsExtended(element) {
3348	var uid = getUniqueElementID(element);
3349	return (uid in EXTENDED);
3350}
3351
3352function extend(element) {
3353	if (!element || elementIsExtended(element)) return element;
3354	if (element.nodeType !== Node.ELEMENT_NODE || element == window)
3355	return element;
3356
3357	var methods = Object.clone(Methods),
3358	tagName = element.tagName.toUpperCase();
3359
3360	if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
3361
3362	extendElementWith(element, methods);
3363	EXTENDED[getUniqueElementID(element)] = true;
3364	return element;
3365}
3366
3367function extend_IE8(element) {
3368	if (!element || elementIsExtended(element)) return element;
3369
3370	var t = element.tagName;
3371	if (t && (/^(?:object|applet|embed)$/i.test(t))) {
3372	extendElementWith(element, Element.Methods);
3373	extendElementWith(element, Element.Methods.Simulated);
3374	extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
3375	}
3376
3377	return element;
3378}
3379
3380if (F.SpecificElementExtensions) {
3381	extend = HTMLOBJECTELEMENT_PROTOTYPE_BUGGY ? extend_IE8 : Prototype.K;
3382}
3383
3384function addMethodsToTagName(tagName, methods) {
3385	tagName = tagName.toUpperCase();
3386	if (!ByTag[tagName]) ByTag[tagName] = {};
3387	Object.extend(ByTag[tagName], methods);
3388}
3389
3390function mergeMethods(destination, methods, onlyIfAbsent) {
3391	if (Object.isUndefined(onlyIfAbsent)) onlyIfAbsent = false;
3392	for (var property in methods) {
3393	var value = methods[property];
3394	if (!Object.isFunction(value)) continue;
3395	if (!onlyIfAbsent || !(property in destination))
3396		destination[property] = value.methodize();
3397	}
3398}
3399
3400function findDOMClass(tagName) {
3401	var klass;
3402	var trans = {
3403	"OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
3404	"FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
3405	"DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
3406	"H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
3407	"INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
3408	"TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
3409	"TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
3410	"TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
3411	"FrameSet", "IFRAME": "IFrame"
3412	};
3413	if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
3414	if (window[klass]) return window[klass];
3415	klass = 'HTML' + tagName + 'Element';
3416	if (window[klass]) return window[klass];
3417	klass = 'HTML' + tagName.capitalize() + 'Element';
3418	if (window[klass]) return window[klass];
3419
3420	var element = document.createElement(tagName),
3421	proto = element['__proto__'] || element.constructor.prototype;
3422
3423	element = null;
3424	return proto;
3425}
3426
3427function addMethods(methods) {
3428	if (arguments.length === 0) addFormMethods();
3429
3430	if (arguments.length === 2) {
3431	var tagName = methods;
3432	methods = arguments[1];
3433	}
3434
3435	if (!tagName) {
3436	Object.extend(Element.Methods, methods || {});
3437	} else {
3438	if (Object.isArray(tagName)) {
3439		for (var i = 0, tag; tag = tagName[i]; i++)
3440		addMethodsToTagName(tag, methods);
3441	} else {
3442		addMethodsToTagName(tagName, methods);
3443	}
3444	}
3445
3446	var ELEMENT_PROTOTYPE = window.HTMLElement ? HTMLElement.prototype :
3447	Element.prototype;
3448
3449	if (F.ElementExtensions) {
3450		if (window.SVGElement) {
3451			mergeMethods(SVGElement.prototype, Element.Methods);
3452			mergeMethods(SVGElement.prototype, Element.Methods.Simulated, true);
3453		}
3454		mergeMethods(ELEMENT_PROTOTYPE, Element.Methods);
3455		mergeMethods(ELEMENT_PROTOTYPE, Element.Methods.Simulated, true);
3456	}
3457
3458	if (F.SpecificElementExtensions) {
3459	for (var tag in Element.Methods.ByTag) {
3460		var klass = findDOMClass(tag);
3461		if (Object.isUndefined(klass)) continue;
3462		mergeMethods(klass.prototype, ByTag[tag]);
3463	}
3464	}
3465
3466	Object.extend(Element, Element.Methods);
3467	Object.extend(Element, Element.Methods.Simulated);
3468	delete Element.ByTag;
3469	delete Element.Simulated;
3470
3471	Element.extend.refresh();
3472
3473	ELEMENT_CACHE = {};
3474}
3475
3476Object.extend(GLOBAL.Element, {
3477	extend:     extend,
3478	addMethods: addMethods
3479});
3480
3481if (extend === Prototype.K) {
3482	GLOBAL.Element.extend.refresh = Prototype.emptyFunction;
3483} else {
3484	GLOBAL.Element.extend.refresh = function() {
3485	if (Prototype.BrowserFeatures.ElementExtensions) return;
3486	Object.extend(Methods, Element.Methods);
3487	Object.extend(Methods, Element.Methods.Simulated);
3488
3489	EXTENDED = {};
3490	};
3491}
3492
3493function addFormMethods() {
3494	Object.extend(Form, Form.Methods);
3495	Object.extend(Form.Element, Form.Element.Methods);
3496	Object.extend(Element.Methods.ByTag, {
3497	"FORM":     Object.clone(Form.Methods),
3498	"INPUT":    Object.clone(Form.Element.Methods),
3499	"SELECT":   Object.clone(Form.Element.Methods),
3500	"TEXTAREA": Object.clone(Form.Element.Methods),
3501	"BUTTON":   Object.clone(Form.Element.Methods)
3502	});
3503}
3504
3505Element.addMethods(methods);
3506
3507function destroyCache_IE() {
3508	DIV = null;
3509	ELEMENT_CACHE = null;
3510}
3511
3512if (window.attachEvent)
3513	window.attachEvent('onunload', destroyCache_IE);
3514
3515})(this);
3516(function() {
3517
3518function toDecimal(pctString) {
3519	var match = pctString.match(/^(\d+)%?$/i);
3520	if (!match) return null;
3521	return (Number(match[1]) / 100);
3522}
3523
3524function getRawStyle(element, style) {
3525	element = $(element);
3526
3527	var value = element.style[style];
3528	if (!value || value === 'auto') {
3529	var css = document.defaultView.getComputedStyle(element, null);
3530	value = css ? css[style] : null;
3531	}
3532
3533	if (style === 'opacity') return value ? parseFloat(value) : 1.0;
3534	return value === 'auto' ? null : value;
3535}
3536
3537function getRawStyle_IE(element, style) {
3538	var value = element.style[style];
3539	if (!value && element.currentStyle) {
3540	value = element.currentStyle[style];
3541	}
3542	return value;
3543}
3544
3545function getContentWidth(element, context) {
3546	var boxWidth = element.offsetWidth;
3547
3548	var bl = getPixelValue(element, 'borderLeftWidth',  context) || 0;
3549	var br = getPixelValue(element, 'borderRightWidth', context) || 0;
3550	var pl = getPixelValue(element, 'paddingLeft',      context) || 0;
3551	var pr = getPixelValue(element, 'paddingRight',     context) || 0;
3552
3553	return boxWidth - bl - br - pl - pr;
3554}
3555
3556if ('currentStyle' in document.documentElement) {
3557	getRawStyle = getRawStyle_IE;
3558}
3559
3560
3561function getPixelValue(value, property, context) {
3562	var element = null;
3563	if (Object.isElement(value)) {
3564	element = value;
3565	value = getRawStyle(element, property);
3566	}
3567
3568	if (value === null || Object.isUndefined(value)) {
3569	return null;
3570	}
3571
3572	if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) {
3573	return window.parseFloat(value);
3574	}
3575
3576	var isPercentage = value.include('%'), isViewport = (context === document.viewport);
3577
3578	if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) {
3579	var style = element.style.left, rStyle = element.runtimeStyle.left;
3580	element.runtimeStyle.left = element.currentStyle.left;
3581	element.style.left = value || 0;
3582	value = element.style.pixelLeft;
3583	element.style.left = style;
3584	element.runtimeStyle.left = rStyle;
3585
3586	return value;
3587	}
3588
3589	if (element && isPercentage) {
3590	context = context || element.parentNode;
3591	var decimal = toDecimal(value), whole = null;
3592
3593	var isHorizontal = property.include('left') || property.include('right') ||
3594	property.include('width');
3595
3596	var isVertical   = property.include('top') || property.include('bottom') ||
3597		property.include('height');
3598
3599	if (context === document.viewport) {
3600		if (isHorizontal) {
3601		whole = document.viewport.getWidth();
3602		} else if (isVertical) {
3603		whole = document.viewport.getHeight();
3604		}
3605	} else {
3606		if (isHorizontal) {
3607		whole = $(context).measure('width');
3608		} else if (isVertical) {
3609		whole = $(context).measure('height');
3610		}
3611	}
3612
3613	return (whole === null) ? 0 : whole * decimal;
3614	}
3615
3616	return 0;
3617}
3618
3619function toCSSPixels(number) {
3620	if (Object.isString(number) && number.endsWith('px'))
3621	return number;
3622	return number + 'px';
3623}
3624
3625function isDisplayed(element) {
3626	while (element && element.parentNode) {
3627	var display = element.getStyle('display');
3628	if (display === 'none') {
3629		return false;
3630	}
3631	element = $(element.parentNode);
3632	}
3633	return true;
3634}
3635
3636var hasLayout = Prototype.K;
3637if ('currentStyle' in document.documentElement) {
3638	hasLayout = function(element) {
3639	if (!element.currentStyle.hasLayout) {
3640		element.style.zoom = 1;
3641	}
3642	return element;
3643	};
3644}
3645
3646function cssNameFor(key) {
3647	if (key.include('border')) key = key + '-width';
3648	return key.camelize();
3649}
3650
3651Element.Layout = Class.create(Hash, {
3652	initialize: function($super, element, preCompute) {
3653	$super();
3654	this.element = $(element);
3655
3656	Element.Layout.PROPERTIES.each( function(property) {
3657		this._set(property, null);
3658	}, this);
3659
3660	if (preCompute) {
3661		this._preComputing = true;
3662		this._begin();
3663		Element.Layout.PROPERTIES.each( this._compute, this );
3664		this._end();
3665		this._preComputing = false;
3666	}
3667	},
3668
3669	_set: function(property, value) {
3670	return Hash.prototype.set.call(this, property, value);
3671	},
3672
3673	set: function(property, value) {
3674	throw "Properties of Element.Layout are read-only.";
3675	},
3676
3677	get: function($super, property) {
3678	var value = $super(property);
3679	return value === null ? this._compute(property) : value;
3680	},
3681
3682	_begin: function() {
3683	if (this._isPrepared()) return;
3684
3685	var element = this.element;
3686	if (isDisplayed(element)) {
3687		this._setPrepared(true);
3688		return;
3689	}
3690
3691
3692	var originalStyles = {
3693		position:   element.style.position   || '',
3694		width:      element.style.width      || '',
3695		visibility: element.style.visibility || '',
3696		display:    element.style.display    || ''
3697	};
3698
3699	element.store('prototype_original_styles', originalStyles);
3700
3701	var position = getRawStyle(element, 'position'), width = element.offsetWidth;
3702
3703	if (width === 0 || width === null) {
3704		element.style.display = 'block';
3705		width = element.offsetWidth;
3706	}
3707
3708	var context = (position === 'fixed') ? document.viewport :
3709	element.parentNode;
3710
3711	var tempStyles = {
3712		visibility: 'hidden',
3713		display:    'block'
3714	};
3715
3716	if (position !== 'fixed') tempStyles.position = 'absolute';
3717
3718	element.setStyle(tempStyles);
3719
3720	var positionedWidth = element.offsetWidth, newWidth;
3721	if (width && (positionedWidth === width)) {
3722		newWidth = getContentWidth(element, context);
3723	} else if (position === 'absolute' || position === 'fixed') {
3724		newWidth = getContentWidth(element, context);
3725	} else {
3726		var parent = element.parentNode, pLayout = $(parent).getLayout();
3727
3728		newWidth = pLayout.get('width') -
3729		this.get('margin-left') -
3730		this.get('border-left') -
3731		this.get('padding-left') -
3732		this.get('padding-right') -
3733		this.get('border-right') -
3734		this.get('margin-right');
3735	}
3736
3737	element.setStyle({ width: newWidth + 'px' });
3738
3739	this._setPrepared(true);
3740	},
3741
3742	_end: function() {
3743	var element = this.element;
3744	var originalStyles = element.retrieve('prototype_original_styles');
3745	element.store('prototype_original_styles', null);
3746	element.setStyle(originalStyles);
3747	this._setPrepared(false);
3748	},
3749
3750	_compute: function(property) {
3751	var COMPUTATIONS = Element.Layout.COMPUTATIONS;
3752	if (!(property in COMPUTATIONS)) {
3753		throw "Property not found.";
3754	}
3755
3756	return this._set(property, COMPUTATIONS[property].call(this, this.element));
3757	},
3758
3759	_isPrepared: function() {
3760	return this.element.retrieve('prototype_element_layout_prepared', false);
3761	},
3762
3763	_setPrepared: function(bool) {
3764	return this.element.store('prototype_element_layout_prepared', bool);
3765	},
3766
3767	toObject: function() {
3768	var args = $A(arguments);
3769	var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3770	args.join(' ').split(' ');
3771	var obj = {};
3772	keys.each( function(key) {
3773		if (!Element.Layout.PROPERTIES.include(key)) return;
3774		var value = this.get(key);
3775		if (value != null) obj[key] = value;
3776	}, this);
3777	return obj;
3778	},
3779
3780	toHash: function() {
3781	var obj = this.toObject.apply(this, arguments);
3782	return new Hash(obj);
3783	},
3784
3785	toCSS: function() {
3786	var args = $A(arguments);
3787	var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3788	args.join(' ').split(' ');
3789	var css = {};
3790
3791	keys.each( function(key) {
3792		if (!Element.Layout.PROPERTIES.include(key)) return;
3793		if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return;
3794
3795		var value = this.get(key);
3796		if (value != null) css[cssNameFor(key)] = value + 'px';
3797	}, this);
3798	return css;
3799	},
3800
3801	inspect: function() {
3802	return "#<Element.Layout>";
3803	}
3804});
3805
3806Object.extend(Element.Layout, {
3807	PROPERTIES: $w('height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height'),
3808
3809	COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'),
3810
3811	COMPUTATIONS: {
3812	'height': function(element) {
3813		if (!this._preComputing) this._begin();
3814
3815		var bHeight = this.get('border-box-height');
3816		if (bHeight <= 0) {
3817		if (!this._preComputing) this._end();
3818		return 0;
3819		}
3820
3821		var bTop = this.get('border-top'),
3822		bBottom = this.get('border-bottom');
3823
3824		var pTop = this.get('padding-top'),
3825		pBottom = this.get('padding-bottom');
3826
3827		if (!this._preComputing) this._end();
3828
3829		return bHeight - bTop - bBottom - pTop - pBottom;
3830	},
3831
3832	'width': function(element) {
3833		if (!this._preComputing) this._begin();
3834
3835		var bWidth = this.get('border-box-width');
3836		if (bWidth <= 0) {
3837		if (!this._preComputing) this._end();
3838		return 0;
3839		}
3840
3841		var bLeft = this.get('border-left'),
3842		bRight = this.get('border-right');
3843
3844		var pLeft = this.get('padding-left'),
3845		pRight = this.get('padding-right');
3846
3847		if (!this._preComputing) this._end();
3848		return bWidth - bLeft - bRight - pLeft - pRight;
3849	},
3850
3851	'padding-box-height': function(element) {
3852		var height = this.get('height'),
3853		pTop = this.get('padding-top'),
3854		pBottom = this.get('padding-bottom');
3855
3856		return height + pTop + pBottom;
3857	},
3858
3859	'padding-box-width': function(element) {
3860		var width = this.get('width'),
3861		pLeft = this.get('padding-left'),
3862		pRight = this.get('padding-right');
3863
3864		return width + pLeft + pRight;
3865	},
3866
3867	'border-box-height': function(element) {
3868		if (!this._preComputing) this._begin();
3869		var height = element.offsetHeight;
3870		if (!this._preComputing) this._end();
3871		return height;
3872	},
3873
3874	'border-box-width': function(element) {
3875		if (!this._preComputing) this._begin();
3876		var width = element.offsetWidth;
3877		if (!this._preComputing) this._end();
3878		return width;
3879	},
3880
3881	'margin-box-height': function(element) {
3882		var bHeight = this.get('border-box-height'),
3883		mTop = this.get('margin-top'),
3884		mBottom = this.get('margin-bottom');
3885
3886		if (bHeight <= 0) return 0;
3887
3888		return bHeight + mTop + mBottom;
3889	},
3890
3891	'margin-box-width': function(element) {
3892		var bWidth = this.get('border-box-width'),
3893		mLeft = this.get('margin-left'),
3894		mRight = this.get('margin-right');
3895
3896		if (bWidth <= 0) return 0;
3897
3898		return bWidth + mLeft + mRight;
3899	},
3900
3901	'top': function(element) {
3902		var offset = element.positionedOffset();
3903		return offset.top;
3904	},
3905
3906	'bottom': function(element) {
3907		var offset = element.positionedOffset(),
3908		parent = element.getOffsetParent(),
3909		pHeight = parent.measure('height');
3910
3911		var mHeight = this.get('border-box-height');
3912
3913		return pHeight - mHeight - offset.top;
3914	},
3915
3916	'left': function(element) {
3917		var offset = element.positionedOffset();
3918		return offset.left;
3919	},
3920
3921	'right': function(element) {
3922		var offset = element.positionedOffset(),
3923		parent = element.getOffsetParent(),
3924		pWidth = parent.measure('width');
3925
3926		var mWidth = this.get('border-box-width');
3927
3928		return pWidth - mWidth - offset.left;
3929	},
3930
3931	'padding-top': function(element) {
3932		return getPixelValue(element, 'paddingTop');
3933	},
3934
3935	'padding-bottom': function(element) {
3936		return getPixelValue(element, 'paddingBottom');
3937	},
3938
3939	'padding-left': function(element) {
3940		return getPixelValue(element, 'paddingLeft');
3941	},
3942
3943	'padding-right': function(element) {
3944		return getPixelValue(element, 'paddingRight');
3945	},
3946
3947	'border-top': function(element) {
3948		return getPixelValue(element, 'borderTopWidth');
3949	},
3950
3951	'border-bottom': function(element) {
3952		return getPixelValue(element, 'borderBottomWidth');
3953	},
3954
3955	'border-left': function(element) {
3956		return getPixelValue(element, 'borderLeftWidth');
3957	},
3958
3959	'border-right': function(element) {
3960		return getPixelValue(element, 'borderRightWidth');
3961	},
3962
3963	'margin-top': function(element) {
3964		return getPixelValue(element, 'marginTop');
3965	},
3966
3967	'margin-bottom': function(element) {
3968		return getPixelValue(element, 'marginBottom');
3969	},
3970
3971	'margin-left': function(element) {
3972		return getPixelValue(element, 'marginLeft');
3973	},
3974
3975	'margin-right': function(element) {
3976		return getPixelValue(element, 'marginRight');
3977	}
3978	}
3979});
3980
3981if ('getBoundingClientRect' in document.documentElement) {
3982	Object.extend(Element.Layout.COMPUTATIONS, {
3983	'right': function(element) {
3984		var parent = hasLayout(element.getOffsetParent());
3985		var rect = element.getBoundingClientRect(),
3986		pRect = parent.getBoundingClientRect();
3987
3988		return (pRect.right - rect.right).round();
3989	},
3990
3991	'bottom': function(element) {
3992		var parent = hasLayout(element.getOffsetParent());
3993		var rect = element.getBoundingClientRect(),
3994		pRect = parent.getBoundingClientRect();
3995
3996		return (pRect.bottom - rect.bottom).round();
3997	}
3998	});
3999}
4000
4001Element.Offset = Class.create({
4002	initialize: function(left, top) {
4003	this.left = left.round();
4004	this.top  = top.round();
4005
4006	this[0] = this.left;
4007	this[1] = this.top;
4008	},
4009
4010	relativeTo: function(offset) {
4011	return new Element.Offset(
4012		this.left - offset.left,
4013		this.top  - offset.top
4014	);
4015	},
4016
4017	inspect: function() {
4018	return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this);
4019	},
4020
4021	toString: function() {
4022	return "[#{left}, #{top}]".interpolate(this);
4023	},
4024
4025	toArray: function() {
4026	return [this.left, this.top];
4027	}
4028});
4029
4030function getLayout(element, preCompute) {
4031	return new Element.Layout(element, preCompute);
4032}
4033
4034function measure(element, property) {
4035	return $(element).getLayout().get(property);
4036}
4037
4038function getHeight(element) {
4039	return Element.getDimensions(element).height;
4040}
4041
4042function getWidth(element) {
4043	return Element.getDimensions(element).width;
4044}
4045
4046function getDimensions(element) {
4047	element = $(element);
4048	var display = Element.getStyle(element, 'display');
4049
4050	if (display && display !== 'none') {
4051	return { width: element.offsetWidth, height: element.offsetHeight };
4052	}
4053
4054	var style = element.style;
4055	var originalStyles = {
4056	visibility: style.visibility,
4057	position:   style.position,
4058	display:    style.display
4059	};
4060
4061	var newStyles = {
4062	visibility: 'hidden',
4063	display:    'block'
4064	};
4065
4066	if (originalStyles.position !== 'fixed')
4067	newStyles.position = 'absolute';
4068
4069	Element.setStyle(element, newStyles);
4070
4071	var dimensions = {
4072	width:  element.offsetWidth,
4073	height: element.offsetHeight
4074	};
4075
4076	Element.setStyle(element, originalStyles);
4077
4078	return dimensions;
4079}
4080
4081function getOffsetParent(element) {
4082	element = $(element);
4083
4084	if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
4085	return $(document.body);
4086
4087	var isInline = (Element.getStyle(element, 'display') === 'inline');
4088	if (!isInline && element.offsetParent) return $(element.offsetParent);
4089
4090	while ((element = element.parentNode) && element !== document.body) {
4091	if (Element.getStyle(element, 'position') !== 'static') {
4092		return isHtml(element) ? $(document.body) : $(element);
4093	}
4094	}
4095
4096	return $(document.body);
4097}
4098
4099
4100function cumulativeOffset(element) {
4101	element = $(element);
4102	var valueT = 0, valueL = 0;
4103	if (element.parentNode) {
4104	do {
4105		valueT += element.offsetTop  || 0;
4106		valueL += element.offsetLeft || 0;
4107		element = element.offsetParent;
4108	} while (element);
4109	}
4110	return new Element.Offset(valueL, valueT);
4111}
4112
4113function positionedOffset(element) {
4114	element = $(element);
4115
4116	var layout = element.getLayout();
4117
4118	var valueT = 0, valueL = 0;
4119	do {
4120	valueT += element.offsetTop  || 0;
4121	valueL += element.offsetLeft || 0;
4122	element = element.offsetParent;
4123	if (element) {
4124		if (isBody(element)) break;
4125		var p = Element.getStyle(element, 'position');
4126		if (p !== 'static') break;
4127	}
4128	} while (element);
4129
4130	valueL -= layout.get('margin-top');
4131	valueT -= layout.get('margin-left');
4132
4133	return new Element.Offset(valueL, valueT);
4134}
4135
4136function cumulativeScrollOffset(element) {
4137	var valueT = 0, valueL = 0;
4138	do {
4139	if (element === document.body) {
4140		var bodyScrollNode = document.documentElement || document.body.parentNode || document.body;
4141		valueT += !Object.isUndefined(window.pageYOffset) ? window.pageYOffset : bodyScrollNode.scrollTop || 0;
4142		valueL += !Object.isUndefined(window.pageXOffset) ? window.pageXOffset : bodyScrollNode.scrollLeft || 0;
4143		break;
4144	} else {
4145		valueT += element.scrollTop  || 0;
4146		valueL += element.scrollLeft || 0;
4147		element = element.parentNode;
4148	}
4149	} while (element);
4150	return new Element.Offset(valueL, valueT);
4151}
4152
4153function viewportOffset(forElement) {
4154	var valueT = 0, valueL = 0, docBody = document.body;
4155
4156	forElement = $(forElement);
4157	var element = forElement;
4158	do {
4159	valueT += element.offsetTop  || 0;
4160	valueL += element.offsetLeft || 0;
4161	if (element.offsetParent == docBody &&
4162		Element.getStyle(element, 'position') == 'absolute') break;
4163	} while (element = element.offsetParent);
4164
4165	element = forElement;
4166	do {
4167	if (element != docBody) {
4168		valueT -= element.scrollTop  || 0;
4169		valueL -= element.scrollLeft || 0;
4170	}
4171	} while (element = element.parentNode);
4172	return new Element.Offset(valueL, valueT);
4173}
4174
4175function absolutize(element) {
4176	element = $(element);
4177
4178	if (Element.getStyle(element, 'position') === 'absolute') {
4179	return element;
4180	}
4181
4182	var offsetParent = getOffsetParent(element);
4183	var eOffset = element.viewportOffset(),
4184	pOffset = offsetParent.viewportOffset();
4185
4186	var offset = eOffset.relativeTo(pOffset);
4187	var layout = element.getLayout();
4188
4189	element.store('prototype_absolutize_original_styles', {
4190	position: element.getStyle('position'),
4191	left:     element.getStyle('left'),
4192	top:      element.getStyle('top'),
4193	width:    element.getStyle('width'),
4194	height:   element.getStyle('height')
4195	});
4196
4197	element.setStyle({
4198	position: 'absolute',
4199	top:    offset.top + 'px',
4200	left:   offset.left + 'px',
4201	width:  layout.get('width') + 'px',
4202	height: layout.get('height') + 'px'
4203	});
4204
4205	return element;
4206}
4207
4208function relativize(element) {
4209	element = $(element);
4210	if (Element.getStyle(element, 'position') === 'relative') {
4211	return element;
4212	}
4213
4214	var originalStyles =
4215	element.retrieve('prototype_absolutize_original_styles');
4216
4217	if (originalStyles) element.setStyle(originalStyles);
4218	return element;
4219}
4220
4221
4222function scrollTo(element) {
4223	element = $(element);
4224	var pos = Element.cumulativeOffset(element);
4225	window.scrollTo(pos.left, pos.top);
4226	return element;
4227}
4228
4229
4230function makePositioned(element) {
4231	element = $(element);
4232	var position = Element.getStyle(element, 'position'), styles = {};
4233	if (position === 'static' || !position) {
4234	styles.position = 'relative';
4235	if (Prototype.Browser.Opera) {
4236		styles.top  = 0;
4237		styles.left = 0;
4238	}
4239	Element.setStyle(element, styles);
4240	Element.store(element, 'prototype_made_positioned', true);
4241	}
4242	return element;
4243}
4244
4245function undoPositioned(element) {
4246	element = $(element);
4247	var storage = Element.getStorage(element),
4248	madePositioned = storage.get('prototype_made_positioned');
4249
4250	if (madePositioned) {
4251	storage.unset('prototype_made_positioned');
4252	Element.setStyle(element, {
4253		position: '',
4254		top:      '',
4255		bottom:   '',
4256		left:     '',
4257		right:    ''
4258	});
4259	}
4260	return element;
4261}
4262
4263function makeClipping(element) {
4264	element = $(element);
4265
4266	var storage = Element.getStorage(element),
4267	madeClipping = storage.get('prototype_made_clipping');
4268
4269	if (Object.isUndefined(madeClipping)) {
4270	var overflow = Element.getStyle(element, 'overflow');
4271	storage.set('prototype_made_clipping', overflow);
4272	if (overflow !== 'hidden')
4273		element.style.overflow = 'hidden';
4274	}
4275
4276	return element;
4277}
4278
4279function undoClipping(element) {
4280	element = $(element);
4281	var storage = Element.getStorage(element),
4282	overflow = storage.get('prototype_made_clipping');
4283
4284	if (!Object.isUndefined(overflow)) {
4285	storage.unset('prototype_made_clipping');
4286	element.style.overflow = overflow || '';
4287	}
4288
4289	return element;
4290}
4291
4292function clonePosition(element, source, options) {
4293	options = Object.extend({
4294	setLeft:    true,
4295	setTop:     true,
4296	setWidth:   true,
4297	setHeight:  true,
4298	offsetTop:  0,
4299	offsetLeft: 0
4300	}, options || {});
4301
4302	source  = $(source);
4303	element = $(element);
4304	var p, delta, layout, styles = {};
4305
4306	if (options.setLeft || options.setTop) {
4307	p = Element.viewportOffset(source);
4308	delta = [0, 0];
4309	if (Element.getStyle(element, 'position') === 'absolute') {
4310		var parent = Element.getOffsetParent(element);
4311		if (parent !== document.body) delta = Element.viewportOffset(parent);
4312	}
4313	}
4314
4315	if (options.setWidth || options.setHeight) {
4316	layout = Element.getLayout(source);
4317	}
4318
4319	if (options.setLeft)
4320	styles.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
4321	if (options.setTop)
4322	styles.top  = (p[1] - delta[1] + options.offsetTop)  + 'px';
4323
4324	if (options.setWidth)
4325	styles.width  = layout.get('border-box-width')  + 'px';
4326	if (options.setHeight)
4327	styles.height = layout.get('border-box-height') + 'px';
4328
4329	return Element.setStyle(element, styles);
4330}
4331
4332
4333if (Prototype.Browser.IE) {
4334	getOffsetParent = getOffsetParent.wrap(
4335	function(proceed, element) {
4336		element = $(element);
4337
4338		if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
4339		return $(document.body);
4340
4341		var position = element.getStyle('position');
4342		if (position !== 'static') return proceed(element);
4343
4344		element.setStyle({ position: 'relative' });
4345		var value = proceed(element);
4346		element.setStyle({ position: position });
4347		return value;
4348	}
4349	);
4350
4351	positionedOffset = positionedOffset.wrap(function(proceed, element) {
4352	element = $(element);
4353	if (!element.parentNode) return new Element.Offset(0, 0);
4354	var position = element.getStyle('position');
4355	if (position !== 'static') return proceed(element);
4356
4357	var offsetParent = element.getOffsetParent();
4358	if (offsetParent && offsetParent.getStyle('position') === 'fixed')
4359		hasLayout(offsetParent);
4360
4361	element.setStyle({ position: 'relative' });
4362	var value = proceed(element);
4363	element.setStyle({ position: position });
4364	return value;
4365	});
4366} else if (Prototype.Browser.Webkit) {
4367	cumulativeOffset = function(element) {
4368	element = $(element);
4369	var valueT = 0, valueL = 0;
4370	do {
4371		valueT += element.offsetTop  || 0;
4372		valueL += element.offsetLeft || 0;
4373		if (element.offsetParent == document.body) {
4374		if (Element.getStyle(element, 'position') == 'absolute') break;
4375		}
4376
4377		element = element.offsetParent;
4378	} while (element);
4379
4380	return new Element.Offset(valueL, valueT);
4381	};
4382}
4383
4384
4385Element.addMethods({
4386	getLayout:              getLayout,
4387	measure:                measure,
4388	getWidth:               getWidth,
4389	getHeight:              getHeight,
4390	getDimensions:          getDimensions,
4391	getOffsetParent:        getOffsetParent,
4392	cumulativeOffset:       cumulativeOffset,
4393	positionedOffset:       positionedOffset,
4394	cumulativeScrollOffset: cumulativeScrollOffset,
4395	viewportOffset:         viewportOffset,
4396	absolutize:             absolutize,
4397	relativize:             relativize,
4398	scrollTo:               scrollTo,
4399	makePositioned:         makePositioned,
4400	undoPositioned:         undoPositioned,
4401	makeClipping:           makeClipping,
4402	undoClipping:           undoClipping,
4403	clonePosition:          clonePosition
4404});
4405
4406function isBody(element) {
4407	return element.nodeName.toUpperCase() === 'BODY';
4408}
4409
4410function isHtml(element) {
4411	return element.nodeName.toUpperCase() === 'HTML';
4412}
4413
4414function isDocument(element) {
4415	return element.nodeType === Node.DOCUMENT_NODE;
4416}
4417
4418function isDetached(element) {
4419	return element !== document.body &&
4420	!Element.descendantOf(element, document.body);
4421}
4422
4423if ('getBoundingClientRect' in document.documentElement) {
4424	Element.addMethods({
4425	viewportOffset: function(element) {
4426		element = $(element);
4427		if (isDetached(element)) return new Element.Offset(0, 0);
4428
4429		var rect = element.getBoundingClientRect(),
4430		docEl = document.documentElement;
4431		return new Element.Offset(rect.left - docEl.clientLeft,
4432		rect.top - docEl.clientTop);
4433	}
4434	});
4435}
4436
4437
4438})();
4439
4440(function() {
4441
4442var IS_OLD_OPERA = Prototype.Browser.Opera &&
4443(window.parseFloat(window.opera.version()) < 9.5);
4444var ROOT = null;
4445function getRootElement() {
4446	if (ROOT) return ROOT;
4447	ROOT = IS_OLD_OPERA ? document.body : document.documentElement;
4448	return ROOT;
4449}
4450
4451function getDimensions() {
4452	return { width: this.getWidth(), height: this.getHeight() };
4453}
4454
4455function getWidth() {
4456	return getRootElement().clientWidth;
4457}
4458
4459function getHeight() {
4460	return getRootElement().clientHeight;
4461}
4462
4463function getScrollOffsets() {
4464	var x = window.pageXOffset || document.documentElement.scrollLeft ||
4465	document.body.scrollLeft;
4466	var y = window.pageYOffset || document.documentElement.scrollTop ||
4467	document.body.scrollTop;
4468
4469	return new Element.Offset(x, y);
4470}
4471
4472document.viewport = {
4473	getDimensions:    getDimensions,
4474	getWidth:         getWidth,
4475	getHeight:        getHeight,
4476	getScrollOffsets: getScrollOffsets
4477};
4478
4479})();
4480window.$$ = function() {
4481var expression = $A(arguments).join(', ');
4482return Prototype.Selector.select(expression, document);
4483};
4484
4485Prototype.Selector = (function() {
4486
4487function select() {
4488	throw new Error('Method "Prototype.Selector.select" must be defined.');
4489}
4490
4491function match() {
4492	throw new Error('Method "Prototype.Selector.match" must be defined.');
4493}
4494
4495function find(elements, expression, index) {
4496	index = index || 0;
4497	var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i;
4498
4499	for (i = 0; i < length; i++) {
4500	if (match(elements[i], expression) && index == matchIndex++) {
4501		return Element.extend(elements[i]);
4502	}
4503	}
4504}
4505
4506function extendElements(elements) {
4507	for (var i = 0, length = elements.length; i < length; i++) {
4508	Element.extend(elements[i]);
4509	}
4510	return elements;
4511}
4512
4513
4514var K = Prototype.K;
4515
4516return {
4517	select: select,
4518	match: match,
4519	find: find,
4520	extendElements: (Element.extend === K) ? K : extendElements,
4521	extendElement: Element.extend
4522};
4523})();
4524Prototype._original_property = window.Sizzle;
4525/*!
4526* Sizzle CSS Selector Engine v@VERSION
4527* http://sizzlejs.com/
4528*
4529* Copyright 2013 jQuery Foundation, Inc. and other contributors
4530* Released under the MIT license
4531* http://jquery.org/license
4532*
4533* Date: @DATE
4534*/
4535(function( window ) {
4536
4537var i,
4538	support,
4539	Expr,
4540	getText,
4541	isXML,
4542	compile,
4543	select,
4544	outermostContext,
4545	sortInput,
4546	hasDuplicate,
4547
4548	setDocument,
4549	document,
4550	docElem,
4551	documentIsHTML,
4552	rbuggyQSA,
4553	rbuggyMatches,
4554	matches,
4555	contains,
4556
4557	expando = "sizzle" + -(new Date()),
4558	preferredDoc = window.document,
4559	dirruns = 0,
4560	done = 0,
4561	classCache = createCache(),
4562	tokenCache = createCache(),
4563	compilerCache = createCache(),
4564	sortOrder = function( a, b ) {
4565		if ( a === b ) {
4566			hasDuplicate = true;
4567		}
4568		return 0;
4569	},
4570
4571	strundefined = typeof undefined,
4572	MAX_NEGATIVE = 1 << 31,
4573
4574	hasOwn = ({}).hasOwnProperty,
4575	arr = [],
4576	pop = arr.pop,
4577	push_native = arr.push,
4578	push = arr.push,
4579	slice = arr.slice,
4580	indexOf = arr.indexOf || function( elem ) {
4581		var i = 0,
4582			len = this.length;
4583		for ( ; i < len; i++ ) {
4584			if ( this[i] === elem ) {
4585				return i;
4586			}
4587		}
4588		return -1;
4589	},
4590
4591	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
4592
4593
4594	whitespace = "[\\x20\\t\\r\\n\\f]",
4595	characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
4596
4597	identifier = characterEncoding.replace( "w", "w#" ),
4598
4599	attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
4600		"*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
4601
4602	pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
4603
4604	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
4605
4606	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
4607	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
4608
4609	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
4610
4611	rpseudo = new RegExp( pseudos ),
4612	ridentifier = new RegExp( "^" + identifier + "$" ),
4613
4614	matchExpr = {
4615		"ID": new RegExp( "^#(" + characterEncoding + ")" ),
4616		"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
4617		"TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
4618		"ATTR": new RegExp( "^" + attributes ),
4619		"PSEUDO": new RegExp( "^" + pseudos ),
4620		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
4621			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
4622			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
4623		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
4624		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
4625			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
4626	},
4627
vendor: 38,545 bytes, lines 4628-6181
4628	rinputs = /^(?:input|select|textarea|button)$/i,
4629	rheader = /^h\d$/i,
4630
4631	rnative = /^[^{]+\{\s*\[native \w/,
4632
4633	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
4634
4635	rsibling = /[+~]/,
4636	rescape = /'|\\/g,
4637
4638	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
4639	funescape = function( _, escaped, escapedWhitespace ) {
4640		var high = "0x" + escaped - 0x10000;
4641		return high !== high || escapedWhitespace ?
4642			escaped :
4643			high < 0 ?
4644				String.fromCharCode( high + 0x10000 ) :
4645				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
4646	};
4647
4648try {
4649	push.apply(
4650		(arr = slice.call( preferredDoc.childNodes )),
4651		preferredDoc.childNodes
4652	);
4653	arr[ preferredDoc.childNodes.length ].nodeType;
4654} catch ( e ) {
4655	push = { apply: arr.length ?
4656
4657		function( target, els ) {
4658			push_native.apply( target, slice.call(els) );
4659		} :
4660
4661		function( target, els ) {
4662			var j = target.length,
4663				i = 0;
4664			while ( (target[j++] = els[i++]) ) {}
4665			target.length = j - 1;
4666		}
4667	};
4668}
4669
4670function Sizzle( selector, context, results, seed ) {
4671	var match, elem, m, nodeType,
4672		i, groups, old, nid, newContext, newSelector;
4673
4674	if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
4675		setDocument( context );
4676	}
4677
4678	context = context || document;
4679	results = results || [];
4680
4681	if ( !selector || typeof selector !== "string" ) {
4682		return results;
4683	}
4684
4685	if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
4686		return [];
4687	}
4688
4689	if ( documentIsHTML && !seed ) {
4690
4691		if ( (match = rquickExpr.exec( selector )) ) {
4692			if ( (m = match[1]) ) {
4693				if ( nodeType === 9 ) {
4694					elem = context.getElementById( m );
4695					if ( elem && elem.parentNode ) {
4696						if ( elem.id === m ) {
4697							results.push( elem );
4698							return results;
4699						}
4700					} else {
4701						return results;
4702					}
4703				} else {
4704					if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
4705						contains( context, elem ) && elem.id === m ) {
4706						results.push( elem );
4707						return results;
4708					}
4709				}
4710
4711			} else if ( match[2] ) {
4712				push.apply( results, context.getElementsByTagName( selector ) );
4713				return results;
4714
4715			} else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
4716				push.apply( results, context.getElementsByClassName( m ) );
4717				return results;
4718			}
4719		}
4720
4721		if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
4722			nid = old = expando;
4723			newContext = context;
4724			newSelector = nodeType === 9 && selector;
4725
4726			if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4727				groups = tokenize( selector );
4728
4729				if ( (old = context.getAttribute("id")) ) {
4730					nid = old.replace( rescape, "\\$&" );
4731				} else {
4732					context.setAttribute( "id", nid );
4733				}
4734				nid = "[id='" + nid + "'] ";
4735
4736				i = groups.length;
4737				while ( i-- ) {
4738					groups[i] = nid + toSelector( groups[i] );
4739				}
4740				newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
4741				newSelector = groups.join(",");
4742			}
4743
4744			if ( newSelector ) {
4745				try {
4746					push.apply( results,
4747						newContext.querySelectorAll( newSelector )
4748					);
4749					return results;
4750				} catch(qsaError) {
4751				} finally {
4752					if ( !old ) {
4753						context.removeAttribute("id");
4754					}
4755				}
4756			}
4757		}
4758	}
4759
4760	return select( selector.replace( rtrim, "$1" ), context, results, seed );
4761}
4762
4763/**
4764* Create key-value caches of limited size
4765* @returns {Function(string, Object)} Returns the Object data after storing it on itself with
4766*	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
4767*	deleting the oldest entry
4768*/
4769function createCache() {
4770	var keys = [];
4771
4772	function cache( key, value ) {
4773		if ( keys.push( key + " " ) > Expr.cacheLength ) {
4774			delete cache[ keys.shift() ];
4775		}
4776		return (cache[ key + " " ] = value);
4777	}
4778	return cache;
4779}
4780
4781/**
4782* Mark a function for special use by Sizzle
4783* @param {Function} fn The function to mark
4784*/
4785function markFunction( fn ) {
4786	fn[ expando ] = true;
4787	return fn;
4788}
4789
4790/**
4791* Support testing using an element
4792* @param {Function} fn Passed the created div and expects a boolean result
4793*/
4794function assert( fn ) {
4795	var div = document.createElement("div");
4796
4797	try {
4798		return !!fn( div );
4799	} catch (e) {
4800		return false;
4801	} finally {
4802		if ( div.parentNode ) {
4803			div.parentNode.removeChild( div );
4804		}
4805		div = null;
4806	}
4807}
4808
4809/**
4810* Adds the same handler for all of the specified attrs
4811* @param {String} attrs Pipe-separated list of attributes
4812* @param {Function} handler The method that will be applied
4813*/
4814function addHandle( attrs, handler ) {
4815	var arr = attrs.split("|"),
4816		i = attrs.length;
4817
4818	while ( i-- ) {
4819		Expr.attrHandle[ arr[i] ] = handler;
4820	}
4821}
4822
4823/**
4824* Checks document order of two siblings
4825* @param {Element} a
4826* @param {Element} b
4827* @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
4828*/
4829function siblingCheck( a, b ) {
4830	var cur = b && a,
4831		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
4832			( ~b.sourceIndex || MAX_NEGATIVE ) -
4833			( ~a.sourceIndex || MAX_NEGATIVE );
4834
4835	if ( diff ) {
4836		return diff;
4837	}
4838
4839	if ( cur ) {
4840		while ( (cur = cur.nextSibling) ) {
4841			if ( cur === b ) {
4842				return -1;
4843			}
4844		}
4845	}
4846
4847	return a ? 1 : -1;
4848}
4849
4850/**
4851* Returns a function to use in pseudos for input types
4852* @param {String} type
4853*/
4854function createInputPseudo( type ) {
4855	return function( elem ) {
4856		var name = elem.nodeName.toLowerCase();
4857		return name === "input" && elem.type === type;
4858	};
4859}
4860
4861/**
4862* Returns a function to use in pseudos for buttons
4863* @param {String} type
4864*/
4865function createButtonPseudo( type ) {
4866	return function( elem ) {
4867		var name = elem.nodeName.toLowerCase();
4868		return (name === "input" || name === "button") && elem.type === type;
4869	};
4870}
4871
4872/**
4873* Returns a function to use in pseudos for positionals
4874* @param {Function} fn
4875*/
4876function createPositionalPseudo( fn ) {
4877	return markFunction(function( argument ) {
4878		argument = +argument;
4879		return markFunction(function( seed, matches ) {
4880			var j,
4881				matchIndexes = fn( [], seed.length, argument ),
4882				i = matchIndexes.length;
4883
4884			while ( i-- ) {
4885				if ( seed[ (j = matchIndexes[i]) ] ) {
4886					seed[j] = !(matches[j] = seed[j]);
4887				}
4888			}
4889		});
4890	});
4891}
4892
4893/**
4894* Checks a node for validity as a Sizzle context
4895* @param {Element|Object=} context
4896* @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
4897*/
4898function testContext( context ) {
4899	return context && typeof context.getElementsByTagName !== strundefined && context;
4900}
4901
4902support = Sizzle.support = {};
4903
4904/**
4905* Detects XML nodes
4906* @param {Element|Object} elem An element or a document
4907* @returns {Boolean} True iff elem is a non-HTML XML node
4908*/
4909isXML = Sizzle.isXML = function( elem ) {
4910	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
4911	return documentElement ? documentElement.nodeName !== "HTML" : false;
4912};
4913
4914/**
4915* Sets document-related variables once based on the current document
4916* @param {Element|Object} [doc] An element or document object to use to set the document
4917* @returns {Object} Returns the current document
4918*/
4919setDocument = Sizzle.setDocument = function( node ) {
4920	var hasCompare,
4921		doc = node ? node.ownerDocument || node : preferredDoc,
4922		parent = doc.defaultView;
4923
4924	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
4925		return document;
4926	}
4927
4928	document = doc;
4929	docElem = doc.documentElement;
4930
4931	documentIsHTML = !isXML( doc );
4932
4933	if ( parent && parent !== parent.top ) {
4934		if ( parent.addEventListener ) {
4935			parent.addEventListener( "unload", function() {
4936				setDocument();
4937			}, false );
4938		} else if ( parent.attachEvent ) {
4939			parent.attachEvent( "onunload", function() {
4940				setDocument();
4941			});
4942		}
4943	}
4944
4945	/* Attributes
4946	---------------------------------------------------------------------- */
4947
4948	support.attributes = assert(function( div ) {
4949		div.className = "i";
4950		return !div.getAttribute("className");
4951	});
4952
4953	/* getElement(s)By*
4954	---------------------------------------------------------------------- */
4955
4956	support.getElementsByTagName = assert(function( div ) {
4957		div.appendChild( doc.createComment("") );
4958		return !div.getElementsByTagName("*").length;
4959	});
4960
4961	support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
4962		div.innerHTML = "<div class='a'></div><div class='a i'></div>";
4963
4964		div.firstChild.className = "i";
4965		return div.getElementsByClassName("i").length === 2;
4966	});
4967
4968	support.getById = assert(function( div ) {
4969		docElem.appendChild( div ).id = expando;
4970		return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
4971	});
4972
4973	if ( support.getById ) {
4974		Expr.find["ID"] = function( id, context ) {
4975			if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
4976				var m = context.getElementById( id );
4977				return m && m.parentNode ? [m] : [];
4978			}
4979		};
4980		Expr.filter["ID"] = function( id ) {
4981			var attrId = id.replace( runescape, funescape );
4982			return function( elem ) {
4983				return elem.getAttribute("id") === attrId;
4984			};
4985		};
4986	} else {
4987		delete Expr.find["ID"];
4988
4989		Expr.filter["ID"] =  function( id ) {
4990			var attrId = id.replace( runescape, funescape );
4991			return function( elem ) {
4992				var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
4993				return node && node.value === attrId;
4994			};
4995		};
4996	}
4997
4998	Expr.find["TAG"] = support.getElementsByTagName ?
4999		function( tag, context ) {
5000			if ( typeof context.getElementsByTagName !== strundefined ) {
5001				return context.getElementsByTagName( tag );
5002			}
5003		} :
5004		function( tag, context ) {
5005			var elem,
5006				tmp = [],
5007				i = 0,
5008				results = context.getElementsByTagName( tag );
5009
5010			if ( tag === "*" ) {
5011				while ( (elem = results[i++]) ) {
5012					if ( elem.nodeType === 1 ) {
5013						tmp.push( elem );
5014					}
5015				}
5016
5017				return tmp;
5018			}
5019			return results;
5020		};
5021
5022	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
5023		if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
5024			return context.getElementsByClassName( className );
5025		}
5026	};
5027
5028	/* QSA/matchesSelector
5029	---------------------------------------------------------------------- */
5030
5031
5032	rbuggyMatches = [];
5033
5034	rbuggyQSA = [];
5035
5036	if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
5037		assert(function( div ) {
5038			div.innerHTML = "<select t=''><option selected=''></option></select>";
5039
5040			if ( div.querySelectorAll("[t^='']").length ) {
5041				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
5042			}
5043
5044			if ( !div.querySelectorAll("[selected]").length ) {
5045				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
5046			}
5047
5048			if ( !div.querySelectorAll(":checked").length ) {
5049				rbuggyQSA.push(":checked");
5050			}
5051		});
5052
5053		assert(function( div ) {
5054			var input = doc.createElement("input");
5055			input.setAttribute( "type", "hidden" );
5056			div.appendChild( input ).setAttribute( "name", "D" );
5057
5058			if ( div.querySelectorAll("[name=d]").length ) {
5059				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
5060			}
5061
5062			if ( !div.querySelectorAll(":enabled").length ) {
5063				rbuggyQSA.push( ":enabled", ":disabled" );
5064			}
5065
5066			div.querySelectorAll("*,:x");
5067			rbuggyQSA.push(",.*:");
5068		});
5069	}
5070
5071	if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
5072		docElem.mozMatchesSelector ||
5073		docElem.oMatchesSelector ||
5074		docElem.msMatchesSelector) )) ) {
5075
5076		assert(function( div ) {
5077			support.disconnectedMatch = matches.call( div, "div" );
5078
5079			matches.call( div, "[s!='']:x" );
5080			rbuggyMatches.push( "!=", pseudos );
5081		});
5082	}
5083
5084	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
5085	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
5086
5087	/* Contains
5088	---------------------------------------------------------------------- */
5089	hasCompare = rnative.test( docElem.compareDocumentPosition );
5090
5091	contains = hasCompare || rnative.test( docElem.contains ) ?
5092		function( a, b ) {
5093			var adown = a.nodeType === 9 ? a.documentElement : a,
5094				bup = b && b.parentNode;
5095			return a === bup || !!( bup && bup.nodeType === 1 && (
5096				adown.contains ?
5097					adown.contains( bup ) :
5098					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
5099			));
5100		} :
5101		function( a, b ) {
5102			if ( b ) {
5103				while ( (b = b.parentNode) ) {
5104					if ( b === a ) {
5105						return true;
5106					}
5107				}
5108			}
5109			return false;
5110		};
5111
5112	/* Sorting
5113	---------------------------------------------------------------------- */
5114
5115	sortOrder = hasCompare ?
5116	function( a, b ) {
5117
5118		if ( a === b ) {
5119			hasDuplicate = true;
5120			return 0;
5121		}
5122
5123		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
5124		if ( compare ) {
5125			return compare;
5126		}
5127
5128		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
5129			a.compareDocumentPosition( b ) :
5130
5131			1;
5132
5133		if ( compare & 1 ||
5134			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
5135
5136			if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
5137				return -1;
5138			}
5139			if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
5140				return 1;
5141			}
5142
5143			return sortInput ?
5144				( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
5145				0;
5146		}
5147
5148		return compare & 4 ? -1 : 1;
5149	} :
5150	function( a, b ) {
5151		if ( a === b ) {
5152			hasDuplicate = true;
5153			return 0;
5154		}
5155
5156		var cur,
5157			i = 0,
5158			aup = a.parentNode,
5159			bup = b.parentNode,
5160			ap = [ a ],
5161			bp = [ b ];
5162
5163		if ( !aup || !bup ) {
5164			return a === doc ? -1 :
5165				b === doc ? 1 :
5166				aup ? -1 :
5167				bup ? 1 :
5168				sortInput ?
5169				( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
5170				0;
5171
5172		} else if ( aup === bup ) {
5173			return siblingCheck( a, b );
5174		}
5175
5176		cur = a;
5177		while ( (cur = cur.parentNode) ) {
5178			ap.unshift( cur );
5179		}
5180		cur = b;
5181		while ( (cur = cur.parentNode) ) {
5182			bp.unshift( cur );
5183		}
5184
5185		while ( ap[i] === bp[i] ) {
5186			i++;
5187		}
5188
5189		return i ?
5190			siblingCheck( ap[i], bp[i] ) :
5191
5192			ap[i] === preferredDoc ? -1 :
5193			bp[i] === preferredDoc ? 1 :
5194			0;
5195	};
5196
5197	return doc;
5198};
5199
5200Sizzle.matches = function( expr, elements ) {
5201	return Sizzle( expr, null, null, elements );
5202};
5203
5204Sizzle.matchesSelector = function( elem, expr ) {
5205	if ( ( elem.ownerDocument || elem ) !== document ) {
5206		setDocument( elem );
5207	}
5208
5209	expr = expr.replace( rattributeQuotes, "='$1']" );
5210
5211	if ( support.matchesSelector && documentIsHTML &&
5212		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
5213		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
5214
5215		try {
5216			var ret = matches.call( elem, expr );
5217
5218			if ( ret || support.disconnectedMatch ||
5219					elem.document && elem.document.nodeType !== 11 ) {
5220				return ret;
5221			}
5222		} catch(e) {}
5223	}
5224
5225	return Sizzle( expr, document, null, [elem] ).length > 0;
5226};
5227
5228Sizzle.contains = function( context, elem ) {
5229	if ( ( context.ownerDocument || context ) !== document ) {
5230		setDocument( context );
5231	}
5232	return contains( context, elem );
5233};
5234
5235Sizzle.attr = function( elem, name ) {
5236	if ( ( elem.ownerDocument || elem ) !== document ) {
5237		setDocument( elem );
5238	}
5239
5240	var fn = Expr.attrHandle[ name.toLowerCase() ],
5241		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
5242			fn( elem, name, !documentIsHTML ) :
5243			undefined;
5244
5245	return val !== undefined ?
5246		val :
5247		support.attributes || !documentIsHTML ?
5248			elem.getAttribute( name ) :
5249			(val = elem.getAttributeNode(name)) && val.specified ?
5250				val.value :
5251				null;
5252};
5253
5254Sizzle.error = function( msg ) {
5255	throw new Error( "Syntax error, unrecognized expression: " + msg );
5256};
5257
5258/**
5259* Document sorting and removing duplicates
5260* @param {ArrayLike} results
5261*/
5262Sizzle.uniqueSort = function( results ) {
5263	var elem,
5264		duplicates = [],
5265		j = 0,
5266		i = 0;
5267
5268	hasDuplicate = !support.detectDuplicates;
5269	sortInput = !support.sortStable && results.slice( 0 );
5270	results.sort( sortOrder );
5271
5272	if ( hasDuplicate ) {
5273		while ( (elem = results[i++]) ) {
5274			if ( elem === results[ i ] ) {
5275				j = duplicates.push( i );
5276			}
5277		}
5278		while ( j-- ) {
5279			results.splice( duplicates[ j ], 1 );
5280		}
5281	}
5282
5283	sortInput = null;
5284
5285	return results;
5286};
5287
5288/**
5289* Utility function for retrieving the text value of an array of DOM nodes
5290* @param {Array|Element} elem
5291*/
5292getText = Sizzle.getText = function( elem ) {
5293	var node,
5294		ret = "",
5295		i = 0,
5296		nodeType = elem.nodeType;
5297
5298	if ( !nodeType ) {
5299		while ( (node = elem[i++]) ) {
5300			ret += getText( node );
5301		}
5302	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
5303		if ( typeof elem.textContent === "string" ) {
5304			return elem.textContent;
5305		} else {
5306			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
5307				ret += getText( elem );
5308			}
5309		}
5310	} else if ( nodeType === 3 || nodeType === 4 ) {
5311		return elem.nodeValue;
5312	}
5313
5314	return ret;
5315};
5316
5317Expr = Sizzle.selectors = {
5318
5319	cacheLength: 50,
5320
5321	createPseudo: markFunction,
5322
5323	match: matchExpr,
5324
5325	attrHandle: {},
5326
5327	find: {},
5328
5329	relative: {
5330		">": { dir: "parentNode", first: true },
5331		" ": { dir: "parentNode" },
5332		"+": { dir: "previousSibling", first: true },
5333		"~": { dir: "previousSibling" }
5334	},
5335
5336	preFilter: {
5337		"ATTR": function( match ) {
5338			match[1] = match[1].replace( runescape, funescape );
5339
5340			match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
5341
5342			if ( match[2] === "~=" ) {
5343				match[3] = " " + match[3] + " ";
5344			}
5345
5346			return match.slice( 0, 4 );
5347		},
5348
5349		"CHILD": function( match ) {
5350			/* matches from matchExpr["CHILD"]
5351				1 type (only|nth|...)
5352				2 what (child|of-type)
5353				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
5354				4 xn-component of xn+y argument ([+-]?\d*n|)
5355				5 sign of xn-component
5356				6 x of xn-component
5357				7 sign of y-component
5358				8 y of y-component
5359			*/
5360			match[1] = match[1].toLowerCase();
5361
5362			if ( match[1].slice( 0, 3 ) === "nth" ) {
5363				if ( !match[3] ) {
5364					Sizzle.error( match[0] );
5365				}
5366
5367				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
5368				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
5369
5370			} else if ( match[3] ) {
5371				Sizzle.error( match[0] );
5372			}
5373
5374			return match;
5375		},
5376
5377		"PSEUDO": function( match ) {
5378			var excess,
5379				unquoted = !match[5] && match[2];
5380
5381			if ( matchExpr["CHILD"].test( match[0] ) ) {
5382				return null;
5383			}
5384
5385			if ( match[3] && match[4] !== undefined ) {
5386				match[2] = match[4];
5387
5388			} else if ( unquoted && rpseudo.test( unquoted ) &&
5389				(excess = tokenize( unquoted, true )) &&
5390				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
5391
5392				match[0] = match[0].slice( 0, excess );
5393				match[2] = unquoted.slice( 0, excess );
5394			}
5395
5396			return match.slice( 0, 3 );
5397		}
5398	},
5399
5400	filter: {
5401
5402		"TAG": function( nodeNameSelector ) {
5403			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
5404			return nodeNameSelector === "*" ?
5405				function() { return true; } :
5406				function( elem ) {
5407					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
5408				};
5409		},
5410
5411		"CLASS": function( className ) {
5412			var pattern = classCache[ className + " " ];
5413
5414			return pattern ||
5415				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
5416				classCache( className, function( elem ) {
5417					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
5418				});
5419		},
5420
5421		"ATTR": function( name, operator, check ) {
5422			return function( elem ) {
5423				var result = Sizzle.attr( elem, name );
5424
5425				if ( result == null ) {
5426					return operator === "!=";
5427				}
5428				if ( !operator ) {
5429					return true;
5430				}
5431
5432				result += "";
5433
5434				return operator === "=" ? result === check :
5435					operator === "!=" ? result !== check :
5436					operator === "^=" ? check && result.indexOf( check ) === 0 :
5437					operator === "*=" ? check && result.indexOf( check ) > -1 :
5438					operator === "$=" ? check && result.slice( -check.length ) === check :
5439					operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
5440					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
5441					false;
5442			};
5443		},
5444
5445		"CHILD": function( type, what, argument, first, last ) {
5446			var simple = type.slice( 0, 3 ) !== "nth",
5447				forward = type.slice( -4 ) !== "last",
5448				ofType = what === "of-type";
5449
5450			return first === 1 && last === 0 ?
5451
5452				function( elem ) {
5453					return !!elem.parentNode;
5454				} :
5455
5456				function( elem, context, xml ) {
5457					var cache, outerCache, node, diff, nodeIndex, start,
5458						dir = simple !== forward ? "nextSibling" : "previousSibling",
5459						parent = elem.parentNode,
5460						name = ofType && elem.nodeName.toLowerCase(),
5461						useCache = !xml && !ofType;
5462
5463					if ( parent ) {
5464
5465						if ( simple ) {
5466							while ( dir ) {
5467								node = elem;
5468								while ( (node = node[ dir ]) ) {
5469									if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
5470										return false;
5471									}
5472								}
5473								start = dir = type === "only" && !start && "nextSibling";
5474							}
5475							return true;
5476						}
5477
5478						start = [ forward ? parent.firstChild : parent.lastChild ];
5479
5480						if ( forward && useCache ) {
5481							outerCache = parent[ expando ] || (parent[ expando ] = {});
5482							cache = outerCache[ type ] || [];
5483							nodeIndex = cache[0] === dirruns && cache[1];
5484							diff = cache[0] === dirruns && cache[2];
5485							node = nodeIndex && parent.childNodes[ nodeIndex ];
5486
5487							while ( (node = ++nodeIndex && node && node[ dir ] ||
5488
5489								(diff = nodeIndex = 0) || start.pop()) ) {
5490
5491								if ( node.nodeType === 1 && ++diff && node === elem ) {
5492									outerCache[ type ] = [ dirruns, nodeIndex, diff ];
5493									break;
5494								}
5495							}
5496
5497						} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
5498							diff = cache[1];
5499
5500						} else {
5501							while ( (node = ++nodeIndex && node && node[ dir ] ||
5502								(diff = nodeIndex = 0) || start.pop()) ) {
5503
5504								if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
5505									if ( useCache ) {
5506										(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
5507									}
5508
5509									if ( node === elem ) {
5510										break;
5511									}
5512								}
5513							}
5514						}
5515
5516						diff -= last;
5517						return diff === first || ( diff % first === 0 && diff / first >= 0 );
5518					}
5519				};
5520		},
5521
5522		"PSEUDO": function( pseudo, argument ) {
5523			var args,
5524				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
5525					Sizzle.error( "unsupported pseudo: " + pseudo );
5526
5527			if ( fn[ expando ] ) {
5528				return fn( argument );
5529			}
5530
5531			if ( fn.length > 1 ) {
5532				args = [ pseudo, pseudo, "", argument ];
5533				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
5534					markFunction(function( seed, matches ) {
5535						var idx,
5536							matched = fn( seed, argument ),
5537							i = matched.length;
5538						while ( i-- ) {
5539							idx = indexOf.call( seed, matched[i] );
5540							seed[ idx ] = !( matches[ idx ] = matched[i] );
5541						}
5542					}) :
5543					function( elem ) {
5544						return fn( elem, 0, args );
5545					};
5546			}
5547
5548			return fn;
5549		}
5550	},
5551
5552	pseudos: {
5553		"not": markFunction(function( selector ) {
5554			var input = [],
5555				results = [],
5556				matcher = compile( selector.replace( rtrim, "$1" ) );
5557
5558			return matcher[ expando ] ?
5559				markFunction(function( seed, matches, context, xml ) {
5560					var elem,
5561						unmatched = matcher( seed, null, xml, [] ),
5562						i = seed.length;
5563
5564					while ( i-- ) {
5565						if ( (elem = unmatched[i]) ) {
5566							seed[i] = !(matches[i] = elem);
5567						}
5568					}
5569				}) :
5570				function( elem, context, xml ) {
5571					input[0] = elem;
5572					matcher( input, null, xml, results );
5573					return !results.pop();
5574				};
5575		}),
5576
5577		"has": markFunction(function( selector ) {
5578			return function( elem ) {
5579				return Sizzle( selector, elem ).length > 0;
5580			};
5581		}),
5582
5583		"contains": markFunction(function( text ) {
5584			return function( elem ) {
5585				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
5586			};
5587		}),
5588
5589		"lang": markFunction( function( lang ) {
5590			if ( !ridentifier.test(lang || "") ) {
5591				Sizzle.error( "unsupported lang: " + lang );
5592			}
5593			lang = lang.replace( runescape, funescape ).toLowerCase();
5594			return function( elem ) {
5595				var elemLang;
5596				do {
5597					if ( (elemLang = documentIsHTML ?
5598						elem.lang :
5599						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
5600
5601						elemLang = elemLang.toLowerCase();
5602						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
5603					}
5604				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
5605				return false;
5606			};
5607		}),
5608
5609		"target": function( elem ) {
5610			var hash = window.location && window.location.hash;
5611			return hash && hash.slice( 1 ) === elem.id;
5612		},
5613
5614		"root": function( elem ) {
5615			return elem === docElem;
5616		},
5617
5618		"focus": function( elem ) {
5619			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
5620		},
5621
5622		"enabled": function( elem ) {
5623			return elem.disabled === false;
5624		},
5625
5626		"disabled": function( elem ) {
5627			return elem.disabled === true;
5628		},
5629
5630		"checked": function( elem ) {
5631			var nodeName = elem.nodeName.toLowerCase();
5632			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
5633		},
5634
5635		"selected": function( elem ) {
5636			if ( elem.parentNode ) {
5637				elem.parentNode.selectedIndex;
5638			}
5639
5640			return elem.selected === true;
5641		},
5642
5643		"empty": function( elem ) {
5644			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
5645				if ( elem.nodeType < 6 ) {
5646					return false;
5647				}
5648			}
5649			return true;
5650		},
5651
5652		"parent": function( elem ) {
5653			return !Expr.pseudos["empty"]( elem );
5654		},
5655
5656		"header": function( elem ) {
5657			return rheader.test( elem.nodeName );
5658		},
5659
5660		"input": function( elem ) {
5661			return rinputs.test( elem.nodeName );
5662		},
5663
5664		"button": function( elem ) {
5665			var name = elem.nodeName.toLowerCase();
5666			return name === "input" && elem.type === "button" || name === "button";
5667		},
5668
5669		"text": function( elem ) {
5670			var attr;
5671			return elem.nodeName.toLowerCase() === "input" &&
5672				elem.type === "text" &&
5673
5674				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
5675		},
5676
5677		"first": createPositionalPseudo(function() {
5678			return [ 0 ];
5679		}),
5680
5681		"last": createPositionalPseudo(function( matchIndexes, length ) {
5682			return [ length - 1 ];
5683		}),
5684
5685		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
5686			return [ argument < 0 ? argument + length : argument ];
5687		}),
5688
5689		"even": createPositionalPseudo(function( matchIndexes, length ) {
5690			var i = 0;
5691			for ( ; i < length; i += 2 ) {
5692				matchIndexes.push( i );
5693			}
5694			return matchIndexes;
5695		}),
5696
5697		"odd": createPositionalPseudo(function( matchIndexes, length ) {
5698			var i = 1;
5699			for ( ; i < length; i += 2 ) {
5700				matchIndexes.push( i );
5701			}
5702			return matchIndexes;
5703		}),
5704
5705		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
5706			var i = argument < 0 ? argument + length : argument;
5707			for ( ; --i >= 0; ) {
5708				matchIndexes.push( i );
5709			}
5710			return matchIndexes;
5711		}),
5712
5713		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
5714			var i = argument < 0 ? argument + length : argument;
5715			for ( ; ++i < length; ) {
5716				matchIndexes.push( i );
5717			}
5718			return matchIndexes;
5719		})
5720	}
5721};
5722
5723Expr.pseudos["nth"] = Expr.pseudos["eq"];
5724
5725for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
5726	Expr.pseudos[ i ] = createInputPseudo( i );
5727}
5728for ( i in { submit: true, reset: true } ) {
5729	Expr.pseudos[ i ] = createButtonPseudo( i );
5730}
5731
5732function setFilters() {}
5733setFilters.prototype = Expr.filters = Expr.pseudos;
5734Expr.setFilters = new setFilters();
5735
5736function tokenize( selector, parseOnly ) {
5737	var matched, match, tokens, type,
5738		soFar, groups, preFilters,
5739		cached = tokenCache[ selector + " " ];
5740
5741	if ( cached ) {
5742		return parseOnly ? 0 : cached.slice( 0 );
5743	}
5744
5745	soFar = selector;
5746	groups = [];
5747	preFilters = Expr.preFilter;
5748
5749	while ( soFar ) {
5750
5751		if ( !matched || (match = rcomma.exec( soFar )) ) {
5752			if ( match ) {
5753				soFar = soFar.slice( match[0].length ) || soFar;
5754			}
5755			groups.push( (tokens = []) );
5756		}
5757
5758		matched = false;
5759
5760		if ( (match = rcombinators.exec( soFar )) ) {
5761			matched = match.shift();
5762			tokens.push({
5763				value: matched,
5764				type: match[0].replace( rtrim, " " )
5765			});
5766			soFar = soFar.slice( matched.length );
5767		}
5768
5769		for ( type in Expr.filter ) {
5770			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
5771				(match = preFilters[ type ]( match ))) ) {
5772				matched = match.shift();
5773				tokens.push({
5774					value: matched,
5775					type: type,
5776					matches: match
5777				});
5778				soFar = soFar.slice( matched.length );
5779			}
5780		}
5781
5782		if ( !matched ) {
5783			break;
5784		}
5785	}
5786
5787	return parseOnly ?
5788		soFar.length :
5789		soFar ?
5790			Sizzle.error( selector ) :
5791			tokenCache( selector, groups ).slice( 0 );
5792}
5793
5794function toSelector( tokens ) {
5795	var i = 0,
5796		len = tokens.length,
5797		selector = "";
5798	for ( ; i < len; i++ ) {
5799		selector += tokens[i].value;
5800	}
5801	return selector;
5802}
5803
5804function addCombinator( matcher, combinator, base ) {
5805	var dir = combinator.dir,
5806		checkNonElements = base && dir === "parentNode",
5807		doneName = done++;
5808
5809	return combinator.first ?
5810		function( elem, context, xml ) {
5811			while ( (elem = elem[ dir ]) ) {
5812				if ( elem.nodeType === 1 || checkNonElements ) {
5813					return matcher( elem, context, xml );
5814				}
5815			}
5816		} :
5817
5818		function( elem, context, xml ) {
5819			var oldCache, outerCache,
5820				newCache = [ dirruns, doneName ];
5821
5822			if ( xml ) {
5823				while ( (elem = elem[ dir ]) ) {
5824					if ( elem.nodeType === 1 || checkNonElements ) {
5825						if ( matcher( elem, context, xml ) ) {
5826							return true;
5827						}
5828					}
5829				}
5830			} else {
5831				while ( (elem = elem[ dir ]) ) {
5832					if ( elem.nodeType === 1 || checkNonElements ) {
5833						outerCache = elem[ expando ] || (elem[ expando ] = {});
5834						if ( (oldCache = outerCache[ dir ]) &&
5835							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
5836
5837							return (newCache[ 2 ] = oldCache[ 2 ]);
5838						} else {
5839							outerCache[ dir ] = newCache;
5840
5841							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
5842								return true;
5843							}
5844						}
5845					}
5846				}
5847			}
5848		};
5849}
5850
5851function elementMatcher( matchers ) {
5852	return matchers.length > 1 ?
5853		function( elem, context, xml ) {
5854			var i = matchers.length;
5855			while ( i-- ) {
5856				if ( !matchers[i]( elem, context, xml ) ) {
5857					return false;
5858				}
5859			}
5860			return true;
5861		} :
5862		matchers[0];
5863}
5864
5865function multipleContexts( selector, contexts, results ) {
5866	var i = 0,
5867		len = contexts.length;
5868	for ( ; i < len; i++ ) {
5869		Sizzle( selector, contexts[i], results );
5870	}
5871	return results;
5872}
5873
5874function condense( unmatched, map, filter, context, xml ) {
5875	var elem,
5876		newUnmatched = [],
5877		i = 0,
5878		len = unmatched.length,
5879		mapped = map != null;
5880
5881	for ( ; i < len; i++ ) {
5882		if ( (elem = unmatched[i]) ) {
5883			if ( !filter || filter( elem, context, xml ) ) {
5884				newUnmatched.push( elem );
5885				if ( mapped ) {
5886					map.push( i );
5887				}
5888			}
5889		}
5890	}
5891
5892	return newUnmatched;
5893}
5894
5895function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
5896	if ( postFilter && !postFilter[ expando ] ) {
5897		postFilter = setMatcher( postFilter );
5898	}
5899	if ( postFinder && !postFinder[ expando ] ) {
5900		postFinder = setMatcher( postFinder, postSelector );
5901	}
5902	return markFunction(function( seed, results, context, xml ) {
5903		var temp, i, elem,
5904			preMap = [],
5905			postMap = [],
5906			preexisting = results.length,
5907
5908			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
5909
5910			matcherIn = preFilter && ( seed || !selector ) ?
5911				condense( elems, preMap, preFilter, context, xml ) :
5912				elems,
5913
5914			matcherOut = matcher ?
5915				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
5916
5917					[] :
5918
5919					results :
5920				matcherIn;
5921
5922		if ( matcher ) {
5923			matcher( matcherIn, matcherOut, context, xml );
5924		}
5925
5926		if ( postFilter ) {
5927			temp = condense( matcherOut, postMap );
5928			postFilter( temp, [], context, xml );
5929
5930			i = temp.length;
5931			while ( i-- ) {
5932				if ( (elem = temp[i]) ) {
5933					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
5934				}
5935			}
5936		}
5937
5938		if ( seed ) {
5939			if ( postFinder || preFilter ) {
5940				if ( postFinder ) {
5941					temp = [];
5942					i = matcherOut.length;
5943					while ( i-- ) {
5944						if ( (elem = matcherOut[i]) ) {
5945							temp.push( (matcherIn[i] = elem) );
5946						}
5947					}
5948					postFinder( null, (matcherOut = []), temp, xml );
5949				}
5950
5951				i = matcherOut.length;
5952				while ( i-- ) {
5953					if ( (elem = matcherOut[i]) &&
5954						(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
5955
5956						seed[temp] = !(results[temp] = elem);
5957					}
5958				}
5959			}
5960
5961		} else {
5962			matcherOut = condense(
5963				matcherOut === results ?
5964					matcherOut.splice( preexisting, matcherOut.length ) :
5965					matcherOut
5966			);
5967			if ( postFinder ) {
5968				postFinder( null, results, matcherOut, xml );
5969			} else {
5970				push.apply( results, matcherOut );
5971			}
5972		}
5973	});
5974}
5975
5976function matcherFromTokens( tokens ) {
5977	var checkContext, matcher, j,
5978		len = tokens.length,
5979		leadingRelative = Expr.relative[ tokens[0].type ],
5980		implicitRelative = leadingRelative || Expr.relative[" "],
5981		i = leadingRelative ? 1 : 0,
5982
5983		matchContext = addCombinator( function( elem ) {
5984			return elem === checkContext;
5985		}, implicitRelative, true ),
5986		matchAnyContext = addCombinator( function( elem ) {
5987			return indexOf.call( checkContext, elem ) > -1;
5988		}, implicitRelative, true ),
5989		matchers = [ function( elem, context, xml ) {
5990			return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
5991				(checkContext = context).nodeType ?
5992					matchContext( elem, context, xml ) :
5993					matchAnyContext( elem, context, xml ) );
5994		} ];
5995
5996	for ( ; i < len; i++ ) {
5997		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
5998			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
5999		} else {
6000			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
6001
6002			if ( matcher[ expando ] ) {
6003				j = ++i;
6004				for ( ; j < len; j++ ) {
6005					if ( Expr.relative[ tokens[j].type ] ) {
6006						break;
6007					}
6008				}
6009				return setMatcher(
6010					i > 1 && elementMatcher( matchers ),
6011					i > 1 && toSelector(
6012						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
6013					).replace( rtrim, "$1" ),
6014					matcher,
6015					i < j && matcherFromTokens( tokens.slice( i, j ) ),
6016					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
6017					j < len && toSelector( tokens )
6018				);
6019			}
6020			matchers.push( matcher );
6021		}
6022	}
6023
6024	return elementMatcher( matchers );
6025}
6026
6027function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
6028	var bySet = setMatchers.length > 0,
6029		byElement = elementMatchers.length > 0,
6030		superMatcher = function( seed, context, xml, results, outermost ) {
6031			var elem, j, matcher,
6032				matchedCount = 0,
6033				i = "0",
6034				unmatched = seed && [],
6035				setMatched = [],
6036				contextBackup = outermostContext,
6037				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
6038				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
6039				len = elems.length;
6040
6041			if ( outermost ) {
6042				outermostContext = context !== document && context;
6043			}
6044
6045			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
6046				if ( byElement && elem ) {
6047					j = 0;
6048					while ( (matcher = elementMatchers[j++]) ) {
6049						if ( matcher( elem, context, xml ) ) {
6050							results.push( elem );
6051							break;
6052						}
6053					}
6054					if ( outermost ) {
6055						dirruns = dirrunsUnique;
6056					}
6057				}
6058
6059				if ( bySet ) {
6060					if ( (elem = !matcher && elem) ) {
6061						matchedCount--;
6062					}
6063
6064					if ( seed ) {
6065						unmatched.push( elem );
6066					}
6067				}
6068			}
6069
6070			matchedCount += i;
6071			if ( bySet && i !== matchedCount ) {
6072				j = 0;
6073				while ( (matcher = setMatchers[j++]) ) {
6074					matcher( unmatched, setMatched, context, xml );
6075				}
6076
6077				if ( seed ) {
6078					if ( matchedCount > 0 ) {
6079						while ( i-- ) {
6080							if ( !(unmatched[i] || setMatched[i]) ) {
6081								setMatched[i] = pop.call( results );
6082							}
6083						}
6084					}
6085
6086					setMatched = condense( setMatched );
6087				}
6088
6089				push.apply( results, setMatched );
6090
6091				if ( outermost && !seed && setMatched.length > 0 &&
6092					( matchedCount + setMatchers.length ) > 1 ) {
6093
6094					Sizzle.uniqueSort( results );
6095				}
6096			}
6097
6098			if ( outermost ) {
6099				dirruns = dirrunsUnique;
6100				outermostContext = contextBackup;
6101			}
6102
6103			return unmatched;
6104		};
6105
6106	return bySet ?
6107		markFunction( superMatcher ) :
6108		superMatcher;
6109}
6110
6111compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
6112	var i,
6113		setMatchers = [],
6114		elementMatchers = [],
6115		cached = compilerCache[ selector + " " ];
6116
6117	if ( !cached ) {
6118		if ( !match ) {
6119			match = tokenize( selector );
6120		}
6121		i = match.length;
6122		while ( i-- ) {
6123			cached = matcherFromTokens( match[i] );
6124			if ( cached[ expando ] ) {
6125				setMatchers.push( cached );
6126			} else {
6127				elementMatchers.push( cached );
6128			}
6129		}
6130
6131		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
6132
6133		cached.selector = selector;
6134	}
6135	return cached;
6136};
6137
6138/**
6139* A low-level selection function that works with Sizzle's compiled
6140*  selector functions
6141* @param {String|Function} selector A selector or a pre-compiled
6142*  selector function built with Sizzle.compile
6143* @param {Element} context
6144* @param {Array} [results]
6145* @param {Array} [seed] A set of elements to match against
6146*/
6147select = Sizzle.select = function( selector, context, results, seed ) {
6148	var i, tokens, token, type, find,
6149		compiled = typeof selector === "function" && selector,
6150		match = !seed && tokenize( (selector = compiled.selector || selector) );
6151
6152	results = results || [];
6153
6154	if ( match.length === 1 ) {
6155
6156		tokens = match[0] = match[0].slice( 0 );
6157		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
6158				support.getById && context.nodeType === 9 && documentIsHTML &&
6159				Expr.relative[ tokens[1].type ] ) {
6160
6161			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
6162			if ( !context ) {
6163				return results;
6164
6165			} else if ( compiled ) {
6166				context = context.parentNode;
6167			}
6168
6169			selector = selector.slice( tokens.shift().value.length );
6170		}
6171
6172		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
6173		while ( i-- ) {
6174			token = tokens[i];
6175
6176			if ( Expr.relative[ (type = token.type) ] ) {
6177				break;
6178			}
6179			if ( (find = Expr.find[ type ]) ) {
6180				if ( (seed = find(
6181					token.matches[0].replace( runescape, funescape ),
6182					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
6183				)) ) {
6184
6185					tokens.splice( i, 1 );
6186					selector = seed.length && toSelector( tokens );
6187					if ( !selector ) {
6188						push.apply( results, seed );
6189						return results;
6190					}
6191
6192					break;
6193				}
6194			}
6195		}
6196	}
6197
6198	( compiled || compile( selector, match ) )(
6199		seed,
6200		context,
6201		!documentIsHTML,
6202		results,
6203		rsibling.test( selector ) && testContext( context.parentNode ) || context
6204	);
6205	return results;
6206};
6207
6208
6209support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
6210
6211support.detectDuplicates = !!hasDuplicate;
6212
6213setDocument();
6214
6215support.sortDetached = assert(function( div1 ) {
6216	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
6217});
6218
6219if ( !assert(function( div ) {
6220	div.innerHTML = "<a href='#'></a>";
6221	return div.firstChild.getAttribute("href") === "#" ;
6222}) ) {
6223	addHandle( "type|href|height|width", function( elem, name, isXML ) {
6224		if ( !isXML ) {
6225			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
6226		}
6227	});
6228}
6229
6230if ( !support.attributes || !assert(function( div ) {
6231	div.innerHTML = "<input/>";
6232	div.firstChild.setAttribute( "value", "" );
6233	return div.firstChild.getAttribute( "value" ) === "";
6234}) ) {
6235	addHandle( "value", function( elem, name, isXML ) {
6236		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
6237			return elem.defaultValue;
6238		}
6239	});
6240}
6241
6242if ( !assert(function( div ) {
6243	return div.getAttribute("disabled") == null;
6244}) ) {
6245	addHandle( booleans, function( elem, name, isXML ) {
6246		var val;
6247		if ( !isXML ) {
6248			return elem[ name ] === true ? name.toLowerCase() :
6249					(val = elem.getAttributeNode( name )) && val.specified ?
6250					val.value :
6251				null;
6252		}
6253	});
6254}
6255
6256if ( typeof define === "function" && define.amd ) {
6257	define(function() { return Sizzle; });
6258} else if ( typeof module !== "undefined" && module.exports ) {
6259	module.exports = Sizzle;
6260} else {
6261	window.Sizzle = Sizzle;
6262}
6263
6264})( window );
6265
6266;(function(engine) {
6267var extendElements = Prototype.Selector.extendElements;
6268
6269function select(selector, scope) {
6270	return extendElements(engine(selector, scope || document));
6271}
6272
6273function match(element, selector) {
6274	return engine.matches(selector, [element]).length == 1;
6275}
6276
6277Prototype.Selector.engine = engine;
6278Prototype.Selector.select = select;
6279Prototype.Selector.match = match;
6280})(Sizzle);
6281
6282window.Sizzle = Prototype._original_property;
6283delete Prototype._original_property;
6284
6285var Form = {
6286reset: function(form) {
6287	form = $(form);
6288	form.reset();
6289	return form;
6290},
6291
6292serializeElements: function(elements, options) {
6293	if (typeof options != 'object') options = { hash: !!options };
6294	else if (Object.isUndefined(options.hash)) options.hash = true;
6295	var key, value, submitted = false, submit = options.submit, accumulator, initial;
6296
6297	if (options.hash) {
6298	initial = {};
6299	accumulator = function(result, key, value) {
6300		if (key in result) {
6301		if (!Object.isArray(result[key])) result[key] = [result[key]];
6302		result[key] = result[key].concat(value);
6303		} else result[key] = value;
6304		return result;
6305	};
6306	} else {
6307	initial = '';
6308	accumulator = function(result, key, values) {
6309		if (!Object.isArray(values)) {values = [values];}
6310		if (!values.length) {return result;}
6311		var encodedKey = encodeURIComponent(key).gsub(/%20/, '+');
6312		return result + (result ? "&" : "") + values.map(function (value) {
6313		value = value.gsub(/(\r)?\n/, '\r\n');
6314		value = encodeURIComponent(value);
6315		value = value.gsub(/%20/, '+');
6316		return encodedKey + "=" + value;
6317		}).join("&");
6318	};
6319	}
6320
6321	return elements.inject(initial, function(result, element) {
6322	if (!element.disabled && element.name) {
6323		key = element.name; value = $(element).getValue();
6324		if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
6325			submit !== false && (!submit || key == submit) && (submitted = true)))) {
6326		result = accumulator(result, key, value);
6327		}
6328	}
6329	return result;
6330	});
6331}
6332};
6333
6334Form.Methods = {
6335serialize: function(form, options) {
6336	return Form.serializeElements(Form.getElements(form), options);
6337},
6338
6339
6340getElements: function(form) {
6341	var elements = $(form).getElementsByTagName('*');
6342	var element, results = [], serializers = Form.Element.Serializers;
6343
6344	for (var i = 0; element = elements[i]; i++) {
6345	if (serializers[element.tagName.toLowerCase()])
6346		results.push(Element.extend(element));
6347	}
6348	return results;
6349},
6350
6351getInputs: function(form, typeName, name) {
6352	form = $(form);
6353	var inputs = form.getElementsByTagName('input');
6354
6355	if (!typeName && !name) return $A(inputs).map(Element.extend);
6356
6357	for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
6358	var input = inputs[i];
6359	if ((typeName && input.type != typeName) || (name && input.name != name))
6360		continue;
6361	matchingInputs.push(Element.extend(input));
6362	}
6363
6364	return matchingInputs;
6365},
6366
6367disable: function(form) {
6368	form = $(form);
6369	Form.getElements(form).invoke('disable');
6370	return form;
6371},
6372
6373enable: function(form) {
6374	form = $(form);
6375	Form.getElements(form).invoke('enable');
6376	return form;
6377},
6378
6379findFirstElement: function(form) {
6380	var elements = $(form).getElements().findAll(function(element) {
6381	return 'hidden' != element.type && !element.disabled;
6382	});
6383	var firstByIndex = elements.findAll(function(element) {
6384	return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
6385	}).sortBy(function(element) { return element.tabIndex }).first();
6386
6387	return firstByIndex ? firstByIndex : elements.find(function(element) {
6388	return /^(?:input|select|textarea)$/i.test(element.tagName);
6389	});
6390},
6391
6392focusFirstElement: function(form) {
6393	form = $(form);
6394	var element = form.findFirstElement();
6395	if (element) element.activate();
6396	return form;
6397},
6398
6399request: function(form, options) {
6400	form = $(form), options = Object.clone(options || { });
6401
6402	var params = options.parameters, action = form.readAttribute('action') || '';
6403	if (action.blank()) action = window.location.href;
6404	options.parameters = form.serialize(true);
6405
6406	if (params) {
6407	if (Object.isString(params)) params = params.toQueryParams();
6408	Object.extend(options.parameters, params);
6409	}
6410
6411	if (form.hasAttribute('method') && !options.method)
6412	options.method = form.method;
6413
6414	return new Ajax.Request(action, options);
6415}
6416};
6417
6418/*--------------------------------------------------------------------------*/
6419
6420
6421Form.Element = {
6422focus: function(element) {
6423	$(element).focus();
6424	return element;
6425},
6426
6427select: function(element) {
6428	$(element).select();
6429	return element;
6430}
6431};
6432
6433Form.Element.Methods = {
6434
6435serialize: function(element) {
6436	element = $(element);
6437	if (!element.disabled && element.name) {
6438	var value = element.getValue();
6439	if (value != undefined) {
6440		var pair = { };
6441		pair[element.name] = value;
6442		return Object.toQueryString(pair);
6443	}
6444	}
6445	return '';
6446},
6447
6448getValue: function(element) {
6449	element = $(element);
6450	var method = element.tagName.toLowerCase();
6451	return Form.Element.Serializers[method](element);
6452},
6453
6454setValue: function(element, value) {
6455	element = $(element);
6456	var method = element.tagName.toLowerCase();
6457	Form.Element.Serializers[method](element, value);
6458	return element;
6459},
6460
6461clear: function(element) {
6462	$(element).value = '';
6463	return element;
6464},
6465
6466present: function(element) {
6467	return $(element).value != '';
6468},
6469
6470activate: function(element) {
6471	element = $(element);
6472	try {
6473	element.focus();
6474	if (element.select && (element.tagName.toLowerCase() != 'input' ||
6475		!(/^(?:button|reset|submit)$/i.test(element.type))))
6476		element.select();
6477	} catch (e) { }
6478	return element;
6479},
6480
6481disable: function(element) {
6482	element = $(element);
6483	element.disabled = true;
6484	return element;
6485},
6486
6487enable: function(element) {
6488	element = $(element);
6489	element.disabled = false;
6490	return element;
6491}
6492};
6493
6494/*--------------------------------------------------------------------------*/
6495
6496var Field = Form.Element;
6497
6498var $F = Form.Element.Methods.getValue;
6499
6500/*--------------------------------------------------------------------------*/
6501
6502Form.Element.Serializers = (function() {
6503function input(element, value) {
6504	switch (element.type.toLowerCase()) {
6505	case 'checkbox':
6506	case 'radio':
6507		return inputSelector(element, value);
6508	default:
6509		return valueSelector(element, value);
6510	}
6511}
6512
6513function inputSelector(element, value) {
6514	if (Object.isUndefined(value))
6515	return element.checked ? element.value : null;
6516	else element.checked = !!value;
6517}
6518
6519function valueSelector(element, value) {
6520	if (Object.isUndefined(value)) return element.value;
6521	else element.value = value;
6522}
6523
6524function select(element, value) {
6525	if (Object.isUndefined(value))
6526	return (element.type === 'select-one' ? selectOne : selectMany)(element);
6527
6528	var opt, currentValue, single = !Object.isArray(value);
6529	for (var i = 0, length = element.length; i < length; i++) {
6530	opt = element.options[i];
6531	currentValue = this.optionValue(opt);
6532	if (single) {
6533		if (currentValue == value) {
6534		opt.selected = true;
6535		return;
6536		}
6537	}
6538	else opt.selected = value.include(currentValue);
6539	}
6540}
6541
6542function selectOne(element) {
6543	var index = element.selectedIndex;
6544	return index >= 0 ? optionValue(element.options[index]) : null;
6545}
6546
6547function selectMany(element) {
6548	var values, length = element.length;
6549	if (!length) return null;
6550
6551	for (var i = 0, values = []; i < length; i++) {
6552	var opt = element.options[i];
6553	if (opt.selected) values.push(optionValue(opt));
6554	}
6555	return values;
6556}
6557
6558function optionValue(opt) {
6559	return Element.hasAttribute(opt, 'value') ? opt.value : opt.text;
6560}
6561
6562return {
6563	input:         input,
6564	inputSelector: inputSelector,
6565	textarea:      valueSelector,
6566	select:        select,
6567	selectOne:     selectOne,
6568	selectMany:    selectMany,
6569	optionValue:   optionValue,
6570	button:        valueSelector
6571};
6572})();
6573
6574/*--------------------------------------------------------------------------*/
6575
6576
6577Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
6578initialize: function($super, element, frequency, callback) {
6579	$super(callback, frequency);
6580	this.element   = $(element);
6581	this.lastValue = this.getValue();
6582},
6583
6584execute: function() {
6585	var value = this.getValue();
6586	if (Object.isString(this.lastValue) && Object.isString(value) ?
6587		this.lastValue != value : String(this.lastValue) != String(value)) {
6588	this.callback(this.element, value);
6589	this.lastValue = value;
6590	}
6591}
6592});
6593
6594Form.Element.Observer = Class.create(Abstract.TimedObserver, {
6595getValue: function() {
6596	return Form.Element.getValue(this.element);
6597}
6598});
6599
6600Form.Observer = Class.create(Abstract.TimedObserver, {
6601getValue: function() {
6602	return Form.serialize(this.element);
6603}
6604});
6605
6606/*--------------------------------------------------------------------------*/
6607
6608Abstract.EventObserver = Class.create({
6609initialize: function(element, callback) {
6610	this.element  = $(element);
6611	this.callback = callback;
6612
6613	this.lastValue = this.getValue();
6614	if (this.element.tagName.toLowerCase() == 'form')
6615	this.registerFormCallbacks();
6616	else
6617	this.registerCallback(this.element);
6618},
6619
6620onElementEvent: function() {
6621	var value = this.getValue();
6622	if (this.lastValue != value) {
6623	this.callback(this.element, value);
6624	this.lastValue = value;
6625	}
6626},
6627
6628registerFormCallbacks: function() {
6629	Form.getElements(this.element).each(this.registerCallback, this);
6630},
6631
6632registerCallback: function(element) {
6633	if (element.type) {
6634	switch (element.type.toLowerCase()) {
6635		case 'checkbox':
6636		case 'radio':
6637		Event.observe(element, 'click', this.onElementEvent.bind(this));
6638		break;
6639		default:
6640		Event.observe(element, 'change', this.onElementEvent.bind(this));
6641		break;
6642	}
6643	}
6644}
6645});
6646
6647Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
6648getValue: function() {
6649	return Form.Element.getValue(this.element);
6650}
6651});
6652
6653Form.EventObserver = Class.create(Abstract.EventObserver, {
6654getValue: function() {
6655	return Form.serialize(this.element);
6656}
6657});
6658(function(GLOBAL) {
6659var DIV = document.createElement('div');
6660var docEl = document.documentElement;
6661var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
6662&& 'onmouseleave' in docEl;
6663
6664var Event = {
6665	KEY_BACKSPACE: 8,
6666	KEY_TAB:       9,
6667	KEY_RETURN:   13,
6668	KEY_ESC:      27,
6669	KEY_LEFT:     37,
6670	KEY_UP:       38,
6671	KEY_RIGHT:    39,
6672	KEY_DOWN:     40,
6673	KEY_DELETE:   46,
6674	KEY_HOME:     36,
6675	KEY_END:      35,
6676	KEY_PAGEUP:   33,
6677	KEY_PAGEDOWN: 34,
6678	KEY_INSERT:   45
6679};
6680
6681
6682var isIELegacyEvent = function(event) { return false; };
6683
6684if (window.attachEvent) {
6685	if (window.addEventListener) {
6686	isIELegacyEvent = function(event) {
6687		return !(event instanceof window.Event);
6688	};
6689	} else {
6690	isIELegacyEvent = function(event) { return true; };
6691	}
6692}
6693
6694var _isButton;
6695
6696function _isButtonForDOMEvents(event, code) {
6697	return event.which ? (event.which === code + 1) : (event.button === code);
6698}
6699
6700var legacyButtonMap = { 0: 1, 1: 4, 2: 2 };
6701function _isButtonForLegacyEvents(event, code) {
6702	return event.button === legacyButtonMap[code];
6703}
6704
6705function _isButtonForWebKit(event, code) {
6706	switch (code) {
6707	case 0: return event.which == 1 && !event.metaKey;
6708	case 1: return event.which == 2 || (event.which == 1 && event.metaKey);
6709	case 2: return event.which == 3;
6710	default: return false;
6711	}
6712}
6713
6714if (window.attachEvent) {
6715	if (!window.addEventListener) {
6716	_isButton = _isButtonForLegacyEvents;
6717	} else {
6718	_isButton = function(event, code) {
6719		return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) :
6720		_isButtonForDOMEvents(event, code);
6721	}
6722	}
6723} else if (Prototype.Browser.WebKit) {
6724	_isButton = _isButtonForWebKit;
6725} else {
6726	_isButton = _isButtonForDOMEvents;
6727}
6728
6729function isLeftClick(event)   { return _isButton(event, 0) }
6730
6731function isMiddleClick(event) { return _isButton(event, 1) }
6732
6733function isRightClick(event)  { return _isButton(event, 2) }
6734
6735function element(event) {
6736	return Element.extend(_element(event));
6737}
6738
6739function _element(event) {
6740	event = Event.extend(event);
6741
6742	var node = event.target, type = event.type,
6743	currentTarget = event.currentTarget;
6744
6745	if (currentTarget && currentTarget.tagName) {
6746	if (type === 'load' || type === 'error' ||
6747		(type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
6748		&& currentTarget.type === 'radio'))
6749			node = currentTarget;
6750	}
6751
6752	return node.nodeType == Node.TEXT_NODE ? node.parentNode : node;
6753}
6754
6755function findElement(event, expression) {
6756	var element = _element(event), selector = Prototype.Selector;
6757	if (!expression) return Element.extend(element);
6758	while (element) {
6759	if (Object.isElement(element) && selector.match(element, expression))
6760		return Element.extend(element);
6761	element = element.parentNode;
6762	}
6763}
6764
6765function pointer(event) {
6766	return { x: pointerX(event), y: pointerY(event) };
6767}
6768
6769function pointerX(event) {
6770	var docElement = document.documentElement,
6771	body = document.body || { scrollLeft: 0 };
6772
6773	return event.pageX || (event.clientX +
6774	(docElement.scrollLeft || body.scrollLeft) -
6775	(docElement.clientLeft || 0));
6776}
6777
6778function pointerY(event) {
6779	var docElement = document.documentElement,
6780	body = document.body || { scrollTop: 0 };
6781
6782	return  event.pageY || (event.clientY +
6783	(docElement.scrollTop || body.scrollTop) -
6784	(docElement.clientTop || 0));
6785}
6786
6787
6788function stop(event) {
6789	Event.extend(event);
6790	event.preventDefault();
6791	event.stopPropagation();
6792
6793	event.stopped = true;
6794}
6795
6796
6797Event.Methods = {
6798	isLeftClick:   isLeftClick,
6799	isMiddleClick: isMiddleClick,
6800	isRightClick:  isRightClick,
6801
6802	element:     element,
6803	findElement: findElement,
6804
6805	pointer:  pointer,
6806	pointerX: pointerX,
6807	pointerY: pointerY,
6808
6809	stop: stop
6810};
6811
6812var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
6813	m[name] = Event.Methods[name].methodize();
6814	return m;
6815});
6816
6817if (window.attachEvent) {
6818	function _relatedTarget(event) {
6819	var element;
6820	switch (event.type) {
6821		case 'mouseover':
6822		case 'mouseenter':
6823		element = event.fromElement;
6824		break;
6825		case 'mouseout':
6826		case 'mouseleave':
6827		element = event.toElement;
6828		break;
6829		default:
6830		return null;
6831	}
6832	return Element.extend(element);
6833	}
6834
6835	var additionalMethods = {
6836	stopPropagation: function() { this.cancelBubble = true },
6837	preventDefault:  function() { this.returnValue = false },
6838	inspect: function() { return '[object Event]' }
6839	};
6840
6841	Event.extend = function(event, element) {
6842	if (!event) return false;
6843
6844	if (!isIELegacyEvent(event)) return event;
6845
6846	if (event._extendedByPrototype) return event;
6847	event._extendedByPrototype = Prototype.emptyFunction;
6848
6849	var pointer = Event.pointer(event);
6850
6851	Object.extend(event, {
6852		target: event.srcElement || element,
6853		relatedTarget: _relatedTarget(event),
6854		pageX:  pointer.x,
6855		pageY:  pointer.y
6856	});
6857
6858	Object.extend(event, methods);
6859	Object.extend(event, additionalMethods);
6860
6861	return event;
6862	};
6863} else {
6864	Event.extend = Prototype.K;
6865}
6866
6867if (window.addEventListener) {
6868	Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
6869	Object.extend(Event.prototype, methods);
6870}
6871
6872var EVENT_TRANSLATIONS = {
6873	mouseenter: 'mouseover',
6874	mouseleave: 'mouseout'
6875};
6876
6877function getDOMEventName(eventName) {
6878	return EVENT_TRANSLATIONS[eventName] || eventName;
6879}
6880
6881if (MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED)
6882	getDOMEventName = Prototype.K;
6883
6884function getUniqueElementID(element) {
6885	if (element === window) return 0;
6886
6887	if (typeof element._prototypeUID === 'undefined')
6888	element._prototypeUID = Element.Storage.UID++;
6889	return element._prototypeUID;
6890}
6891
6892function getUniqueElementID_IE(element) {
6893	if (element === window) return 0;
6894	if (element == document) return 1;
6895	return element.uniqueID;
6896}
6897
6898if ('uniqueID' in DIV)
6899	getUniqueElementID = getUniqueElementID_IE;
6900
6901function isCustomEvent(eventName) {
6902	return eventName.include(':');
6903}
6904
6905Event._isCustomEvent = isCustomEvent;
6906
6907function getRegistryForElement(element, uid) {
6908	var CACHE = GLOBAL.Event.cache;
6909	if (Object.isUndefined(uid))
6910	uid = getUniqueElementID(element);
6911	if (!CACHE[uid]) CACHE[uid] = { element: element };
6912	return CACHE[uid];
6913}
6914
6915function destroyRegistryForElement(element, uid) {
6916	if (Object.isUndefined(uid))
6917	uid = getUniqueElementID(element);
6918	delete GLOBAL.Event.cache[uid];
6919}
6920
6921
6922function register(element, eventName, handler) {
6923	var registry = getRegistryForElement(element);
6924	if (!registry[eventName]) registry[eventName] = [];
6925	var entries = registry[eventName];
6926
6927	var i = entries.length;
6928	while (i--)
6929	if (entries[i].handler === handler) return null;
6930
6931	var uid = getUniqueElementID(element);
6932	var responder = GLOBAL.Event._createResponder(uid, eventName, handler);
6933	var entry = {
6934	responder: responder,
6935	handler:   handler
6936	};
6937
6938	entries.push(entry);
6939	return entry;
6940}
6941
6942function unregister(element, eventName, handler) {
6943	var registry = getRegistryForElement(element);
6944	var entries = registry[eventName];
6945	if (!entries) return;
6946
6947	var i = entries.length, entry;
6948	while (i--) {
6949	if (entries[i].handler === handler) {
6950		entry = entries[i];
6951		break;
6952	}
6953	}
6954
6955	if (!entry) return;
6956
6957	var index = entries.indexOf(entry);
6958	entries.splice(index, 1);
6959
6960	return entry;
6961}
6962
6963
6964function observe(element, eventName, handler) {
6965	element = $(element);
6966	var entry = register(element, eventName, handler);
6967
6968	if (entry === null) return element;
6969
6970	var responder = entry.responder;
6971	if (isCustomEvent(eventName))
6972	observeCustomEvent(element, eventName, responder);
6973	else
6974	observeStandardEvent(element, eventName, responder);
6975
6976	return element;
6977}
6978
6979function observeStandardEvent(element, eventName, responder) {
6980	var actualEventName = getDOMEventName(eventName);
6981	if (element.addEventListener) {
6982	element.addEventListener(actualEventName, responder, false);
6983	} else {
6984	element.attachEvent('on' + actualEventName, responder);
6985	}
6986}
6987
6988function observeCustomEvent(element, eventName, responder) {
6989	if (element.addEventListener) {
6990	element.addEventListener('dataavailable', responder, false);
6991	} else {
6992	element.attachEvent('ondataavailable', responder);
6993	element.attachEvent('onlosecapture',   responder);
6994	}
6995}
6996
6997function stopObserving(element, eventName, handler) {
6998	element = $(element);
6999	var handlerGiven = !Object.isUndefined(handler),
7000	eventNameGiven = !Object.isUndefined(eventName);
7001
7002	if (!eventNameGiven && !handlerGiven) {
7003	stopObservingElement(element);
7004	return element;
7005	}
7006
7007	if (!handlerGiven) {
7008	stopObservingEventName(element, eventName);
7009	return element;
7010	}
7011
7012	var entry = unregister(element, eventName, handler);
7013
7014	if (!entry) return element;
7015	removeEvent(element, eventName, entry.responder);
7016	return element;
7017}
7018
7019function stopObservingStandardEvent(element, eventName, responder) {
7020	var actualEventName = getDOMEventName(eventName);
7021	if (element.removeEventListener) {
7022	element.removeEventListener(actualEventName, responder, false);
7023	} else {
7024	element.detachEvent('on' + actualEventName, responder);
7025	}
7026}
7027
7028function stopObservingCustomEvent(element, eventName, responder) {
7029	if (element.removeEventListener) {
7030	element.removeEventListener('dataavailable', responder, false);
7031	} else {
7032	element.detachEvent('ondataavailable', responder);
7033	element.detachEvent('onlosecapture',   responder);
7034	}
7035}
7036
7037
7038
7039function stopObservingElement(element) {
7040	var uid = getUniqueElementID(element), registry = GLOBAL.Event.cache[uid];
7041	if (!registry) return;
7042
7043	destroyRegistryForElement(element, uid);
7044
7045	var entries, i;
7046	for (var eventName in registry) {
7047	if (eventName === 'element') continue;
7048
7049	entries = registry[eventName];
7050	i = entries.length;
7051	while (i--)
7052		removeEvent(element, eventName, entries[i].responder);
7053	}
7054}
7055
7056function stopObservingEventName(element, eventName) {
7057	var registry = getRegistryForElement(element);
7058	var entries = registry[eventName];
7059	if (!entries) return;
7060	delete registry[eventName];
7061
7062	var i = entries.length;
7063	while (i--)
7064	removeEvent(element, eventName, entries[i].responder);
7065}
7066
7067
7068function removeEvent(element, eventName, handler) {
7069	if (isCustomEvent(eventName))
7070	stopObservingCustomEvent(element, eventName, handler);
7071	else
7072	stopObservingStandardEvent(element, eventName, handler);
7073}
7074
7075
7076
7077function getFireTarget(element) {
7078	if (element !== document) return element;
7079	if (document.createEvent && !element.dispatchEvent)
7080	return document.documentElement;
7081	return element;
7082}
7083
7084function fire(element, eventName, memo, bubble) {
7085	element = getFireTarget($(element));
7086	if (Object.isUndefined(bubble)) bubble = true;
7087	memo = memo || {};
7088
7089	var event = fireEvent(element, eventName, memo, bubble);
7090	return Event.extend(event);
7091}
7092
7093function fireEvent_DOM(element, eventName, memo, bubble) {
7094	var event = document.createEvent('HTMLEvents');
7095	event.initEvent('dataavailable', bubble, true);
7096
7097	event.eventName = eventName;
7098	event.memo = memo;
7099
7100	element.dispatchEvent(event);
7101	return event;
7102}
7103
7104function fireEvent_IE(element, eventName, memo, bubble) {
7105	var event = document.createEventObject();
7106	event.eventType = bubble ? 'ondataavailable' : 'onlosecapture';
7107
7108	event.eventName = eventName;
7109	event.memo = memo;
7110
7111	element.fireEvent(event.eventType, event);
7112	return event;
7113}
7114
7115var fireEvent = document.createEvent ? fireEvent_DOM : fireEvent_IE;
7116
7117
7118
7119Event.Handler = Class.create({
7120	initialize: function(element, eventName, selector, callback) {
7121	this.element   = $(element);
7122	this.eventName = eventName;
7123	this.selector  = selector;
7124	this.callback  = callback;
7125	this.handler   = this.handleEvent.bind(this);
7126	},
7127
7128
7129	start: function() {
7130	Event.observe(this.element, this.eventName, this.handler);
7131	return this;
7132	},
7133
7134	stop: function() {
7135	Event.stopObserving(this.element, this.eventName, this.handler);
7136	return this;
7137	},
7138
7139	handleEvent: function(event) {
7140	var element = Event.findElement(event, this.selector);
7141	if (element) this.callback.call(this.element, event, element);
7142	}
7143});
7144
7145function on(element, eventName, selector, callback) {
7146	element = $(element);
7147	if (Object.isFunction(selector) && Object.isUndefined(callback)) {
7148	callback = selector, selector = null;
7149	}
7150
7151	return new Event.Handler(element, eventName, selector, callback).start();
7152}
7153
7154Object.extend(Event, Event.Methods);
7155
7156Object.extend(Event, {
7157	fire:          fire,
7158	observe:       observe,
7159	stopObserving: stopObserving,
7160	on:            on
7161});
7162
7163Element.addMethods({
7164	fire:          fire,
7165
7166	observe:       observe,
7167
7168	stopObserving: stopObserving,
7169
7170	on:            on
7171});
7172
7173Object.extend(document, {
7174	fire:          fire.methodize(),
7175
7176	observe:       observe.methodize(),
7177
7178	stopObserving: stopObserving.methodize(),
7179
7180	on:            on.methodize(),
7181
7182	loaded:        false
7183});
7184
7185if (GLOBAL.Event) Object.extend(window.Event, Event);
7186else GLOBAL.Event = Event;
7187
7188GLOBAL.Event.cache = {};
7189
7190function destroyCache_IE() {
7191	GLOBAL.Event.cache = null;
7192}
7193
7194if (window.attachEvent)
7195	window.attachEvent('onunload', destroyCache_IE);
7196
7197DIV = null;
7198docEl = null;
7199})(this);
7200
7201(function(GLOBAL) {
7202/* Code for creating leak-free event responders is based on work by
7203John-David Dalton. */
7204
7205var docEl = document.documentElement;
7206var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
7207	&& 'onmouseleave' in docEl;
7208
7209function isSimulatedMouseEnterLeaveEvent(eventName) {
7210	return !MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
7211	(eventName === 'mouseenter' || eventName === 'mouseleave');
7212}
7213
7214function createResponder(uid, eventName, handler) {
7215	if (Event._isCustomEvent(eventName))
7216	return createResponderForCustomEvent(uid, eventName, handler);
7217	if (isSimulatedMouseEnterLeaveEvent(eventName))
7218	return createMouseEnterLeaveResponder(uid, eventName, handler);
7219
7220	return function(event) {
7221	if (!Event.cache) return;
7222
7223	var element = Event.cache[uid].element;
7224	Event.extend(event, element);
7225	handler.call(element, event);
7226	};
7227}
7228
7229function createResponderForCustomEvent(uid, eventName, handler) {
7230	return function(event) {
7231	var element = Event.cache[uid].element;
7232
7233	if (Object.isUndefined(event.eventName))
7234		return false;
7235
7236	if (event.eventName !== eventName)
7237		return false;
7238
7239	Event.extend(event, element);
7240	handler.call(element, event);
7241	};
7242}
7243
7244function createMouseEnterLeaveResponder(uid, eventName, handler) {
7245	return function(event) {
7246	var element = Event.cache[uid].element;
7247
7248	Event.extend(event, element);
7249	var parent = event.relatedTarget;
7250
7251	while (parent && parent !== element) {
7252		try { parent = parent.parentNode; }
7253		catch(e) { parent = element; }
7254	}
7255
7256	if (parent === element) return;
7257	handler.call(element, event);
7258	}
7259}
7260
7261GLOBAL.Event._createResponder = createResponder;
7262docEl = null;
7263})(this);
7264
7265(function(GLOBAL) {
7266/* Support for the DOMContentLoaded event is based on work by Dan Webb,
7267	Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
7268
7269var TIMER;
7270
7271function fireContentLoadedEvent() {
7272	if (document.loaded) return;
7273	if (TIMER) window.clearTimeout(TIMER);
7274	document.loaded = true;
7275	document.fire('dom:loaded');
7276}
7277
7278function checkReadyState() {
7279	if (document.readyState === 'complete') {
7280	document.detachEvent('onreadystatechange', checkReadyState);
7281	fireContentLoadedEvent();
7282	}
7283}
7284
7285function pollDoScroll() {
7286	try {
7287	document.documentElement.doScroll('left');
7288	} catch (e) {
7289	TIMER = pollDoScroll.defer();
7290	return;
7291	}
7292
7293	fireContentLoadedEvent();
7294}
7295
7296
7297if (document.readyState === 'complete') {
7298	fireContentLoadedEvent();
7299	return;
7300}
7301
7302if (document.addEventListener) {
7303	document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
7304} else {
7305	document.attachEvent('onreadystatechange', checkReadyState);
7306	if (window == top) TIMER = pollDoScroll.defer();
7307}
7308
7309Event.observe(window, 'load', fireContentLoadedEvent);
7310})(this);
7311
7312
7313Element.addMethods();
7314/*------------------------------- DEPRECATED -------------------------------*/
7315
7316Hash.toQueryString = Object.toQueryString;
7317
7318var Toggle = { display: Element.toggle };
7319
7320Element.Methods.childOf = Element.Methods.descendantOf;
7321
7322var Insertion = {
7323Before: function(element, content) {
7324	return Element.insert(element, {before:content});
7325},
7326
7327Top: function(element, content) {
7328	return Element.insert(element, {top:content});
7329},
7330
7331Bottom: function(element, content) {
7332	return Element.insert(element, {bottom:content});
7333},
7334
7335After: function(element, content) {
7336	return Element.insert(element, {after:content});
7337}
7338};
7339
7340var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
7341
7342var Position = {
7343includeScrollOffsets: false,
7344
7345prepare: function() {
7346	this.deltaX =  window.pageXOffset
7347				|| document.documentElement.scrollLeft
7348				|| document.body.scrollLeft
7349				|| 0;
7350	this.deltaY =  window.pageYOffset
7351				|| document.documentElement.scrollTop
7352				|| document.body.scrollTop
7353				|| 0;
7354},
7355
7356within: function(element, x, y) {
7357	if (this.includeScrollOffsets)
7358	return this.withinIncludingScrolloffsets(element, x, y);
7359	this.xcomp = x;
7360	this.ycomp = y;
7361	this.offset = Element.cumulativeOffset(element);
7362
7363	return (y >= this.offset[1] &&
7364			y <  this.offset[1] + element.offsetHeight &&
7365			x >= this.offset[0] &&
7366			x <  this.offset[0] + element.offsetWidth);
7367},
7368
7369withinIncludingScrolloffsets: function(element, x, y) {
7370	var offsetcache = Element.cumulativeScrollOffset(element);
7371
7372	this.xcomp = x + offsetcache[0] - this.deltaX;
7373	this.ycomp = y + offsetcache[1] - this.deltaY;
7374	this.offset = Element.cumulativeOffset(element);
7375
7376	return (this.ycomp >= this.offset[1] &&
7377			this.ycomp <  this.offset[1] + element.offsetHeight &&
7378			this.xcomp >= this.offset[0] &&
7379			this.xcomp <  this.offset[0] + element.offsetWidth);
7380},
7381
7382overlap: function(mode, element) {
7383	if (!mode) return 0;
7384	if (mode == 'vertical')
7385	return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
7386		element.offsetHeight;
7387	if (mode == 'horizontal')
7388	return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
7389		element.offsetWidth;
7390},
7391
7392
7393cumulativeOffset: Element.Methods.cumulativeOffset,
7394
7395positionedOffset: Element.Methods.positionedOffset,
7396
7397absolutize: function(element) {
7398	Position.prepare();
7399	return Element.absolutize(element);
7400},
7401
7402relativize: function(element) {
7403	Position.prepare();
7404	return Element.relativize(element);
7405},
7406
7407realOffset: Element.Methods.cumulativeScrollOffset,
7408
7409offsetParent: Element.Methods.getOffsetParent,
7410
7411page: Element.Methods.viewportOffset,
7412
7413clone: function(source, target, options) {
7414	options = options || { };
7415	return Element.clonePosition(target, source, options);
7416}
7417};
7418
7419/*--------------------------------------------------------------------------*/
7420
7421if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
7422function iter(name) {
7423	return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
7424}
7425
7426instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
7427function(element, className) {
7428	className = className.toString().strip();
7429	var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
7430	return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
7431} : function(element, className) {
7432	className = className.toString().strip();
7433	var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
7434	if (!classNames && !className) return elements;
7435
7436	var nodes = $(element).getElementsByTagName('*');
7437	className = ' ' + className + ' ';
7438
7439	for (var i = 0, child, cn; child = nodes[i]; i++) {
7440	if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
7441		(classNames && classNames.all(function(name) {
7442			return !name.toString().blank() && cn.include(' ' + name + ' ');
7443		}))))
7444		elements.push(Element.extend(child));
7445	}
7446	return elements;
7447};
7448
7449return function(className, parentElement) {
7450	return $(parentElement || document.body).getElementsByClassName(className);
7451};
7452}(Element.Methods);
7453
7454/*--------------------------------------------------------------------------*/
7455
7456Element.ClassNames = Class.create();
7457Element.ClassNames.prototype = {
7458initialize: function(element) {
7459	this.element = $(element);
7460},
7461
7462_each: function(iterator, context) {
7463	this.element.className.split(/\s+/).select(function(name) {
7464	return name.length > 0;
7465	})._each(iterator, context);
7466},
7467
7468set: function(className) {
7469	this.element.className = className;
7470},
7471
7472add: function(classNameToAdd) {
7473	if (this.include(classNameToAdd)) return;
7474	this.set($A(this).concat(classNameToAdd).join(' '));
7475},
7476
7477remove: function(classNameToRemove) {
7478	if (!this.include(classNameToRemove)) return;
7479	this.set($A(this).without(classNameToRemove).join(' '));
7480},
7481
7482toString: function() {
7483	return $A(this).join(' ');
7484}
7485};
7486
7487Object.extend(Element.ClassNames.prototype, Enumerable);
7488
7489/*--------------------------------------------------------------------------*/
7490
7491(function() {
7492window.Selector = Class.create({
7493	initialize: function(expression) {
7494	this.expression = expression.strip();
7495	},
7496
7497	findElements: function(rootElement) {
7498	return Prototype.Selector.select(this.expression, rootElement);
7499	},
7500
7501	match: function(element) {
7502	return Prototype.Selector.match(element, this.expression);
7503	},
7504
7505	toString: function() {
7506	return this.expression;
7507	},
7508
7509	inspect: function() {
7510	return "#<Selector: " + this.expression + ">";
7511	}
7512});
7513
7514Object.extend(Selector, {
7515	matchElements: function(elements, expression) {
7516	var match = Prototype.Selector.match,
7517		results = [];
7518
7519	for (var i = 0, length = elements.length; i < length; i++) {
7520		var element = elements[i];
7521		if (match(element, expression)) {
7522		results.push(Element.extend(element));
7523		}
7524	}
7525	return results;
7526	},
7527
7528	findElement: function(elements, expression, index) {
7529	index = index || 0;
7530	var matchIndex = 0, element;
7531	for (var i = 0, length = elements.length; i < length; i++) {
7532		element = elements[i];
7533		if (Prototype.Selector.match(element, expression) && index === matchIndex++) {
7534		return Element.extend(element);
7535		}
7536	}
7537	},
7538
7539	findChildElements: function(element, expressions) {
7540	var selector = expressions.toArray().join(', ');
7541	return Prototype.Selector.select(selector, element || document);
7542	}
7543});
7544})();
7545// script.aculo.us scriptaculous.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
7546
7547// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
7548//
7549// Permission is hereby granted, free of charge, to any person obtaining
7550// a copy of this software and associated documentation files (the
7551// "Software"), to deal in the Software without restriction, including
7552// without limitation the rights to use, copy, modify, merge, publish,
7553// distribute, sublicense, and/or sell copies of the Software, and to
7554// permit persons to whom the Software is furnished to do so, subject to
7555// the following conditions:
7556//
7557// The above copyright notice and this permission notice shall be
7558// included in all copies or substantial portions of the Software.
7559//
7560// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
7561// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7562// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
7563// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
7564// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
7565// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
7566// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7567//
7568// For details, see the script.aculo.us web site: http://script.aculo.us/
7569
7570var Scriptaculous = {
7571  Version: '1.8.3',
7572  require: function(libraryName) {
7573    try{
7574      // inserting via DOM fails in Safari 2.0, so brute force approach
7575      document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
7576    } catch(e) {
7577      // for xhtml+xml served content, fall back to DOM methods
7578      var script = document.createElement('script');
7579      script.type = 'text/javascript';
7580      script.src = libraryName;
7581      document.getElementsByTagName('head')[0].appendChild(script);
7582    }
7583  },
7584  REQUIRED_PROTOTYPE: '1.6.0.3',
7585  load: function() {
7586    function convertVersionString(versionString) {
7587      var v = versionString.replace(/_.*|\./g, '');
7588      v = parseInt(v + '0'.times(4-v.length));
7589      return versionString.indexOf('_') > -1 ? v-1 : v;
7590    }
7591
7592    if((typeof Prototype=='undefined') ||
7593       (typeof Element == 'undefined') ||
7594       (typeof Element.Methods=='undefined') ||
7595       (convertVersionString(Prototype.Version) <
7596        convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
7597       throw("script.aculo.us requires the Prototype JavaScript framework >= " +
7598        Scriptaculous.REQUIRED_PROTOTYPE);
7599
7600    var js = /scriptaculous\.js(\?.*)?$/;
7601    $$('head script[src]').findAll(function(s) {
7602      return s.src.match(js);
7603    }).each(function(s) {
7604      var path = s.src.replace(js, ''),
7605      includes = s.src.match(/\?.*load=([a-z,]*)/);
7606      (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
7607       function(include) { Scriptaculous.require(path+include+'.js') });
7608    });
7609  }
7610};
7611
7612Scriptaculous.load();// script.aculo.us effects.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
7613
7614// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
7615// Contributors:
7616//  Justin Palmer (http://encytemedia.com/)
7617//  Mark Pilgrim (http://diveintomark.org/)
7618//  Martin Bialasinki
7619//
7620// script.aculo.us is freely distributable under the terms of an MIT-style license.
7621// For details, see the script.aculo.us web site: http://script.aculo.us/
7622
7623// converts rgb() and #xxx to #xxxxxx format,
7624// returns self (or first argument) if not convertable
7625String.prototype.parseColor = function() {
7626  var color = '#';
7627  if (this.slice(0,4) == 'rgb(') {
7628    var cols = this.slice(4,this.length-1).split(',');
7629    var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
7630  } else {
7631    if (this.slice(0,1) == '#') {
7632      if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
7633      if (this.length==7) color = this.toLowerCase();
7634    }
7635  }
7636  return (color.length==7 ? color : (arguments[0] || this));
7637};
7638
7639/*--------------------------------------------------------------------------*/
7640
7641Element.collectTextNodes = function(element) {
7642  return $A($(element).childNodes).collect( function(node) {
7643    return (node.nodeType==3 ? node.nodeValue :
7644      (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
7645  }).flatten().join('');
7646};
7647
7648Element.collectTextNodesIgnoreClass = function(element, className) {
7649  return $A($(element).childNodes).collect( function(node) {
7650    return (node.nodeType==3 ? node.nodeValue :
7651      ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
7652        Element.collectTextNodesIgnoreClass(node, className) : ''));
7653  }).flatten().join('');
7654};
7655
7656Element.setContentZoom = function(element, percent) {
7657  element = $(element);
7658  element.setStyle({fontSize: (percent/100) + 'em'});
7659  if (Prototype.Browser.WebKit) window.scrollBy(0,0);
7660  return element;
7661};
7662
7663Element.getInlineOpacity = function(element){
7664  return $(element).style.opacity || '';
7665};
7666
7667Element.forceRerendering = function(element) {
7668  try {
7669    element = $(element);
7670    var n = document.createTextNode(' ');
7671    element.appendChild(n);
7672    element.removeChild(n);
7673  } catch(e) { }
7674};
7675
7676/*--------------------------------------------------------------------------*/
7677
7678var Effect = {
7679  _elementDoesNotExistError: {
7680    name: 'ElementDoesNotExistError',
7681    message: 'The specified DOM element does not exist, but is required for this effect to operate'
7682  },
7683  Transitions: {
7684    linear: Prototype.K,
7685    sinoidal: function(pos) {
7686      return (-Math.cos(pos*Math.PI)/2) + .5;
7687    },
7688    reverse: function(pos) {
7689      return 1-pos;
7690    },
7691    flicker: function(pos) {
7692      var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
7693      return pos > 1 ? 1 : pos;
7694    },
7695    wobble: function(pos) {
7696      return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
7697    },
7698    pulse: function(pos, pulses) {
7699      return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
7700    },
7701    spring: function(pos) {
7702      return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
7703    },
7704    none: function(pos) {
7705      return 0;
7706    },
7707    full: function(pos) {
7708      return 1;
7709    }
7710  },
7711  DefaultOptions: {
7712    duration:   1.0,   // seconds
7713    fps:        100,   // 100= assume 66fps max.
7714    sync:       false, // true for combining
7715    from:       0.0,
7716    to:         1.0,
7717    delay:      0.0,
7718    queue:      'parallel'
7719  },
7720  tagifyText: function(element) {
7721    var tagifyStyle = 'position:relative';
7722    if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
7723
7724    element = $(element);
7725    $A(element.childNodes).each( function(child) {
7726      if (child.nodeType==3) {
7727        child.nodeValue.toArray().each( function(character) {
7728          element.insertBefore(
7729            new Element('span', {style: tagifyStyle}).update(
7730              character == ' ' ? String.fromCharCode(160) : character),
7731              child);
7732        });
7733        Element.remove(child);
7734      }
7735    });
7736  },
7737  multiple: function(element, effect) {
7738    var elements;
7739    if (((typeof element == 'object') ||
7740        Object.isFunction(element)) &&
7741       (element.length))
7742      elements = element;
7743    else
7744      elements = $(element).childNodes;
7745
7746    var options = Object.extend({
7747      speed: 0.1,
7748      delay: 0.0
7749    }, arguments[2] || { });
7750    var masterDelay = options.delay;
7751
7752    $A(elements).each( function(element, index) {
7753      new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
7754    });
7755  },
7756  PAIRS: {
7757    'slide':  ['SlideDown','SlideUp'],
7758    'blind':  ['BlindDown','BlindUp'],
7759    'appear': ['Appear','Fade']
7760  },
7761  toggle: function(element, effect, options) {
7762    element = $(element);
7763    effect  = (effect || 'appear').toLowerCase();
7764    
7765    return Effect[ Effect.PAIRS[ effect ][ element.visible() ? 1 : 0 ] ](element, Object.extend({
7766      queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
7767    }, options || {}));
7768  }
7769};
7770
7771Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
7772
7773/* ------------- core effects ------------- */
7774
7775Effect.ScopedQueue = Class.create(Enumerable, {
7776  initialize: function() {
7777    this.effects  = [];
7778    this.interval = null;
7779  },
7780  _each: function(iterator) {
7781    this.effects._each(iterator);
7782  },
7783  add: function(effect) {
7784    var timestamp = new Date().getTime();
7785
7786    var position = Object.isString(effect.options.queue) ?
7787      effect.options.queue : effect.options.queue.position;
7788
7789    switch(position) {
7790      case 'front':
7791        // move unstarted effects after this effect
7792        this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
7793            e.startOn  += effect.finishOn;
7794            e.finishOn += effect.finishOn;
7795          });
7796        break;
7797      case 'with-last':
7798        timestamp = this.effects.pluck('startOn').max() || timestamp;
7799        break;
7800      case 'end':
7801        // start effect after last queued effect has finished
7802        timestamp = this.effects.pluck('finishOn').max() || timestamp;
7803        break;
7804    }
7805
7806    effect.startOn  += timestamp;
7807    effect.finishOn += timestamp;
7808
7809    if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
7810      this.effects.push(effect);
7811
7812    if (!this.interval)
7813      this.interval = setInterval(this.loop.bind(this), 15);
7814  },
7815  remove: function(effect) {
7816    this.effects = this.effects.reject(function(e) { return e==effect });
7817    if (this.effects.length == 0) {
7818      clearInterval(this.interval);
7819      this.interval = null;
7820    }
7821  },
7822  loop: function() {
7823    var timePos = new Date().getTime();
7824    for(var i=0, len=this.effects.length;i<len;i++)
7825      this.effects[i] && this.effects[i].loop(timePos);
7826  }
7827});
7828
7829Effect.Queues = {
7830  instances: $H(),
7831  get: function(queueName) {
7832    if (!Object.isString(queueName)) return queueName;
7833
7834    return this.instances.get(queueName) ||
7835      this.instances.set(queueName, new Effect.ScopedQueue());
7836  }
7837};
7838Effect.Queue = Effect.Queues.get('global');
7839
7840Effect.Base = Class.create({
7841  position: null,
7842  start: function(options) {
7843    if (options && options.transition === false) options.transition = Effect.Transitions.linear;
7844    this.options      = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
7845    this.currentFrame = 0;
7846    this.state        = 'idle';
7847    this.startOn      = this.options.delay*1000;
7848    this.finishOn     = this.startOn+(this.options.duration*1000);
7849    this.fromToDelta  = this.options.to-this.options.from;
7850    this.totalTime    = this.finishOn-this.startOn;
7851    this.totalFrames  = this.options.fps*this.options.duration;
7852
7853    this.render = (function() {
7854      function dispatch(effect, eventName) {
7855        if (effect.options[eventName + 'Internal'])
7856          effect.options[eventName + 'Internal'](effect);
7857        if (effect.options[eventName])
7858          effect.options[eventName](effect);
7859      }
7860
7861      return function(pos) {
7862        if (this.state === "idle") {
7863          this.state = "running";
7864          dispatch(this, 'beforeSetup');
7865          if (this.setup) this.setup();
7866          dispatch(this, 'afterSetup');
7867        }
7868        if (this.state === "running") {
7869          pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from;
7870          this.position = pos;
7871          dispatch(this, 'beforeUpdate');
7872          if (this.update) this.update(pos);
7873          dispatch(this, 'afterUpdate');
7874        }
7875      };
7876    })();
7877
7878    this.event('beforeStart');
7879    if (!this.options.sync)
7880      Effect.Queues.get(Object.isString(this.options.queue) ?
7881        'global' : this.options.queue.scope).add(this);
7882  },
7883  loop: function(timePos) {
7884    if (timePos >= this.startOn) {
7885      if (timePos >= this.finishOn) {
7886        this.render(1.0);
7887        this.cancel();
7888        this.event('beforeFinish');
7889        if (this.finish) this.finish();
7890        this.event('afterFinish');
7891        return;
7892      }
7893      var pos   = (timePos - this.startOn) / this.totalTime,
7894          frame = (pos * this.totalFrames).round();
7895      if (frame > this.currentFrame) {
7896        this.render(pos);
7897        this.currentFrame = frame;
7898      }
7899    }
7900  },
7901  cancel: function() {
7902    if (!this.options.sync)
7903      Effect.Queues.get(Object.isString(this.options.queue) ?
7904        'global' : this.options.queue.scope).remove(this);
7905    this.state = 'finished';
7906  },
7907  event: function(eventName) {
7908    if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
7909    if (this.options[eventName]) this.options[eventName](this);
7910  },
7911  inspect: function() {
7912    var data = $H();
7913    for(property in this)
7914      if (!Object.isFunction(this[property])) data.set(property, this[property]);
7915    return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
7916  }
7917});
7918
7919Effect.Parallel = Class.create(Effect.Base, {
7920  initialize: function(effects) {
7921    this.effects = effects || [];
7922    this.start(arguments[1]);
7923  },
7924  update: function(position) {
7925    this.effects.invoke('render', position);
7926  },
7927  finish: function(position) {
7928    this.effects.each( function(effect) {
7929      effect.render(1.0);
7930      effect.cancel();
7931      effect.event('beforeFinish');
7932      if (effect.finish) effect.finish(position);
7933      effect.event('afterFinish');
7934    });
7935  }
7936});
7937
7938Effect.Tween = Class.create(Effect.Base, {
7939  initialize: function(object, from, to) {
7940    object = Object.isString(object) ? $(object) : object;
7941    var args = $A(arguments), method = args.last(),
7942      options = args.length == 5 ? args[3] : null;
7943    this.method = Object.isFunction(method) ? method.bind(object) :
7944      Object.isFunction(object[method]) ? object[method].bind(object) :
7945      function(value) { object[method] = value };
7946    this.start(Object.extend({ from: from, to: to }, options || { }));
7947  },
7948  update: function(position) {
7949    this.method(position);
7950  }
7951});
7952
7953Effect.Event = Class.create(Effect.Base, {
7954  initialize: function() {
7955    this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
7956  },
7957  update: Prototype.emptyFunction
7958});
7959
7960Effect.Opacity = Class.create(Effect.Base, {
7961  initialize: function(element) {
7962    this.element = $(element);
7963    if (!this.element) throw(Effect._elementDoesNotExistError);
7964    // make this work on IE on elements without 'layout'
7965    if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
7966      this.element.setStyle({zoom: 1});
7967    var options = Object.extend({
7968      from: this.element.getOpacity() || 0.0,
7969      to:   1.0
7970    }, arguments[1] || { });
7971    this.start(options);
7972  },
7973  update: function(position) {
7974    this.element.setOpacity(position);
7975  }
7976});
7977
7978Effect.Move = Class.create(Effect.Base, {
7979  initialize: function(element) {
7980    this.element = $(element);
7981    if (!this.element) throw(Effect._elementDoesNotExistError);
7982    var options = Object.extend({
7983      x:    0,
7984      y:    0,
7985      mode: 'relative'
7986    }, arguments[1] || { });
7987    this.start(options);
7988  },
7989  setup: function() {
7990    this.element.makePositioned();
7991    this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
7992    this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
7993    if (this.options.mode == 'absolute') {
7994      this.options.x = this.options.x - this.originalLeft;
7995      this.options.y = this.options.y - this.originalTop;
7996    }
7997  },
7998  update: function(position) {
7999    this.element.setStyle({
8000      left: (this.options.x  * position + this.originalLeft).round() + 'px',
8001      top:  (this.options.y  * position + this.originalTop).round()  + 'px'
8002    });
8003  }
8004});
8005
8006// for backwards compatibility
8007Effect.MoveBy = function(element, toTop, toLeft) {
8008  return new Effect.Move(element,
8009    Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
8010};
8011
8012Effect.Scale = Class.create(Effect.Base, {
8013  initialize: function(element, percent) {
8014    this.element = $(element);
8015    if (!this.element) throw(Effect._elementDoesNotExistError);
8016    var options = Object.extend({
8017      scaleX: true,
8018      scaleY: true,
8019      scaleContent: true,
8020      scaleFromCenter: false,
8021      scaleMode: 'box',        // 'box' or 'contents' or { } with provided values
8022      scaleFrom: 100.0,
8023      scaleTo:   percent
8024    }, arguments[2] || { });
8025    this.start(options);
8026  },
8027  setup: function() {
8028    this.restoreAfterFinish = this.options.restoreAfterFinish || false;
8029    this.elementPositioning = this.element.getStyle('position');
8030
8031    this.originalStyle = { };
8032    ['top','left','width','height','fontSize'].each( function(k) {
8033      this.originalStyle[k] = this.element.style[k];
8034    }.bind(this));
8035
8036    this.originalTop  = this.element.offsetTop;
8037    this.originalLeft = this.element.offsetLeft;
8038
8039    var fontSize = this.element.getStyle('font-size') || '100%';
8040    ['em','px','%','pt'].each( function(fontSizeType) {
8041      if (fontSize.indexOf(fontSizeType)>0) {
8042        this.fontSize     = parseFloat(fontSize);
8043        this.fontSizeType = fontSizeType;
8044      }
8045    }.bind(this));
8046
8047    this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
8048
8049    this.dims = null;
8050    if (this.options.scaleMode=='box')
8051      this.dims = [this.element.offsetHeight, this.element.offsetWidth];
8052    if (/^content/.test(this.options.scaleMode))
8053      this.dims = [this.element.scrollHeight, this.element.scrollWidth];
8054    if (!this.dims)
8055      this.dims = [this.options.scaleMode.originalHeight,
8056                   this.options.scaleMode.originalWidth];
8057  },
8058  update: function(position) {
8059    var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
8060    if (this.options.scaleContent && this.fontSize)
8061      this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
8062    this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
8063  },
8064  finish: function(position) {
8065    if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
8066  },
8067  setDimensions: function(height, width) {
8068    var d = { };
8069    if (this.options.scaleX) d.width = width.round() + 'px';
8070    if (this.options.scaleY) d.height = height.round() + 'px';
8071    if (this.options.scaleFromCenter) {
8072      var topd  = (height - this.dims[0])/2;
8073      var leftd = (width  - this.dims[1])/2;
8074      if (this.elementPositioning == 'absolute') {
8075        if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
8076        if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
8077      } else {
8078        if (this.options.scaleY) d.top = -topd + 'px';
8079        if (this.options.scaleX) d.left = -leftd + 'px';
8080      }
8081    }
8082    this.element.setStyle(d);
8083  }
8084});
8085
8086Effect.Highlight = Class.create(Effect.Base, {
8087  initialize: function(element) {
8088    this.element = $(element);
8089    if (!this.element) throw(Effect._elementDoesNotExistError);
8090    var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
8091    this.start(options);
8092  },
8093  setup: function() {
8094    // Prevent executing on elements not in the layout flow
8095    if (this.element.getStyle('display')=='none') { this.cancel(); return; }
8096    // Disable background image during the effect
8097    this.oldStyle = { };
8098    if (!this.options.keepBackgroundImage) {
8099      this.oldStyle.backgroundImage = this.element.getStyle('background-image');
8100      this.element.setStyle({backgroundImage: 'none'});
8101    }
8102    if (!this.options.endcolor)
8103      this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
8104    if (!this.options.restorecolor)
8105      this.options.restorecolor = this.element.getStyle('background-color');
8106    // init color calculations
8107    this._base  = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
8108    this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
8109  },
8110  update: function(position) {
8111    this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
8112      return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
8113  },
8114  finish: function() {
8115    this.element.setStyle(Object.extend(this.oldStyle, {
8116      backgroundColor: this.options.restorecolor
8117    }));
8118  }
8119});
8120
8121Effect.ScrollTo = function(element) {
8122  var options = arguments[1] || { },
8123  scrollOffsets = document.viewport.getScrollOffsets(),
8124  elementOffsets = $(element).cumulativeOffset();
8125
8126  if (options.offset) elementOffsets[1] += options.offset;
8127
8128  return new Effect.Tween(null,
8129    scrollOffsets.top,
8130    elementOffsets[1],
8131    options,
8132    function(p){ scrollTo(scrollOffsets.left, p.round()); }
8133  );
8134};
8135
8136/* ------------- combination effects ------------- */
8137
8138Effect.Fade = function(element) {
8139  element = $(element);
8140  var oldOpacity = element.getInlineOpacity();
8141  var options = Object.extend({
8142    from: element.getOpacity() || 1.0,
8143    to:   0.0,
8144    afterFinishInternal: function(effect) {
8145      if (effect.options.to!=0) return;
8146      effect.element.hide().setStyle({opacity: oldOpacity});
8147    }
8148  }, arguments[1] || { });
8149  return new Effect.Opacity(element,options);
8150};
8151
8152Effect.Appear = function(element) {
8153  element = $(element);
8154  var options = Object.extend({
8155  from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
8156  to:   1.0,
8157  // force Safari to render floated elements properly
8158  afterFinishInternal: function(effect) {
8159    effect.element.forceRerendering();
8160  },
8161  beforeSetup: function(effect) {
8162    effect.element.setOpacity(effect.options.from).show();
8163  }}, arguments[1] || { });
8164  return new Effect.Opacity(element,options);
8165};
8166
8167Effect.Puff = function(element) {
8168  element = $(element);
8169  var oldStyle = {
8170    opacity: element.getInlineOpacity(),
8171    position: element.getStyle('position'),
8172    top:  element.style.top,
8173    left: element.style.left,
8174    width: element.style.width,
8175    height: element.style.height
8176  };
8177  return new Effect.Parallel(
8178   [ new Effect.Scale(element, 200,
8179      { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
8180     new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
8181     Object.extend({ duration: 1.0,
8182      beforeSetupInternal: function(effect) {
8183        Position.absolutize(effect.effects[0].element);
8184      },
8185      afterFinishInternal: function(effect) {
8186         effect.effects[0].element.hide().setStyle(oldStyle); }
8187     }, arguments[1] || { })
8188   );
8189};
8190
8191Effect.BlindUp = function(element) {
8192  element = $(element);
8193  element.makeClipping();
8194  return new Effect.Scale(element, 0,
8195    Object.extend({ scaleContent: false,
8196      scaleX: false,
8197      restoreAfterFinish: true,
8198      afterFinishInternal: function(effect) {
8199        effect.element.hide().undoClipping();
8200      }
8201    }, arguments[1] || { })
8202  );
8203};
8204
8205Effect.BlindDown = function(element) {
8206  element = $(element);
8207  var elementDimensions = element.getDimensions();
8208  return new Effect.Scale(element, 100, Object.extend({
8209    scaleContent: false,
8210    scaleX: false,
8211    scaleFrom: 0,
8212    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
8213    restoreAfterFinish: true,
8214    afterSetup: function(effect) {
8215      effect.element.makeClipping().setStyle({height: '0px'}).show();
8216    },
8217    afterFinishInternal: function(effect) {
8218      effect.element.undoClipping();
8219    }
8220  }, arguments[1] || { }));
8221};
8222
8223Effect.SwitchOff = function(element) {
8224  element = $(element);
8225  var oldOpacity = element.getInlineOpacity();
8226  return new Effect.Appear(element, Object.extend({
8227    duration: 0.4,
8228    from: 0,
8229    transition: Effect.Transitions.flicker,
8230    afterFinishInternal: function(effect) {
8231      new Effect.Scale(effect.element, 1, {
8232        duration: 0.3, scaleFromCenter: true,
8233        scaleX: false, scaleContent: false, restoreAfterFinish: true,
8234        beforeSetup: function(effect) {
8235          effect.element.makePositioned().makeClipping();
8236        },
8237        afterFinishInternal: function(effect) {
8238          effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
8239        }
8240      });
8241    }
8242  }, arguments[1] || { }));
8243};
8244
8245Effect.DropOut = function(element) {
8246  element = $(element);
8247  var oldStyle = {
8248    top: element.getStyle('top'),
8249    left: element.getStyle('left'),
8250    opacity: element.getInlineOpacity() };
8251  return new Effect.Parallel(
8252    [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
8253      new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
8254    Object.extend(
8255      { duration: 0.5,
8256        beforeSetup: function(effect) {
8257          effect.effects[0].element.makePositioned();
8258        },
8259        afterFinishInternal: function(effect) {
8260          effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
8261        }
8262      }, arguments[1] || { }));
8263};
8264
8265Effect.Shake = function(element) {
8266  element = $(element);
8267  var options = Object.extend({
8268    distance: 20,
8269    duration: 0.5
8270  }, arguments[1] || {});
8271  var distance = parseFloat(options.distance);
8272  var split = parseFloat(options.duration) / 10.0;
8273  var oldStyle = {
8274    top: element.getStyle('top'),
8275    left: element.getStyle('left') };
8276    return new Effect.Move(element,
8277      { x:  distance, y: 0, duration: split, afterFinishInternal: function(effect) {
8278    new Effect.Move(effect.element,
8279      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
8280    new Effect.Move(effect.element,
8281      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
8282    new Effect.Move(effect.element,
8283      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
8284    new Effect.Move(effect.element,
8285      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
8286    new Effect.Move(effect.element,
8287      { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
8288        effect.element.undoPositioned().setStyle(oldStyle);
8289  }}); }}); }}); }}); }}); }});
8290};
8291
8292Effect.SlideDown = function(element) {
8293  element = $(element).cleanWhitespace();
8294  // SlideDown need to have the content of the element wrapped in a container element with fixed height!
8295  var oldInnerBottom = element.down().getStyle('bottom');
8296  var elementDimensions = element.getDimensions();
8297  return new Effect.Scale(element, 100, Object.extend({
8298    scaleContent: false,
8299    scaleX: false,
8300    scaleFrom: window.opera ? 0 : 1,
8301    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
8302    restoreAfterFinish: true,
8303    afterSetup: function(effect) {
8304      effect.element.makePositioned();
8305      effect.element.down().makePositioned();
8306      if (window.opera) effect.element.setStyle({top: ''});
8307      effect.element.makeClipping().setStyle({height: '0px'}).show();
8308    },
8309    afterUpdateInternal: function(effect) {
8310      effect.element.down().setStyle({bottom:
8311        (effect.dims[0] - effect.element.clientHeight) + 'px' });
8312    },
8313    afterFinishInternal: function(effect) {
8314      effect.element.undoClipping().undoPositioned();
8315      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
8316    }, arguments[1] || { })
8317  );
8318};
8319
8320Effect.SlideUp = function(element) {
8321  element = $(element).cleanWhitespace();
8322  var oldInnerBottom = element.down().getStyle('bottom');
8323  var elementDimensions = element.getDimensions();
8324  return new Effect.Scale(element, window.opera ? 0 : 1,
8325   Object.extend({ scaleContent: false,
8326    scaleX: false,
8327    scaleMode: 'box',
8328    scaleFrom: 100,
8329    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
8330    restoreAfterFinish: true,
8331    afterSetup: function(effect) {
8332      effect.element.makePositioned();
8333      effect.element.down().makePositioned();
8334      if (window.opera) effect.element.setStyle({top: ''});
8335      effect.element.makeClipping().show();
8336    },
8337    afterUpdateInternal: function(effect) {
8338      effect.element.down().setStyle({bottom:
8339        (effect.dims[0] - effect.element.clientHeight) + 'px' });
8340    },
8341    afterFinishInternal: function(effect) {
8342      effect.element.hide().undoClipping().undoPositioned();
8343      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
8344    }
8345   }, arguments[1] || { })
8346  );
8347};
8348
8349// Bug in opera makes the TD containing this element expand for a instance after finish
8350Effect.Squish = function(element) {
8351  return new Effect.Scale(element, window.opera ? 1 : 0, {
8352    restoreAfterFinish: true,
8353    beforeSetup: function(effect) {
8354      effect.element.makeClipping();
8355    },
8356    afterFinishInternal: function(effect) {
8357      effect.element.hide().undoClipping();
8358    }
8359  });
8360};
8361
8362Effect.Grow = function(element) {
8363  element = $(element);
8364  var options = Object.extend({
8365    direction: 'center',
8366    moveTransition: Effect.Transitions.sinoidal,
8367    scaleTransition: Effect.Transitions.sinoidal,
8368    opacityTransition: Effect.Transitions.full
8369  }, arguments[1] || { });
8370  var oldStyle = {
8371    top: element.style.top,
8372    left: element.style.left,
8373    height: element.style.height,
8374    width: element.style.width,
8375    opacity: element.getInlineOpacity() };
8376
8377  var dims = element.getDimensions();
8378  var initialMoveX, initialMoveY;
8379  var moveX, moveY;
8380
8381  switch (options.direction) {
8382    case 'top-left':
8383      initialMoveX = initialMoveY = moveX = moveY = 0;
8384      break;
8385    case 'top-right':
8386      initialMoveX = dims.width;
8387      initialMoveY = moveY = 0;
8388      moveX = -dims.width;
8389      break;
8390    case 'bottom-left':
8391      initialMoveX = moveX = 0;
8392      initialMoveY = dims.height;
8393      moveY = -dims.height;
8394      break;
8395    case 'bottom-right':
8396      initialMoveX = dims.width;
8397      initialMoveY = dims.height;
8398      moveX = -dims.width;
8399      moveY = -dims.height;
8400      break;
8401    case 'center':
8402      initialMoveX = dims.width / 2;
8403      initialMoveY = dims.height / 2;
8404      moveX = -dims.width / 2;
8405      moveY = -dims.height / 2;
8406      break;
8407  }
8408
8409  return new Effect.Move(element, {
8410    x: initialMoveX,
8411    y: initialMoveY,
8412    duration: 0.01,
8413    beforeSetup: function(effect) {
8414      effect.element.hide().makeClipping().makePositioned();
8415    },
8416    afterFinishInternal: function(effect) {
8417      new Effect.Parallel(
8418        [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
8419          new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
8420          new Effect.Scale(effect.element, 100, {
8421            scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
8422            sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
8423        ], Object.extend({
8424             beforeSetup: function(effect) {
8425               effect.effects[0].element.setStyle({height: '0px'}).show();
8426             },
8427             afterFinishInternal: function(effect) {
8428               effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
8429             }
8430           }, options)
8431      );
8432    }
8433  });
8434};
8435
8436Effect.Shrink = function(element) {
8437  element = $(element);
8438  var options = Object.extend({
8439    direction: 'center',
8440    moveTransition: Effect.Transitions.sinoidal,
8441    scaleTransition: Effect.Transitions.sinoidal,
8442    opacityTransition: Effect.Transitions.none
8443  }, arguments[1] || { });
8444  var oldStyle = {
8445    top: element.style.top,
8446    left: element.style.left,
8447    height: element.style.height,
8448    width: element.style.width,
8449    opacity: element.getInlineOpacity() };
8450
8451  var dims = element.getDimensions();
8452  var moveX, moveY;
8453
8454  switch (options.direction) {
8455    case 'top-left':
8456      moveX = moveY = 0;
8457      break;
8458    case 'top-right':
8459      moveX = dims.width;
8460      moveY = 0;
8461      break;
8462    case 'bottom-left':
8463      moveX = 0;
8464      moveY = dims.height;
8465      break;
8466    case 'bottom-right':
8467      moveX = dims.width;
8468      moveY = dims.height;
8469      break;
8470    case 'center':
8471      moveX = dims.width / 2;
8472      moveY = dims.height / 2;
8473      break;
8474  }
8475
8476  return new Effect.Parallel(
8477    [ new Effect.Opacity(elemen
8477t, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
8478      new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
8479      new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
8480    ], Object.extend({
8481         beforeStartInternal: function(effect) {
8482           effect.effects[0].element.makePositioned().makeClipping();
8483         },
8484         afterFinishInternal: function(effect) {
8485           effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
8486       }, options)
8487  );
8488};
8489
8490Effect.Pulsate = function(element) {
8491  element = $(element);
8492  var options    = arguments[1] || { },
8493    oldOpacity = element.getInlineOpacity(),
8494    transition = options.transition || Effect.Transitions.linear,
8495    reverser   = function(pos){
8496      return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5);
8497    };
8498
8499  return new Effect.Opacity(element,
8500    Object.extend(Object.extend({  duration: 2.0, from: 0,
8501      afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
8502    }, options), {transition: reverser}));
8503};
8504
8505Effect.Fold = function(element) {
8506  element = $(element);
8507  var oldStyle = {
8508    top: element.style.top,
8509    left: element.style.left,
8510    width: element.style.width,
8511    height: element.style.height };
8512  element.makeClipping();
8513  return new Effect.Scale(element, 5, Object.extend({
8514    scaleContent: false,
8515    scaleX: false,
8516    afterFinishInternal: function(effect) {
8517    new Effect.Scale(element, 1, {
8518      scaleContent: false,
8519      scaleY: false,
8520      afterFinishInternal: function(effect) {
8521        effect.element.hide().undoClipping().setStyle(oldStyle);
8522      } });
8523  }}, arguments[1] || { }));
8524};
8525
8526Effect.Morph = Class.create(Effect.Base, {
8527  initialize: function(element) {
8528    this.element = $(element);
8529    if (!this.element) throw(Effect._elementDoesNotExistError);
8530    var options = Object.extend({
8531      style: { }
8532    }, arguments[1] || { });
8533
8534    if (!Object.isString(options.style)) this.style = $H(options.style);
8535    else {
8536      if (options.style.include(':'))
8537        this.style = options.style.parseStyle();
8538      else {
8539        this.element.addClassName(options.style);
8540        this.style = $H(this.element.getStyles());
8541        this.element.removeClassName(options.style);
8542        var css = this.element.getStyles();
8543        this.style = this.style.reject(function(style) {
8544          return style.value == css[style.key];
8545        });
8546        options.afterFinishInternal = function(effect) {
8547          effect.element.addClassName(effect.options.style);
8548          effect.transforms.each(function(transform) {
8549            effect.element.style[transform.style] = '';
8550          });
8551        };
8552      }
8553    }
8554    this.start(options);
8555  },
8556
8557  setup: function(){
8558    function parseColor(color){
8559      if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
8560      color = color.parseColor();
8561      return $R(0,2).map(function(i){
8562        return parseInt( color.slice(i*2+1,i*2+3), 16 );
8563      });
8564    }
8565    this.transforms = this.style.map(function(pair){
8566      var property = pair[0], value = pair[1], unit = null;
8567
8568      if (value.parseColor('#zzzzzz') != '#zzzzzz') {
8569        value = value.parseColor();
8570        unit  = 'color';
8571      } else if (property == 'opacity') {
8572        value = parseFloat(value);
8573        if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
8574          this.element.setStyle({zoom: 1});
8575      } else if (Element.CSS_LENGTH.test(value)) {
8576          var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
8577          value = parseFloat(components[1]);
8578          unit = (components.length == 3) ? components[2] : null;
8579      }
8580
8581      var originalValue = this.element.getStyle(property);
8582      return {
8583        style: property.camelize(),
8584        originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
8585        targetValue: unit=='color' ? parseColor(value) : value,
8586        unit: unit
8587      };
8588    }.bind(this)).reject(function(transform){
8589      return (
8590        (transform.originalValue == transform.targetValue) ||
8591        (
8592          transform.unit != 'color' &&
8593          (isNaN(transform.originalValue) || isNaN(transform.targetValue))
8594        )
8595      );
8596    });
8597  },
8598  update: function(position) {
8599    var style = { }, transform, i = this.transforms.length;
8600    while(i--)
8601      style[(transform = this.transforms[i]).style] =
8602        transform.unit=='color' ? '#'+
8603          (Math.round(transform.originalValue[0]+
8604            (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
8605          (Math.round(transform.originalValue[1]+
8606            (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
8607          (Math.round(transform.originalValue[2]+
8608            (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
8609        (transform.originalValue +
8610          (transform.targetValue - transform.originalValue) * position).toFixed(3) +
8611            (transform.unit === null ? '' : transform.unit);
8612    this.element.setStyle(style, true);
8613  }
8614});
8615
8616Effect.Transform = Class.create({
8617  initialize: function(tracks){
8618    this.tracks  = [];
8619    this.options = arguments[1] || { };
8620    this.addTracks(tracks);
8621  },
8622  addTracks: function(tracks){
8623    tracks.each(function(track){
8624      track = $H(track);
8625      var data = track.values().first();
8626      this.tracks.push($H({
8627        ids:     track.keys().first(),
8628        effect:  Effect.Morph,
8629        options: { style: data }
8630      }));
8631    }.bind(this));
8632    return this;
8633  },
8634  play: function(){
8635    return new Effect.Parallel(
8636      this.tracks.map(function(track){
8637        var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
8638        var elements = [$(ids) || $$(ids)].flatten();
8639        return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
8640      }).flatten(),
8641      this.options
8642    );
8643  }
8644});
8645
8646Element.CSS_PROPERTIES = $w(
8647  'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
8648  'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
8649  'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
8650  'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
8651  'fontSize fontWeight height left letterSpacing lineHeight ' +
8652  'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
8653  'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
8654  'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
8655  'right textIndent top width wordSpacing zIndex');
8656
8657Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
8658
8659String.__parseStyleElement = document.createElement('div');
8660String.prototype.parseStyle = function(){
8661  var style, styleRules = $H();
8662  if (Prototype.Browser.WebKit)
8663    style = new Element('div',{style:this}).style;
8664  else {
8665    String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
8666    style = String.__parseStyleElement.childNodes[0].style;
8667  }
8668
8669  Element.CSS_PROPERTIES.each(function(property){
8670    if (style[property]) styleRules.set(property, style[property]);
8671  });
8672
8673  if (Prototype.Browser.IE && this.include('opacity'))
8674    styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
8675
8676  return styleRules;
8677};
8678
8679if (document.defaultView && document.defaultView.getComputedStyle) {
8680  Element.getStyles = function(element) {
8681    var css = document.defaultView.getComputedStyle($(element), null);
8682    return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
8683      styles[property] = css[property];
8684      return styles;
8685    });
8686  };
8687} else {
8688  Element.getStyles = function(element) {
8689    element = $(element);
8690    var css = element.currentStyle, styles;
8691    styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
8692      results[property] = css[property];
8693      return results;
8694    });
8695    if (!styles.opacity) styles.opacity = element.getOpacity();
8696    return styles;
8697  };
8698}
8699
8700Effect.Methods = {
8701  morph: function(element, style) {
8702    element = $(element);
8703    new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
8704    return element;
8705  },
8706  visualEffect: function(element, effect, options) {
8707    element = $(element);
8708    var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
8709    new Effect[klass](element, options);
8710    return element;
8711  },
8712  highlight: function(element, options) {
8713    element = $(element);
8714    new Effect.Highlight(element, options);
8715    return element;
8716  }
8717};
8718
8719$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
8720  'pulsate shake puff squish switchOff dropOut').each(
8721  function(effect) {
8722    Effect.Methods[effect] = function(element, options){
8723      element = $(element);
8724      Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
8725      return element;
8726    };
8727  }
8728);
8729
8730$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
8731  function(f) { Effect.Methods[f] = Element[f]; }
8732);
8733
8734Element.addMethods(Effect.Methods);// script.aculo.us dragdrop.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
8735
8736// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
8737//
8738// script.aculo.us is freely distributable under the terms of an MIT-style license.
8739// For details, see the script.aculo.us web site: http://script.aculo.us/
8740
8741if(Object.isUndefined(Effect))
8742  throw("dragdrop.js requires including script.aculo.us' effects.js library");
8743
8744var Droppables = {
8745  drops: [],
8746
8747  remove: function(element) {
8748    this.drops = this.drops.reject(function(d) { return d.element==$(element) });
8749  },
8750
8751  add: function(element) {
8752    element = $(element);
8753    var options = Object.extend({
8754      greedy:     true,
8755      hoverclass: null,
8756      tree:       false
8757    }, arguments[1] || { });
8758
8759    // cache containers
8760    if(options.containment) {
8761      options._containers = [];
8762      var containment = options.containment;
8763      if(Object.isArray(containment)) {
8764        containment.each( function(c) { options._containers.push($(c)) });
8765      } else {
8766        options._containers.push($(containment));
8767      }
8768    }
8769
8770    if(options.accept) options.accept = [options.accept].flatten();
8771
8772    Element.makePositioned(element); // fix IE
8773    options.element = element;
8774
8775    this.drops.push(options);
8776  },
8777
8778  findDeepestChild: function(drops) {
8779    deepest = drops[0];
8780
8781    for (i = 1; i < drops.length; ++i)
8782      if (Element.isParent(drops[i].element, deepest.element))
8783        deepest = drops[i];
8784
8785    return deepest;
8786  },
8787
8788  isContained: function(element, drop) {
8789    var containmentNode;
8790    if(drop.tree) {
8791      containmentNode = element.treeNode;
8792    } else {
8793      containmentNode = element.parentNode;
8794    }
8795    return drop._containers.detect(function(c) { return containmentNode == c });
8796  },
8797
8798  isAffected: function(point, element, drop) {
8799    return (
8800      (drop.element!=element) &&
8801      ((!drop._containers) ||
8802        this.isContained(element, drop)) &&
8803      ((!drop.accept) ||
8804        (Element.classNames(element).detect(
8805          function(v) { return drop.accept.include(v) } ) )) &&
8806      Position.within(drop.element, point[0], point[1]) );
8807  },
8808
8809  deactivate: function(drop) {
8810    if(drop.hoverclass)
8811      Element.removeClassName(drop.element, drop.hoverclass);
8812    this.last_active = null;
8813  },
8814
8815  activate: function(drop) {
8816    if(drop.hoverclass)
8817      Element.addClassName(drop.element, drop.hoverclass);
8818    this.last_active = drop;
8819  },
8820
8821  show: function(point, element) {
8822    if(!this.drops.length) return;
8823    var drop, affected = [];
8824
8825    this.drops.each( function(drop) {
8826      if(Droppables.isAffected(point, element, drop))
8827        affected.push(drop);
8828    });
8829
8830    if(affected.length>0)
8831      drop = Droppables.findDeepestChild(affected);
8832
8833    if(this.last_active && this.last_active != drop) this.deactivate(this.last_active);
8834    if (drop) {
8835      Position.within(drop.element, point[0], point[1]);
8836      if(drop.onHover)
8837        drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
8838
8839      if (drop != this.last_active) Droppables.activate(drop);
8840    }
8841  },
8842
8843  fire: function(event, element) {
8844    if(!this.last_active) return;
8845    Position.prepare();
8846
8847    if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
8848      if (this.last_active.onDrop) {
8849        this.last_active.onDrop(element, this.last_active.element, event);
8850        return true;
8851      }
8852  },
8853
8854  reset: function() {
8855    if(this.last_active)
8856      this.deactivate(this.last_active);
8857  }
8858};
8859
8860var Draggables = {
8861  drags: [],
8862  observers: [],
8863
8864  register: function(draggable) {
8865    if(this.drags.length == 0) {
8866      this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
8867      this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
8868      this.eventKeypress  = this.keyPress.bindAsEventListener(this);
8869
8870      Event.observe(document, "mouseup", this.eventMouseUp);
8871      Event.observe(document, "mousemove", this.eventMouseMove);
8872      Event.observe(document, "keypress", this.eventKeypress);
8873    }
8874    this.drags.push(draggable);
8875  },
8876
8877  unregister: function(draggable) {
8878    this.drags = this.drags.reject(function(d) { return d==draggable });
8879    if(this.drags.length == 0) {
8880      Event.stopObserving(document, "mouseup", this.eventMouseUp);
8881      Event.stopObserving(document, "mousemove", this.eventMouseMove);
8882      Event.stopObserving(document, "keypress", this.eventKeypress);
8883    }
8884  },
8885
8886  activate: function(draggable) {
8887    if(draggable.options.delay) {
8888      this._timeout = setTimeout(function() {
8889        Draggables._timeout = null;
8890        window.focus();
8891        Draggables.activeDraggable = draggable;
8892      }.bind(this), draggable.options.delay);
8893    } else {
8894      window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
8895      this.activeDraggable = draggable;
8896    }
8897  },
8898
8899  deactivate: function() {
8900    this.activeDraggable = null;
8901  },
8902
8903  updateDrag: function(event) {
8904    if(!this.activeDraggable) return;
8905    var pointer = [Event.pointerX(event), Event.pointerY(event)];
8906    // Mozilla-based browsers fire successive mousemove events with
8907    // the same coordinates, prevent needless redrawing (moz bug?)
8908    if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
8909    this._lastPointer = pointer;
8910
8911    this.activeDraggable.updateDrag(event, pointer);
8912  },
8913
8914  endDrag: function(event) {
8915    if(this._timeout) {
8916      clearTimeout(this._timeout);
8917      this._timeout = null;
8918    }
8919    if(!this.activeDraggable) return;
8920    this._lastPointer = null;
8921    this.activeDraggable.endDrag(event);
8922    this.activeDraggable = null;
8923  },
8924
8925  keyPress: function(event) {
8926    if(this.activeDraggable)
8927      this.activeDraggable.keyPress(event);
8928  },
8929
8930  addObserver: function(observer) {
8931    this.observers.push(observer);
8932    this._cacheObserverCallbacks();
8933  },
8934
8935  removeObserver: function(element) {  // element instead of observer fixes mem leaks
8936    this.observers = this.observers.reject( function(o) { return o.element==element });
8937    this._cacheObserverCallbacks();
8938  },
8939
8940  notify: function(eventName, draggable, event) {  // 'onStart', 'onEnd', 'onDrag'
8941    if(this[eventName+'Count'] > 0)
8942      this.observers.each( function(o) {
8943        if(o[eventName]) o[eventName](eventName, draggable, event);
8944      });
8945    if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
8946  },
8947
8948  _cacheObserverCallbacks: function() {
8949    ['onStart','onEnd','onDrag'].each( function(eventName) {
8950      Draggables[eventName+'Count'] = Draggables.observers.select(
8951        function(o) { return o[eventName]; }
8952      ).length;
8953    });
8954  }
8955};
8956
8957/*--------------------------------------------------------------------------*/
8958
8959var Draggable = Class.create({
8960  initialize: function(element) {
8961    var defaults = {
8962      handle: false,
8963      reverteffect: function(element, top_offset, left_offset) {
8964        var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
8965        new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
8966          queue: {scope:'_draggable', position:'end'}
8967        });
8968      },
8969      endeffect: function(element) {
8970        var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
8971        new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
8972          queue: {scope:'_draggable', position:'end'},
8973          afterFinish: function(){
8974            Draggable._dragging[element] = false
8975          }
8976        });
8977      },
8978      zindex: 1000,
8979      revert: false,
8980      quiet: false,
8981      scroll: false,
8982      scrollSensitivity: 20,
8983      scrollSpeed: 15,
8984      snap: false,  // false, or xy or [x,y] or function(x,y){ return [x,y] }
8985      delay: 0
8986    };
8987
8988    if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
8989      Object.extend(defaults, {
8990        starteffect: function(element) {
8991          element._opacity = Element.getOpacity(element);
8992          Draggable._dragging[element] = true;
8993          new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
8994        }
8995      });
8996
8997    var options = Object.extend(defaults, arguments[1] || { });
8998
8999    this.element = $(element);
9000
9001    if(options.handle && Object.isString(options.handle))
9002      this.handle = this.element.down('.'+options.handle, 0);
9003
9004    if(!this.handle) this.handle = $(options.handle);
9005    if(!this.handle) this.handle = this.element;
9006
9007    if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
9008      options.scroll = $(options.scroll);
9009      this._isScrollChild = Element.childOf(this.element, options.scroll);
9010    }
9011
9012    Element.makePositioned(this.element); // fix IE
9013
9014    this.options  = options;
9015    this.dragging = false;
9016
9017    this.eventMouseDown = this.initDrag.bindAsEventListener(this);
9018    Event.observe(this.handle, "mousedown", this.eventMouseDown);
9019
9020    Draggables.register(this);
9021  },
9022
9023  destroy: function() {
9024    Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
9025    Draggables.unregister(this);
9026  },
9027
9028  currentDelta: function() {
9029    return([
9030      parseInt(Element.getStyle(this.element,'left') || '0'),
9031      parseInt(Element.getStyle(this.element,'top') || '0')]);
9032  },
9033
9034  initDrag: function(event) {
9035    if(!Object.isUndefined(Draggable._dragging[this.element]) &&
9036      Draggable._dragging[this.element]) return;
9037    if(Event.isLeftClick(event)) {
9038      // abort on form elements, fixes a Firefox issue
9039      var src = Event.element(event);
9040      if((tag_name = src.tagName.toUpperCase()) && (
9041        tag_name=='INPUT' ||
9042        tag_name=='SELECT' ||
9043        tag_name=='OPTION' ||
9044        tag_name=='BUTTON' ||
9045        tag_name=='TEXTAREA')) return;
9046
9047      var pointer = [Event.pointerX(event), Event.pointerY(event)];
9048      var pos     = this.element.cumulativeOffset();
9049      this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
9050
9051      Draggables.activate(this);
9052      Event.stop(event);
9053    }
9054  },
9055
9056  startDrag: function(event) {
9057    this.dragging = true;
9058    if(!this.delta)
9059      this.delta = this.currentDelta();
9060
9061    if(this.options.zindex) {
9062      this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
9063      this.element.style.zIndex = this.options.zindex;
9064    }
9065
9066    if(this.options.ghosting) {
9067      this._clone = this.element.cloneNode(true);
9068      this._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
9069      if (!this._originallyAbsolute)
9070        Position.absolutize(this.element);
9071      this.element.parentNode.insertBefore(this._clone, this.element);
9072    }
9073
9074    if(this.options.scroll) {
9075      if (this.options.scroll == window) {
9076        var where = this._getWindowScroll(this.options.scroll);
9077        this.originalScrollLeft = where.left;
9078        this.originalScrollTop = where.top;
9079      } else {
9080        this.originalScrollLeft = this.options.scroll.scrollLeft;
9081        this.originalScrollTop = this.options.scroll.scrollTop;
9082      }
9083    }
9084
9085    Draggables.notify('onStart', this, event);
9086
9087    if(this.options.starteffect) this.options.starteffect(this.element);
9088  },
9089
9090  updateDrag: function(event, pointer) {
9091    if(!this.dragging) this.startDrag(event);
9092
9093    if(!this.options.quiet){
9094      Position.prepare();
9095      Droppables.show(pointer, this.element);
9096    }
9097
9098    Draggables.notify('onDrag', this, event);
9099
9100    this.draw(pointer);
9101    if(this.options.change) this.options.change(this);
9102
9103    if(this.options.scroll) {
9104      this.stopScrolling();
9105
9106      var p;
9107      if (this.options.scroll == window) {
9108        with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
9109      } else {
9110        p = Position.page(this.options.scroll);
9111        p[0] += this.options.scroll.scrollLeft + Position.deltaX;
9112        p[1] += this.options.scroll.scrollTop + Position.deltaY;
9113        p.push(p[0]+this.options.scroll.offsetWidth);
9114        p.push(p[1]+this.options.scroll.offsetHeight);
9115      }
9116      var speed = [0,0];
9117      if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity);
9118      if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity);
9119      if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity);
9120      if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
9121      this.startScrolling(speed);
9122    }
9123
9124    // fix AppleWebKit rendering
9125    if(Prototype.Browser.WebKit) window.scrollBy(0,0);
9126
9127    Event.stop(event);
9128  },
9129
9130  finishDrag: function(event, success) {
9131    this.dragging = false;
9132
9133    if(this.options.quiet){
9134      Position.prepare();
9135      var pointer = [Event.pointerX(event), Event.pointerY(event)];
9136      Droppables.show(pointer, this.element);
9137    }
9138
9139    if(this.options.ghosting) {
9140      if (!this._originallyAbsolute)
9141        Position.relativize(this.element);
9142      delete this._originallyAbsolute;
9143      Element.remove(this._clone);
9144      this._clone = null;
9145    }
9146
9147    var dropped = false;
9148    if(success) {
9149      dropped = Droppables.fire(event, this.element);
9150      if (!dropped) dropped = false;
9151    }
9152    if(dropped && this.options.onDropped) this.options.onDropped(this.element);
9153    Draggables.notify('onEnd', this, event);
9154
9155    var revert = this.options.revert;
9156    if(revert && Object.isFunction(revert)) revert = revert(this.element);
9157
9158    var d = this.currentDelta();
9159    if(revert && this.options.reverteffect) {
9160      if (dropped == 0 || revert != 'failure')
9161        this.options.reverteffect(this.element,
9162          d[1]-this.delta[1], d[0]-this.delta[0]);
9163    } else {
9164      this.delta = d;
9165    }
9166
9167    if(this.options.zindex)
9168      this.element.style.zIndex = this.originalZ;
9169
9170    if(this.options.endeffect)
9171      this.options.endeffect(this.element);
9172
9173    Draggables.deactivate(this);
9174    Droppables.reset();
9175  },
9176
9177  keyPress: function(event) {
9178    if(event.keyCode!=Event.KEY_ESC) return;
9179    this.finishDrag(event, false);
9180    Event.stop(event);
9181  },
9182
9183  endDrag: function(event) {
9184    if(!this.dragging) return;
9185    this.stopScrolling();
9186    this.finishDrag(event, true);
9187    Event.stop(event);
9188  },
9189
9190  draw: function(point) {
9191    var pos = this.element.cumulativeOffset();
9192    if(this.options.ghosting) {
9193      var r   = Position.realOffset(this.element);
9194      pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
9195    }
9196
9197    var d = this.currentDelta();
9198    pos[0] -= d[0]; pos[1] -= d[1];
9199
9200    if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
9201      pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
9202      pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
9203    }
9204
9205    var p = [0,1].map(function(i){
9206      return (point[i]-pos[i]-this.offset[i])
9207    }.bind(this));
9208
9209    if(this.options.snap) {
9210      if(Object.isFunction(this.options.snap)) {
9211        p = this.options.snap(p[0],p[1],this);
9212      } else {
9213      if(Object.isArray(this.options.snap)) {
9214        p = p.map( function(v, i) {
9215          return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this));
9216      } else {
9217        p = p.map( function(v) {
9218          return (v/this.options.snap).round()*this.options.snap }.bind(this));
9219      }
9220    }}
9221
9222    var style = this.element.style;
9223    if((!this.options.constraint) || (this.options.constraint=='horizontal'))
9224      style.left = p[0] + "px";
9225    if((!this.options.constraint) || (this.options.constraint=='vertical'))
9226      style.top  = p[1] + "px";
9227
9228    if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
9229  },
9230
9231  stopScrolling: function() {
9232    if(this.scrollInterval) {
9233      clearInterval(this.scrollInterval);
9234      this.scrollInterval = null;
9235      Draggables._lastScrollPointer = null;
9236    }
9237  },
9238
9239  startScrolling: function(speed) {
9240    if(!(speed[0] || speed[1])) return;
9241    this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
9242    this.lastScrolled = new Date();
9243    this.scrollInterval = setInterval(this.scroll.bind(this), 10);
9244  },
9245
9246  scroll: function() {
9247    var current = new Date();
9248    var delta = current - this.lastScrolled;
9249    this.lastScrolled = current;
9250    if(this.options.scroll == window) {
9251      with (this._getWindowScroll(this.options.scroll)) {
9252        if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
9253          var d = delta / 1000;
9254          this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] );
9255        }
9256      }
9257    } else {
9258      this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
9259      this.options.scroll.scrollTop  += this.scrollSpeed[1] * delta / 1000;
9260    }
9261
9262    Position.prepare();
9263    Droppables.show(Draggables._lastPointer, this.element);
9264    Draggables.notify('onDrag', this);
9265    if (this._isScrollChild) {
9266      Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
9267      Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
9268      Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
9269      if (Draggables._lastScrollPointer[0] < 0)
9270        Draggables._lastScrollPointer[0] = 0;
9271      if (Draggables._lastScrollPointer[1] < 0)
9272        Draggables._lastScrollPointer[1] = 0;
9273      this.draw(Draggables._lastScrollPointer);
9274    }
9275
9276    if(this.options.change) this.options.change(this);
9277  },
9278
9279  _getWindowScroll: function(w) {
9280    var T, L, W, H;
9281    with (w.document) {
9282      if (w.document.documentElement && documentElement.scrollTop) {
9283        T = documentElement.scrollTop;
9284        L = documentElement.scrollLeft;
9285      } else if (w.document.body) {
9286        T = body.scrollTop;
9287        L = body.scrollLeft;
9288      }
9289      if (w.innerWidth) {
9290        W = w.innerWidth;
9291        H = w.innerHeight;
9292      } else if (w.document.documentElement && documentElement.clientWidth) {
9293        W = documentElement.clientWidth;
9294        H = documentElement.clientHeight;
9295      } else {
9296        W = body.offsetWidth;
9297        H = body.offsetHeight;
9298      }
9299    }
9300    return { top: T, left: L, width: W, height: H };
9301  }
9302});
9303
9304Draggable._dragging = { };
9305
9306/*--------------------------------------------------------------------------*/
9307
9308var SortableObserver = Class.create({
9309  initialize: function(element, observer) {
9310    this.element   = $(element);
9311    this.observer  = observer;
9312    this.lastValue = Sortable.serialize(this.element);
9313  },
9314
9315  onStart: function() {
9316    this.lastValue = Sortable.serialize(this.element);
9317  },
9318
9319  onEnd: function() {
9320    Sortable.unmark();
9321    if(this.lastValue != Sortable.serialize(this.element))
9322      this.observer(this.element)
9323  }
9324});
9325
9326var Sortable = {
9327  SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
9328
9329  sortables: { },
9330
9331  _findRootElement: function(element) {
9332    while (element.tagName.toUpperCase() != "BODY") {
9333      if(element.id && Sortable.sortables[element.id]) return element;
9334      element = element.parentNode;
9335    }
9336  },
9337
9338  options: function(element) {
9339    element = Sortable._findRootElement($(element));
9340    if(!element) return;
9341    return Sortable.sortables[element.id];
9342  },
9343
9344  destroy: function(element){
9345    element = $(element);
9346    var s = Sortable.sortables[element.id];
9347
9348    if(s) {
9349      Draggables.removeObserver(s.element);
9350      s.droppables.each(function(d){ Droppables.remove(d) });
9351      s.draggables.invoke('destroy');
9352
9353      delete Sortable.sortables[s.element.id];
9354    }
9355  },
9356
9357  create: function(element) {
9358    element = $(element);
9359    var options = Object.extend({
9360      element:     element,
9361      tag:         'li',       // assumes li children, override with tag: 'tagname'
9362      dropOnEmpty: false,
9363      tree:        false,
9364      treeTag:     'ul',
9365      overlap:     'vertical', // one of 'vertical', 'horizontal'
9366      constraint:  'vertical', // one of 'vertical', 'horizontal', false
9367      containment: element,    // also takes array of elements (or id's); or false
9368      handle:      false,      // or a CSS class
9369      only:        false,
9370      delay:       0,
9371      hoverclass:  null,
9372      ghosting:    false,
9373      quiet:       false,
9374      scroll:      false,
9375      scrollSensitivity: 20,
9376      scrollSpeed: 15,
9377      format:      this.SERIALIZE_RULE,
9378      revert:      'failure',
9379
9380      // these take arrays of elements or ids and can be
9381      // used for better initialization performance
9382      elements:    false,
9383      handles:     false,
9384
9385      onChange:    Prototype.emptyFunction,
9386      onUpdate:    Prototype.emptyFunction
9387    }, arguments[1] || { });
9388
9389    // clear any old sortable with same element
9390    this.destroy(element);
9391
9392    // build options for the draggables
9393    var options_for_draggable = {
9394      revert:      options.revert, // Boogie - Dodamo možnost, da spreminjamo obnašanje ob spuščanu (če imamo slučajno kak droppable kje)
9395      quiet:       options.quiet,
9396      scroll:      options.scroll,
9397      scrollSpeed: options.scrollSpeed,
9398      scrollSensitivity: options.scrollSensitivity,
9399      delay:       options.delay,
9400      ghosting:    options.ghosting,
9401      constraint:  options.constraint,
9402      handle:      options.handle };
9403
9404    if(options.starteffect)
9405      options_for_draggable.starteffect = options.starteffect;
9406
9407    if(options.reverteffect)
9408      options_for_draggable.reverteffect = options.reverteffect;
9409    else
9410      if(options.ghosting) options_for_draggable.reverteffect = function(element) {
9411        element.style.top  = 0;
9412        element.style.left = 0;
9413      };
9414
9415    if(options.endeffect)
9416      options_for_draggable.endeffect = options.endeffect;
9417
9418    if(options.zindex)
9419      options_for_draggable.zindex = options.zindex;
9420
9421    // build options for the droppables
9422    var options_for_droppable = {
9423      overlap:     options.overlap,
9424      containment: options.containment,
9425      tree:        options.tree,
9426      hoverclass:  options.hoverclass,
9427      onHover:     Sortable.onHover
9428    };
9429
9430    var options_for_tree = {
9431      onHover:      Sortable.onEmptyHover,
9432      overlap:      options.overlap,
9433      containment:  options.containment,
9434      hoverclass:   options.hoverclass
9435    };
9436
9437    // fix for gecko engine
9438    Element.cleanWhitespace(element);
9439
9440    options.draggables = [];
9441    options.droppables = [];
9442
9443    // drop on empty handling
9444    if(options.dropOnEmpty || options.tree) {
9445      Droppables.add(element, options_for_tree);
9446      options.droppables.push(element);
9447    }
9448
9449    (options.elements || this.findElements(element, options) || []).each( function(e,i) {
9450      var handle = options.handles ? $(options.handles[i]) :
9451        (options.handle ? $(e).select('.' + options.handle)[0] : e);
9452      options.draggables.push(
9453        new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
9454      Droppables.add(e, options_for_droppable);
9455      if(options.tree) e.treeNode = element;
9456      options.droppables.push(e);
9457    });
9458
9459    if(options.tree) {
9460      (Sortable.findTreeElements(element, options) || []).each( function(e) {
9461        Droppables.add(e, options_for_tree);
9462        e.treeNode = element;
9463        options.droppables.push(e);
9464      });
9465    }
9466
9467    // keep reference
9468    this.sortables[element.identify()] = options;
9469
9470    // for onupdate
9471    Draggables.addObserver(new SortableObserver(element, options.onUpdate));
9472
9473  },
9474
9475  // return all suitable-for-sortable elements in a guaranteed order
9476  findElements: function(element, options) {
9477    return Element.findChildren(
9478      element, options.only, options.tree ? true : false, options.tag);
9479  },
9480
9481  findTreeElements: function(element, options) {
9482    return Element.findChildren(
9483      element, options.only, options.tree ? true : false, options.treeTag);
9484  },
9485
9486  onHover: function(element, dropon, overlap) {
9487    if(Element.isParent(dropon, element)) return;
9488
9489    if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) {
9490      return;
9491    } else if(overlap>0.5) {
9492      Sortable.mark(dropon, 'before');
9493      if(dropon.previousSibling != element) {
9494        var oldParentNode = element.parentNode;
9495        element.style.visibility = "hidden"; // fix gecko rendering
9496        dropon.parentNode.insertBefore(element, dropon);
9497        if(dropon.parentNode!=oldParentNode)
9498          Sortable.options(oldParentNode).onChange(element);
9499        Sortable.options(dropon.parentNode).onChange(element);
9500      }
9501    } else {
9502      Sortable.mark(dropon, 'after');
9503      var nextElement = dropon.nextSibling || null;
9504      if(nextElement != element) {
9505        var oldParentNode = element.parentNode;
9506        element.style.visibility = "hidden"; // fix gecko rendering
9507        dropon.parentNode.insertBefore(element, nextElement);
9508        if(dropon.parentNode!=oldParentNode)
9509          Sortable.options(oldParentNode).onChange(element);
9510        Sortable.options(dropon.parentNode).onChange(element);
9511      }
9512    }
9513  },
9514
9515  onEmptyHover: function(element, dropon, overlap) {
9516    var oldParentNode = element.parentNode;
9517    var droponOptions = Sortable.options(dropon);
9518
9519    if(!Element.isParent(dropon, element)) {
9520      var index;
9521
9522      var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
9523      var child = null;
9524
9525      if(children) {
9526        var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
9527
9528        for (index = 0; index < children.length; index += 1) {
9529          if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
9530            offset -= Element.offsetSize (children[index], droponOptions.overlap);
9531          } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
9532            child = index + 1 < children.length ? children[index + 1] : null;
9533            break;
9534          } else {
9535            child = children[index];
9536            break;
9537          }
9538        }
9539      }
9540
9541      dropon.insertBefore(element, child);
9542
9543      Sortable.options(oldParentNode).onChange(element);
9544      droponOptions.onChange(element);
9545    }
9546  },
9547
9548  unmark: function() {
9549    if(Sortable._marker) Sortable._marker.hide();
9550  },
9551
9552  mark: function(dropon, position) {
9553    // mark on ghosting only
9554    var sortable = Sortable.options(dropon.parentNode);
9555    if(sortable && !sortable.ghosting) return;
9556
9557    if(!Sortable._marker) {
9558      Sortable._marker =
9559        ($('dropmarker') || Element.extend(document.createElement('DIV'))).
9560          hide().addClassName('dropmarker').setStyle({position:'absolute'});
9561      document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
9562    }
9563    var offsets = dropon.cumulativeOffset();
9564    Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
9565
9566    if(position=='after')
9567      if(sortable.overlap == 'horizontal')
9568        Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
9569      else
9570        Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
9571
9572    Sortable._marker.show();
9573  },
9574
9575  _tree: function(element, options, parent) {
9576    var children = Sortable.findElements(element, options) || [];
9577
9578    for (var i = 0; i < children.length; ++i) {
9579      var match = children[i].id.match(options.format);
9580
9581      if (!match) continue;
9582
9583      var child = {
9584        id: encodeURIComponent(match ? match[1] : null),
9585        element: element,
9586        parent: parent,
9587        children: [],
9588        position: parent.children.length,
9589        container: $(children[i]).down(options.treeTag)
9590      };
9591
9592      /* Get the element containing the children and recurse over it */
9593      if (child.container)
9594        this._tree(child.container, options, child);
9595
9596      parent.children.push (child);
9597    }
9598
9599    return parent;
9600  },
9601
9602  tree: function(element) {
9603    element = $(element);
9604    var sortableOptions = this.options(element);
9605    var options = Object.extend({
9606      tag: sortableOptions.tag,
9607      treeTag: sortableOptions.treeTag,
9608      only: sortableOptions.only,
9609      name: element.id,
9610      format: sortableOptions.format
9611    }, arguments[1] || { });
9612
9613    var root = {
9614      id: null,
9615      parent: null,
9616      children: [],
9617      container: element,
9618      position: 0
9619    };
9620
9621    return Sortable._tree(element, options, root);
9622  },
9623
9624  /* Construct a [i] index for a particular node */
9625  _constructIndex: function(node) {
9626    var index = '';
9627    do {
9628      if (node.id) index = '[' + node.position + ']' + index;
9629    } while ((node = node.parent) != null);
9630    return index;
9631  },
9632
9633  sequence: function(element) {
9634    element = $(element);
9635    var options = Object.extend(this.options(element), arguments[1] || { });
9636
9637    return $(this.findElements(element, options) || []).map( function(item) {
9638      return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
9639    });
9640  },
9641
9642  setSequence: function(element, new_sequence) {
9643    element = $(element);
9644    var options = Object.extend(this.options(element), arguments[2] || { });
9645
9646    var nodeMap = { };
9647    this.findElements(element, options).each( function(n) {
9648        if (n.id.match(options.format))
9649            nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
9650        n.parentNode.removeChild(n);
9651    });
9652
9653    new_sequence.each(function(ident) {
9654      var n = nodeMap[ident];
9655      if (n) {
9656        n[1].appendChild(n[0]);
9657        delete nodeMap[ident];
9658      }
9659    });
9660  },
9661
9662  serialize: function(element) {
9663    element = $(element);
9664    var options = Object.extend(Sortable.options(element), arguments[1] || { });
9665    var name = encodeURIComponent(
9666      (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
9667
9668    if (options.tree) {
9669      return Sortable.tree(element, arguments[1]).children.map( function (item) {
9670        return [name + Sortable._constructIndex(item) + "[id]=" +
9671                encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
9672      }).flatten().join('&');
9673    } else {
9674      return Sortable.sequence(element, arguments[1]).map( function(item) {
9675        return name + "[]=" + encodeURIComponent(item);
9676      }).join('&');
9677    }
9678  }
9679};
9680
9681// Returns true if child is contained within element
9682Element.isParent = function(child, element) {
9683  if (!child.parentNode || child == element) return false;
9684  if (child.parentNode == element) return true;
9685  return Element.isParent(child.parentNode, element);
9686};
9687
9688Element.findChildren = function(element, only, recursive, tagName) {
9689  if(!element.hasChildNodes()) return null;
9690  tagName = tagName.toUpperCase();
9691  if(only) only = [only].flatten();
9692  var elements = [];
9693  $A(element.childNodes).each( function(e) {
9694    if(e.tagName && e.tagName.toUpperCase()==tagName &&
9695      (!only || (Element.classNames(e).detect(function(v) { return only.include(v) }))))
9696        elements.push(e);
9697    if(recursive) {
9698      var grandchildren = Element.findChildren(e, only, recursive, tagName);
9699      if(grandchildren) elements.push(grandchildren);
9700    }
9701  });
9702
9703  return (elements.length>0 ? elements.flatten() : []);
9704};
9705
9706Element.offsetSize = function (element, type) {
9707  return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
9708};// lightwindow.js v2.0
9709//
9710// Copyright (c) 2007 stickmanlabs
9711// Author: Kevin P Miller | http://www.stickmanlabs.com
9712//
9713// LightWindow is freely distributable under the terms of an MIT-style license.
9714//
9715// I don't care what you think about the file size...
9716//   Be a pro:
9717//	    http://www.thinkvitamin.com/features/webapps/serving-javascript-fast
9718//      http://rakaz.nl/item/make_your_pages_load_faster_by_combining_and_compressing_javascript_and_css_files
9719//
9720
9721/*-----------------------------------------------------------------------------------------------*/
9722
9723if(typeof Effect == 'undefined')
9724  throw("lightwindow.js requires including script.aculo.us' effects.js library!");
9725
9726// This will stop image flickering in IE6 when elements with images are moved
9727try {
9728	document.execCommand("BackgroundImageCache", false, true);
9729} catch(e) {}
9730
9731var lwTextNext = 'Next' ;
9732var lwTextPrev = 'Prev' ;
9733
9734var lightwindow = Class.create();
9735lightwindow.prototype = {
9736	//
9737	//	Setup Variables
9738	//
9739	element : null,
9740	contentToFetch : null,
9741	windowActive : false,
9742	dataEffects : [],
9743	dimensions : {
9744		cruft : null,
9745		container : null,
9746		viewport : {
9747			height : null,
9748			width : null,
9749			offsetTop : null,
9750			offsetLeft : null
9751		}
9752	},
9753	pagePosition : {
9754		x : 0,
9755		y : 0
9756	},
9757	pageDimensions : {
9758		width : null,
9759		height : null
9760	},
9761	preloadImage : [],
9762	preloadedImage : [],
9763	galleries : [],
9764	thumbGall: [],
9765	resizeTo : {
9766		height : null,
9767		heightPercent : null,
9768		width : null,
9769		widthPercent : null,
9770		fixedTop : null,
9771		fixedLeft : null
9772	},
9773	scrollbarOffset : 18,
9774	navigationObservers : {
9775		previous : null,
9776		next : null,
9777		thumbNav: null
9778	},
9779	// NOTE - dodal tomaž
9780	thumbnail : {
9781		izracunPremikaPopUp : 0,
9782		numThumbs : 0,
9783		thumbLoaded: false,
9784		twidth:128,
9785		theight:96
9786	},
9787	containerChange : {
9788		height : 0,
9789		width : 0
9790	},
9791	activeGallery : false,
9792	galleryLocation : {
9793		current : 0,
9794		total : 0
9795	},
9796	//
9797	//	Initialize the lightwindow.
9798	//
9799	initialize : function(options) {
9800		this.options = Object.extend({
9801			overlay_id : 'lightwindow_overlay',
9802			resizeSpeed : 8,
9803			contentOffset : {
9804				height : 20,
9805				width : 20
9806			},
9807			dimensions : {
9808				image : {height : 250, width : 250},
9809				page : {height : 250, width : 250},
9810				inline : {height : 250, width : 250},
9811				media : {height : 250, width : 250},
9812				external : {height : 250, width : 250},
9813				titleHeight : 25
9814			},
9815			classNames : {
9816				standard : 'lightwindow',
9817				action : 'lightwindow_action'
9818			},
9819			fileTypes : {
9820				page : ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'pl', 'php4', 'php3', 'php', 'php5', 'phtml', 'rhtml', 'shtml', 'txt', 'vbs', 'rb'],
9821				media : ['aif', 'aiff', 'asf', 'avi', 'divx', 'm1v', 'm2a', 'm2v', 'm3u', 'mid', 'midi', 'mov', 'moov', 'movie', 'mp2', 'mp3', 'mpa', 'mpa', 'mpe', 'mpeg', 'mpg', 'mpg', 'mpga', 'pps', 'qt', 'rm', 'ram', 'swf', 'viv', 'vivo', 'wav'],
9822				image : ['bmp', 'gif', 'jpg', 'png', 'tiff']
9823			},
9824			mimeTypes : {
9825				avi : 'video/avi',
9826				aif : 'audio/aiff',
9827				aiff : 'audio/aiff',
9828				gif : 'image/gif',
9829				bmp : 'image/bmp',
9830				jpeg : 'image/jpeg',
9831				m1v : 'video/mpeg',
9832				m2a : 'audio/mpeg',
9833				m2v : 'video/mpeg',
9834				m3u : 'audio/x-mpequrl',
9835				mid : 'audio/x-midi',
9836				midi : 'audio/x-midi',
9837				mjpg : 'video/x-motion-jpeg',
9838				moov : 'video/quicktime',
9839				mov : 'video/quicktime',
9840				movie : 'video/x-sgi-movie',
9841				mp2 : 'audio/mpeg',
9842				mp3 : 'audio/mpeg3',
9843				mpa : 'audio/mpeg',
9844				mpa : 'video/mpeg',
9845				mpe : 'video/mpeg',
9846				mpeg : 'video/mpeg',
9847				mpg : 'audio/mpeg',
9848				mpg : 'video/mpeg',
9849				mpga : 'audio/mpeg',
9850				pdf : 'application/pdf',
9851				png : 'image/png',
9852				pps : 'application/mspowerpoint',
9853				qt : 'video/quicktime',
9854				ram : 'audio/x-pn-realaudio-plugin',
9855				rm : 'application/vnd.rn-realmedia',
9856				swf	: 'application/x-shockwave-flash',
9857				tiff : 'image/tiff',
9858				viv : 'video/vivo',
9859				vivo : 'video/vivo',
9860				wav : 'audio/wav',
9861				wmv : 'application/x-mplayer2'
9862			},
9863			classids : {
9864				mov : 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B',
9865				swf : 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000',
9866				wmv : 'clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6'
9867			},
9868			codebases : {
9869				mov : 'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0',
9870				swf : 'http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0',
9871				wmv : 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715'
9872			},
9873			viewportPadding : 10,
9874			EOLASFix : 'swf,wmv,fla,flv',
9875			overlay : {
9876				opacity : 0.7,
9877				image : '/P/DeskWM/Gal/black.png',
9878				presetImage : '/P/DeskWM/Gal/black-70.png'
9879			},
9880			skin : 	{
9881				main : 	'<div id="lightwindow_container" >'+
9882							'<div id="lightwindow_title_bar" >'+
9883								'<div id="lw_dragObj">&nbsp;</div>'+
9884								'<div id="lightwindow_title_bar_inner" >'+
9885									'<a id="fb_share" class="auto_fb_share_gallery" style="display:none;"></a>'+
9886									'<span id="lightwindow_title_bar_title"></span>'+
9887									'<a id="lightwindow_title_bar_close_link"></a>'+
9888								'</div>'+
9889							'</div>'+
9890							'<div id="lightwindow_stage" >'+
9891								'<div id="lightwindow_contents" >'+
9892								'</div>'+
9893								'<div id="lightwindow_navigation" >'+
9894									'<a href="#" id="lightwindow_previous" >'+
9895										'<div class="Smer">'+lwTextPrev+'</div><span id="lightwindow_previous_title"></span>'+
9896									'</a>'+
9897									'<a href="#" id="lightwindow_next" >'+
9898										'<div class="Smer">'+lwTextNext+'</div><span id="lightwindow_next_title"></span>'+
9899									'</a>'+
9900									'<iframe name="lightwindow_navigation_shim" id="lightwindow_navigation_shim" src="javascript:false;" frameBorder="0" scrolling="no"></iframe>'+
9901								'</div>'+
9902								'<div id="lightwindow_galleries">'+
9903									'<div id="lightwindow_galleries_tab_container" >'+
9904										'<a href="#" id="lightwindow_galleries_tab" >'+
9905											'<span id="lightwindow_galleries_tab_span" class="up" >Galerija</span>'+
9906										'</a>'+
9907									'</div>'+
9908									'<div id="lightwindow_galleries_list" >'+
9909									'</div>'+
9910								'</div>'+
9911							'</div>'+
9912							'<div id="lightwindow_data_slide" >'+
9913								'<div id="lightwindow_data_slide_inner" >'+
9914									'<div id="lightwindow_data_details" >'+
9915										'<div id="lightwindow_data_gallery_container" >'+
9916											'<span id="lightwindow_data_gallery_current"></span>'+
9917											' of '+
9918											'<span id="lightwindow_data_gallery_total"></span>'+
9919										'</div>'+
9920										'<div id="lightwindow_data_author_container" >'+
9921											'by <span id="lightwindow_data_author"></span>'+
9922										'</div>'+
9923									'</div>'+
9924									'<div id="lightwindow_data_caption" >'+
9925									'</div>'+
9926								'</div>'+
9927							'</div>'+
9928							'<div id="lightwindow_galleries_thumbnail"></div>'+
9929						'</div>',
9930				loading : 	'<div id="lightwindow_loading" >'+
9931								'<div class="ico_mask ico_wait ico_special" alt="loading"></div>'+
9932								'<span>Nalaganje - <a href="javascript: myLightWindow.deactivate();">Prekini</a></span>'+
9933								'<iframe name="lightwindow_loading_shim" id="lightwindow_loading_shim" src="javascript:false;" frameBorder="0" scrolling="no"></iframe>'+
9934							'</div>',
9935				iframe : 	'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'+
9936							'<html xmlns="http://www.w3.org/1999/xhtml">'+
9937								'<body>'+
9938									'{body_replace}'+
9939								'</body>'+
9940							'</html>',
9941				thumbnail : '<div id="LightGalleryThumb">' +
9942								'<ul id="LightThumb" class="LightThumb">'+
9943									'{gallery_thumbnail}' +
9944								'</ul>' +
9945							'</div>' ,
9946				gallery : {
9947					top :		'<div class="lightwindow_galleries_list">'+
9948									'<h1>{gallery_title_replace}</h1>'+
9949									'<ul>',
9950					middle : 			'<li>'+
9951											'{gallery_link_replace}'+
9952										'</li>',
9953					bottom : 		'</ul>'+
9954								'</div>'
9955				}
9956			},
9957			formMethod : 'get',
9958			hideFlash : false,
9959			hideGalleryTab : true,
9960			showTitleBar : true,
9961			animationHandler : false,
9962			navigationHandler : false,
9963			transitionHandler : false,
9964			finalAnimationHandler : false,
9965			formHandler : false,
9966			galleryAnimationHandler : false,
9967			showGalleryCount : true,
9968			onClose : null
9969		}, options || {});
9970		this.duration = ((11-this.options.resizeSpeed)*0.15);
9971		this._setupLinks();
9972		this._getScroll();
9973		this._getPageDimensions();
9974		this._browserDimensions();
9975		this._addLightWindowMarkup(false);
9976		this._setupDimensions();
9977		this.buildGalleryList();
9978		
9979		// NOTE Naložimo male sličice za navigacijo - naredil Tomaž
9980		this.loadThumbnail();
9981	},
9982	//
9983	//	Activate the lightwindow.
9984	//
9985	activate : function(e, link){
9986		
9987		// Clear out the window Contents
9988		this._clearWindowContents(true);
9989
9990		// Add back in out loading panel
9991		this._addLoadingWindowMarkup();
9992
9993		// Setup the element properties
9994		this._setupWindowElements(link);
9995
9996		// Setup everything
9997		this._getScroll();
9998		this._browserDimensions();
9999		this._setupDimensions();
10000		this._toggleTroubleElements('hidden', false);
10001		this._displayLightWindow('block', 'hidden');
10002		this._setStatus(true);
10003		this._monitorKeyboard(true);
10004		this._prepareIE(true);
10005		this._loadWindow();
10006	},
10007	//
10008	//	Turn off the window
10009	//
10010	doDeactivate : function(){
10011		// The window is not active
10012		this.windowActive = false;
10013
10014		// Boogie - Dodamo event pri zapiranju
10015		if (this.element && (typeof(this.element.onClose)=="function"))
10016			this.element.onClose() ;
10017		// Boogie
10018
10019		// There is no longer a gallery active
10020		this.activeGallery = false;
10021		if (!this.options.hideGalleryTab) {
10022			this._handleGalleryAnimation(false);
10023		}
10024
10025		// Kill the animation
10026		this.animating = false;
10027
10028		// Clear our element
10029		this.element = null;
10030
10031		// hide the window.
10032		this._displayLightWindow('none', 'visible');
10033
10034		// Clear out the window Contents
10035		this._clearWindowContents(false);
10036
10037		// Stop all animation
10038		var queue = Effect.Queues.get('lightwindowAnimation').each(function(e){e.cancel();});
10039
10040		// Undo the setup
10041		this._prepareIE(false);
10042		this._setupDimensions();
10043		this._toggleTroubleElements('visible', false);
10044		this._monitorKeyboard(false);
10045	},
10046	deactivate : function(){
10047
10048		// HACK Najprej pogledamo še enkrat v IFRAME in pogledamo če obstaja funkcija onBeforeSave
10049		var getBeforeSave = document.getElementById("lightwindow_iframe");
10050		if (getBeforeSave) {
10051			try { // Da se izognemo CORS-u
10052				if (typeof(getBeforeSave.contentWindow.onBeforeClose) == "function")
10053					getBeforeSave.contentWindow.onBeforeClose();
10054				else
10055					this.doDeactivate() ;
10056			} catch(err) {
10057				this.doDeactivate() ;
10058			}
10059		} else
10060			this.doDeactivate() ;
10061		
10062		// NOTE Nastavimo vse na default v primeru, če imamo aktvirane thumbnaile - TOMAž
10063		if($("LightThumb")) {
10064			$("LightThumb").setStyle({left:0+'px'});
10065			this.thumbnail.izracunPremikaPopUp = 0;
10066		}
10067	},
10068	//
10069	//  Initialize specific window
10070	//
10071	createWindow : function(element, attributes) {
10072		this._processLink($(element));
10073	},
10074	//
10075	//  Open a Window from a hash of attributes
10076	//
10077	activateWindow : function(options) {
10078		this.element = Object.extend({
10079			href : null,
10080			title : null,
10081			author : null,
10082			caption : null,
10083			rel : null,
10084			top : null,
10085			left : null,
10086			type : null,
10087			showImages : null,
10088			height : null,
10089			width : null,
10090			loadingAnimation : null,
10091			iframeEmbed : null,
10092			form : null,
10093			onClose : null
10094		}, options || {});
10095
10096		// Set the window type
10097		this.contentToFetch = this.element.href;
10098		this.windowType = this.element.type ? this.element.type : this._fileType(this.element.href);
10099
10100		// Clear out the window Contents
10101		this._clearWindowContents(true);
10102
10103		// Add back in out loading panel
10104		this._addLoadingWindowMarkup();
10105
10106		// Setup everything
10107		this._getScroll();
10108		this._browserDimensions();
10109		this._setupDimensions();
10110		this._toggleTroubleElements('hidden', false);
10111		this._displayLightWindow('block', 'hidden');
10112		this._setStatus(true);
10113		this._monitorKeyboard(true);
10114		this._prepareIE(true);
10115		this._loadWindow();
10116	},
10117	//
10118	//  Fire off our Form handler
10119	//
10120	submitForm : function(e) {
10121		if (this.options.formHandler) {
10122			this.options.formHandler(e);
10123		} else {
10124			this._defaultFormHandler(e);
10125		}
10126	},
10127	//
10128	//	Reload the window with another location
10129	//
10130	openWindow : function(element) {
10131		var element = $(element);
10132
10133		// The window is active
10134		this.windowActive = true;
10135
10136		// Clear out the window Contents
10137		this._clearWindowContents(true);
10138		
10139		// Add back in out loading panel
10140		this._addLoadingWindowMarkup();
10141		
10142		// Setup the element properties
10143		this._setupWindowElements(element);
10144
10145		this._setStatus(true);
10146		this._handleTransition();
10147	},
10148	//
10149	//  Navigate the window
10150	//
10151	navigateWindow : function(direction) {
10152		this._handleNavigation(false);
10153		if (direction == 'previous') {
10154			this.openWindow(this.navigationObservers.previous);
10155		} else if (direction == 'next'){
10156			this.openWindow(this.navigationObservers.next);
10157		} else if(direction == 'thumb') {
10158			this.openWindow(this.navigationObservers.thumbNav);
10159		}
10160	},
10161	//
10162	//  Build the Gallery List and Load it
10163	//
10164	buildGalleryList : function() {
10165		var output = '';
10166		var galleryLink;
10167		for (i in this.galleries) {
10168			if (typeof this.galleries[i] == 'object') {
10169				output += (this.options.skin.gallery.top).replace('{gallery_title_replace}', unescape(i));
10170				for (j in this.galleries[i]) {
10171					if (typeof this.galleries[i][j] == 'object') {
10172						galleryLink = '<a href="#" id="lightwindow_gallery_'+i+'_'+j+'" >'+unescape(j)+'</a>';
10173						output += (this.options.skin.gallery.middle).replace('{gallery_link_replace}', galleryLink);
10174					}
10175				}
10176				output += this.options.skin.gallery.bottom;
10177			}
10178		}
10179		new Insertion.Top('lightwindow_galleries_list', output);
10180
10181		// Attach Events
10182		for (i in this.galleries) {
10183			if (typeof this.galleries[i] == 'object') {
10184				for (j in this.galleries[i]) {
10185					if (typeof this.galleries[i][j] == 'object') {
10186						Event.observe($('lightwindow_gallery_'+i+'_'+j), 'click', this.openWindow.bind(this, this.galleries[i][j][0]), false);
10187						$('lightwindow_gallery_'+i+'_'+j).onclick = function() {return false;};
10188					}
10189				}
10190			}
10191		}
10192	},
10193	//
10194	//  Load thumbnail to gallery
10195	//  NOTE Pridobi vse slike galerije in jih spremeni v thumnaile - naredil Tomaž
10196	loadThumbnail : function() {
10197		this.thumbnail.thumbLoaded = false;
10198		var galleryContent = "";
10199		var thumbWidth = 128;
10200		var thumbHeight = 96;
10201		
10202		if (this.thumbGall.length > 0) {
10203			var splitStr = this.thumbGall[0].split(","); 
10204
10205			for (var b = 0; b < splitStr.length; b++) {
10206				if(String(splitStr[b]).search("lightwindow_twidth") == 0) {
10207					thumbWidth = String(splitStr[b]).replace("lightwindow_twidth=","");
10208					this.thumbnail.twidth = thumbWidth;
10209				} else if(String(splitStr[b]).search("lightwindow_theight") == 0) {
10210					thumbHeight = String(splitStr[b]).replace("lightwindow_theight=","");
10211					this.thumbnail.theight = thumbHeight;
10212				}
10213			}
10214		}
10215
10216		for (i in this.galleries) {
10217			if (typeof this.galleries[i] == 'object') {
10218				for (j in this.galleries[i]) {
10219					if (typeof this.galleries[i][j] == 'object') {
10220						for(var g = 0; g < this.galleries[i][j].length; g++) {
10221							var galleryImg = this.galleries[i][j][g];
10222							if(String(galleryImg).search("/b_") >= 0) {
10223
10224								galleryContent += '<li class="LightWindowThumb NoElementResize">' +
10225														'<a class="lightwindowT LightWindowThumbHide GalThumb'+j+'" rel="'+i+'['+j+']" href="'+galleryImg+'" onclick="return false;">' +
10226															'<img src="'+String(galleryImg).replace("/b_","/s_")+'" width="'+thumbWidth+'px" height="'+thumbHeight+'px" />' +
10227														'</a>' +
10228													'</li>';
10229										
10230							}
10231						}
10232					}
10233				}
10234			}
10235		}
10236		new Insertion.Top("lightwindow_galleries_thumbnail", (this.options.skin.thumbnail).replace("{gallery_thumbnail}",galleryContent));
10237		
10238		// Postavimo observerje na sliko
10239		$$("a.lightwindowT").each(function(e) {
10240			$(e).observe("click", function() {
10241				myLightWindow.navigationObservers.thumbNav = this;
10242
10243				if(typeof(myLightWindow.navigationObservers.next.rel) == "undefined") 
10244					myLightWindow.navigationObservers.thumbNav.rel = myLightWindow.navigationObservers.previous.rel;
10245				else 
10246					myLightWindow.navigationObservers.thumbNav.rel = myLightWindow.navigationObservers.next.rel;
10247
10248				myLightWindow.navigateWindow('thumb');
10249			});
10250		});
10251	},
10252	
10253	//
10254	//  Set Links Up
10255	//
10256	_setupLinks : function() {
10257		var links = $$('.'+this.options.classNames.standard);
10258		links.each(function(link) {
10259			this._processLink(link);
10260		}.bind(this));
10261	},
10262	//
10263	//  Process a Link
10264	//
10265	_processLink : function(link) {
10266		if ((this._fileType(link.getAttribute('href')) == 'image' || this._fileType(link.getAttribute('href')) == 'media')) {
10267			if (gallery = this._getGalleryInfo(link.rel)) {
10268				if (!this.galleries[gallery[0]]) {
10269					this.galleries[gallery[0]] = new Array();
10270				}
10271				if (!this.galleries[gallery[0]][gallery[1]]) {
10272					this.galleries[gallery[0]][gallery[1]] = new Array();
10273				}
10274				// Boogie - eliminiramo duplikat v galeriji na prvem mestu, če se slučajno pojavi
10275				if (!((this.galleries[gallery[0]][gallery[1]].length == 1) && (this.galleries[gallery[0]][gallery[1]][0].href == link.href))) {
10276					// Vse k imajo v url-ju parameter TNo (Thumbnail NO) se ne smejo prikazati med slikami
10277					if(String(link).search("TNo") < 0) 
10278						this.galleries[gallery[0]][gallery[1]].push(link);
10279				}
10280			}
10281		}
10282
10283		if(link.getAttribute('params') != null)
10284			this.thumbGall[0] = (link.getAttribute('params'));
10285		
10286		// Take care of our inline content
10287		var url = link.getAttribute('href');
10288		if (url.indexOf('?') > -1) {
10289			url = url.substring(0, url.indexOf('?'));
10290		}
10291
10292		var container = url.substring(url.indexOf('#')+1);
10293		if ($D(container)) {
10294			$(container).setStyle({
10295				display : 'none'
10296			});
10297		}
10298
10299		Event.observe(link, 'click', this.activate.bindAsEventListener(this, link), false);
10300		link.onclick = function() {return false;};
10301	},
10302	//
10303	//	Setup our actions
10304	//
10305	_setupActions : function() {
10306		var links = $$('#lightwindow_container .'+this.options.classNames.action);
10307		links.each(function(link) {
10308			Event.observe(link, 'click', this[link.getAttribute('rel')].bindAsEventListener(this, link), false);
10309			link.onclick = function() {return false;};
10310		}.bind(this));
10311		
10312		if(Number(this._getParameter('lightwindow_thumb')) == 1) {
10313			// NOTE Na load naredimo še observe na thumbnaile
10314			// Pridobimo dimenzije prvega thumbnaila
10315			this.thumbnail.numThumbs = this.galleryLocation.total;
10316			
10317			if(!$("PopNav")) {
10318				$("lightwindow_galleries_thumbnail").insert({after:'<div id="PopNav" class="ThumbNav" style="position:absolute;"><a id="imgPrev" class="prevThumb"></a><a id="imgNext" class="nextThumb"></a></div>'});
10319				// Naredimo se clone
10320				$("PopNav").clonePosition("lightwindow_galleries_thumbnail",{
10321					setLeft:false,
10322					setTop:true,
10323					setWidth:false,
10324					setHeight:false
10325				});
10326			}
10327			
10328			var curGallery;
10329			if(typeof(myLightWindow.navigationObservers.next.rel) == "undefined") 
10330				curGallery = myLightWindow.navigationObservers.previous.rel;
10331			else 
10332				curGallery = myLightWindow.navigationObservers.next.rel;
10333
10334			if(curGallery != undefined) {
10335				$("lightwindow_galleries_thumbnail").setStyle({'height':$("lightwindow_galleries_thumbnail").down("img").height+'px','display': 'block'});
10336			} else {
10337				$("lightwindow_galleries_thumbnail").setStyle({'height':'0px','display': 'none'});
10338			}
10339			
10340			if(this.thumbnail.thumbLoaded == false) {
10341				$("imgNext").observe("click", function(event){
10342					// Pridobimo vse padding in margine, če obstajajo - za li
10343					var leftLiPadding = $("lightwindow_galleries_thumbnail").down("ul").down(0).getStyle("paddingLeft");
10344					var rightLiPadding = $("lightwindow_galleries_thumbnail").down("ul").down(0).getStyle("paddingRight");
10345					var leftLiMargin = $("lightwindow_galleries_thumbnail").down("ul").down(0).getStyle("marginLeft");
10346					var rightLiMargin = $("lightwindow_galleries_thumbnail").down("ul").down(0).getStyle("marginRight");
10347					
10348					var racPadding = Number(leftLiPadding.substr(0,leftLiPadding.length - 2)) + Number(rightLiPadding.substr(0,rightLiPadding.length - 2)) ;
10349					var racMargin = Number(leftLiMargin.substr(0,leftLiMargin.length - 2)) + Number(rightLiMargin.substr(0,rightLiMargin.length - 2)) ;
10350					
10351					var thumbWithPadMar = Number($("lightwindow_galleries_thumbnail").down("img").width) + Number(racPadding) + Number(racMargin);
10352					var maxPosMove = (Number(myLightWindow.thumbnail.numThumbs) * Number(thumbWithPadMar)) - Number($("lightwindow_galleries_thumbnail").getWidth());
10353					var izracunPremika = Number(myLightWindow.thumbnail.izracunPremikaPopUp) - Number($("LightGalleryThumb").getWidth());
10354					// Pogledamo ali lahko premaknemo toliko slider
10355					if(Number(izracunPremika) > -1)
10356						izracunPremika = (-izracunPremika);
10357					
10358					if(Number(maxPosMove) > -1)
10359						maxPosMove = (-maxPosMove);
10360
10361					if(izracunPremika > maxPosMove) {
10362						// Premaknemo slider za polno dolžino - v levo
10363						myLightWindow.thumbnail.izracunPremikaPopUp = izracunPremika;
10364					} else {
10365						// Slider premaknemo samo še za toliko kolikor je ostalo sličic
10366						if(Number(myLightWindow.thumbnail.izracunPremikaPopUp) == 0 && maxPosMove >= (-thumbWithPadMar))
10367							maxPosMove = 0;
10368						else
10369						  maxPosMove = maxPosMove + thumbWithPadMar;
10370
10371						myLightWindow.thumbnail.izracunPremikaPopUp = maxPosMove ;
10372					}
10373
10374					new Effect.Move($("LightGalleryThumb").down(0), { x: myLightWindow.thumbnail.izracunPremikaPopUp, y: 0, mode: 'absolute' });
10375				});
10376				
10377				$("imgPrev").observe("click", function(event){
10378					var izracunPremika = Number(myLightWindow.thumbnail.izracunPremikaPopUp) + Number($("LightGalleryThumb").getWidth());
10379					if(izracunPremika <= 0) {
10380						// Premaknemo slider za polno dolžino - v desno
10381						myLightWindow.thumbnail.izracunPremikaPopUp = izracunPremika;
10382					} else {
10383						// Slider premaknemo samo še za toliko kolikor je ostalo do ničerlne točke
10384						myLightWindow.thumbnail.izracunPremikaPopUp = 0;
10385					}
10386					new Effect.Move($("LightGalleryThumb").down(0), { x: myLightWindow.thumbnail.izracunPremikaPopUp, y: 0, mode: 'absolute' });
10387				});
10388			}
10389
10390			this.thumbnail.thumbLoaded = true;
10391		}
10392	},
10393	//
10394	//	Add the markup to the page.
10395	//
10396	_addLightWindowMarkup : function(rebuild) {
10397		var overlay = Element.extend(document.createElement('div'));
10398		overlay.setAttribute('id', this.options.overlay_id);
10399		this._getPageDimensions();
10400		// FF Mac has a problem with putting Flash above a layer without a 100% opacity background, so we need to use a pre-made
10401		if (Prototype.Browser.Gecko) {
10402			overlay.setStyle({
10403				backgroundImage: 'url('+this.options.overlay.presetImage+')',
10404				backgroundRepeat: 'repeat',
10405				height: this.pageDimensions.height+'px'
10406			});
10407		} else {
10408			overlay.setStyle({
10409				opacity: this.options.overlay.opacity,
10410				backgroundImage: 'url('+this.options.overlay.image+')',
10411				backgroundRepeat: 'repeat',
10412				height: this.pageDimensions.height+'px'
10413			});
10414		}
10415
10416		var lw = document.createElement('div');
10417		lw.setAttribute('id', 'lightwindow');
10418		lw.innerHTML = this.options.skin.main;
10419
10420		var body = document.getElementsByTagName('body')[0];
10421		body.appendChild(overlay);
10422		body.appendChild(lw);
10423
10424		if ($('lightwindow_title_bar_close_link')) {
10425			Event.observe('lightwindow_title_bar_close_link', 'click', this.deactivate.bindAsEventListener(this));
10426			$('lightwindow_title_bar_close_link').onclick = function() {return false;};
10427		}
10428
10429		Event.observe($('lightwindow_previous'), 'click', this.navigateWindow.bind(this, 'previous'), false);
10430		$('lightwindow_previous').onclick = function() {return false;};
10431		Event.observe($('lightwindow_next'), 'click', this.navigateWindow.bind(this, 'next'), false);
10432		$('lightwindow_next').onclick = function() {return false;};
10433
10434		if (!this.options.hideGalleryTab) {
10435			Event.observe($('lightwindow_galleries_tab'), 'click', this._handleGalleryAnimation.bind(this, true), false);
10436			$('lightwindow_galleries_tab').onclick = function() {return false;};
10437		}
10438
10439		// Because we use position absolute, kill the scroll Wheel on animations
10440		if (Prototype.Browser.IE) {
10441			Event.observe(document, 'mousewheel', this._stopScrolling.bindAsEventListener(this), false);
10442		} else {
10443			Event.observe(window, 'DOMMouseScroll', this._stopScrolling.bindAsEventListener(this), false);
10444		}
10445
10446		Event.observe(overlay, 'click', this.deactivate.bindAsEventListener(this), false);
10447		overlay.onclick = function() {return false;};
10448		
10449	},
10450	//
10451	//  Add loading window markup
10452	//
10453	_addLoadingWindowMarkup : function() {
10454		$('lightwindow_contents').innerHTML += this.options.skin.loading;
10455	},
10456	//
10457	//  Setup the window elements
10458	//
10459	_setupWindowElements : function(link) {
10460		this.element = link;
10461		this.element.title = null ? '' : link.getAttribute('title');
10462		this.element.author = null ? '' : link.getAttribute('author');
10463		this.element.caption = null ? '' : link.getAttribute('caption');
10464		this.element.rel = null ? '' : link.getAttribute('rel');
10465		this.element.params = null ? '' : link.getAttribute('params');
10466
10467		// Set the window type
10468		this.contentToFetch = this.element.href;
10469		this.windowType = this._getParameter('lightwindow_type') ? this._getParameter('lightwindow_type') : this._fileType(this.contentToFetch);
10470
10471		if(Number(this._getParameter('lightwindow_thumb')) == 1) {
10472			var curGallery = this._getGalleryInfo(this.element.rel);
10473			
10474			$$("a.LightWindowThumb").each(function(e) {
10475				$(e).removeClassName("LightWindowThumb");
10476				$(e).addClassName("LightWindowThumbHide");
10477				$(e).up("li").addClassName("NoElementResize");
10478			});
10479
10480			$$("a.GalThumb"+curGallery[1]).each(function(e) {
10481				$(e).removeClassName("LightWindowThumbHide");
10482				$(e).up("li").removeClassName("NoElementResize");
10483				$(e).addClassName("LightWindowThumb");
10484				
10485				// Nastavimo še parametre
10486				if(!$(e).hasAttribute("params")) {
10487					
10488					var lightwindowWidth = "lightwindow_width=800";
10489					var lightwindowHeight = "lightwindow_height=600";
10490					var lightwindowThumb = "lightwindow_thumb=0";
10491					var lightwindowtWidth = "lightwindow_twidth=128";
10492					var lightwindowtHeight = "lightwindow_theight=96";
10493					var lightwindowShare = "lightwindow_share=0";
10494					
10495					if(myLightWindow._getParameter('lightwindow_width'))
10496						lightwindowWidth = "lightwindow_width="+myLightWindow._getParameter('lightwindow_width');
10497					if(myLightWindow._getParameter('lightwindow_height'))
10498						lightwindowHeight = "lightwindow_height="+myLightWindow._getParameter('lightwindow_height');
10499					if(myLightWindow._getParameter('lightwindow_twidth'))
10500						lightwindowtWidth = "lightwindow_twidth="+myLightWindow._getParameter('lightwindow_twidth');
10501					if(myLightWindow._getParameter('lightwindow_theight'))
10502						lightwindowtHeight = "lightwindow_theight="+myLightWindow._getParameter('lightwindow_theight');
10503					if(myLightWindow._getParameter('lightwindow_thumb'))
10504						lightwindowThumb = "lightwindow_thumb="+myLightWindow._getParameter('lightwindow_thumb');
10505					if(myLightWindow._getParameter('lightwindow_share'))
10506						lightwindowShare = "lightwindow_share="+myLightWindow._getParameter('lightwindow_share');
10507					
10508					$(e).writeAttribute("params",lightwindowWidth + "," + lightwindowHeight + "," + lightwindowThumb + "," + lightwindowtWidth + "," + lightwindowtHeight + "," + lightwindowShare);
10509				}
10510			});
10511
10512			if(myLightWindow._getParameter('lightwindow_share') == 1)
10513				socialNetShare.extraShareElements("auto_fb_share_gallery");
10514		}
10515	},
10516	//
10517	//  Clear the window contents out
10518	//
10519	_clearWindowContents : function(contents) {
10520		// If there is an iframe, its got to go
10521		if ($D('lightwindow_iframe')) {
10522			Element.remove($('lightwindow_iframe'));
10523		}
10524
10525		// Stop playing an object if its still around
10526		if ($D('lightwindow_media_primary')) {
10527			try {
10528				$('lightwindow_media_primary').Stop();
10529			} catch(e) {}
10530			Element.remove($('lightwindow_media_primary'));
10531		}
10532
10533		// Stop playing an object if its still around
10534		if ($D('lightwindow_media_secondary')) {
10535			try {
10536				$('lightwindow_media_secondary').Stop();
10537			} catch(e) {}
10538			Element.remove($('lightwindow_media_secondary'));
10539		}
10540
10541		this.activeGallery = false;
10542		this._handleNavigation(this.activeGallery);
10543
10544		if (contents) {
10545			// Empty the contents
10546			$('lightwindow_contents').innerHTML = '';
10547
10548			// Reset the scroll bars
10549			$('lightwindow_contents').setStyle({
10550				overflow: 'hidden'
10551			});
10552
10553			if (!this.windowActive) {
10554				$('lightwindow_data_slide_inner').setStyle({
10555					display: 'none'
10556				});
10557
10558				$('lightwindow_title_bar_title').innerHTML = '';
10559			}
10560
10561			// Because of browser differences and to maintain flexible captions we need to reset this height at close
10562			$('lightwindow_data_slide').setStyle({
10563				height: 'auto'
10564			});
10565		}
10566
10567		this.resizeTo.height = null;
10568		this.resizeTo.width = null;
10569	},
10570	//
10571	//	Set the status of our animation to keep things from getting clunky
10572	//
10573	_setStatus : function(status) {
10574		this.animating = status;
10575		if (status) {
10576			Element.show('lightwindow_loading');
10577		}
10578		if (!(/MSIE 6./i.test(navigator.userAgent))) {
10579			this._fixedWindow(status);
10580		}
10581	},
10582	//
10583	//  Make this window Fixed
10584	//
10585	_fixedWindow : function(status) {
10586		if (status) {
10587			if (this.windowActive) {
10588				this._getScroll();
10589				$('lightwindow').setStyle({
10590					position: 'absolute',
10591					top: parseFloat($('lightwindow').getStyle('top'))+this.pagePosition.y+'px',
10592					left: parseFloat($('lightwindow').getStyle('left'))+this.pagePosition.x+'px'
10593				});
10594			} else {
10595				$('lightwindow').setStyle({
10596					position: 'absolute'
10597				});
10598			}
10599		} else {
10600			if (this.windowActive) {
10601				this._getScroll();
10602				$('lightwindow').setStyle({
10603					position: 'fixed',
10604					top: parseFloat($('lightwindow').getStyle('top'))-this.pagePosition.y+'px',
10605					left: parseFloat($('lightwindow').getStyle('left'))-this.pagePosition.x+'px'
10606				});
10607			} else {
10608				if ($D('lightwindow_iframe')) {
10609					// Ideally here we would set a 50% value for top and left, but Safari rears it ugly head again and we need to do it by pixels
10610					this._browserDimensions();
10611				}
10612				$('lightwindow').setStyle({
10613					position: 'fixed',
10614					top: (parseFloat(this._getParameter('lightwindow_top')) ? parseFloat(this._getParameter('lightwindow_top'))+'px' : this.dimensions.viewport.height/2+'px'),
10615					left: (parseFloat(this._getParameter('lightwindow_left')) ? parseFloat(this._getParameter('lightwindow_left'))+'px' : this.dimensions.viewport.width/2+'px')
10616				});
10617			}
10618		}
10619	},
10620	//
10621	//	Prepare the window for IE.
10622	//
10623	_prepareIE : function(setup) {
10624		if (Prototype.Browser.IE) {
10625			var height, overflowX, overflowY;
10626			if (setup) {
10627				var height = '100%';
10628			} else {
10629				var height = 'auto';
10630			}
10631			var body = document.getElementsByTagName('body')[0];
10632			var html = document.getElementsByTagName('html')[0];
10633			html.style.height = body.style.height = height;
10634		}
10635	},
10636	_stopScrolling : function(e) {
10637		if (this.animating) {
10638			if (e.preventDefault) {
10639				e.preventDefault();
10640			}
10641			e.returnValue = false;
10642		}
10643	},
10644	//
10645	//	Get the scroll for the page.
10646	//
10647	_getScroll : function(){
10648      	if(typeof(window.pageYOffset) == 'number') {
10649        	this.pagePosition.x = window.pageXOffset;
10650        	this.pagePosition.y = window.pageYOffset;
10651      	} else if(document.body && (document.body.scrollLeft || document.body.scrollTop)) {
10652	       	this.pagePosition.x = document.body.scrollLeft;
10653        	this.pagePosition.y = document.body.scrollTop;
10654		} else if(document.documentElement) {
10655        	this.pagePosition.x = document.documentElement.scrollLeft;
10656        	this.pagePosition.y = document.documentElement.scrollTop;
10657      	}
10658	},
10659	//
10660	//	Reset the scroll.
10661	//
10662	_setScroll : function(x, y) {
10663		document.documentElement.scrollLeft = x;
10664		document.documentElement.scrollTop = y;
10665	},
10666	//
10667	//	Hide Selects from the page because of IE.
10668	//     We could use iframe shims instead here but why add all the extra markup for one browser when this is much easier and cleaner
10669	//
10670	_toggleTroubleElements : function(visibility, content){
10671
10672		if (content) {
10673			var selects = $('lightwindow_contents').getElementsByTagName('select');
10674		} else {
10675			var selects = document.getElementsByTagName('select');
10676		}
10677
10678		for(var i = 0; i < selects.length; i++) {
10679			selects[i].style.visibility = visibility;
10680		}
10681
10682		if (!content) {
10683			if (this.options.hideFlash){
10684				var objects = document.getElementsByTagName('object');
10685				for (i = 0; i != objects.length; i++) {
10686					objects[i].style.visibility = visibility;
10687				}
10688				var embeds = document.getElementsByTagName('embed');
10689				for (i = 0; i != embeds.length; i++) {
10690					embeds[i].style.visibility = visibility;
10691				}
10692			}
10693			var iframes = document.getElementsByTagName('iframe');
10694			for (i = 0; i != iframes.length; i++) {
10695				iframes[i].style.visibility = visibility;
10696			}
10697		}
10698	},
10699	//
10700	//  Get the actual page size
10701	//
10702	_getPageDimensions : function() {
10703		var xScroll, yScroll;
10704		if (window.innerHeight && window.scrollMaxY) {
10705			xScroll = document.body.scrollWidth;
10706			yScroll = window.innerHeight + window.scrollMaxY;
10707		} else if (document.body.scrollHeight > document.body.offsetHeight){
10708			xScroll = document.body.scrollWidth;
10709			yScroll = document.body.scrollHeight;
10710		} else {
10711			xScroll = document.body.offsetWidth;
10712			yScroll = document.body.offsetHeight;
10713		}
10714
10715		var windowWidth, windowHeight;
10716		if (self.innerHeight) {
10717			windowWidth = self.innerWidth;
10718			windowHeight = self.innerHeight;
10719		} else if (document.documentElement && document.documentElement.clientHeight) {
10720			windowWidth = document.documentElement.clientWidth;
10721			windowHeight = document.documentElement.clientHeight;
10722		} else if (document.body) {
10723			windowWidth = document.body.clientWidth;
10724			windowHeight = document.body.clientHeight;
10725		}
10726
10727		if(yScroll < windowHeight){
10728			this.pageDimensions.height = windowHeight;
10729		} else {
10730			this.pageDimensions.height = yScroll;
10731		}
10732
10733		if(xScroll < windowWidth){
10734			this.pageDimensions.width = windowWidth;
10735		} else {
10736			this.pageDimensions.width = xScroll;
10737		}
10738	},
10739	//
10740	//	Display the lightWindow.
10741	//
10742	_displayLightWindow : function(display, visibility) {
10743		$(this.options.overlay_id).style.display = $('lightwindow').style.display = $('lightwindow_container').style.display = display;
10744		$(this.options.overlay_id).style.visibility = $('lightwindow').style.visibility = $('lightwindow_container').style.visibility = visibility;
10745	},
10746	//
10747	//	Setup Dimensions of lightwindow.
10748
10749	//
10750	_setupDimensions : function() {
10751
10752		var originalHeight, originalWidth;
10753		switch (this.windowType) {
10754			case 'page' :
10755				originalHeight = this.options.dimensions.page.height;
10756				originalWidth = this.options.dimensions.page.width;
10757				break;
10758
10759			case 'image' :
10760				originalHeight = this.options.dimensions.image.height;
10761				originalWidth = this.options.dimensions.image.width;
10762				break;
10763
10764			case 'media' :
10765				originalHeight = this.options.dimensions.media.height;
10766				originalWidth = this.options.dimensions.media.width;
10767				break;
10768
10769			case 'external' :
10770				originalHeight = this.options.dimensions.external.height;
10771				originalWidth = this.options.dimensions.external.width;
10772				break;
10773
10774			case 'inline' :
10775				originalHeight = this.options.dimensions.inline.height;
10776				originalWidth = this.options.dimensions.inline.width;
10777				break;
10778
10779			default :
10780				originalHeight = this.options.dimensions.page.height;
10781				originalWidth = this.options.dimensions.page.width;
10782				break;
10783
10784		}
10785
10786		var offsetHeight = this._getParameter('lightwindow_top') ? parseFloat(this._getParameter('lightwindow_top'))+this.pagePosition.y : this.dimensions.viewport.height/2+this.pagePosition.y;
10787		var offsetWidth = this._getParameter('lightwindow_left') ? parseFloat(this._getParameter('lightwindow_left'))+this.pagePosition.x : this.dimensions.viewport.width/2+this.pagePosition.x;
10788
10789		// So if a theme has say shadowed edges, they should be consistant and take care of in the contentOffset
10790		$('lightwindow').setStyle({
10791			top: offsetHeight+'px',
10792			left: offsetWidth+'px'
10793		});
10794
10795		$('lightwindow_container').setStyle({
10796			height: originalHeight+'px',
10797			width: originalWidth+'px',
10798			left: -(originalWidth/2)+'px',
10799			top: -(originalHeight/2)+'px'
10800		});
10801
10802		$('lightwindow_contents').setStyle({
10803			height: originalHeight+'px',
10804			width: originalWidth+'px'
10805		});
10806	},
10807	//
10808	//	Get the type of file.
10809	//
10810	_fileType : function(url) {
10811		var image = new RegExp("[^\.]\.("+this.options.fileTypes.image.join('|')+")\s*$", "i");
10812		if (url.indexOf('?') > -1) {
10813			var turl = url.substring(0, url.indexOf('?'));
10814			if (image.test(turl)) return 'image';
10815		} else
10816			if (image.test(url)) return 'image';
10817		if (url.indexOf('#') > -1 && (document.domain == this._getDomain(url))) return 'inline';
10818		if (url.indexOf('?') > -1) url = url.substring(0, url.indexOf('?'));
10819		var type = 'unknown';
10820		var page = new RegExp("[^\.]\.("+this.options.fileTypes.page.join('|')+")\s*$", "i");
10821		var media = new RegExp("[^\.]\.("+this.options.fileTypes.media.join('|')+")\s*$", "i");
10822		if (document.domain != this._getDomain(url)) type = 'external';
10823	  	if (media.test(url)) type = 'media';
10824		if (type == 'external' || type == 'media') return type;
10825	  	if (page.test(url) || url.substr((url.length-1), url.length) == '/') type = 'page';
10826		return type;
10827	},
10828	//
10829	//  Get file Extension
10830	//
10831	_fileExtension : function(url) {
10832		if (url.indexOf('?') > -1) {
10833			url = url.substring(0, url.indexOf('?'));
10834		}
10835		var extenstion = '';
10836		for (var x = (url.length-1); x > -1; x--) {
10837			if (url.charAt(x) == '.') {
10838				return extenstion;
10839			}
10840			extenstion = url.charAt(x)+extenstion;
10841		}
10842	},
10843	//
10844	//	Monitor the keyboard while this lightwindow is up
10845	//
10846	_monitorKeyboard : function(status) {
10847		if (status) document.onkeydown = this._eventKeypress.bind(this);
10848		else document.onkeydown = '';
10849	},
10850	//
10851	//  Perform keyboard actions
10852	//
10853	_eventKeypress : function(e) {
10854		if (e == null) {
10855			var keycode = event.keyCode;
10856		} else {
10857			var keycode = e.which;
10858		}
10859
10860		switch (keycode) {
10861			case 27:
10862				this.deactivate();
10863				break;
10864
10865			case 13:
10866				return;
10867
10868			default:
10869				break;
10870		}
10871
10872		// Gotta stop those quick fingers
10873		if (this.animating) {
10874			return false;
10875		}
10876
10877		switch (String.fromCharCode(keycode).toLowerCase()) {
10878			case 'p':
10879				if (this.navigationObservers.previous) {
10880					this.navigateWindow('previous');
10881				}
10882				break;
10883
10884			case 'n':
10885				if (this.navigationObservers.next) {
10886					this.navigateWindow('next');
10887				}
10888				break;
10889
10890			default:
10891				break;
10892		}
10893	},
10894	//
10895	//	Get Gallery Information
10896	//
10897	_getGalleryInfo : function(rel) {
10898		if (!rel) return false;
10899		if (rel.indexOf('[') > -1) {
10900			return new Array(escape(rel.substring(0, rel.indexOf('['))), escape(rel.substring(rel.indexOf('[')+1, rel.indexOf(']'))));
10901		} else {
10902			return false;
10903		}
10904	},
10905	//
10906	//	Get the domain from a string.
10907	//
10908	_getDomain : function(url) {
10909        var leadSlashes = url.indexOf('//');
10910        var domainStart = leadSlashes+2;
10911        var withoutResource = url.substring(domainStart, url.length);
10912        var nextSlash = withoutResource.indexOf('/');
10913        var domain = withoutResource.substring(0, nextSlash);
10914		if (domain.indexOf(':') > -1){
10915			var portColon = domain.indexOf(':');
10916			domain = domain.substring(0, portColon);
10917       	}
10918		return domain;
10919    },
10920	//
10921	//	Get the value from the params attribute string.
10922	//
10923	_getParameter : function(parameter, parameters) {
10924		if (!this.element) return false;
10925		if (parameter == 'lightwindow_top' && this.element.top) {
10926			return unescape(this.element.top);
10927		} else if (parameter == 'lightwindow_left' && this.element.left) {
10928			return unescape(this.element.left);
10929		} else if (parameter == 'lightwindow_type' && this.element.type) {
10930			return unescape(this.element.type);
10931		} else if (parameter == 'lightwindow_show_images' && this.element.showImages) {
10932			return unescape(this.element.showImages);
10933		} else if (parameter == 'lightwindow_height' && this.element.height) {
10934			return unescape(this.element.height);
10935		} else if (parameter == 'lightwindow_width' && this.element.width) {
10936			return unescape(this.element.width);
10937		} else if (parameter == 'lightwindow_loading_animation' && this.element.loadingAnimation) {
10938			return unescape(this.element.loadingAnimation);
10939		} else if (parameter == 'lightwindow_iframe_embed' && this.element.iframeEmbed) {
10940			return unescape(this.element.iframeEmbed);
10941		} else if (parameter == 'lightwindow_form' && this.element.form) {
10942			return unescape(this.element.form);
10943		} else if (parameter == 'lightwindow_thumb' && this.element.lightwindow_thumb) {
10944			return unescape(this.element.lightwindow_thumb);
10945		} else {
10946			if (!parameters) {
10947				if (this.element.params) parameters = this.element.params;
10948				else return;
10949			}
10950			var value;
10951			var parameterArray = parameters.split(',');
10952			var compareString = parameter+'=';
10953			var compareLength = compareString.length;
10954			for (var i = 0; i < parameterArray.length; i++) {
10955				if (parameterArray[i].substr(0, compareLength) == compareString) {
10956					var currentParameter = parameterArray[i].split('=');
10957					value = currentParameter[1];
10958					break;
10959				}
10960			}
10961			if (!value) return false;
10962			else return unescape(value);
10963		}
10964	},
10965	//
10966	//  Get the Browser Viewport Dimensions
10967	//
10968	_browserDimensions : function() {
10969		if (Prototype.Browser.IE) {
10970            this.dimensions.viewport.height = document.documentElement.clientHeight;
10971            this.dimensions.viewport.width = document.documentElement.clientWidth;
10972        } else {
10973            this.dimensions.viewport.height = window.innerHeight;
10974            this.dimensions.viewport.width = document.width || document.body.offsetWidth;
10975        }
10976	},
10977	//
10978	//  Get the scrollbar offset, I don't like this method but there is really no other way I can find.
10979	//
10980	_getScrollerWidth : function() {
10981	    var scrollDiv = Element.extend(document.createElement('div'));
10982		scrollDiv.setAttribute('id', 'lightwindow_scroll_div');
10983		scrollDiv.setStyle({
10984			position: 'absolute',
10985			top: '-10000px',
10986			left: '-10000px',
10987			width: '100px',
10988			height: '100px',
10989			overflow: 'hidden'
10990		});
10991
10992
10993
10994	    var contentDiv = Element.extend(document.createElement('div'));
10995		contentDiv.setAttribute('id', 'lightwindow_content_scroll_div');
10996		contentDiv.setStyle({
10997			width: '100%',
10998			height: '200px'
10999		});
11000
11001	    scrollDiv.appendChild(contentDiv);
11002
11003		var body = document.getElementsByTagName('body')[0];
11004		body.appendChild(scrollDiv);
11005
11006	    var noScroll = $('lightwindow_content_scroll_div').offsetWidth;
11007	    scrollDiv.style.overflow = 'auto';
11008    	var withScroll = $('lightwindow_content_scroll_div').offsetWidth;
11009
11010	   	Element.remove($('lightwindow_scroll_div'));
11011
11012	    this.scrollbarOffset = noScroll-withScroll;
11013	},
11014
11015
11016	//
11017	//  Add a param to an object dynamically created
11018	//
11019	_addParamToObject : function(name, value, object, id) {
11020		var param = document.createElement('param');
11021		param.setAttribute('value', value);
11022		param.setAttribute('name', name);
11023		if (id) {
11024			param.setAttribute('id', id);
11025		}
11026		object.appendChild(param);
11027		return object;
11028	},
11029	//
11030	//  Get the outer HTML of an object CROSS BROWSER
11031	//
11032	_outerHTML : function(object) {
11033 		if (Prototype.Browser.IE) {
11034			return object.outerHTML;
11035		} else {
11036			var clone = object.cloneNode(true);
11037			var cloneDiv = document.createElement('div');
11038			cloneDiv.appendChild(clone);
11039			return cloneDiv.innerHTML;
11040		}
11041	},
11042	//
11043	//  Convert an object to markup
11044	//
11045	_convertToMarkup : function(object, closeTag) {
11046		var markup = this._outerHTML(object).replace('</'+closeTag+'>', '');
11047		if (Prototype.Browser.IE) {
11048			for (var i = 0; i < object.childNodes.length; i++){
11049				markup += this._outerHTML(object.childNodes[i]);
11050			}
11051			markup += '</'+closeTag+'>';
11052		}
11053		return markup;
11054	},
11055	//
11056	//  Depending what type of browser it is we have to append the object differently... DAMN YOU IE!!
11057	//
11058	_appendObject : function(object, closeTag, appendTo) {
11059		if (Prototype.Browser.IE) {
11060			appendTo.innerHTML += this._convertToMarkup(object, closeTag);
11061
11062			// Fix the Eolas activate thing but only for specified media, for example doing this to a quicktime film breaks it.
11063			if (this.options.EOLASFix.indexOf(this._fileType(this.element.href)) > -1) {
11064				var objectElements = document.getElementsByTagName('object');
11065				for (var i = 0; i < objectElements.length; i++) {
11066					if (objectElements[i].getAttribute("data")) objectElements[i].removeAttribute('data');
11067					objectElements[i].outerHTML = objectElements[i].outerHTML;
11068					objectElements[i].style.visibility = "visible";
11069				}
11070			}
11071		} else {
11072			appendTo.appendChild(object);
11073		}
11074	},
11075	//
11076	//  Add in iframe
11077	//
11078	_appendIframe : function(scroll) {
11079		var iframe = document.createElement('iframe');
11080		iframe.setAttribute('id', 'lightwindow_iframe');
11081		iframe.setAttribute('name', 'lightwindow_iframe');
11082		iframe.setAttribute('src', 'about:blank');
11083		iframe.setAttribute('height', '100%');
11084		iframe.setAttribute('width', '100%');
11085		iframe.setAttribute('frameborder', '0');
11086		iframe.setAttribute('marginwidth', '0');
11087		iframe.setAttribute('marginheight', '0');
11088		iframe.setAttribute('scrolling', scroll);
11089
11090		this._appendObject(iframe, 'iframe', $('lightwindow_contents'));
11091	},
11092	//
11093	//  Write Content to the iframe using the skin
11094	//
11095	_writeToIframe : function(content) {
11096		var template = this.options.skin.iframe;
11097		template = template.replace('{body_replace}', content);
11098		if ($('lightwindow_iframe').contentWindow){
11099			$('lightwindow_iframe').contentWindow.document.open();
11100			$('lightwindow_iframe').contentWindow.document.write(template);
11101			$('lightwindow_iframe').contentWindow.document.close();
11102		} else {
11103			$('lightwindow_iframe').contentDocument.open();
11104			$('lightwindow_iframe').contentDocument.write(template);
11105			$('lightwindow_iframe').contentDocument.close();
11106		}
11107	},
11108	//
11109	//  Load the window Information
11110	//
11111	_loadWindow : function() {
11112		switch (this.windowType) {
11113			case 'image' :
11114
11115				var current = 0;
11116				var images = [];
11117				this.checkImage = [];
11118				this.resizeTo.height = this.resizeTo.width = 0;
11119				this.imageCount = this._getParameter('lightwindow_show_images') ? parseInt(this._getParameter('lightwindow_show_images')) : 1;
11120
11121				// If there is a gallery get it
11122				if (gallery = this._getGalleryInfo(this.element.rel)) {
11123					for (current = 0; current < this.galleries[gallery[0]][gallery[1]].length; current++) {
11124						if (this.contentToFetch.indexOf(this.galleries[gallery[0]][gallery[1]][current].href) > -1) {
11125							break;
11126						}
11127					}
11128					if (this.galleries[gallery[0]][gallery[1]][current-this.imageCount]) {
11129						this.navigationObservers.previous = this.galleries[gallery[0]][gallery[1]][current-this.imageCount];
11130					} else {
11131						this.navigationObservers.previous = false;
11132					}
11133					if (this.galleries[gallery[0]][gallery[1]][current+this.imageCount]) {
11134						this.navigationObservers.next = this.galleries[gallery[0]][gallery[1]][current+this.imageCount];
11135					} else {
11136						this.navigationObservers.next = false;
11137					}
11138
11139					this.activeGallery = true;
11140
11141				} else {
11142					this.navigationObservers.previous = false;
11143					this.navigationObservers.next = false;
11144
11145					this.activeGallery = false;
11146				}
11147
11148				for (var i = current; i < (current+this.imageCount); i++) {
11149
11150					if (gallery && this.galleries[gallery[0]][gallery[1]][i]) {
11151						this.contentToFetch = this.galleries[gallery[0]][gallery[1]][i].href;
11152
11153						this.galleryLocation = {current: (i+1)/this.imageCount, total: (this.galleries[gallery[0]][gallery[1]].length)/this.imageCount};
11154
11155						if (!this.galleries[gallery[0]][gallery[1]][i+this.imageCount]) {
11156							$('lightwindow_next').setStyle({
11157								display: 'none'
11158							});
11159						} else {
11160							$('lightwindow_next').setStyle({
11161								display: 'block'
11162							});
11163							$('lightwindow_next_title').innerHTML = this.galleries[gallery[0]][gallery[1]][i+this.imageCount].title;
11164						}
11165
11166						if (!this.galleries[gallery[0]][gallery[1]][i-this.imageCount]) {
11167							$('lightwindow_previous').setStyle({
11168								display: 'none'
11169							});
11170						} else {
11171							$('lightwindow_previous').setStyle({
11172								display: 'block'
11173							});
11174							$('lightwindow_previous_title').innerHTML = this.galleries[gallery[0]][gallery[1]][i-this.imageCount].title;
11175						}
11176					}
11177
11178					images[i] = document.createElement('img');
11179					images[i].setAttribute('id', 'lightwindow_image_'+i);
11180					images[i].addClassName("currentImage");
11181					images[i].setAttribute('border', '0');
11182					images[i].setAttribute('src', this.contentToFetch);
11183					$('lightwindow_contents').appendChild(images[i]);
11184
11185					// We have to do this instead of .onload
11186					this.checkImage[i] = new PeriodicalExecuter(function(i) {
11187// 						console.log("Čeking image "+i+" : "+$('lightwindow_image_'+i).naturalWidth) ;
11188						if(typeof($('lightwindow_image_'+i).naturalWidth) == "number") {
11189// 							console.log(i) ;
11190							if (!(typeof $('lightwindow_image_'+i).naturalWidth != "undefined" && $('lightwindow_image_'+i).naturalWidth == 0)) {
11191// 								console.log("True :"+i+" :"+this.checkImage[i].currentlyExecuting) ;
11192								this.checkImage[i].stop();
11193								
11194								if(Number(this._getParameter('lightwindow_thumb')) == 1) {
11195									if (this._getParameter('lightwindow_iframe_embed')) {
11196										this.resizeTo.height = this.dimensions.viewport.height;
11197										this.resizeTo.width = this.dimensions.viewport.width;
11198									} else {
11199										this.resizeTo.height = this._getParameter('lightwindow_height');
11200										this.resizeTo.width = this._getParameter('lightwindow_width');
11201									}
11202									
11203									this.imageCount--;
11204
11205									$('lightwindow_image_'+i).setStyle({
11206										height: this.resizeTo.height+'px'
11207									});
11208
11209									
11210									if (this.imageCount == 0) {
11211										this._processWindow();
11212									}
11213								} else {
11214									var imageHeight = $('lightwindow_image_'+i).getHeight();
11215									if (imageHeight > this.resizeTo.height) {
11216										this.resizeTo.height = imageHeight;
11217									}
11218									this.resizeTo.width += $('lightwindow_image_'+i).getWidth();
11219									this.imageCount--;
11220
11221									$('lightwindow_image_'+i).setStyle({
11222										height: '100%'
11223									});
11224
11225									if (this.imageCount == 0) {
11226										this._processWindow();
11227									}
11228								}
11229							}
11230						}
11231					}.bind(this, i), 1);
11232				}
11233			break;
11234
11235		case 'media' :
11236
11237			var current = 0;
11238			this.resizeTo.height = this.resizeTo.width = 0;
11239
11240			// If there is a gallery get it
11241			if (gallery = this._getGalleryInfo(this.element.rel)) {
11242				for (current = 0; current < this.galleries[gallery[0]][gallery[1]].length; current++) {
11243					if (this.contentToFetch.indexOf(this.galleries[gallery[0]][gallery[1]][current].href) > -1) {
11244						break;
11245					}
11246				}
11247
11248				if (this.galleries[gallery[0]][gallery[1]][current-1]) {
11249					this.navigationObservers.previous = this.galleries[gallery[0]][gallery[1]][current-1];
11250				} else {
11251					this.navigationObservers.previous = false;
11252				}
11253				if (this.galleries[gallery[0]][gallery[1]][current+1]) {
11254					this.navigationObservers.next = this.galleries[gallery[0]][gallery[1]][current+1];
11255				} else {
11256					this.navigationObservers.next = false;
11257				}
11258
11259				this.activeGallery = true;
11260			} else {
11261				this.navigationObservers.previous = false;
11262				this.navigationObservers.next = false;
11263
11264				this.activeGallery = false;
11265			}
11266
11267
11268			if (gallery && this.galleries[gallery[0]][gallery[1]][current]) {
11269				this.contentToFetch = this.galleries[gallery[0]][gallery[1]][current].href;
11270
11271				this.galleryLocation = {current: current+1, total: this.galleries[gallery[0]][gallery[1]].length};
11272
11273				if (!this.galleries[gallery[0]][gallery[1]][current+1]) {
11274					$('lightwindow_next').setStyle({
11275						display: 'none'
11276					});
11277				} else {
11278					$('lightwindow_next').setStyle({
11279						display: 'block'
11280					});
11281					$('lightwindow_next_title').innerHTML = this.galleries[gallery[0]][gallery[1]][current+1].title;
11282				}
11283
11284				if (!this.galleries[gallery[0]][gallery[1]][current-1]) {
11285					$('lightwindow_previous').setStyle({
11286						display: 'none'
11287					});
11288				} else {
11289					$('lightwindow_previous').setStyle({
11290						display: 'block'
11291					});
11292					$('lightwindow_previous_title').innerHTML = this.galleries[gallery[0]][gallery[1]][current-1].title;
11293				}
11294			}
11295
11296			if (this._getParameter('lightwindow_iframe_embed')) {
11297				this.resizeTo.height = this.dimensions.viewport.height;
11298				this.resizeTo.width = this.dimensions.viewport.width;
11299			} else {
11300				this.resizeTo.height = this._getParameter('lightwindow_height');
11301				this.resizeTo.width = this._getParameter('lightwindow_width');
11302			}
11303			
11304			this._processWindow();
11305
11306			break;
11307
11308		case 'external' :
11309
11310			this._appendIframe('auto');
11311
11312			this.resizeTo.height = this.dimensions.viewport.height;
11313			this.resizeTo.width = this.dimensions.viewport.width;
11314
11315			this._processWindow();
11316
11317			break;
11318
11319		case 'page' :
11320
11321			var newAJAX = new Ajax.Request(
11322				this.contentToFetch, {
11323					method: 'get',
11324					parameters: '',
11325					onComplete: function(response) {
11326						$('lightwindow_contents').innerHTML += response.responseText;
11327						this.resizeTo.height = $('lightwindow_contents').scrollHeight+(this.options.contentOffset.height);
11328						this.resizeTo.width = $('lightwindow_contents').scrollWidth+(this.options.contentOffset.width);
11329						this._processWindow();
11330					}.bind(this)
11331				}
11332			);
11333
11334			break;
11335
11336		case 'inline' :
11337
11338			var content = this.contentToFetch;
11339			if (content.indexOf('?') > -1) {
11340				content = content.substring(0, content.indexOf('?'));
11341			}
11342			content = content.substring(content.indexOf('#')+1);
11343
11344			new Insertion.Top($('lightwindow_contents'), $(content).innerHTML);
11345
11346			this.resizeTo.height = $('lightwindow_contents').scrollHeight+(this.options.contentOffset.height);
11347			this.resizeTo.width = $('lightwindow_contents').scrollWidth+(this.options.contentOffset.width);
11348
11349			this._toggleTroubleElements('hidden', true);
11350			this._processWindow();
11351
11352			break;
11353
11354		default :
11355			throw("Page Type could not be determined, please amend this lightwindow URL "+this.contentToFetch);
11356			break;
11357		}
11358
11359		// Dodamo observer za draggable za okno
11360		new Draggable('lightwindow_container', { handle: 'lw_dragObj' });
11361	},
11362	//
11363	//  Resize the Window to fit the viewport if necessary
11364	//
11365	_resizeWindowToFit : function() {
11366		if (this.resizeTo.height+this.dimensions.cruft.height > this.dimensions.viewport.height) {
11367			var heightRatio = this.resizeTo.height/this.resizeTo.width;
11368			this.resizeTo.height = this.dimensions.viewport.height-this.dimensions.cruft.height-(2*this.options.viewportPadding);
11369			// We only care about ratio's with this window type
11370			if (this.windowType == 'image' || (this.windowType == 'media' && !this._getParameter('lightwindow_iframe_embed'))) {
11371				this.resizeTo.width = this.resizeTo.height/heightRatio;
11372				if ((typeof MinLWindowWidth != 'undefined') && (this.resizeTo.width < MinLWindowWidth))
11373					this.resizeTo.width = MinLWindowWidth ;
11374				$('lightwindow_data_slide_inner').setStyle({
11375					width: this.resizeTo.width+'px'
11376				});
11377			}
11378		}
11379		if (this.resizeTo.width+this.dimensions.cruft.width > this.dimensions.viewport.width) {
11380			var widthRatio = this.resizeTo.width/this.resizeTo.height;
11381			this.resizeTo.width = this.dimensions.viewport.width-2*this.dimensions.cruft.width-(2*this.options.viewportPadding);
11382			// We only care about ratio's with this window type
11383			if (this.windowType == 'image' || (this.windowType == 'media' && !this._getParameter('lightwindow_iframe_embed'))) {
11384				this.resizeTo.height = this.resizeTo.width/widthRatio;
11385				$('lightwindow_data_slide_inner').setStyle({
11386					height: this.resizeTo.height+'px'
11387				});
11388			}
11389		}
11390		
11391		if(Number(this._getParameter('lightwindow_thumb')) == 1) {
11392			var currentImageEl = $("lightwindow_contents").down("img.currentImage");
11393			if(currentImageEl.getHeight() > this.resizeTo.height)
11394				$(currentImageEl).setStyle({height: this.resizeTo.height+'px'});
11395		}
11396
11397	},
11398	//
11399	//  Set the Window to a preset size
11400	//
11401	_presetWindowSize : function() {
11402		
11403		if (this._getParameter('lightwindow_height')) {
11404			var thumbHeight = 0;
11405			if(Number(this._getParameter('lightwindow_thumb')) == 1) 
11406				thumbHeight = this.thumbnail.theight;
11407			
11408			this.resizeTo.height = parseFloat(this._getParameter('lightwindow_height')) - thumbHeight;
11409		}
11410		if (this._getParameter('lightwindow_width')) {
11411			this.resizeTo.width = parseFloat(this._getParameter('lightwindow_width'));
11412		}
11413	},
11414	//
11415	//  Process the Window
11416	//
11417	_processWindow : function() {
11418		// Clean out our effects
11419		this.dimensions.dataEffects = [];
11420
11421		if ((typeof MinLWindowWidth != 'undefined') && (this.resizeTo.width < MinLWindowWidth)) {
11422			this.element.width = MinLWindowWidth ;
11423			this.resizeTo.width = MinLWindowWidth ;
11424		}
11425
11426		// Set up the data-slide if we have caption information
11427		if (this.element.caption || this.element.author || (this.activeGallery && this.options.showGalleryCount)) {
11428			if (this.element.caption) {
11429				$('lightwindow_data_caption').innerHTML = this.element.caption;
11430				$('lightwindow_data_caption').setStyle({
11431					display: 'block'
11432				});
11433			} else {
11434				$('lightwindow_data_caption').setStyle({
11435					display: 'none'
11436				});
11437			}
11438			if (this.element.author) {
11439				$('lightwindow_data_author').innerHTML = this.element.author;
11440				$('lightwindow_data_author_container').setStyle({
11441					display: 'block'
11442				});
11443			} else {
11444				$('lightwindow_data_author_container').setStyle({
11445					display: 'none'
11446				});
11447			}
11448			if (this.activeGallery && this.options.showGalleryCount) {
11449				$('lightwindow_data_gallery_current').innerHTML = this.galleryLocation.current;
11450				$('lightwindow_data_gallery_total').innerHTML = this.galleryLocation.total;
11451				$('lightwindow_data_gallery_container').setStyle({
11452					display: 'block'
11453				});
11454			} else {
11455				$('lightwindow_data_gallery_container').setStyle({
11456					display: 'none'
11457				});
11458			}
11459
11460			$('lightwindow_data_slide_inner').setStyle({
11461				width: this.resizeTo.width+'px',
11462				height: 'auto',
11463				visibility: 'visible',
11464				display: 'block'
11465			});
11466			
11467			$('lightwindow_data_slide').setStyle({
11468				height: $('lightwindow_data_slide').getHeight()+'px',
11469				width: '1px',
11470				overflow: 'hidden',
11471				display: 'block'
11472			});
11473
11474		} else {
11475			$('lightwindow_data_slide').setStyle({
11476				display: 'none',
11477				width: 'auto'
11478			});
11479			$('lightwindow_data_slide_inner').setStyle({
11480				display: 'none',
11481				visibility: 'hidden',
11482				width: this.resizeTo.width+'px',
11483				height: '0px'
11484			});
11485		}
11486
11487		if (this.element.title != 'null') {
11488			$('lightwindow_title_bar_title').innerHTML = this.element.title;
11489		} else {
11490			$('lightwindow_title_bar_title').innerHTML = '';
11491		}
11492		
11493		/*$("fb_share").setStyle({display:'none'});
11494		if(this._getParameter('lightwindow_share') == 1)
11495			$("fb_share").setStyle({display:'block'});*/
11496	
11497		var originalContainerDimensions = {height: $('lightwindow_container').getHeight(), width: $('lightwindow_container').getWidth()};
11498		// Position the window
11499    	$('lightwindow_container').setStyle({
11500			height: 'auto',
11501			// We need to set the width to a px not auto as opera has problems with it
11502			width: $('lightwindow_container').getWidth()+this.options.contentOffset.width-(this.windowActive ? this.options.contentOffset.width : 0)+'px'
11503		});
11504		var newContainerDimensions = {height: $('lightwindow_container').getHeight(), width: $('lightwindow_container').getWidth()};
11505
11506		// We need to record the container dimension changes
11507		this.containerChange = {height: originalContainerDimensions.height-newContainerDimensions.height, width: originalContainerDimensions.width-newContainerDimensions.width};
11508
11509		// Get out general dimensions
11510		this.dimensions.container = {height: $('lightwindow_container').getHeight(), width: $('lightwindow_container').getWidth()};
11511		this.dimensions.cruft = {height: this.dimensions.container.height-$('lightwindow_contents').getHeight()+this.options.contentOffset.height, width: this.dimensions.container.width-$('lightwindow_contents').getWidth()+this.options.contentOffset.width};
11512		//Number(this.thumbnail.theight) + (Number(this.thumbnail.theight)/2)
11513		// Set Sizes if we need too
11514		this._presetWindowSize();
11515		this._resizeWindowToFit(); // Even if the window is preset we still don't want it to go outside of the viewport
11516
11517		if (!this.windowActive) {
11518			// Position the window
11519			var correctThumbs = 0;
11520			if(Number(this._getParameter('lightwindow_thumb')) == 1) 
11521				correctThumbs = this.thumbnail.theight / 4;
11522		   
11523		   $('lightwindow_container').setStyle({
11524				left: -(this.dimensions.container.width/2)+'px',
11525				top: -((this.dimensions.container.height/2) - correctThumbs)+'px'
11526			});
11527		}
11528		
11529	   	$('lightwindow_container').setStyle({
11530			height: this.dimensions.container.height+'px',
11531			width: this.dimensions.container.width+'px'
11532		});
11533
11534		// We are ready, lets show this puppy off!
11535		this._displayLightWindow('fixed', 'visible');
11536		this._animateLightWindow();
11537	},
11538	//
11539	//  Fire off our animation handler
11540	//
11541	_animateLightWindow : function() {
11542		if (this.options.animationHandler) {
11543			this.options.animationHandler().bind(this);
11544		} else {
11545			this._defaultAnimationHandler();
11546		}
11547	},
11548	//
11549	//  Fire off our transition handler
11550	//
11551	_handleNavigation : function(display) {
11552		if (this.options.navigationHandler) {
11553			this.options.navigationHandler().bind(this, display);
11554		} else {
11555			this._defaultDisplayNavigation(display);
11556		}
11557	},
11558	//
11559	//  Fire off our transition handler
11560	//
11561	_handleTransition : function() {
11562		if (this.options.transitionHandler) {
11563			this.options.transitionHandler().bind(this);
11564		} else {
11565			this._defaultTransitionHandler();
11566		}
11567	},
11568	//
11569	//  Handle the finish of the window animation
11570	//
11571	_handleFinalWindowAnimation : function(delay) {
11572		if (this.options.finalAnimationHandler) {
11573			this.options.finalAnimationHandler().bind(this, delay);
11574		} else {
11575			this._defaultfinalWindowAnimationHandler(delay);
11576		}
11577	},
11578	//
11579	//  Handle the gallery Animation
11580	//
11581	_handleGalleryAnimation : function(list) {
11582		if (this.options.galleryAnimationHandler) {
11583			this.options.galleryAnimationHandler().bind(this, list);
11584		} else {
11585			this._defaultGalleryAnimationHandler(list);
11586		}
11587	},
11588	//
11589	//  Display the navigation
11590	//
11591	_defaultDisplayNavigation : function(display) {
11592		if (display) {
11593			$('lightwindow_navigation').setStyle({
11594				display: 'block',
11595				height: $('lightwindow_contents').getHeight()+'px',
11596				width: '100%',
11597				marginTop: this.options.dimensions.titleHeight+'px'
11598			});
11599			
11600		} else {
11601			$('lightwindow_navigation').setStyle({
11602				display: 'none',
11603				height: 'auto',
11604				width: 'auto'
11605			});
11606		}
11607	},
11608	//
11609	//  This is the default animation handler for LightWindow
11610	//
11611	_defaultAnimationHandler : function() {
11612		// Now that we have figures out the cruft lets make the caption go away and add its effects
11613		if (this.element.caption || this.element.author || (this.activeGallery && this.options.showGalleryCount)) {
11614			$('lightwindow_data_slide').setStyle({
11615				display: 'none',
11616				width: 'auto'
11617			});
11618			this.dimensions.dataEffects.push(
11619				new Effect.SlideDown('lightwindow_data_slide', {sync: true}),
11620				new Effect.Appear('lightwindow_data_slide', {sync: true, from: 0.0, to: 1.0})
11621			);
11622		}
11623		
11624		// NOTE Dodal tomaž
11625		if(Number(this._getParameter('lightwindow_thumb')) == 1) {
11626			if(this.thumbnail.thumbLoaded === false) {
11627				$('lightwindow_galleries_thumbnail').setStyle({
11628					width: 100+'%',
11629					position: 'relative',
11630					overflow: 'hidden'
11631				});
11632				
11633				$("lightwindow_galleries_thumbnail").down("ul").setStyle({
11634					'marginLeft':'0px',
11635					'marginRight':'0px',
11636					'paddingLeft':'0px',
11637					'paddingRight':'0px'
11638				});
11639			
11640				this.dimensions.dataEffects.push(
11641					new Effect.SlideDown('lightwindow_galleries_thumbnail', {sync: true}),
11642					new Effect.Appear('lightwindow_galleries_thumbnail', {sync: true, from: 0.0, to: 1.0})
11643				);
11644			}
11645		}
11646	
11647		// Set up the Title if we have one
11648		$('lightwindow_title_bar_inner').setStyle({
11649			height: '0px',
11650			marginTop: this.options.dimensions.titleHeight+'px'
11651		});
11652
11653		// We always want the title bar as well
11654		this.dimensions.dataEffects.push(
11655			new Effect.Morph('lightwindow_title_bar_inner', {sync: true, style: {height: this.options.dimensions.titleHeight+'px', marginTop: '0px'}}),
11656		 	new Effect.Appear('lightwindow_title_bar_inner', {sync: true, from: 0.0, to: 1.0})
11657		);
11658
11659		if (!this.options.hideGalleryTab) {
11660			this._handleGalleryAnimation(false);
11661			if ($('lightwindow_galleries_tab_container').getHeight() == 0) {
11662				this.dimensions.dataEffects.push(
11663					new Effect.Morph('lightwindow_galleries_tab_container', {sync: true, style: {height: '20px', marginTop: '0px'}})
11664				);
11665				$('lightwindow_galleries').setStyle({
11666					width: '0px'
11667				});
11668			}
11669		}
11670
11671		var resized = false;
11672		var ratio = this.dimensions.container.width-$('lightwindow_contents').getWidth()+this.resizeTo.width+this.options.contentOffset.width;
11673		if (ratio != $('lightwindow_container').getWidth()) {
11674			new Effect.Parallel([
11675					new Effect.Scale('lightwindow_contents', 100*(this.resizeTo.width/$('lightwindow_contents').getWidth()), {scaleFrom: 100*($('lightwindow_contents').getWidth()/($('lightwindow_contents').getWidth()+(this.options.contentOffset.width))), sync: true,  scaleY: false, scaleContent: false}),
11676					new Effect.Scale('lightwindow_container', 100*(ratio/(this.dimensions.container.width)), {sync: true, scaleY: false, scaleFromCenter: true, scaleContent: false})
11677				], {
11678					duration: this.duration,
11679					delay: 0.25,
11680					queue: {position: 'end', scope: 'lightwindowAnimation'}
11681				}
11682			);
11683		}
11684
11685		// NOTE Pri konstrukciji je potrebno upoštevati tudi velikost thumbnailov - Tomaž
11686		if(Number(this._getParameter('lightwindow_thumb')) == 1) 
11687			this.dimensions.container.height = this.dimensions.container.height - $('lightwindow_galleries_thumbnail').down("img").height - 25;
11688		
11689		ratio = this.dimensions.container.height-$('lightwindow_contents').getHeight()+this.resizeTo.height+this.options.contentOffset.height;
11690		if (ratio != $('lightwindow_container').getHeight()) {
11691			new Effect.Parallel([
11692					new Effect.Scale('lightwindow_contents', 100*(this.resizeTo.height/$('lightwindow_contents').getHeight()), {scaleFrom: 100*($('lightwindow_contents').getHeight()/($('lightwindow_contents').getHeight()+(this.options.contentOffset.height))), sync: true, scaleX: false, scaleContent: false}),
11693					new Effect.Scale('lightwindow_container', 100*(ratio/(this.dimensions.container.height)), {sync: true, scaleX: false, scaleFromCenter: true, scaleContent: false})
11694				], {
11695					duration: this.duration,
11696					afterFinish: function() {
11697						if (this.dimensions.dataEffects.length > 0) {
11698							if (!this.options.hideGalleryTab) {
11699								$('lightwindow_galleries').setStyle({
11700									width: this.resizeTo.width+'px'
11701								});
11702							}
11703							new Effect.Parallel(this.dimensions.dataEffects, {
11704									duration: this.duration,
11705									afterFinish: function() {
11706										this._finishWindow();
11707									}.bind(this),
11708									queue: {position: 'end', scope: 'lightwindowAnimation'}
11709								}
11710							);
11711						}
11712					}.bind(this),
11713					queue: {position: 'end', scope: 'lightwindowAnimation'}
11714				}
11715			);
11716			resized = true;
11717		}
11718
11719		// We need to do our data effect since there was no resizing
11720		if (!resized && this.dimensions.dataEffects.length > 0) {
11721			new Effect.Parallel(this.dimensions.dataEffects, {
11722					duration: this.duration,
11723					beforeStart: function() {
11724						if (!this.options.hideGalleryTab) {
11725							$('lightwindow_galleries').setStyle({
11726								width: this.resizeTo.width+'px'
11727							});
11728						}
11729						if (this.containerChange.height != 0 || this.containerChange.width != 0) {
11730							new Effect.MoveBy('lightwindow_container', this.containerChange.height, this.containerChange.width, {transition: Effect.Transitions.sinoidal});
11731						}
11732					}.bind(this),
11733					afterFinish: function() {
11734						this._finishWindow();
11735					}.bind(this),
11736					queue: {position: 'end', scope: 'lightwindowAnimation'}
11737				}
11738			);
11739		}
11740
11741	},
11742	//
11743	//  Finish up Window Animation
11744	//
11745	_defaultfinalWindowAnimationHandler : function(delay) {
11746		if (this.windowType == 'media' || this._getParameter('lightwindow_loading_animation')) {
11747			// Because of major flickering with the overlay we just hide it in this case
11748			Element.hide('lightwindow_loading');
11749			this._handleNavigation(this.activeGallery);
11750			this._setStatus(false);
11751		} else {
11752			Effect.Fade('lightwindow_loading', {
11753				duration: 0.15,
11754				delay: 0,
11755				afterFinish: function() {
11756					// Just in case we need some scroll goodness (this also avoids the swiss cheese effect)
11757					if (this.windowType != 'image' && this.windowType != 'media' && this.windowType != 'external') {
11758						$('lightwindow_contents').setStyle({
11759							overflow: 'auto'
11760						});
11761					}
11762					this._handleNavigation(this.activeGallery);
11763					this._defaultGalleryAnimationHandler();
11764					this._setStatus(false);
11765				}.bind(this),
11766				queue: {position: 'end', scope: 'lightwindowAnimation'}
11767			});
11768		}
11769	},
11770	//
11771	//  Handle the gallery Animation
11772	//
11773	_defaultGalleryAnimationHandler : function(list) {
11774		if (this.activeGallery) {
11775			$('lightwindow_galleries').setStyle({
11776				display: 'block',
11777				marginBottom: $('lightwindow_data_slide').getHeight()+this.options.contentOffset.height/2+'px'
11778			});
11779			$('lightwindow_navigation').setStyle({
11780				height: $('lightwindow_contents').getHeight()-20+'px'
11781			});
11782		} else {
11783			$('lightwindow_galleries').setStyle({
11784				display: 'none'
11785			});
11786			$('lightwindow_galleries_tab_container').setStyle({
11787				height: '0px',
11788				marginTop: '20px'
11789			});
11790			$('lightwindow_galleries_list').setStyle({
11791				height: '0px'
11792			});
11793			return false;
11794		}
11795
11796		if (list) {
11797			if ($('lightwindow_galleries_list').getHeight() == 0) {
11798				var height = $('lightwindow_contents').getHeight()*0.80;
11799				$('lightwindow_galleries_tab_span').className = 'down';
11800			} else {
11801				var height = 0;
11802				$('lightwindow_galleries_tab_span').className = 'up';
11803			}
11804
11805			new Effect.Morph('lightwindow_galleries_list', {
11806				duration: this.duration,
11807				transition: Effect.Transitions.sinoidal,
11808				style: {height: height+'px'},
11809				beforeStart: function() {
11810					$('lightwindow_galleries_list').setStyle({
11811						overflow: 'hidden'
11812					});
11813				},
11814				afterFinish: function() {
11815					$('lightwindow_galleries_list').setStyle({
11816						overflow: 'auto'
11817					});
11818				},
11819				queue: {position: 'end', scope: 'lightwindowAnimation'}
11820			});
11821
11822		}
11823	},
11824	//
11825	//  Default Transition Handler
11826	//
11827	_defaultTransitionHandler : function() {
11828		// Clean out our effects
11829		this.dimensions.dataEffects = [];
11830
11831		// Now that we have figures out the cruft lets make the caption go away and add its effects
11832		if ($('lightwindow_data_slide').getStyle('display') != 'none') {
11833			this.dimensions.dataEffects.push(
11834				new Effect.SlideUp('lightwindow_data_slide', {sync: true}),
11835				new Effect.Fade('lightwindow_data_slide', {sync: true, from: 1.0, to: 0.0})
11836			);
11837		}
11838
11839		if (!this.options.hideGalleryTab) {
11840			if ($('lightwindow_galleries').getHeight() != 0 && !this.options.hideGalleryTab) {
11841				this.dimensions.dataEffects.push(
11842					new Effect.Morph('lightwindow_galleries_tab_container', {sync: true, style: {height: '0px', marginTop: '20px'}})
11843				);
11844			}
11845
11846			if ($('lightwindow_galleries_list').getHeight() != 0) {
11847				$('lightwindow_galleries_tab_span').className = 'up';
11848				this.dimensions.dataEffects.push(
11849					new Effect.Morph('lightwindow_galleries_list', {
11850						sync: true,
11851						style: {height: '0px'},
11852						transition: Effect.Transitions.sinoidal,
11853						beforeStart: function() {
11854							$('lightwindow_galleries_list').setStyle({
11855								overflow: 'hidden'
11856							});
11857						},
11858						afterFinish: function() {
11859							$('lightwindow_galleries_list').setStyle({
11860								overflow: 'auto'
11861							});
11862						}
11863					})
11864				);
11865			}
11866		}
11867
11868		// We always want the title bar as well
11869		this.dimensions.dataEffects.push(
11870			new Effect.Morph('lightwindow_title_bar_inner', {sync: true, style: {height: '0px', marginTop: this.options.dimensions.titleHeight+'px'}}),
11871		 	new Effect.Fade('lightwindow_title_bar_inner', {sync: true, from: 1.0, to: 0.0})
11872		);
11873
11874		new Effect.Parallel(this.dimensions.dataEffects, {
11875				duration: this.duration,
11876				afterFinish: function() {
11877					this._loadWindow();
11878				}.bind(this),
11879				queue: {position: 'end', scope: 'lightwindowAnimation'}
11880			}
11881		);
11882	},
11883	//
11884	//	Default Form handler for LightWindow
11885	//
11886	_defaultFormHandler : function(e) {
11887		var element = Event.element(e).parentNode;
11888		var parameterString = Form.serialize(this._getParameter('lightwindow_form', element.getAttribute('params')));
11889		if (this.options.formMethod == 'post') {
11890			var newAJAX = new Ajax.Request(element.href, {
11891				method: 'post',
11892				postBody: parameterString,
11893				onComplete: this.openWindow.bind(this, element)
11894			});
11895		} else if (this.options.formMethod == 'get') {
11896			var newAJAX = new Ajax.Request(element.href, {
11897				method: 'get',
11898				parameters: parameterString,
11899				onComplete: this.openWindow.bind(this, element)
11900			});
11901		}
11902	},
11903	//
11904	//  Wrap everything up
11905	//
11906	_finishWindow : function() {
11907		if (this.windowType == 'external') {
11908			// We set the externals source here because it allows for a much smoother animation
11909			$('lightwindow_iframe').setAttribute('src', this.element.href);
11910			this._handleFinalWindowAnimation(1);
11911		} else if (this.windowType == 'media') {
11912
11913			var outerObject = document.createElement('object');
11914			outerObject.setAttribute('classid', this.options.classids[this._fileExtension(this.contentToFetch)]);
11915			outerObject.setAttribute('codebase', this.options.codebases[this._fileExtension(this.contentToFetch)]);
11916			outerObject.setAttribute('id', 'lightwindow_media_primary');
11917			outerObject.setAttribute('name', 'lightwindow_media_primary');
11918			outerObject.setAttribute('width', this.resizeTo.width);
11919			outerObject.setAttribute('height', this.resizeTo.height);
11920			outerObject = this._addParamToObject('movie', this.contentToFetch, outerObject);
11921			outerObject = this._addParamToObject('src', this.contentToFetch, outerObject);
11922			outerObject = this._addParamToObject('controller', 'true', outerObject);
11923			outerObject = this._addParamToObject('wmode', 'transparent', outerObject);
11924			outerObject = this._addParamToObject('cache', 'false', outerObject);
11925			outerObject = this._addParamToObject('quality', 'high', outerObject);
11926
11927			if (!Prototype.Browser.IE) {
11928				var innerObject = document.createElement('object');
11929				innerObject.setAttribute('type', this.options.mimeTypes[this._fileExtension(this.contentToFetch)]);
11930				innerObject.setAttribute('data', this.contentToFetch);
11931				innerObject.setAttribute('id', 'lightwindow_media_secondary');
11932				innerObject.setAttribute('name', 'lightwindow_media_secondary');
11933				innerObject.setAttribute('width', this.resizeTo.width);
11934				innerObject.setAttribute('height', this.resizeTo.height);
11935				innerObject = this._addParamToObject('controller', 'true', innerObject);
11936				innerObject = this._addParamToObject('wmode', 'transparent', innerObject);
11937				innerObject = this._addParamToObject('cache', 'false', innerObject);
11938				innerObject = this._addParamToObject('quality', 'high', innerObject);
11939
11940				outerObject.appendChild(innerObject);
11941			}
11942
11943			if (this._getParameter('lightwindow_iframe_embed')) {
11944				this._appendIframe('no');
11945				this._writeToIframe(this._convertToMarkup(outerObject, 'object'));
11946			} else {
11947				this._appendObject(outerObject, 'object', $('lightwindow_contents'));
11948			}
11949
11950			this._handleFinalWindowAnimation(0);
11951		} else {
11952			this._handleFinalWindowAnimation(0);
11953		}
11954
11955		// Initialize any actions
11956		this._setupActions();
11957	}
11958}
11959
11960/*-----------------------------------------------------------------------------------------------*/
11961
11962Event.observe(window, 'load', lightwindowInit, false);
11963
11964//
11965//	Set up all of our links
11966//
11967var myLightWindow = null;
11968function lightwindowInit() {
11969	myLightWindow = new lightwindow({
11970		resizeSpeed : 10
11971	});
11972}
11973// script.aculo.us controls.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
11974
11975// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
11976//           (c) 2005-2009 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
11977//           (c) 2005-2009 Jon Tirsen (http://www.tirsen.com)
11978// Contributors:
11979//  Richard Livsey
11980//  Rahul Bhargava
11981//  Rob Wills
11982//
11983// script.aculo.us is freely distributable under the terms of an MIT-style license.
11984// For details, see the script.aculo.us web site: http://script.aculo.us/
11985
11986// Autocompleter.Base handles all the autocompletion functionality
11987// that's independent of the data source for autocompletion. This
11988// includes drawing the autocompletion menu, observing keyboard
11989// and mouse events, and similar.
11990//
11991// Specific autocompleters need to provide, at the very least,
11992// a getUpdatedChoices function that will be invoked every time
11993// the text inside the monitored textbox changes. This method
11994// should get the text for which to provide autocompletion by
11995// invoking this.getToken(), NOT by directly accessing
11996// this.element.value. This is to allow incremental tokenized
11997// autocompletion. Specific auto-completion logic (AJAX, etc)
11998// belongs in getUpdatedChoices.
11999//
12000// Tokenized incremental autocompletion is enabled automatically
12001// when an autocompleter is instantiated with the 'tokens' option
12002// in the options parameter, e.g.:
12003// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
12004// will incrementally autocomplete with a comma as the token.
12005// Additionally, ',' in the above example can be replaced with
12006// a token array, e.g. { tokens: [',', '\n'] } which
12007// enables autocompletion on multiple tokens. This is most
12008// useful when one of the tokens is \n (a newline), as it
12009// allows smart autocompletion after linebreaks.
12010
12011if(typeof Effect == 'undefined')
12012  throw("controls.js requires including script.aculo.us' effects.js library");
12013
12014var Autocompleter = { };
12015Autocompleter.Base = Class.create({
12016  baseInitialize: function(element, update, options) {
12017    element          = $(element);
12018    this.element     = element;
12019    this.update      = $(update);
12020    this.hasFocus    = false;
12021    this.changed     = false;
12022    this.active      = false;
12023    this.index       = 0;
12024    this.entryCount  = 0;
12025    this.oldElementValue = this.element.value;
12026
12027    if(this.setOptions)
12028      this.setOptions(options);
12029    else
12030      this.options = options || { };
12031
12032    this.options.paramName    = this.options.paramName || this.element.name;
12033    this.options.tokens       = this.options.tokens || [];
12034    this.options.frequency    = this.options.frequency || 0.4;
12035    this.options.minChars     = this.options.minChars || 1;
12036    this.options.onShow       = this.options.onShow ||
12037      function(element, update){
12038        if(!update.style.position || update.style.position=='absolute') {
12039          var cloneWidth = true;
12040		  if(element.hasAttribute("data-width")) {
12041			  cloneWidth = false;
12042		  }
12043			
12044		  update.style.position = 'absolute';
12045          Position.clone(element, update, {
12046			setWidth: cloneWidth,
12047			setHeight: false,
12048            offsetTop: element.offsetHeight
12049          });
12050		  
12051		  if(element.hasAttribute("data-width")) {
12052			  $(update).setStyle({'width': element.readAttribute("data-width")});
12053		  }
12054        }
12055        Effect.Appear(update,{duration:0.15});
12056      };
12057    this.options.onHide = this.options.onHide ||
12058      function(element, update){ new Effect.Fade(update,{duration:0.15}) };
12059
12060    if(typeof(this.options.tokens) == 'string')
12061      this.options.tokens = new Array(this.options.tokens);
12062    // Force carriage returns as token delimiters anyway
12063    if (!this.options.tokens.include('\n'))
12064      this.options.tokens.push('\n');
12065
12066    this.observer = null;
12067
12068    this.element.setAttribute('autocomplete','off');
12069
12070    Element.hide(this.update);
12071
12072    Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
12073    Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
12074  },
12075
12076  show: function() {
12077    if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
12078    if(!this.iefix &&
12079      (Prototype.Browser.IE) &&
12080      (Element.getStyle(this.update, 'position')=='absolute')) {
12081      new Insertion.After(this.update,
12082       '<iframe id="' + this.update.id + '_iefix" '+
12083       'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
12084       'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
12085      this.iefix = $(this.update.id+'_iefix');
12086    }
12087    if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
12088  },
12089
12090  fixIEOverlapping: function() {
12091    Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
12092    this.iefix.style.zIndex = 1;
12093    this.update.style.zIndex = 2;
12094    Element.show(this.iefix);
12095  },
12096
12097  hide: function() {
12098    this.stopIndicator();
12099    if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
12100    if(this.iefix) Element.hide(this.iefix);
12101  },
12102
12103  startIndicator: function() {
12104    if(this.options.indicator) Element.show(this.options.indicator);
12105  },
12106
12107  stopIndicator: function() {
12108    if(this.options.indicator) Element.hide(this.options.indicator);
12109  },
12110
12111  onKeyPress: function(event) {
12112	  if(this.active)
12113      switch(event.keyCode) {
12114       case Event.KEY_TAB:
12115       case Event.KEY_RETURN:
12116         this.selectEntry();
12117         Event.stop(event);
12118       case Event.KEY_ESC:
12119         this.hide();
12120         this.active = false;
12121         Event.stop(event);
12122         return;
12123       case Event.KEY_LEFT:
12124       case Event.KEY_RIGHT:
12125         return;
12126       case Event.KEY_UP:
12127         this.markPrevious();
12128         this.render();
12129		 Event.stop(event);
12130         return;
12131       case Event.KEY_DOWN:
12132		console.log("Test");
12133         this.markNext();
12134         this.render();
12135         Event.stop(event);
12136         return;
12137      }
12138     else
12139       if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
12140         (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
12141
12142    this.changed = true;
12143    this.hasFocus = true;
12144
12145    if(this.observer) clearTimeout(this.observer);
12146      this.observer =
12147        setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
12148  },
12149
12150  activate: function() {
12151    this.changed = false;
12152    this.hasFocus = true;
12153    this.getUpdatedChoices();
12154  },
12155
12156  onHover: function(event) {
12157    var element = Event.findElement(event, 'LI');
12158    if(this.index != element.autocompleteIndex)
12159    {
12160        this.index = element.autocompleteIndex;
12161        this.render();
12162    }
12163    Event.stop(event);
12164  },
12165
12166  onClick: function(event) {
12167    var element = Event.findElement(event, 'LI');
12168    this.index = element.autocompleteIndex;
12169    this.selectEntry();
12170    this.hide();
12171  },
12172
12173  onBlur: function(event) {
12174    // needed to make click events working
12175    setTimeout(this.hide.bind(this), 250);
12176    this.hasFocus = false;
12177    this.active = false;
12178  },
12179
12180  render: function() {
12181    if(this.entryCount > 0) {
12182      for (var i = 0; i < this.entryCount; i++)
12183        this.index==i ?
12184          Element.addClassName(this.getEntry(i),"selected") :
12185          Element.removeClassName(this.getEntry(i),"selected");
12186      if(this.hasFocus) {
12187        this.show();
12188        this.active = true;
12189      }
12190    } else {
12191      this.active = false;
12192      this.hide();
12193    }
12194  },
12195
12196  markPrevious: function() {
12197    if(this.index > 0) this.index--;
12198      else this.index = this.entryCount-1;
12199    //this.getEntry(this.index).scrollIntoView(true);
12200  },
12201
12202  markNext: function() {
12203    if(this.index < this.entryCount-1) this.index++;
12204      else this.index = 0;
12205    //this.getEntry(this.index).scrollIntoView(false);
12206  },
12207
12208  getEntry: function(index) {
12209    return this.update.firstChild.childNodes[index];
12210  },
12211
12212  getCurrentEntry: function() {
12213    return this.getEntry(this.index);
12214  },
12215
12216  selectEntry: function() {
12217    this.active = false;
12218    this.updateElement(this.getCurrentEntry());
12219  },
12220
12221  updateElement: function(selectedElement) {
12222    if (this.options.updateElement) {
12223      this.options.updateElement(selectedElement);
12224      return;
12225    }
12226    var value = '';
12227    if (this.options.select) {
12228      var nodes = $(selectedElement).select('.' + this.options.select) || [];
12229      if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
12230    } else
12231      value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
12232
12233    var bounds = this.getTokenBounds();
12234    if (bounds[0] != -1) {
12235      var newValue = this.element.value.substr(0, bounds[0]);
12236      var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
12237      if (whitespace)
12238        newValue += whitespace[0];
12239      this.element.value = newValue + value + this.element.value.substr(bounds[1]);
12240    } else {
12241      this.element.value = value;
12242    }
12243    this.oldElementValue = this.element.value;
12244    this.element.focus();
12245
12246    if (this.options.afterUpdateElement)
12247      this.options.afterUpdateElement(this.element, selectedElement);
12248  },
12249
12250  updateChoices: function(choices) {
12251    if(!this.changed && this.hasFocus) {
12252      this.update.innerHTML = choices;
12253      Element.cleanWhitespace(this.update);
12254      Element.cleanWhitespace(this.update.down());
12255
12256      if(this.update.firstChild && this.update.down().childNodes) {
12257        this.entryCount =
12258          this.update.down().childNodes.length;
12259        for (var i = 0; i < this.entryCount; i++) {
12260          var entry = this.getEntry(i);
12261          entry.autocompleteIndex = i;
12262          this.addObservers(entry);
12263        }
12264      } else {
12265        this.entryCount = 0;
12266      }
12267
12268      this.stopIndicator();
12269      this.index = 0;
12270
12271      if(this.entryCount==1 && this.options.autoSelect) {
12272        this.selectEntry();
12273        this.hide();
12274      } else {
12275        this.render();
12276      }
12277    }
12278  },
12279
12280  addObservers: function(element) {
12281    Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
12282    Event.observe(element, "click", this.onClick.bindAsEventListener(this));
12283  },
12284
12285  onObserverEvent: function() {
12286    this.changed = false;
12287    this.tokenBounds = null;
12288    if(this.getToken().length>=this.options.minChars) {
12289      this.getUpdatedChoices();
12290    } else {
12291      this.active = false;
12292      this.hide();
12293    }
12294    this.oldElementValue = this.element.value;
12295  },
12296
12297  getToken: function() {
12298    var bounds = this.getTokenBounds();
12299    return this.element.value.substring(bounds[0], bounds[1]).strip();
12300  },
12301
12302  getTokenBounds: function() {
12303    if (null != this.tokenBounds) return this.tokenBounds;
12304    var value = this.element.value;
12305    if (value.strip().empty()) return [-1, 0];
12306    var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
12307    var offset = (diff == this.oldElementValue.length ? 1 : 0);
12308    var prevTokenPos = -1, nextTokenPos = value.length;
12309    var tp;
12310    for (var index = 0, l = this.options.tokens.length; index < l; ++index) {
12311      tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
12312      if (tp > prevTokenPos) prevTokenPos = tp;
12313      tp = value.indexOf(this.options.tokens[index], diff + offset);
12314      if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
12315    }
12316    return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
12317  }
12318});
12319
12320Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) {
12321  var boundary = Math.min(newS.length, oldS.length);
12322  for (var index = 0; index < boundary; ++index)
12323    if (newS[index] != oldS[index])
12324      return index;
12325  return boundary;
12326};
12327
12328Ajax.Autocompleter = Class.create(Autocompleter.Base, {
12329  initialize: function(element, update, url, options) {
12330    this.baseInitialize(element, update, options);
12331    this.options.asynchronous  = true;
12332    this.options.onComplete    = this.onComplete.bind(this);
12333    this.options.defaultParams = this.options.parameters || null;
12334    this.url                   = url;
12335  },
12336
12337  getUpdatedChoices: function() {
12338    this.startIndicator();
12339
12340    var entry = encodeURIComponent(this.options.paramName) + '=' +
12341      encodeURIComponent(this.getToken());
12342
12343    this.options.parameters = this.options.callback ?
12344      this.options.callback(this.element, entry) : entry;
12345
12346    if(this.options.defaultParams)
12347      this.options.parameters += '&' + this.options.defaultParams;
12348
12349    new Ajax.Request(this.url, this.options);
12350  },
12351
12352  onComplete: function(request) {
12353    this.updateChoices(request.responseText);
12354  }
12355});
12356
12357// The local array autocompleter. Used when you'd prefer to
12358// inject an array of autocompletion options into the page, rather
12359// than sending out Ajax queries, which can be quite slow sometimes.
12360//
12361// The constructor takes four parameters. The first two are, as usual,
12362// the id of the monitored textbox, and id of the autocompletion menu.
12363// The third is the array you want to autocomplete from, and the fourth
12364// is the options block.
12365//
12366// Extra local autocompletion options:
12367// - choices - How many autocompletion choices to offer
12368//
12369// - partialSearch - If false, the autocompleter will match entered
12370//                    text only at the beginning of strings in the
12371//                    autocomplete array. Defaults to true, which will
12372//                    match text at the beginning of any *word* in the
12373//                    strings in the autocomplete array. If you want to
12374//                    search anywhere in the string, additionally set
12375//                    the option fullSearch to true (default: off).
12376//
12377// - fullSsearch - Search anywhere in autocomplete array strings.
12378//
12379// - partialChars - How many characters to enter before triggering
12380//                   a partial match (unlike minChars, which defines
12381//                   how many characters are required to do any match
12382//                   at all). Defaults to 2.
12383//
12384// - ignoreCase - Whether to ignore case when autocompleting.
12385//                 Defaults to true.
12386//
12387// It's possible to pass in a custom function as the 'selector'
12388// option, if you prefer to write your own autocompletion logic.
12389// In that case, the other options above will not apply unless
12390// you support them.
12391
12392Autocompleter.Local = Class.create(Autocompleter.Base, {
12393  initialize: function(element, update, array, options) {
12394    this.baseInitialize(element, update, options);
12395    this.options.array = array;
12396  },
12397
12398  getUpdatedChoices: function() {
12399    this.updateChoices(this.options.selector(this));
12400  },
12401
12402  setOptions: function(options) {
12403    this.options = Object.extend({
12404      choices: 10,
12405      partialSearch: true,
12406      partialChars: 2,
12407      ignoreCase: true,
12408      fullSearch: false,
12409      selector: function(instance) {
12410        var ret       = []; // Beginning matches
12411        var partial   = []; // Inside matches
12412        var entry     = instance.getToken();
12413        var count     = 0;
12414
12415        for (var i = 0; i < instance.options.array.length &&
12416          ret.length < instance.options.choices ; i++) {
12417
12418          var elem = instance.options.array[i];
12419          var foundPos = instance.options.ignoreCase ?
12420            elem.toLowerCase().indexOf(entry.toLowerCase()) :
12421            elem.indexOf(entry);
12422
12423          while (foundPos != -1) {
12424            if (foundPos == 0 && elem.length != entry.length) {
12425              ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
12426                elem.substr(entry.length) + "</li>");
12427              break;
12428            } else if (entry.length >= instance.options.partialChars &&
12429              instance.options.partialSearch && foundPos != -1) {
12430              if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
12431                partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
12432                  elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
12433                  foundPos + entry.length) + "</li>");
12434                break;
12435              }
12436            }
12437
12438            foundPos = instance.options.ignoreCase ?
12439              elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
12440              elem.indexOf(entry, foundPos + 1);
12441
12442          }
12443        }
12444        if (partial.length)
12445          ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
12446        return "<ul>" + ret.join('') + "</ul>";
12447      }
12448    }, options || { });
12449  }
12450});
12451
12452// AJAX in-place editor and collection editor
12453// Full rewrite by Christophe Porteneuve <[email protected]> (April 2007).
12454
12455// Use this if you notice weird scrolling problems on some browsers,
12456// the DOM might be a bit confused when this gets called so do this
12457// waits 1 ms (with setTimeout) until it does the activation
12458Field.scrollFreeActivate = function(field) {
12459  setTimeout(function() {
12460    Field.activate(field);
12461  }, 1);
12462};
12463
12464Ajax.InPlaceEditor = Class.create({
12465  initialize: function(element, url, options) {
12466    this.url = url;
12467    this.element = element = $(element);
12468    this.prepareOptions();
12469    this._controls = { };
12470    arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
12471    Object.extend(this.options, options || { });
12472    if (!this.options.formId && this.element.id) {
12473      this.options.formId = this.element.id + '-inplaceeditor';
12474      if ($(this.options.formId))
12475        this.options.formId = '';
12476    }
12477    if (this.options.externalControl)
12478      this.options.externalControl = $(this.options.externalControl);
12479    if (!this.options.externalControl)
12480      this.options.externalControlOnly = false;
12481    this._originalBackground = this.element.getStyle('background-color') || 'transparent';
12482    this.element.title = this.options.clickToEditText;
12483    this._boundCancelHandler = this.handleFormCancellation.bind(this);
12484    this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
12485    this._boundFailureHandler = this.handleAJAXFailure.bind(this);
12486    this._boundSubmitHandler = this.handleFormSubmission.bind(this);
12487    this._boundWrapperHandler = this.wrapUp.bind(this);
12488    this.registerListeners();
12489  },
12490  checkForEscapeOrReturn: function(e) {
12491    if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
12492    if (Event.KEY_ESC == e.keyCode)
12493      this.handleFormCancellation(e);
12494    else if (Event.KEY_RETURN == e.keyCode)
12495      this.handleFormSubmission(e);
12496  },
12497  createControl: function(mode, handler, extraClasses) {
12498    var control = this.options[mode + 'Control'];
12499    var text = this.options[mode + 'Text'];
12500    if ('button' == control) {
12501      var btn = document.createElement('input');
12502      btn.type = 'submit';
12503      btn.value = text;
12504      btn.className = 'editor_' + mode + '_button';
12505      if ('cancel' == mode)
12506        btn.onclick = this._boundCancelHandler;
12507      this._form.appendChild(btn);
12508      this._controls[mode] = btn;
12509    } else if ('link' == control) {
12510      var link = document.createElement('a');
12511      link.href = '#';
12512      link.appendChild(document.createTextNode(text));
12513      link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler;
12514      link.className = 'editor_' + mode + '_link';
12515      if (extraClasses)
12516        link.className += ' ' + extraClasses;
12517      this._form.appendChild(link);
12518      this._controls[mode] = link;
12519    }
12520  },
12521  createEditField: function() {
12522    var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
12523    var fld;
12524    if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) {
12525      fld = document.createElement('input');
12526      fld.type = 'text';
12527      var size = this.options.size || this.options.cols || 0;
12528      if (0 < size) fld.size = size;
12529    } else {
12530      fld = document.createElement('textarea');
12531      fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
12532      fld.cols = this.options.cols || 40;
12533    }
12534    fld.name = this.options.paramName;
12535    fld.value = text; // No HTML breaks conversion anymore
12536    fld.className = 'editor_field';
12537    if (this.options.submitOnBlur)
12538      fld.onblur = this._boundSubmitHandler;
12539    this._controls.editor = fld;
12540    if (this.options.loadTextURL)
12541      this.loadExternalText();
12542    this._form.appendChild(this._controls.editor);
12543  },
12544  createForm: function() {
12545    var ipe = this;
12546    function addText(mode, condition) {
12547      var text = ipe.options['text' + mode + 'Controls'];
12548      if (!text || condition === false) return;
12549      ipe._form.appendChild(document.createTextNode(text));
12550    };
12551    this._form = $(document.createElement('form'));
12552    this._form.id = this.options.formId;
12553    this._form.addClassName(this.options.formClassName);
12554    this._form.onsubmit = this._boundSubmitHandler;
12555    this.createEditField();
12556    if ('textarea' == this._controls.editor.tagName.toLowerCase())
12557      this._form.appendChild(document.createElement('br'));
12558    if (this.options.onFormCustomization)
12559      this.options.onFormCustomization(this, this._form);
12560    addText('Before', this.options.okControl || this.options.cancelControl);
12561    this.createControl('ok', this._boundSubmitHandler);
12562    addText('Between', this.options.okControl && this.options.cancelControl);
12563    this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
12564    addText('After', this.options.okControl || this.options.cancelControl);
12565  },
12566  destroy: function() {
12567    if (this._oldInnerHTML)
12568      this.element.innerHTML = this._oldInnerHTML;
12569    this.leaveEditMode();
12570    this.unregisterListeners();
12571  },
12572  enterEditMode: function(e) {
12573    if (this._saving || this._editing) return;
12574    this._editing = true;
12575    this.triggerCallback('onEnterEditMode');
12576    if (this.options.externalControl)
12577      this.options.externalControl.hide();
12578    this.element.hide();
12579    this.createForm();
12580    this.element.parentNode.insertBefore(this._form, this.element);
12581    if (!this.options.loadTextURL)
12582      this.postProcessEditField();
12583    if (e) Event.stop(e);
12584  },
12585  enterHover: function(e) {
12586    if (this.options.hoverClassName)
12587      this.element.addClassName(this.options.hoverClassName);
12588    if (this._saving) return;
12589    this.triggerCallback('onEnterHover');
12590  },
12591  getText: function() {
12592    return this.element.innerHTML.unescapeHTML();
12593  },
12594  handleAJAXFailure: function(transport) {
12595    this.triggerCallback('onFailure', transport);
12596    if (this._oldInnerHTML) {
12597      this.element.innerHTML = this._oldInnerHTML;
12598      this._oldInnerHTML = null;
12599    }
12600  },
12601  handleFormCancellation: function(e) {
12602    this.wrapUp();
12603    if (e) Event.stop(e);
12604  },
12605  handleFormSubmission: function(e) {
12606    var form = this._form;
12607    var value = $F(this._controls.editor);
12608    this.prepareSubmission();
12609    var params = this.options.callback(form, value) || '';
12610    if (Object.isString(params))
12611      params = params.toQueryParams();
12612    params.editorId = this.element.id;
12613    if (this.options.htmlResponse) {
12614      var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
12615      Object.extend(options, {
12616        parameters: params,
12617        onComplete: this._boundWrapperHandler,
12618        onFailure: this._boundFailureHandler
12619      });
12620      new Ajax.Updater({ success: this.element }, this.url, options);
12621    } else {
12622      var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
12623      Object.extend(options, {
12624        parameters: params,
12625        onComplete: this._boundWrapperHandler,
12626        onFailure: this._boundFailureHandler
12627      });
12628      new Ajax.Request(this.url, options);
12629    }
12630    if (e) Event.stop(e);
12631  },
12632  leaveEditMode: function() {
12633    this.element.removeClassName(this.options.savingClassName);
12634    this.removeForm();
12635    this.leaveHover();
12636    this.element.style.backgroundColor = this._originalBackground;
12637    this.element.show();
12638    if (this.options.externalControl)
12639      this.options.externalControl.show();
12640    this._saving = false;
12641    this._editing = false;
12642    this._oldInnerHTML = null;
12643    this.triggerCallback('onLeaveEditMode');
12644  },
12645  leaveHover: function(e) {
12646    if (this.options.hoverClassName)
12647      this.element.removeClassName(this.options.hoverClassName);
12648    if (this._saving) return;
12649    this.triggerCallback('onLeaveHover');
12650  },
12651  loadExternalText: function() {
12652    this._form.addClassName(this.options.loadingClassName);
12653    this._controls.editor.disabled = true;
12654    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
12655    Object.extend(options, {
12656      parameters: 'editorId=' + encodeURIComponent(this.element.id),
12657      onComplete: Prototype.emptyFunction,
12658      onSuccess: function(transport) {
12659        this._form.removeClassName(this.options.loadingClassName);
12660        var text = transport.responseText;
12661        if (this.options.stripLoadedTextTags)
12662          text = text.stripTags();
12663        this._controls.editor.value = text;
12664        this._controls.editor.disabled = false;
12665        this.postProcessEditField();
12666      }.bind(this),
12667      onFailure: this._boundFailureHandler
12668    });
12669    new Ajax.Request(this.options.loadTextURL, options);
12670  },
12671  postProcessEditField: function() {
12672    var fpc = this.options.fieldPostCreation;
12673    if (fpc)
12674      $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
12675  },
12676  prepareOptions: function() {
12677    this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
12678    Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
12679    [this._extraDefaultOptions].flatten().compact().each(function(defs) {
12680      Object.extend(this.options, defs);
12681    }.bind(this));
12682  },
12683  prepareSubmission: function() {
12684    this._saving = true;
12685    this.removeForm();
12686    this.leaveHover();
12687    this.showSaving();
12688  },
12689  registerListeners: function() {
12690    this._listeners = { };
12691    var listener;
12692    $H(Ajax.InPlaceEditor.Listeners).each(function(pair) {
12693      listener = this[pair.value].bind(this);
12694      this._listeners[pair.key] = listener;
12695      if (!this.options.externalControlOnly)
12696        this.element.observe(pair.key, listener);
12697      if (this.options.externalControl)
12698        this.options.externalControl.observe(pair.key, listener);
12699    }.bind(this));
12700  },
12701  removeForm: function() {
12702    if (!this._form) return;
12703    this._form.remove();
12704    this._form = null;
12705    this._controls = { };
12706  },
12707  showSaving: function() {
12708    this._oldInnerHTML = this.element.innerHTML;
12709    this.element.innerHTML = this.options.savingText;
12710    this.element.addClassName(this.options.savingClassName);
12711    this.element.style.backgroundColor = this._originalBackgroun
12711d;
12712    this.element.show();
12713  },
12714  triggerCallback: function(cbName, arg) {
12715    if ('function' == typeof this.options[cbName]) {
12716      this.options[cbName](this, arg);
12717    }
12718  },
12719  unregisterListeners: function() {
12720    $H(this._listeners).each(function(pair) {
12721      if (!this.options.externalControlOnly)
12722        this.element.stopObserving(pair.key, pair.value);
12723      if (this.options.externalControl)
12724        this.options.externalControl.stopObserving(pair.key, pair.value);
12725    }.bind(this));
12726  },
12727  wrapUp: function(transport) {
12728    this.leaveEditMode();
12729    // Can't use triggerCallback due to backward compatibility: requires
12730    // binding + direct element
12731    this._boundComplete(transport, this.element);
12732  }
12733});
12734
12735Object.extend(Ajax.InPlaceEditor.prototype, {
12736  dispose: Ajax.InPlaceEditor.prototype.destroy
12737});
12738
12739Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
12740  initialize: function($super, element, url, options) {
12741    this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
12742    $super(element, url, options);
12743  },
12744
12745  createEditField: function() {
12746    var list = document.createElement('select');
12747    list.name = this.options.paramName;
12748    list.size = 1;
12749    this._controls.editor = list;
12750    this._collection = this.options.collection || [];
12751    if (this.options.loadCollectionURL)
12752      this.loadCollection();
12753    else
12754      this.checkForExternalText();
12755    this._form.appendChild(this._controls.editor);
12756  },
12757
12758  loadCollection: function() {
12759    this._form.addClassName(this.options.loadingClassName);
12760    this.showLoadingText(this.options.loadingCollectionText);
12761    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
12762    Object.extend(options, {
12763      parameters: 'editorId=' + encodeURIComponent(this.element.id),
12764      onComplete: Prototype.emptyFunction,
12765      onSuccess: function(transport) {
12766        var js = transport.responseText.strip();
12767        if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
12768          throw('Server returned an invalid collection representation.');
12769        this._collection = eval(js);
12770        this.checkForExternalText();
12771      }.bind(this),
12772      onFailure: this.onFailure
12773    });
12774    new Ajax.Request(this.options.loadCollectionURL, options);
12775  },
12776
12777  showLoadingText: function(text) {
12778    this._controls.editor.disabled = true;
12779    var tempOption = this._controls.editor.firstChild;
12780    if (!tempOption) {
12781      tempOption = document.createElement('option');
12782      tempOption.value = '';
12783      this._controls.editor.appendChild(tempOption);
12784      tempOption.selected = true;
12785    }
12786    tempOption.update((text || '').stripScripts().stripTags());
12787  },
12788
12789  checkForExternalText: function() {
12790    this._text = this.getText();
12791    if (this.options.loadTextURL)
12792      this.loadExternalText();
12793    else
12794      this.buildOptionList();
12795  },
12796
12797  loadExternalText: function() {
12798    this.showLoadingText(this.options.loadingText);
12799    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
12800    Object.extend(options, {
12801      parameters: 'editorId=' + encodeURIComponent(this.element.id),
12802      onComplete: Prototype.emptyFunction,
12803      onSuccess: function(transport) {
12804        this._text = transport.responseText.strip();
12805        this.buildOptionList();
12806      }.bind(this),
12807      onFailure: this.onFailure
12808    });
12809    new Ajax.Request(this.options.loadTextURL, options);
12810  },
12811
12812  buildOptionList: function() {
12813    this._form.removeClassName(this.options.loadingClassName);
12814    this._collection = this._collection.map(function(entry) {
12815      return 2 === entry.length ? entry : [entry, entry].flatten();
12816    });
12817    var marker = ('value' in this.options) ? this.options.value : this._text;
12818    var textFound = this._collection.any(function(entry) {
12819      return entry[0] == marker;
12820    }.bind(this));
12821    this._controls.editor.update('');
12822    var option;
12823    this._collection.each(function(entry, index) {
12824      option = document.createElement('option');
12825      option.value = entry[0];
12826      option.selected = textFound ? entry[0] == marker : 0 == index;
12827      option.appendChild(document.createTextNode(entry[1]));
12828      this._controls.editor.appendChild(option);
12829    }.bind(this));
12830    this._controls.editor.disabled = false;
12831    Field.scrollFreeActivate(this._controls.editor);
12832  }
12833});
12834
12835//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! ****
12836//**** This only  exists for a while,  in order to  let ****
12837//**** users adapt to  the new API.  Read up on the new ****
12838//**** API and convert your code to it ASAP!            ****
12839
12840Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) {
12841  if (!options) return;
12842  function fallback(name, expr) {
12843    if (name in options || expr === undefined) return;
12844    options[name] = expr;
12845  };
12846  fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
12847    options.cancelLink == options.cancelButton == false ? false : undefined)));
12848  fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
12849    options.okLink == options.okButton == false ? false : undefined)));
12850  fallback('highlightColor', options.highlightcolor);
12851  fallback('highlightEndColor', options.highlightendcolor);
12852};
12853
12854Object.extend(Ajax.InPlaceEditor, {
12855  DefaultOptions: {
12856    ajaxOptions: { },
12857    autoRows: 3,                                // Use when multi-line w/ rows == 1
12858    cancelControl: 'link',                      // 'link'|'button'|false
12859    cancelText: 'cancel',
12860    clickToEditText: 'Click to edit',
12861    externalControl: null,                      // id|elt
12862    externalControlOnly: false,
12863    fieldPostCreation: 'activate',              // 'activate'|'focus'|false
12864    formClassName: 'inplaceeditor-form',
12865    formId: null,                               // id|elt
12866    highlightColor: '#ffff99',
12867    highlightEndColor: '#ffffff',
12868    hoverClassName: '',
12869    htmlResponse: true,
12870    loadingClassName: 'inplaceeditor-loading',
12871    loadingText: 'Loading...',
12872    okControl: 'button',                        // 'link'|'button'|false
12873    okText: 'ok',
12874    paramName: 'value',
12875    rows: 1,                                    // If 1 and multi-line, uses autoRows
12876    savingClassName: 'inplaceeditor-saving',
12877    savingText: 'Saving...',
12878    size: 0,
12879    stripLoadedTextTags: false,
12880    submitOnBlur: false,
12881    textAfterControls: '',
12882    textBeforeControls: '',
12883    textBetweenControls: ''
12884  },
12885  DefaultCallbacks: {
12886    callback: function(form) {
12887      return Form.serialize(form);
12888    },
12889    onComplete: function(transport, element) {
12890      // For backward compatibility, this one is bound to the IPE, and passes
12891      // the element directly.  It was too often customized, so we don't break it.
12892      new Effect.Highlight(element, {
12893        startcolor: this.options.highlightColor, keepBackgroundImage: true });
12894    },
12895    onEnterEditMode: null,
12896    onEnterHover: function(ipe) {
12897      ipe.element.style.backgroundColor = ipe.options.highlightColor;
12898      if (ipe._effect)
12899        ipe._effect.cancel();
12900    },
12901    onFailure: function(transport, ipe) {
12902      alert('Error communication with the server: ' + transport.responseText.stripTags());
12903    },
12904    onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
12905    onLeaveEditMode: null,
12906    onLeaveHover: function(ipe) {
12907      ipe._effect = new Effect.Highlight(ipe.element, {
12908        startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
12909        restorecolor: ipe._originalBackground, keepBackgroundImage: true
12910      });
12911    }
12912  },
12913  Listeners: {
12914    click: 'enterEditMode',
12915    keydown: 'checkForEscapeOrReturn',
12916    mouseover: 'enterHover',
12917    mouseout: 'leaveHover'
12918  }
12919});
12920
12921Ajax.InPlaceCollectionEditor.DefaultOptions = {
12922  loadingCollectionText: 'Loading options...'
12923};
12924
12925// Delayed observer, like Form.Element.Observer,
12926// but waits for delay after last key input
12927// Ideal for live-search fields
12928
12929Form.Element.DelayedObserver = Class.create({
12930  initialize: function(element, delay, callback) {
12931    this.delay     = delay || 0.5;
12932    this.element   = $(element);
12933    this.callback  = callback;
12934    this.timer     = null;
12935    this.lastValue = $F(this.element);
12936    Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
12937  },
12938  delayedListener: function(event) {
12939    if(this.lastValue == $F(this.element)) return;
12940    if(this.timer) clearTimeout(this.timer);
12941    this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
12942    this.lastValue = $F(this.element);
12943  },
12944  onTimerEvent: function() {
12945    this.timer = null;
12946    this.callback(this.element, $F(this.element));
12947  }
12948});/**
12949 * http://www.openjs.com/scripts/events/keyboard_shortcuts/
12950 * Version : 2.01.B
12951 * By Binny V A
12952 * License : BSD
12953 */
12954shortcut = {
12955	'all_shortcuts':{},//All the shortcuts are stored in this array
12956	'add': function(shortcut_combination,callback,opt) {
12957		//Provide a set of default options
12958		var default_options = {
12959			'type':'keydown',
12960			'propagate':false,
12961			'disable_in_input':false,
12962			'target':document,
12963			'keycode':false
12964		}
12965		if(!opt) opt = default_options;
12966		else {
12967			for(var dfo in default_options) {
12968				if(typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo];
12969			}
12970		}
12971
12972		var ele = opt.target;
12973		if(typeof opt.target == 'string') ele = document.getElementById(opt.target);
12974		var ths = this;
12975		shortcut_combination = shortcut_combination.toLowerCase();
12976
12977		//The function to be called at keypress
12978		var func = function(e) {
12979			e = e || window.event;
12980			
12981			if(opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields
12982				var element;
12983				if(e.target) element=e.target;
12984				else if(e.srcElement) element=e.srcElement;
12985				if(element.nodeType==3) element=element.parentNode;
12986
12987				if(element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return;
12988			}
12989	
12990			//Find Which key is pressed
12991			if (e.keyCode) code = e.keyCode;
12992			else if (e.which) code = e.which;
12993			var character = String.fromCharCode(code).toLowerCase();
12994			
12995			if(code == 188) character=","; //If the user presses , when the type is onkeydown
12996			if(code == 190) character="."; //If the user presses , when the type is onkeydown
12997
12998			var keys = shortcut_combination.split("+");
12999			//Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
13000			var kp = 0;
13001			
13002			//Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
13003			var shift_nums = {
13004				"`":"~",
13005				"1":"!",
13006				"2":"@",
13007				"3":"#",
13008				"4":"$",
13009				"5":"%",
13010				"6":"^",
13011				"7":"&",
13012				"8":"*",
13013				"9":"(",
13014				"0":")",
13015				"-":"_",
13016				"=":"+",
13017				";":":",
13018				"'":"\"",
13019				",":"<",
13020				".":">",
13021				"/":"?",
13022				"\\":"|"
13023			}
13024			//Special Keys - and their codes
13025			var special_keys = {
13026				'esc':27,
13027				'escape':27,
13028				'tab':9,
13029				'space':32,
13030				'return':13,
13031				'enter':13,
13032				'backspace':8,
13033	
13034				'scrolllock':145,
13035				'scroll_lock':145,
13036				'scroll':145,
13037				'capslock':20,
13038				'caps_lock':20,
13039				'caps':20,
13040				'numlock':144,
13041				'num_lock':144,
13042				'num':144,
13043				
13044				'pause':19,
13045				'break':19,
13046				
13047				'insert':45,
13048				'home':36,
13049				'delete':46,
13050				'end':35,
13051				
13052				'pageup':33,
13053				'page_up':33,
13054				'pu':33,
13055	
13056				'pagedown':34,
13057				'page_down':34,
13058				'pd':34,
13059	
13060				'left':37,
13061				'up':38,
13062				'right':39,
13063				'down':40,
13064	
13065				'f1':112,
13066				'f2':113,
13067				'f3':114,
13068				'f4':115,
13069				'f5':116,
13070				'f6':117,
13071				'f7':118,
13072				'f8':119,
13073				'f9':120,
13074				'f10':121,
13075				'f11':122,
13076				'f12':123
13077			}
13078	
13079			var modifiers = { 
13080				shift: { wanted:false, pressed:false},
13081				ctrl : { wanted:false, pressed:false},
13082				alt  : { wanted:false, pressed:false},
13083				meta : { wanted:false, pressed:false}	//Meta is Mac specific
13084			};
13085                        
13086			if(e.ctrlKey)	modifiers.ctrl.pressed = true;
13087			if(e.shiftKey)	modifiers.shift.pressed = true;
13088			if(e.altKey)	modifiers.alt.pressed = true;
13089			if(e.metaKey)   modifiers.meta.pressed = true;
13090                        
13091			for(var i=0; k=keys[i],i<keys.length; i++) {
13092				//Modifiers
13093				if(k == 'ctrl' || k == 'control') {
13094					kp++;
13095					modifiers.ctrl.wanted = true;
13096
13097				} else if(k == 'shift') {
13098					kp++;
13099					modifiers.shift.wanted = true;
13100
13101				} else if(k == 'alt') {
13102					kp++;
13103					modifiers.alt.wanted = true;
13104				} else if(k == 'meta') {
13105					kp++;
13106					modifiers.meta.wanted = true;
13107				} else if(k.length > 1) { //If it is a special key
13108					if(special_keys[k] == code) kp++;
13109					
13110				} else if(opt['keycode']) {
13111					if(opt['keycode'] == code) kp++;
13112
13113				} else { //The special keys did not match
13114					if(character == k) kp++;
13115					else {
13116						if(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase
13117							character = shift_nums[character]; 
13118							if(character == k) kp++;
13119						}
13120					}
13121				}
13122			}
13123			
13124			if(kp == keys.length && 
13125						modifiers.ctrl.pressed == modifiers.ctrl.wanted &&
13126						modifiers.shift.pressed == modifiers.shift.wanted &&
13127						modifiers.alt.pressed == modifiers.alt.wanted &&
13128						modifiers.meta.pressed == modifiers.meta.wanted) {
13129				callback(e);
13130	
13131				if(!opt['propagate']) { //Stop the event
13132					//e.cancelBubble is supported by IE - this will kill the bubbling process.
13133					e.cancelBubble = true;
13134					e.returnValue = false;
13135	
13136					//e.stopPropagation works in Firefox.
13137					if (e.stopPropagation) {
13138						e.stopPropagation();
13139						e.preventDefault();
13140					}
13141					return false;
13142				}
13143			}
13144		}
13145		this.all_shortcuts[shortcut_combination] = {
13146			'callback':func, 
13147			'target':ele, 
13148			'event': opt['type']
13149		};
13150		//Attach the function with the event
13151		if(ele.addEventListener) ele.addEventListener(opt['type'], func, false);
13152		else if(ele.attachEvent) ele.attachEvent('on'+opt['type'], func);
13153		else ele['on'+opt['type']] = func;
13154	},
13155
13156	//Remove the shortcut - just specify the shortcut and I will remove the binding
13157	'remove':function(shortcut_combination) {
13158		shortcut_combination = shortcut_combination.toLowerCase();
13159		var binding = this.all_shortcuts[shortcut_combination];
13160		delete(this.all_shortcuts[shortcut_combination])
13161		if(!binding) return;
13162		var type = binding['event'];
13163		var ele = binding['target'];
13164		var callback = binding['callback'];
13165
13166		if(ele.detachEvent) ele.detachEvent('on'+type, callback);
13167		else if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
13168		else ele['on'+type] = false;
13169	}
13170}//Javascript name: My Date Time Picker
13171//Date created: 16-Nov-2003 23:19
13172//Scripter: TengYong Ng
13173//Website: http://www.rainforestnet.com
13174//Copyright (c) 2003 TengYong Ng
13175//FileName: DateTimePicker_css.js
13176//Version: 2.1
13177// Note: Permission given to use and modify this script in ANY kind of applications if
13178//       header lines are left unchanged.
13179//Date changed: 24-Dec-2007 by Burgsoft (Holland)
13180//Changed: Year picker as drop down. Code optimised. Tables filled with blank fields as needed.
13181//Known (non fatal) issue: javascript remains running after month or year select
13182//New Css style version added by Yvan Lavoie (Québec, Canada) 29-Jan-2009
13183
13184//Global variables
13185var winCal;
13186var dtToday;
13187var Cal;
13188
13189var MonthName;
13190var WeekDayName1;
13191var WeekDayName2;
13192
13193var exDateTime;//Existing Date and Time
13194var selDate;//selected date. version 1.7
13195
13196var calSpanID = "calBorder"; // span ID
13197var domStyle=null; // span DOM object with style
13198var cnLeft="0";//left coordinate of calendar span
13199var cnTop="0";//top coordinate of calendar span
13200var xpos=0; // mouse x position
13201var ypos=0; // mouse y position
13202var calHeight=0; // calendar height
13203var CalWidth=208;// calendar width
13204var CellWidth=30;// width of day cell.
13205var TimeMode=24;// TimeMode value. 12 or 24
13206
13207//Configurable parameters
13208
13209//var WindowTitle="DateTime Picker";//Date Time Picker title.
13210var SpanBorderColor = "#cdcdcd";//span border color
13211var SpanBgColor = "#cdcdcd";//span background color
13212var WeekChar=2;//number of character for week day. if 2 then Mo,Tu,We. if 3 then Mon,Tue,Wed.
13213var DateSeparator=".";//Date Separator, you can change it to "-" if you want.
13214var ShowLongMonth=true;//Show long month name in Calendar header. example: "January".
13215var ShowMonthYear=true;//Show Month and Year in Calendar header.
13216var MonthYearColor="#bf1e2d";//Font Color of Month and Year in Calendar header.
13217var WeekHeadColor="#000000";//Background Color in Week header.
13218var SundayColor="#f1f1f1";//Background color of Sunday.
13219var SaturdayColor="#f1f1f1";//Background color of Saturday.
13220var WeekDayColor="white";//Background color of weekdays.
13221var FontColor="blue";//color of font in Calendar day cell.
13222var TodayColor="#0083cd";//Background color of today.
13223var SelDateColor="#0083cd";//Backgrond color of selected date in textbox.
13224var YrSelColor="#000000";//color of font of Year selector.
13225var MthSelColor="#000000";//color of font of Month selector if "MonthSelector" is "arrow".
13226var ThemeBg="";//Background image of Calendar window.
13227var CalBgColor="";//Backgroud color of Calendar window.
13228var PrecedeZero=true;//Preceding zero [true|false]
13229var MondayFirstDay=false;//true:Use Monday as first day; false:Sunday as first day. [true|false]  //added in version 1.7
13230var UseImageFiles = true;//Use image files with "arrows" and "close" button
13231//use the Month and Weekday in your preferred language.
13232var MonthName=["January", "February", "March", "April", "May", "June","July","August", "September", "October", "
13232November", "December"];
13233var WeekDayName1=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
13234var WeekDayName2=["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"];
13235
13236//end Configurable parameters
13237//end Global variable
13238
13239// Default events configuration
13240document.onmousedown = pickIt;
13241document.onmousemove = dragIt;
13242document.onmouseup = dropIt;
13243
13244function NewCssCal(pCtrl,pFormat,pScroller,pShowTime,pTimeMode,pHideSeconds) {
13245	// get current date and time
13246	dtToday = new Date();
13247	Cal=new Calendar(dtToday);
13248
13249	if ((pShowTime!=null) && (pShowTime)) {
13250		Cal.ShowTime=true;
13251		if ((pTimeMode!=null) &&((pTimeMode=='12')||(pTimeMode=='24')))	{
13252			TimeMode=pTimeMode;
13253		}
13254		else TimeMode='24';
13255
13256        if (pHideSeconds!=null)
13257        {
13258            if (pHideSeconds)
13259            {Cal.ShowSeconds=false;}
13260            else
13261            {Cal.ShowSeconds=true;}
13262        }
13263        else
13264        {
13265            Cal.ShowSeconds=false;
13266        }
13267	}
13268	if (pCtrl!=null)
13269		Cal.Ctrl=pCtrl;
13270
13271	if (pFormat!=null)
13272		Cal.Format=pFormat.toUpperCase();
13273	else
13274	    Cal.Format="MMDDYYYY";
13275
13276	if (pScroller!=null) {
13277		if (pScroller.toUpperCase()=="ARROW") {
13278			Cal.Scroller="ARROW";
13279		}
13280		else {
13281			Cal.Scroller="DROPDOWN";
13282		}
13283    }
13284	exDateTime=document.getElementById(pCtrl).value;
13285
13286	if (exDateTime!="")	{ //Parse existing Date String
13287		var Sp1;//Index of Date Separator 1
13288		var Sp2;//Index of Date Separator 2
13289		var tSp1;//Index of Time Separator 1
13290		var tSp1;//Index of Time Separator 2
13291		var strMonth;
13292		var strDate;
13293		var strYear;
13294		var intMonth;
13295		var YearPattern;
13296		var strHour;
13297		var strMinute;
13298		var strSecond;
13299		var winHeight;
13300		//parse month
13301		Sp1=exDateTime.indexOf(DateSeparator,0)
13302		Sp2=exDateTime.indexOf(DateSeparator,(parseInt(Sp1)+1));
13303
13304		var offset=parseInt(Cal.Format.toUpperCase().lastIndexOf("M"))-parseInt(Cal.Format.toUpperCase().indexOf("M"))-1;
13305		if ((Cal.Format.toUpperCase()=="DDMMYYYY") || (Cal.Format.toUpperCase()=="DDMMMYYYY")) {
13306			if (DateSeparator=="") {
13307				strMonth=exDateTime.substring(2,4+offset);
13308				strDate=exDateTime.substring(0,2);
13309				strYear=exDateTime.substring(4+offset,8+offset);
13310			}
13311			else {
13312				strMonth=exDateTime.substring(Sp1+1,Sp2);
13313				strDate=exDateTime.substring(0,Sp1);
13314				strYear=exDateTime.substring(Sp2+1,Sp2+5);
13315			}
13316		}
13317		else if ((Cal.Format.toUpperCase()=="MMDDYYYY") || (Cal.Format.toUpperCase()=="MMMDDYYYY")) {
13318			if (DateSeparator=="") {
13319				strMonth=exDateTime.substring(0,2+offset);
13320				strDate=exDateTime.substring(2+offset,4+offset);
13321				strYear=exDateTime.substring(4+offset,8+offset);
13322			}
13323			else {
13324				strMonth=exDateTime.substring(0,Sp1);
13325				strDate=exDateTime.substring(Sp1+1,Sp2);
13326				strYear=exDateTime.substring(Sp2+1,Sp2+5);
13327			}
13328		}
13329		else if ((Cal.Format.toUpperCase()=="YYYYMMDD") || (Cal.Format.toUpperCase()=="YYYYMMMDD")) {
13330			if (DateSeparator=="") {
13331				strMonth=exDateTime.substring(4,6+offset);
13332				strDate=exDateTime.substring(6+offset,8+offset);
13333				strYear=exDateTime.substring(0,4);
13334			}
13335			else {
13336				strMonth=exDateTime.substring(Sp1+1,Sp2);
13337				strDate=exDateTime.substring(Sp2+1,Sp2+3);
13338				strYear=exDateTime.substring(0,Sp1);
13339			}
13340		}
13341		if (isNaN(strMonth))
13342			intMonth=Cal.GetMonthIndex(strMonth);
13343		else
13344			intMonth=parseInt(strMonth,10)-1;
13345		if ((parseInt(intMonth,10)>=0) && (parseInt(intMonth,10)<12))
13346			Cal.Month=intMonth;
13347		//end parse month
13348		//parse Date
13349		if ((parseInt(strDate,10)<=Cal.GetMonDays()) && (parseInt(strDate,10)>=1))
13350			Cal.Date=strDate;
13351		//end parse Date
13352		//parse year
13353		YearPattern=/^\d{4}$/;
13354		if (YearPattern.test(strYear))
13355			Cal.Year=parseInt(strYear,10);
13356		//end parse year
13357		//parse time
13358		if (Cal.ShowTime==true)	{
13359			//parse AM or PM
13360			if (TimeMode==12) {
13361				strAMPM=exDateTime.substring(exDateTime.length-2,exDateTime.length)
13362				Cal.AMorPM=strAMPM;
13363			}
13364			tSp1=exDateTime.indexOf(":",0)
13365			tSp2=exDateTime.indexOf(":",(parseInt(tSp1)+1));
13366			if (tSp1>0)	{
13367				strHour=exDateTime.substring(tSp1,(tSp1)-2);
13368				Cal.SetHour(strHour);
13369				strMinute=exDateTime.substring(tSp1+1,tSp1+3);
13370				Cal.SetMinute(strMinute);
13371				strSecond=exDateTime.substring(tSp2+1,tSp2+3);
13372				Cal.SetSecond(strSecond);
13373			}
13374		}
13375	}
13376	selDate=new Date(Cal.Year,Cal.Month,Cal.Date);//version 1.7
13377	RenderCssCal(true);
13378}
13379
13380function RenderCssCal(bNewCal) {
13381	if (typeof bNewCal == "undefined" || bNewCal != true) {bNewCal = false;}
13382	var vCalHeader;
13383	var vCalData;
13384	var vCalTime="";
13385	var i;
13386	var j;
13387	var SelectStr;
13388	var vDayCount=0;
13389	var vFirstDay;
13390	calHeight = 0; // reset the window height on refresh
13391
13392	// Set the default cursor for the calendar
13393	winCalData="<span style='cursor:auto;'>\n";
13394
13395	if (ThemeBg==""){CalBgColor="bgcolor='"+WeekDayColor+"'"}
13396
13397	vCalHeader="<table "+CalBgColor+" background='"+ThemeBg+"' border=1 cellpadding=1 cellspacing=1 width='200' valign='top'>\n";
13398	//Table for Month & Year Selector
13399	vCalHeader+="<tr>\n<td colspan='7'>\n<table border=0 width=200 cellpadding=0 cellspacing=0>\n<tr>\n";
13400
13401	//******************Month and Year selector in dropdown list************************
13402	if (Cal.Scroller=="DROPDOWN") {
13403		vCalHeader+="<td align='center'><select name=\"MonthSelector\" onChange=\"javascript:Cal.SwitchMth(this.selectedIndex);RenderCssCal();\">\n";
13404		for (i=0;i<12;i++) {
13405			if (i==Cal.Month)
13406				SelectStr="Selected";
13407			else
13408				SelectStr="";
13409			    vCalHeader+="<option "+SelectStr+" value="+i+">"+MonthName[i]+"</option>\n";
13410		}
13411		vCalHeader+="</select></td>\n";
13412		//Year selector
13413		vCalHeader+="<td align='center'><select name=\"YearSelector\" size=\"1\" onChange=\"javascript:Cal.SwitchYear(this.value);RenderCssCal();\">\n";
13414		for (i = 1950; i < (dtToday.getFullYear() + 5);i++)	{
13415			if (i==Cal.Year)
13416				SelectStr="Selected";
13417			else
13418				SelectStr="";
13419			vCalHeader+="<option "+SelectStr+" value="+i+">"+i+"</option>\n";
13420		}
13421		vCalHeader+="</select></td>\n";
13422		calHeight += 30;
13423	}
13424	//******************End Month and Year selector in dropdown list*********************
13425	//******************Month and Year selector in arrow*********************************
13426	else if (Cal.Scroller=="ARROW")
13427  {
13428    if (UseImageFiles)
13429    {
13430  		vCalHeader+="<td><img onmousedown='javascript:Cal.DecYear();RenderCssCal();' src='P/DeskWM/Calendar/cal_fastreverse.gif' width='13' height='9' onmouseover='changeBorder(this, 0)' onmouseout='changeBorder(this, 1)' style='border:1px solid white'></td>\n";//Year scroller (decrease 1 year)
13431  		vCalHeader+="<td><img onmousedown='javascript:Cal.DecMonth();RenderCssCal();' src='P/DeskWM/Calendar/cal_reverse.gif' width='13' height='9' onmouseover='changeBorder(this, 0)' onmouseout='changeBorder(this, 1)' style='border:1px solid white'></td>\n";//Month scroller (decrease 1 month)
13432  		vCalHeader+="<td width='70%' class='calR'><font color='"+YrSelColor+"'>"+Cal.GetMonthName(ShowLongMonth)+" "+Cal.Year+"</font></td>\n"//Month and Year
13433  		vCalHeader+="<td><img onmousedown='javascript:Cal.IncMonth();RenderCssCal();' src='P/DeskWM/Calendar/cal_forward.gif' width='13' height='9' onmouseover='changeBorder(this, 0)' onmouseout='changeBorder(this, 1)' style='border:1px solid white'></td>\n";//Month scroller (increase 1 month)
13434  		vCalHeader+="<td><img onmousedown='javascript:Cal.IncYear();RenderCssCal();' src='P/DeskWM/Calendar/cal_fastforward.gif' width='13' height='9' onmouseover='changeBorder(this, 0)' onmouseout='changeBorder(this, 1)' style='border:1px solid white'></td>\n";//Year scroller (increase 1 year)
13435  	    calHeight += 22;
13436	  }
13437	  else
13438	  {
13439	  	vCalHeader+="<td><span id='dec_year' title='reverse year' onmousedown='javascript:Cal.DecYear();RenderCssCal();' onmouseover='changeBorder(this, 0)' onmouseout='changeBorder(this, 1)' style='border:1px solid white; color:"+YrSelColor+"'>-</span></td>";//Year scroller (decrease 1 year)
13440	  	vCalHeader+="<td><span id='dec_month' title='reverse month' onmousedown='javascript:Cal.DecMonth();RenderCssCal();' onmouseover='changeBorder(this, 0)' onmouseout='changeBorder(this, 1)' style='border:1px solid white'>&lt;</span></td>\n";//Month scroller (decrease 1 month)
13441  		vCalHeader+="<td width='70%' class='calR'><font color='"+YrSelColor+"'>"+Cal.GetMonthName(ShowLongMonth)+" "+Cal.Year+"</font></td>\n"//Month and Year
13442  		vCalHeader+="<td><span id='inc_month' title='forward month' onmousedown='javascript:Cal.IncMonth();RenderCssCal();' onmouseover='changeBorder(this, 0)' onmouseout='changeBorder(this, 1)' style='border:1px solid white'>&gt;</span></td>\n";//Month scroller (increase 1 month)
13443  		vCalHeader+="<td><span id='inc_year' title='forward year' onmousedown='javascript:Cal.IncYear();RenderCssCal();'  onmouseover='changeBorder(this, 0)' onmouseout='changeBorder(this, 1)' style='border:1px solid white; color:"+YrSelColor+"'>+</span></td>\n";//Year scroller (increase 1 year)
13444  	    calHeight += 22;
13445	  }
13446	}
13447	vCalHeader+="</tr>\n</table>\n</td>\n</tr>\n"
13448  //******************End Month and Year selector in arrow******************************
13449	//Calendar header shows Month and Year
13450	if ((ShowMonthYear)&&(Cal.Scroller=="DROPDOWN")) {
13451		vCalHeader+="<tr><td colspan='7' class='calR'>\n<font color='"+MonthYearColor+"'>"+Cal.GetMonthName(ShowLongMonth)+" "+Cal.Year+"</font>\n</td></tr>\n";
13452	    calHeight += 19;
13453	}
13454	//Week day header
13455	vCalHeader+="<tr bgcolor="+WeekHeadColor+">\n";
13456	var WeekDayName=new Array();//Added version 1.7
13457	if (MondayFirstDay==true)
13458		WeekDayName=WeekDayName2;
13459	else
13460		WeekDayName=WeekDayName1;
13461	for (i=0;i<7;i++) {
13462		vCalHeader+="<td width='"+CellWidth+"' class='calTD'><font color='white'><strong>"+WeekDayName[i].substr(0,WeekChar)+"</strong></font></td>\n";
13463	}
13464	calHeight += 19;
13465	vCalHeader+="</tr>\n";
13466	//Calendar detail
13467	CalDate=new Date(Cal.Year,Cal.Month);
13468	CalDate.setDate(1);
13469	vFirstDay=CalDate.getDay();
13470	//Added version 1.7
13471	if (MondayFirstDay==true) {
13472		vFirstDay-=1;
13473		if (vFirstDay==-1)
13474			vFirstDay=6;
13475	}
13476	//Added version 1.7
13477	vCalData="<tr>";
13478	calHeight += 19;
13479	for (i=0;i<vFirstDay;i++) {
13480		vCalData=vCalData+GenCell();
13481		vDayCount=vDayCount+1;
13482	}
13483	//Added version 1.7
13484	for (j=1;j<=Cal.GetMonDays();j++) {
13485		var strCell;
13486		if((vDayCount%7==0)&&(j > 1)) {
13487			vCalData=vCalData+"\n<tr>";
13488		}
13489		vDayCount=vDayCount+1;
13490		if ((j==dtToday.getDate())&&(Cal.Month==dtToday.getMonth())&&(Cal.Year==dtToday.getFullYear()))
13491			strCell=GenCell(j,true,TodayColor);//Highlight today's date
13492		else {
13493			if ((j==selDate.getDate())&&(Cal.Month==selDate.getMonth())&&(Cal.Year==selDate.getFullYear())) { //modified version 1.7
13494				strCell=GenCell(j,true,SelDateColor);
13495			}
13496			else {
13497				if (MondayFirstDay==true) {
13498					if (vDayCount%7==0)
13499						strCell=GenCell(j,false,SundayColor);
13500					else if ((vDayCount+1)%7==0)
13501						strCell=GenCell(j,false,SaturdayColor);
13502					else
13503						strCell=GenCell(j,null,WeekDayColor);
13504				}
13505				else {
13506					if (vDayCount%7==0)
13507						strCell=GenCell(j,false,SaturdayColor);
13508					else if ((vDayCount+6)%7==0)
13509						strCell=GenCell(j,false,SundayColor);
13510					else
13511						strCell=GenCell(j,null,WeekDayColor);
13512				}
13513			}
13514		}
13515		vCalData=vCalData+strCell;
13516
13517		if((vDayCount%7==0)&&(j<Cal.GetMonDays())) {
13518			vCalData=vCalData+"\n</tr>";
13519			calHeight += 19;
13520		}
13521	}
13522	// finish the table proper
13523	if(!(vDayCount%7) == 0) {
13524		while(!(vDayCount % 7) == 0) {
13525			vCalData=vCalData+GenCell();
13526			vDayCount=vDayCount+1;
13527		}
13528	}
13529	vCalData=vCalData+"\n</tr>";
13530
13531	//Time picker
13532	if (Cal.ShowTime)
13533	{
13534		var showHour;
13535		var ShowArrows=false;
13536		var HourCellWidth="35px"; //cell width with seconds.
13537		showHour=Cal.getShowHour();
13538
13539		if (Cal.ShowSeconds==false && TimeMode==24 )
13540        {
13541		   ShowArrows=true;
13542		   HourCellWidth="10px";
13543		}
13544
13545		vCalTime="\n<tr>\n<td colspan='7' align='center'><center>\n<table border='0' width='199px' cellpadding='0' cellspacing='2'>\n<tr>\n<td height='5px' width='"+HourCellWidth+"'>&nbsp;</td>\n";
13546
13547		if (ShowArrows && UseImageFiles)
13548		{
13549            vCalTime+="<td align='center'><table cellspacing='0' cellpadding='0' style='line-height:0pt'><tr><td><img onmousedown='javascript:Cal.SetHour(Cal.Hours + 1);RenderCssCal();' src='P/DeskWM/Calendar/cal_plus.gif' width='13' height='9' onmouseover='changeBorder(this, 0)' onmouseout='changeBorder(this, 1)' style='border:1px solid white'></td></tr><tr><td><img onmousedown='javascript:Cal.SetHour(Cal.Hours - 1);RenderCssCal();' src='P/DeskWM/Calendar/cal_minus.gif' width='13' height='9' onmouseover='changeBorder(this, 0)' onmouseout='changeBorder(this, 1)' style='border:1px solid white'></td></tr></table></td>\n";
13550		}
13551
13552		vCalTime+="<td align='center' width='22px'><input type='text' name='hour' maxlength=2 size=1 style=\"WIDTH: 22px\" value="+showHour+" onChange=\"javascript:Cal.SetHour(this.value)\">";
13553		vCalTime+="</td><td align='center'>:</td><td align='center' width='22px'>";
13554		vCalTime+="<input type='text' name='minute' maxlength=2 size=1 style=\"WIDTH: 22px\" value="+Cal.Minutes+" onChange=\"javascript:Cal.SetMinute(this.value)\">";
13555
13556		if (Cal.ShowSeconds) {
13557			vCalTime+="</td><td align='center'>:</td><td align='center' width='22px'>";
13558			vCalTime+="<input type='text' name='second' maxlength=2 size=1 style=\"WIDTH: 22px\" value="+Cal.Seconds+" onChange=\"javascript:Cal.SetSecond(parseInt(this.value,10))\">";
13559		}
13560		if (TimeMode==12) {
13561			var SelectAm =(Cal.AMorPM=="AM")? "Selected":"";
13562			var SelectPm =(Cal.AMorPM=="PM")? "Selected":"";
13563
13564            vCalTime+="</td><td>";
13565			vCalTime+="<select name=\"ampm\" onChange=\"javascript:Cal.SetAmPm(this.options[this.selectedIndex].value);\">\n";
13566			vCalTime+="<option "+SelectAm+" value=\"AM\">AM</option>";
13567			vCalTime+="<option "+SelectPm+" value=\"PM\">PM<option>";
13568			vCalTime+="</select>";
13569		}
13570		if (ShowArrows && UseImageFiles) {
13571		   vCalTime+="</td>\n<td align='center'><table cellspacing='0' cellpadding='0' style='line-height:0pt'><tr><td><img onmousedown='javascript:Cal.SetMinute(parseInt(Cal.Minutes,10) + 1);RenderCssCal();' src='P/DeskWM/Calendar/cal_plus.gif' width='13px' height='9px' onmouseover='changeBorder(this, 0)' onmouseout='changeBorder(this, 1)' style='border:1px solid white'></td></tr><tr><td><img onmousedown='javascript:Cal.SetMinute(parseInt(Cal.Minutes,10) - 1);RenderCssCal();' src='P/DeskWM/Calendar/cal_minus.gif' width='13px' height='9px' onmouseover='changeBorder(this, 0)' onmouseout='changeBorder(this, 1)' style='border:1px solid white'></td></tr></table>";
13572		}
13573		vCalTime+="</td>\n<td align='right' valign='bottom' width='"+HourCellWidth+"'>";
13574
13575	}
13576	else
13577		{vCalTime+="\n<tr>\n<td colspan='7' align='right'>";}
13578	if (UseImageFiles)
13579	{
13580        vCalTime+="<img onmousedown='javascript:closewin(\"" + Cal.Ctrl + "\");' src='P/DeskWM/Calendar/cal_close.gif' width='16' height='14' onmouseover='changeBorder(this, 0)' onmouseout='changeBorder(this, 1)' style='border:1px solid white'></td>";
13581    }
13582    else
13583    {
13584        vCalTime+="<span id='close_cal' title='close' onmousedown='javascript:closewin(\"" + Cal.Ctrl + "\");' onmouseover='changeBorder(this, 0)' onmouseout='changeBorder(this, 1)' style='border:1px solid white; font-family: Arial;font-size: 10pt;'>x</span></td>";
13585    }
13586
13587    vCalTime+="</tr>\n</table></center>\n</td>\n</tr>";
13588    calHeight += 31;
13589	vCalTime+="\n</table>\n</span>";
13590
13591    //end time picker
13592    var funcCalback="function callback(id, datum) {\n";
13593    funcCalback+=" var CalId = document.getElementById(id); CalId.value=datum;\n";
13594    funcCalback+=" if (Cal.ShowTime) {\n";
13595    funcCalback+=" CalId.value+=' '+Cal.getShowHour()+':'+Cal.Minutes;\n";
13596    funcCalback+=" if (Cal.ShowSeconds)\n  CalId.value+=':'+Cal.Seconds;\n";
13597    funcCalback+=" if (TimeMode==12)\n  CalId.value+=' '+Cal.getShowAMorPM();\n";
13598    funcCalback+="}\n CalId.focus(); \n winCal.style.visibility='hidden';\n}\n";
13599
13600	// determines if there is enough space to open the cal above the position where it is called
13601	WindowDim = getPageDimensions(true) ;
13602
13603	// determine position of created calendar
13604	if ((ypos-WindowDim.YOffset) > calHeight) {
13605	   ypos = ypos - calHeight;
13606	} else {
13607	   ypos += 16 ;
13608	}
13609	if ((xpos-WindowDim.XOffset+CalWidth) > WindowDim.windowWidth) {
13610	   xpos = xpos - CalWidth;
13611	}
13612	if (winCal == undefined) {
13613	   var headID = document.getElementsByTagName("head")[0];
13614
13615	   // add javascript function to the span cal
13616       var e = document.createElement("script");
13617       e.type = "text/javascript";
13618       e.language = "javascript";
13619       e.text = funcCalback;
13620       headID.appendChild(e);
13621
13622	   // add stylesheet to the span cal
13623	   var cssStr = ".calTD {font-family: verdana; font-size: 12px; text-align: center;}\n";
13624	   cssStr+= ".calR {font-family: verdana; font-size: 12px; text-align: center; font-weight: bold; color: #ffffff;}"
13625	   var style = document.createElement("style");
13626       style.type = "text/css";
13627       style.rel = "stylesheet";
13628       if(style.styleSheet) { // IE
13629          style.styleSheet.cssText = cssStr;
13630        }
13631	   else { // w3c
13632          var cssText = document.createTextNode(cssStr);
13633          style.appendChild(cssText);
13634		}
13635       headID.appendChild(style);
13636
13637	   // create the outer frame that allows the cal. to be moved
13638	   var span = document.createElement("span");
13639       span.id = calSpanID;
13640
13641	   with (span.style) {position = "absolute"; left = (xpos+8)+'px'; top = (ypos-8)+'px'; width = CalWidth; border = "solid 1px " + SpanBorderColor; padding = "0pt"; cursor = "move"; backgroundColor = SpanBgColor; zIndex = 100;}
13642
13643       document.body.appendChild(span)
13644       winCal=document.getElementById(calSpanID);
13645    }
13646    else {
13647	  winCal.style.visibility = "visible";
13648	  winCal.style.Height = calHeight;
13649
13650	  // set the position for a new calendar only
13651	  if(bNewCal==true){
13652	     winCal.style.left = (xpos+8)+'px';
13653	     winCal.style.top = (ypos-8)+'px';
13654	   }
13655	}
13656	winCal.innerHTML=winCalData + vCalHeader + vCalData + vCalTime;
13657	return true;
13658}
13659
13660function GenCell(pValue,pHighLight,pColor) { //Generate table cell with value
13661	var PValue;
13662	var PCellStr;
13663	var vColor;
13664	var vHLstr1;//HighLight string
13665	var vHlstr2;
13666	var vTimeStr;
13667
13668	if (pValue==null)
13669		PValue="";
13670	else
13671		PValue=pValue;
13672
13673	if (pColor!=null)
13674		vColor="bgcolor=\""+pColor+"\"";
13675	else
13676		vColor=CalBgColor;
13677	    if ((pHighLight!=null)&&(pHighLight)) {
13678		   vHLstr1="<font class='calR'>";vHLstr2="</font>";
13679		 }
13680	    else {
13681		   vHLstr1="";vHLstr2="";
13682		 }
13683	if (Cal.ShowTime) {
13684		vTimeStr=' '+Cal.Hours+':'+Cal.Minutes;
13685		if (Cal.ShowSeconds)
13686			vTimeStr+=':'+Cal.Seconds;
13687		if (TimeMode==12)
13688			vTimeStr+=' '+Cal.AMorPM;
13689	}
13690	else
13691		vTimeStr="";
13692	if (PValue!="")
13693		PCellStr="\n<td "+vColor+" class='calTD' style='cursor: pointer;' onClick=\"javascript:callback('"+Cal.Ctrl+"','"+Cal.FormatDate(PValue)+"');\">"+vHLstr1+PValue+vHLstr2+"</td>";
13694	else
13695		PCellStr="\n<td "+vColor+" class='calTD'>&nbsp;</td>";
13696	return PCellStr;
13697}
13698
13699function Calendar(pDate,pCtrl) {
13700	//Properties
13701	this.Date=pDate.getDate();//selected date
13702	this.Month=pDate.getMonth();//selected month number
13703	this.Year=pDate.getFullYear();//selected year in 4 digits
13704	this.Hours=pDate.getHours();
13705
13706	if (pDate.getMinutes()<10)
13707		this.Minutes="0"+pDate.getMinutes();
13708	else
13709		this.Minutes=pDate.getMinutes();
13710
13711	if (pDate.getSeconds()<10)
13712		this.Seconds="0"+pDate.getSeconds();
13713	else
13714		this.Seconds=pDate.getSeconds();
13715
13716	this.MyWindow=winCal;
13717	this.Ctrl=pCtrl;
13718	this.Format="ddMMyyyy";
13719	this.Separator=DateSeparator;
13720	this.ShowTime=false;
13721	this.Scroller="DROPDOWN";
13722	if (pDate.getHours()<12)
13723		this.AMorPM="AM";
13724	else
13725		this.AMorPM="PM";
13726	this.ShowSeconds=true;
13727}
13728
13729function GetMonthIndex(shortMonthName) {
13730	for (i=0;i<12;i++) {
13731		if (MonthName[i].substring(0,3).toUpperCase()==shortMonthName.toUpperCase())
13732		   {return i;}
13733	}
13734}
13735Calendar.prototype.GetMonthIndex=GetMonthIndex;
13736
13737function IncYear() {
13738	Cal.Year++;}
13739	Calendar.prototype.IncYear=IncYear;
13740
13741function DecYear() {
13742	Cal.Year--;}
13743	Calendar.prototype.DecYear=DecYear;
13744
13745function IncMonth() {
13746	Cal.Month++;
13747	if (Cal.Month>=12) {
13748		Cal.Month=0;
13749		Cal.IncYear();
13750	}
13751}
13752Calendar.prototype.IncMonth=IncMonth;
13753
13754function DecMonth() {
13755	Cal.Month--;
13756	if (Cal.Month<0) {
13757		Cal.Month=11;
13758		Cal.DecYear();
13759	}
13760}
13761Calendar.prototype.DecMonth=DecMonth;
13762
13763function SwitchMth(intMth) {
13764	Cal.Month=intMth;}
13765	Calendar.prototype.SwitchMth=SwitchMth;
13766
13767function SwitchYear(intYear) {
13768	Cal.Year=intYear;}
13769	Calendar.prototype.SwitchYear=SwitchYear;
13770
13771function SetHour(intHour) {
13772	var MaxHour;
13773	var MinHour;
13774	if (TimeMode==24) {
13775		MaxHour=23;MinHour=0}
13776	else if (TimeMode==12) {
13777		MaxHour=12;MinHour=1}
13778	else
13779		alert("TimeMode can only be 12 or 24");
13780	var HourExp=new RegExp("^\\d\\d");
13781	var SingleDigit=new RegExp("\\d");
13782
13783	if ((HourExp.test(intHour) || SingleDigit.test(intHour)) && (parseInt(intHour,10)>MaxHour)) {
13784	    intHour = MinHour;
13785	}
13786	else if ((HourExp.test(intHour) || SingleDigit.test(intHour)) && (parseInt(intHour,10)<MinHour)) {
13787		intHour = MaxHour;
13788	}
13789
13790	if (SingleDigit.test(intHour)) {
13791		intHour="0"+intHour+"";
13792	}
13793
13794	if (HourExp.test(intHour) && (parseInt(intHour,10)<=MaxHour) && (parseInt(intHour,10)>=MinHour)) {
13795		if ((TimeMode==12) && (Cal.AMorPM=="PM")) {
13796			if (parseInt(intHour,10)==12)
13797				Cal.Hours=12;
13798			else
13799				Cal.Hours=parseInt(intHour,10)+12;
13800		}
13801		else if ((TimeMode==12) && (Cal.AMorPM=="AM")) {
13802			if (intHour==12)
13803				intHour-=12;
13804			Cal.Hours=parseInt(intHour,10);
13805		}
13806		else if (TimeMode==24)
13807			Cal.Hours=parseInt(intHour,10);
13808	}
13809}
13810Calendar.prototype.SetHour=SetHour;
13811
13812function SetMinute(intMin) {
13813	var MaxMin=59;
13814	var MinMin=0;
13815	var SingleDigit=new RegExp("\\d");
13816	var SingleDigit2=new RegExp("^\\d{1}$");
13817	var MinExp=new RegExp("^\\d{2}$");
13818
13819	if ((MinExp.test(intMin) || SingleDigit.test(intMin)) && (parseInt(intMin,10)>MaxMin)) {
13820		intMin = MinMin;
13821	}
13822	else if ((MinExp.test(intMin) || SingleDigit.test(intMin)) && (parseInt(intMin,10)<MinMin))	{
13823		intMin = MaxMin;
13824	}
13825	var strMin = intMin + "";
13826	if (SingleDigit2.test(intMin)) {
13827		strMin="0"+strMin+"";
13828	}
13829	if ((MinExp.test(intMin) || SingleDigit.test(intMin))
13830	 && (parseInt(intMin,10)<=59) && (parseInt(intMin,10)>=0)) {
13831	 	Cal.Minutes=strMin;
13832	}
13833}
13834Calendar.prototype.SetMinute=SetMinute;
13835
13836function SetSecond(intSec) {
13837	var SecExp=new RegExp("^\\d\\d$");
13838	if (SecExp.test(intSec) && (intSec<60))
13839		Cal.Seconds=intSec;
13840}
13841Calendar.prototype.SetSecond=SetSecond;
13842
13843function SetAmPm(pvalue) {
13844	this.AMorPM=pvalue;
13845	if (pvalue=="PM") {
13846		this.Hours=(parseInt(this.Hours,10))+12;
13847		if (this.Hours==24)
13848			this.Hours=12;
13849	}
13850	else if (pvalue=="AM")
13851		this.Hours-=12;
13852}
13853Calendar.prototype.SetAmPm=SetAmPm;
13854
13855function getShowHour() {
13856	var finalHour;
13857    if (TimeMode==12) {
13858    	if (parseInt(this.Hours,10)==0) {
13859			this.AMorPM="AM";
13860			finalHour=parseInt(this.Hours,10)+12;
13861		}
13862		else if (parseInt(this.Hours,10)==12) {
13863			this.AMorPM="PM";
13864			finalHour=12;
13865		}
13866		else if (this.Hours>12)	{
13867			this.AMorPM="PM";
13868			if ((this.Hours-12)<10)
13869				finalHour="0"+((parseInt(this.Hours,10))-12);
13870			else
13871				finalHour=parseInt(this.Hours,10)-12;
13872		}
13873		else {
13874			this.AMorPM="AM";
13875			if (this.Hours<10)
13876				finalHour="0"+parseInt(this.Hours,10);
13877			else
13878				finalHour=this.Hours;
13879		}
13880	}
13881	else if (TimeMode==24) {
13882		if (this.Hours<10)
13883			finalHour="0"+parseInt(this.Hours,10);
13884		else
13885			finalHour=this.Hours;
13886	}
13887	return finalHour;
13888}
13889Calendar.prototype.getShowHour=getShowHour;
13890
13891function getShowAMorPM() {
13892	return this.AMorPM;
13893}
13894Calendar.prototype.getShowAMorPM=getShowAMorPM;
13895
13896function GetMonthName(IsLong) {
13897	var Month=MonthName[this.Month];
13898	if (IsLong)
13899		return Month;
13900	else
13901		return Month.substr(0,3);
13902}
13903Calendar.prototype.GetMonthName=GetMonthName;
13904
13905function GetMonDays() { //Get number of days in a month
13906	var DaysInMonth=[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
13907	if (this.IsLeapYear()) {
13908		DaysInMonth[1]=29;
13909	}
13910	return DaysInMonth[this.Month];
13911}
13912Calendar.prototype.GetMonDays=GetMonDays;
13913
13914function IsLeapYear() {
13915	if ((this.Year%4)==0) {
13916		if ((this.Year%100==0) && (this.Year%400)!=0) {
13917			return false;
13918		}
13919		else {
13920			return true;
13921		}
13922	}
13923	else {
13924		return false;
13925	}
13926}
13927Calendar.prototype.IsLeapYear=IsLeapYear;
13928
13929function FormatDate(pDate)
13930{
13931	var MonthDigit=this.Month+1;
13932	if (PrecedeZero==true) {
13933		if (pDate<10)
13934			pDate="0"+pDate;
13935		if (MonthDigit<10)
13936			MonthDigit="0"+MonthDigit;
13937	}
13938
13939	if (this.Format.toUpperCase()=="DDMMYYYY")
13940		return (pDate+DateSeparator+MonthDigit+DateSeparator+this.Year);
13941	else if (this.Format.toUpperCase()=="DDMMMYYYY")
13942		return (pDate+DateSeparator+this.GetMonthName(false)+DateSeparator+this.Year);
13943	else if (this.Format.toUpperCase()=="MMDDYYYY")
13944		return (MonthDigit+DateSeparator+pDate+DateSeparator+this.Year);
13945	else if (this.Format.toUpperCase()=="MMMDDYYYY")
13946		return (this.GetMonthName(false)+DateSeparator+pDate+DateSeparator+this.Year);
13947	else if (this.Format.toUpperCase()=="YYYYMMDD")
13948		return (this.Year+DateSeparator+MonthDigit+DateSeparator+pDate);
13949	else if (this.Format.toUpperCase()=="YYYYMMMDD")
13950		return (this.Year+DateSeparator+this.GetMonthName(false)+DateSeparator+pDate);
13951	else
13952		return (pDate+DateSeparator+(this.Month+1)+DateSeparator+this.Year);
13953}
13954Calendar.prototype.FormatDate=FormatDate;
13955
13956function closewin(id) {
13957   var CalId = document.getElementById(id);
13958   CalId.focus();
13959   winCal.style.visibility='hidden';
13960 }
13961
13962function changeBorder(element, col) {
13963  if (col == 0) {
13964    element.style.borderColor = "black";
13965    element.style.cursor = "pointer";
13966  }
13967  else {
13968    element.style.borderColor = "white";
13969    element.style.cursor = "auto";
13970  }
13971}
13972
13973function pickIt(evt) {
13974   var IE = document.all?true:false
13975
13976   // accesses the element that generates the event and retrieves its ID
13977   if (!IE) { // w3c
13978	  var objectID = evt.target.id;
13979      if (objectID.indexOf(calSpanID) != -1){
13980         var dom = document.getElementById(objectID);
13981         cnLeft=evt.pageX;
13982         cnTop=evt.pageY;
13983
13984         if (dom.offsetLeft){
13985           cnLeft = (cnLeft - dom.offsetLeft); cnTop = (cnTop - dom.offsetTop);
13986          }
13987       }
13988	  // get mouse position on click
13989	  xpos = (evt.pageX);
13990	  ypos = (evt.pageY);
13991	}
13992   else { // IE
13993	  var objectID = event.srcElement.id;
13994      cnLeft=event.offsetX;
13995      cnTop=(event.offsetY);
13996	  // get mouse position on click
13997	  var de = document.documentElement;
13998      var b = document.body;
13999      xpos = event.clientX + (de.scrollLeft || b.scrollLeft) - (de.clientLeft || 0);
14000      ypos = event.clientY + (de.scrollTop || b.scrollTop) - (de.clientTop || 0);
14001    }
14002   // verify if this is a valid element to pick
14003   if (objectID.indexOf(calSpanID) != -1){
14004      domStyle = document.getElementById(objectID).style;
14005    }
14006   if (domStyle) {
14007      domStyle.zIndex = 100;
14008      return false;
vendor: 3,313 bytes, lines 14009-14035
14009    }
14010   else {
14011      domStyle = null;
14012      return;
14013    }
14014 }
14015
14016function dragIt(evt) {
14017   if (domStyle) {
14018      if (window.Event) {
14019         domStyle.left = (evt.clientX-cnLeft + document.body.scrollLeft)+'px';
14020         domStyle.top = (evt.clientY-cnTop + document.body.scrollTop)+'px';
14021       }
14022      else {
14023         domStyle.left = (event.clientX-cnLeft + document.body.scrollLeft)+'px';
14024         domStyle.top = (event.clientY-cnTop + document.body.scrollTop)+'px';
14025       }
14026    }
14027 }
14028
14029function dropIt() {
14030   if (domStyle) {
14031      domStyle.zIndex = 0;
14032      domStyle = null;
14033    }
14034 }/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */
14035!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=Array.isArray(d)))?(e?(e=!1,f=c&&Array.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v
vendor: 19,680 bytes, line 14035
14035)},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e);return!1}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}return!1}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>
vendor: 64,249 bytes, lines 14035-14037
140352&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,N,e),g(f,c,O,e)):(f++,j.call(a,g(f,c,N,e),g(f,c,O,e),g(f,c,N,c.notifyWith))):(d!==N&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S),
14036a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},U=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function V(){this.expando=r.expando+V.uid++}V.uid=1,V.prototype={cache:function(a){var b=a[this.expando];return b||(b={},U(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){Array.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(L)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var W=new V,X=new V,Y=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function $(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:Y.test(a)?JSON.parse(a):a)}function _(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Z,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c=$(c)}catch(e){}X.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return X.hasData(a)||W.hasData(a)},data:function(a,b,c){return X.access(a,b,c)},removeData:function(a,b){X.remove(a,b)},_data:function(a,b,c){return W.access(a,b,c)},_removeData:function(a,b){W.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=X.get(f),1===f.nodeType&&!W.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),_(f,d,e[d])));W.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){X.set(this,a)}):T(this,function(b){var c;if(f&&void 0===b){if(c=X.get(f,a),void 0!==c)return c;if(c=_(f,a),void 0!==c)return c}else this.each(function(){X.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=W.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var aa=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ba=new RegExp("^(?:([+-])=|)("+aa+")([a-z%]*)$","i"),ca=["Top","Right","Bottom","Left"],da=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ea=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function fa(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&ba.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ga={};function ha(a){var b,c=a.ownerDocument,d=a.nodeName,e=ga[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ga[d]=e,e)}function ia(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=W.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&da(d)&&(e[f]=ha(d))):"none"!==c&&(e[f]="none",W.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ia(this,!0)},hide:function(){return ia(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){da(this)?r(this).show():r(this).hide()})}});var ja=/^(?:checkbox|radio)$/i,ka=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c<d;c++)W.set(a[c],"globalEval",!b||W.get(b[c],"globalEval"))}var pa=/<|&#?\w+;/;function qa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(pa.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ka.exec(f)||["",""])[1].toLowerCase(),i=ma[h]||ma._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g,h=[],i=b.delegateCount,j=a.target;if(i&&j.nodeType&&!("click"===a.type&&a.button>=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c<i;c++)d=b[c],e=d.selector+" ",void 0===g[e]&&(g[e]=d.needsContext?r(e,this).index(j)>-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i<b.length&&h.push({elem:j,handlers:b.slice(i)}),h},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==xa()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===xa()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&B(this,"input"))return this.click(),!1},_default:function(a){return B(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?va:wa,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:wa,isPropagationStopped:wa,isImmediatePropagationStopped:wa,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=va,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=va,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=va,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&sa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ta.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return ya(this,a,b,c,d)},one:function(a,b,c,d){return ya(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=wa),this.each(function(){r.event.remove(this,a,c,b)})}});var za=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/<script|<style|<link/i,Ba=/checked\s*(?:[^=]|=\s*.checked.)/i,Ca=/^true\/(.*)/,Da=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}X.hasData(a)&&(h=X.access(a),i=r.extend({},h),X.set(b,i))}}function Ia(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ja.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ja(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,na(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ga),l=0;l<i;l++)j=h[l],la.test(j.type||"")&&!W.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Da,""),k))}return a}function Ka(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(na(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&oa(na(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(za,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d<e;d++)Ia(f[d],g[d]);if(b)if(c)for(f=f||na(a),g=g||na(h),d=0,e=f.length;d<e;d++)Ha(f[d],g[d]);else Ha(a,h);return g=na(h,"script"),g.length>0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(na(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ja(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(na(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var La=/^margin/,Ma=new RegExp("^("+aa+")(?!px)[a-z%]+$","i"),Na=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",ra.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,ra.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Oa(a,b,c){var d,e,f,g,h=a.style;return c=c||Na(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ma.test(g)&&La.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Pa(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Qa=/^(none|table(?!-c[ea]).+)/,Ra=/^--/,Sa={position:"absolute",visibility:"hidden",display:"block"},Ta={letterSpacing:"0",fontWeight:"400"},Ua=["Webkit","Moz","ms"],Va=d.createElement("div").style;function Wa(a){if(a in Va)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ua.length;while(c--)if(a=Ua[c]+b,a in Va)return a}function Xa(a){var b=r.cssProps[a];return b||(b=r.cssProps[a]=Wa(a)||a),b}function Ya(a,b,c){var d=ba.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Za(a,b,c,d,e){var f,g=0;for(f=c===(d?"border":"content")?4:"width"===b?1:0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+ca[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+ca[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+ca[f]+"Width",!0,e))):(g+=r.css(a,"padding"+ca[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+ca[f]+"Width",!0,e)));return g}function $a(a,b,c){var d,e=Na(a),f=Oa(a,b,e),g="border-box"===r.css(a,"boxSizing",!1,e);return Ma.test(f)?f:(d=g&&(o.boxSizingReliable()||f===a.style[b]),"auto"===f&&(f=a["offset"+b[0].toUpperCase()+b.slice(1)]),f=parseFloat(f)||0,f+Za(a,b,c||(g?"border":"content"),d,e)+"px")}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Oa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=Ra.test(b),j=a.style;return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:j[b]:(f=typeof c,"string"===f&&(e=ba.exec(c))&&e[1]&&(c=fa(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(j[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i?j.setProperty(b,c):j[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b),i=Ra.test(b);return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Oa(a,b,d)),"normal"===e&&b in Ta&&(e=Ta[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Qa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?$a(a,b,d):ea(a,Sa,function(){return $a(a,b,d)})},set:function(a,c,d){var e,f=d&&Na(a),g=d&&Za(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=ba.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ya(a,c,g)}}}),r.cssHooks.marginLeft=Pa(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Oa(a,"marginLeft"))||a.getBoundingClientRect().left-ea(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+ca[d]+b]=f[d]||f[d-2]||f[0];return e}},La.test(a)||(r.cssHooks[a+b].set=Ya)}),r.fn.extend({css:function(a,b){return T(this,function(a,b,c){var d,e,f={},g=0;if(Array.isArray(b)){for(d=Na(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&da(a),q=W.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],cb.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=W.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ia([a],!0),j=a.style.display||j,k=r.css(a,"display"),ia([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=W.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ia([a],!0),m.done(function(){p||ia([a]),W.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=hb(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],Array.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=kb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=ab||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(i||h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:ab||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);f<g;f++)if(d=kb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,hb,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j}r.Animation=r.extend(kb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return fa(c.elem,a,ba.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(L);for(var c,d=0,e=a.length;d<e;d++)c=a[d],kb.tweeners[c]=kb.tweeners[c]||[],kb.tweeners[c].unshift(b)},prefilters:[ib],prefilter:function(a,b){b?kb.prefilters.unshift(a):kb.prefilters.push(a)}}),r.speed=function(a,b,c){var d=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off?d.duration=0:"number"!=typeof d.duration&&(d.duration in r.fx.speeds?d.duration=r.fx.speeds[d.duration]:d.duration=r.fx.speeds._default),null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){r.isFunction(d.old)&&d.old.call(this),d.queue&&r.dequeue(this,d.queue)},d},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(da).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=kb(this,r.extend({},a),f);(e||W.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=W.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&db.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=W.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),r.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(ab=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),ab=void 0},r.fx.timer=function(a){r.timers.push(a),r.fx.start()},r.fx.interval=13,r.fx.start=function(){bb||(bb=!0,eb())},r.fx.stop=function(){bb=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var lb,mb=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return T(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),
14037null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d<i;d++)if(c=e[d],(c.selected||d===f)&&!c.disabled&&(!c.parentNode.disabled||!B(c.parentNode,"optgroup"))){if(b=r(c).val(),g)return b;h.push(b)}return h},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Tb=[],Ub=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Tb.pop()||r.expando+"_"+ub++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Ub.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ub.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Ub,"$1"+e):b.jsonp!==!1&&(b.url+=(vb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Tb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=C.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=qa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=pb(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length},r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),b=f.ownerDocument,c=b.documentElement,e=b.defaultView,{top:d.top+e.pageYOffset-c.clientTop,left:d.left+e.pageXOffset-c.clientLeft}):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),B(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||ra})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return T(this,function(a,d,e){var f;return r.isWindow(a)?f=a:9===a.nodeType&&(f=a.defaultView),void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Pa(o.pixelPosition,function(a,c){if(c)return c=Oa(a,b),Ma.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return T(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.holdReady=function(a){a?r.readyWait++:r.ready(!0)},r.isArray=Array.isArray,r.parseJSON=JSON.parse,r.nodeName=B,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Vb=a.jQuery,Wb=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Wb),b&&a.jQuery===r&&(a.jQuery=Vb),r},b||(a.jQuery=a.$=r),r});
14038var $JQ = jQuery.noConflict() ;
14039
14040var CursorTip ;
14041var PremikanjeHeader=false;
14042var TempId=0;
14043var Browser = CheckBrowser() ;
14044var TiskajVNovoOkno = false ;
14045var ns6=document.getElementById&&!document.all
14046var ie4=document.all&&navigator.userAgent.indexOf("Opera")==-1
14047var modalWin = "";
14048var X = 0 ;
14049var WaitArr = [] ;
14050var PageWidth ;
14051var PageHeight ;
14052var POStiskalnik = 0 ;	// Spremenljivka za izbrani POS tiskalnik, iz katerega se tiskajo nalepke
14053
14054// Osnovna ločila za Slovenščino
14055var DecLoc = "," ;
14056var TousLoc = "." ;
14057var FixDec = true ;
14058var LocaleRegX = new RegExp ("(-|)(\\d*)(\\"+TousLoc+"|)(\\d*)(\\"+TousLoc+"|)(\\d*)(\\"+TousLoc+"|)(\\d*)(\\"+TousLoc+"|)(\\d*)(\\"+TousLoc+"|)(\\d*)(\\"+DecLoc+"|)(\\d*)","") ;
14059var LocaleRegXObr = new RegExp ("(-|)(\\d*)(\\"+DecLoc+"|)(\\d*)(\\"+DecLoc+"|)(\\d*)(\\"+DecLoc+"|)(\\d*)(\\"+DecLoc+"|)(\\d*)(\\"+DecLoc+"|)(\\d*)(\\"+TousLoc+"|)(\\d*)","") ;
14060var viewportwidth;
14061var viewportheight;
14062var MainTarg;
14063var infoMainTarg ;
14064var kosKolChangerTimeout ;
14065
14066// Za preprecevanje veckratnega nalaganja kosarice
14067var semaforKosaricaIsLoading = false ;
14068var kosaricaLoadedVsebina ;
14069var kosaricaLoadedVsebinaTimer ;
14070
14071// Compare properties of two objects for shallow equalty
14072function shallowEqual(object1, object2) {
14073	if (object1 && object2) {
14074		const keys1 = Object.keys(object1);
14075		const keys2 = Object.keys(object2);
14076
14077		for (let key of keys1) {
14078			// we ignore objects
14079			if ((typeof(object1[key]) != "object") && (typeof(object1[key]) != "function")) {
14080				if (object1[key] !== object2[key]) {
14081					console.log("shallowEqual - key:"+key+" # "+object1[key]+" != "+object2[key]) ;
14082					return false;
14083				}
14084			}
14085		}
14086		return true;
14087	} else {
14088		return false ;
14089	}
14090}
14091
14092// Extend "console" object with custom color loging functions
14093console.funcStart = function(message) {
14094	console.log("%c[FUNCTION] "+message, "color:blue; background-color:lightgreen;") ;
14095}
14096console.funcEnd = function(message) {
14097	console.log("%c[FUNCTION] "+message, "color:red; background-color:lightgreen;") ;
14098}
14099
14100// nova lightWindow okna naj se odpirajo preko skupne funkcije
14101var lightWindowStack = new Object() ;
14102lightWindowStack.stack = [] ;
14103lightWindowStack.isOpen = false ;
14104lightWindowStack.currentWindow ;
14105lightWindowStack.openWindow = function(lwObj,force) {
14106	console.log("lightWindowStack.openWindow() : isOpen="+lightWindowStack.isOpen) ;
14107	console.log(force) ;
14108
14109	// Ali imamo postavljen "force" ( to se pošlje pri funkciji LookupTable ) ? V tem primeru zapremo vsa okna in pobrižemo kompleten stack
14110	// HACK - Trenutno imamo tole disejblano, ker v določenih primerih, če imamo lookup v popup-u zapre popup namesto da bi odprlo nov lookup - je potrebno to še pogledat
14111// 	if ((typeof(force) != "undefined") && force) {
14112// 		if (parent.myLightWindow)
14113// 			parent.myLightWindow.deactivate();
14114// 		lightWindowStack.stack = [] ;
14115// 		lightWindowStack.isOpen = false ;
14116// 	}
14117
14118	// Če smo dobili objekt za okno, ga dodamo na stack za odpiranje, če ga nismo, to pomeni, da želimo odpreti naslednje okno iz stack-a
14119	if (typeof(lwObj) == "object") {
14120		console.log("Adding window object to stack:") ;
14121		console.log(lwObj) ;
14122		// Preverimo, ali ta objekt že obstaja, ker ga v tem primeru ne dodajamo
14123		var objektObstaja = false ;
14124		if (shallowEqual(lightWindowStack.currentWindow,lwObj)) {
14125			console.log("This is the current window!") ;
14126			objektObstaja = true ; // Željeno okno ima enake parametre kot trenutno odprto okno
14127		} else
14128			lightWindowStack.stack.each(function(winObj) {
14129				console.log(winObj) ;
14130				if (shallowEqual(winObj,lwObj)) {
14131					objektObstaja = true ;
14132				}
14133			}) ;
14134		if (!objektObstaja) {
14135			console.log("ADDED") ;
14136			lightWindowStack.stack.push(lwObj) ;
14137			console.log(lightWindowStack) ;
14138		}
14139	}
14140
14141	if ((!lightWindowStack.isOpen) && (lightWindowStack.stack.length > 0)) {
14142		// Preverimo, če je lightWindow že inicializiran in če ni, sprožimo odpiranje z zamikom
14143		if ((typeof(myLightWindow) == "undefined") || (myLightWindow == null)) {
14144			console.log("lightWindowStack - waiting for myLightWindow to apear") ;
14145			setTimeout("lightWindowStack.openWindow()",1000) ;
14146		} else {
14147			lwObj = lightWindowStack.stack.shift() ;
14148			lightWindowStack.isOpen = true ;
14149			lightWindowStack.currentWindow = lwObj ;
14150			console.log(lwObj) ;
14151
14152			// Trenutno nimamo odprtega nobenega lightWindow-a - se pravi, da ga lahko odpremo
14153			// Dodamo vse posebne funkcije ipd.
14154			if (typeof(lwObj.retFunction) == "function") {
14155				myLightWindow.Vrni = lwObj.retFunction ;
14156			}
14157			if (typeof(lwObj.returnLink) == "function") {
14158				myLightWindow.returnLink = lwObj.returnLink ;
14159			}
14160			if (typeof(lwObj.returnSaveData) == "function") {
14161				myLightWindow.returnSaveData = lwObj.returnSaveData ;
14162			}
14163			if (typeof(lwObj.startKnjizenje) == "function") {
14164				myLightWindow.startKnjizenje = lwObj.startKnjizenje ;
14165			}
14166			if (typeof(lwObj.PlusOne) == "function") {
14167				myLightWindow.PlusOne = lwObj.PlusOne ;
14168			}
14169			if (typeof(lwObj.VrniLink) == "function") {
14170				myLightWindow.VrniLink = lwObj.VrniLink ;
14171			}
14172
14173			if(typeof(lwObj['Multiple']) != "undefined") {
14174				myLightWindow.Multiple = lwObj['Multiple'];
14175				myLightWindow.MultipleAdd = lwObj['Multiple'];
14176			}
14177			if(typeof(lwObj['MultiFilterPolje']) != "undefined") {
14178				MultiFilterPolje = lwObj['MultiFilterPolje'];
14179				lwObj['onClose'] = function() {
14180					ReloadList();
14181					console.log("lightWindowStack.onCloseMulti - stack length:"+lightWindowStack.stack.length) ;
14182					// Zapremo trenutno okno in sprožimo odpiranje novega, če je še na stacku
14183					if (lightWindowStack.stack.length > 0) {
14184						console.log("Running timeout...") ;
14185						setTimeout("lightWindowStack.openWindow()",10) ;
14186					}
14187					lightWindowStack.isOpen = false ;
14188					lightWindowStack.currentWindow = null ;
14189				} ;
14190			} else if (typeof(lwObj['onClose']) == "function") {
14191				lwObj.onCloseOrig = lwObj['onClose'] ;
14192				lwObj['onClose'] = function() {
14193					console.log("lightWindowStack.onCloseOrig - stack length:"+lightWindowStack.stack.length) ;
14194					// Zapremo trenutno okno in sprožimo odpiranje novega, če je še na stacku
14195					if (lightWindowStack.stack.length > 0) {
14196						console.log("Running timeout...") ;
14197						setTimeout("lightWindowStack.openWindow()",10) ;
14198					}
14199					lightWindowStack.isOpen = false ;
14200					lightWindowStack.currentWindow = null ;
14201					lwObj.onCloseOrig() ;
14202				} ;
14203			} else {
14204				lwObj['onClose'] = function() {
14205					console.log("lightWindowStack.onCloseDefault - stack length:"+lightWindowStack.stack.length) ;
14206					// Zapremo trenutno okno in sprožimo odpiranje novega, če je še na stacku
14207					if (lightWindowStack.stack.length > 0) {
14208						console.log("Running timeout...") ;
14209						setTimeout("lightWindowStack.openWindow()",10) ;
14210					}
14211					lightWindowStack.isOpen = false ;
14212					lightWindowStack.currentWindow = null ;
14213				} ;
14214			}
14215
14216			if (typeof(lwObj.DodatniId) != "undefined")
14217				myLightWindow.DodatniId = lwObj.DodatniId ;
14218			if (typeof(lwObj.DodatniOpis) != "undefined")
14219				myLightWindow.DodatniOpis = lwObj.DodatniOpis ;
14220			if (typeof(lwObj.RelocateLink) != "undefined")
14221				myLightWindow.RelocateLink = lwObj.RelocateLink ;
14222			if (typeof(lwObj.IzbiraIzvoza) != "undefined")
14223				myLightWindow.IzbiraIzvoza = lwObj.IzbiraIzvoza ;
14224			if (typeof(lwObj.ShowWarning) != "undefined")
14225				myLightWindow.ShowWarning = lwObj.ShowWarning ;
14226			if (typeof(lwObj.RelocLink) != "undefined")
14227				myLightWindow.RelocLink = lwObj.RelocLink ;
14228			if (typeof(lwObj.StornoRazlog) != "undefined")
14229				myLightWindow.StornoRazlog = lwObj.StornoRazlog ;
14230			if (typeof(lwObj.StornoNapaka) != "undefined")
14231				myLightWindow.StornoNapaka = lwObj.StornoNapaka ;
14232			if (typeof(lwObj.NaloziLink) != "undefined")
14233				myLightWindow.NaloziLink = lwObj.NaloziLink ;
14234			if (typeof(lwObj.vsiESO) != "undefined")
14235				myLightWindow.vsiESO = lwObj.vsiESO ;
14236			if (typeof(lwObj.vseSerijske) != "undefined")
14237				myLightWindow.vseSerijske = lwObj.vseSerijske ;
14238			if (typeof(lwObj.vseVrstice) != "undefined")
14239				myLightWindow.vseVrstice = lwObj.vseVrstice ;
14240			if (typeof(lwObj.vsiAttr) != "undefined")
14241				myLightWindow.vsiAttr = lwObj.vsiAttr ;
14242			if (typeof(lwObj.GradnikiSSO_Povezava) != "undefined")
14243				myLightWindow.GradnikiSSO_Povezava = lwObj.GradnikiSSO_Povezava ;
14244
14245			console.log("Activating myLightWindow") ;
14246			myLightWindow.activateWindow(lwObj) ;
14247		}
14248	}
14249}
14250lightWindowStack.closeWindow = function() {
14251	console.log("lightWindowStack.closeWindow()") ;
14252	// Zapremo trenutno okno in sprožimo odpiranje novega, če je še na stacku
14253	if (lightWindowStack.stack.length > 0) {
14254		setTimeout("lightWindowStack.openWindow()",10) ;
14255	}
14256	lightWindowStack.isOpen = false ;
14257	parent.myLightWindow.deactivate();
14258}
14259
14260// NOTE - Preveri, če kaj vpliva na ostale, drugače se lahko porabi
14261// var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval;
14262//   
14263// window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
14264// 	var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
14265// 	return __nativeST__(vCallback instanceof Function ? function () {
14266// 		vCallback.apply(oThis, aArgs);
14267// 	} : vCallback, nDelay);
14268// };
14269//   
14270// window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
14271// 	var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
14272// 	return __nativeSI__(vCallback instanceof Function ? function () {
14273// 		vCallback.apply(oThis, aArgs);
14274// 	} : vCallback, nDelay);
14275// };
14276
14277history.navigationMode = 'compatible';
14278
14279// Kompatibilnost z IE 11
14280Number.isInteger = Number.isInteger || function(value) {
14281	return typeof value === "number" &&
14282		isFinite(value) &&
14283		Math.floor(value) === value;
14284};
14285
14286// Funkcija za preverjanje, ali element obstaja - brez logiranja, če ne obstaja
14287function $D(element) {
14288	if (arguments.length > 1) {
14289		for (var i = 0, elements = [], length = arguments.length; i < length; i++)
14290			elements.push($D(arguments[i]));
14291		return elements;
14292	}
14293
14294	if (Object.isString(element)) {
14295		if (document.getElementById(element)) {
14296			element = document.getElementById(element) ;
14297		} else {
14298			element = document.getElementById(element) ;
14299		}
14300	}
14301	return Element.extend(element);
14302}
14303
14304function actuallyVisible(DWMElement) {
14305	var toReturn = true ; var finishLooping = false ;
14306	var DWMElementTagName = '' ;
14307
14308	if (typeof(DWMElement) != 'undefined') {
14309		while (finishLooping === false) {
14310			DWMElementTagName = DWMElement.tagName.toLowerCase() ;
14311
14312			if ((DWMElementTagName == 'body') || (DWMElementTagName == 'html')) {
14313				finishLooping = true ;
14314				break;
14315			} else {
14316				if (DWMElement.getStyle('display') == 'none') {
14317					toReturn = false ;
14318					finishLooping = true ;
14319					break ;
14320				} else if (DWMElement.getStyle('visibility') == 'hidden') {
14321					toReturn = false ;
14322					finishLooping = true ;
14323					break ;
14324				}
14325
14326				if (typeof(DWMElement.up()) != 'undefined') {
14327					DWMElement = DWMElement.up() ;
14328				} else {
14329					finishLooping = true ;
14330					break;
14331				}
14332			}
14333		}
14334	} else {
14335		toReturn = false ;
14336	}
14337
14338	return toReturn ;
14339}
14340
14341function getIFrameDocument() {
14342	var historyFrame = document.getElementById("historyFrame");
14343	var doc = historyFrame.contentDocument;
14344	if (doc == undefined) // Internet Explorer
14345		doc = historyFrame.contentWindow.document;
14346
14347	return doc;
14348}
14349
14350function sessionExists() {
14351	var doc = getIFrameDocument();
14352	try {
14353		if (doc.body.innerHTML == "")
14354		return false;
14355	else
14356		return true;
14357	}
14358	catch (exp) {
14359		// sometimes an exception is thrown if a
14360		// value is already in the iframe
14361		return true;
14362	}
14363}
14364
14365function targetFromEvent(e) {
14366	if (!e) var e = window.event ;
14367	if (e.target) targ = e.target;
14368	else if (e.srcElement) targ = e.srcElement;
14369	if (targ.nodeType == 3) // defeat Safari bug
14370		targ = targ.parentNode;
14371	return targ ;
14372}
14373
14374function saveState(message) {
14375	// get our template that we will
14376	// write into the history iframe
14377	var templateDiv = document.getElementById("iframeTemplate");
14378	var currentElement = templateDiv.firstChild;
14379
14380	// loop until we get a COMMENT_NODE
14381	while (currentElement && currentElement.nodeType != 8) {
14382		currentElement = currentElement.nextSibling;
14383	}
14384	var template = currentElement.nodeValue;
14385
14386	// replace the templated value in the
14387	// constants with our new value
14388	var newContent = template.replace(/\%message\%/, message);
14389
14390	// now write out the new contents
14391	var doc = getIFrameDocument();
14392	doc.open();
14393	doc.write(newContent);
14394	doc.close();
14395}
14396
14397function openIFrame(IFrameID, URL){
14398   ifId=document.getElementById(IFrameID)
14399   ifId.src=URL // Opera Bug Fix. ifId.src=URL
14400}
14401
14402function getPageDimensions(Ret) {
14403	var xScroll, yScroll;
14404	if (window.innerHeight && window.scrollMaxY) {
14405		xScroll = document.body.scrollWidth;
14406		yScroll = window.innerHeight + window.scrollMaxY;
14407	} else if (document.body.scrollHeight > document.body.offsetHeight){
14408		xScroll = document.body.scrollWidth;
14409		yScroll = document.body.scrollHeight;
14410	} else {
14411		xScroll = document.body.offsetWidth;
14412		yScroll = document.body.offsetHeight;
14413	}
14414
14415	var windowWidth, windowHeight;
14416	if (self.innerHeight) {
14417		windowWidth = self.innerWidth;
14418		windowHeight = self.innerHeight;
14419	} else if (document.documentElement && document.documentElement.clientHeight) {
14420		windowWidth = document.documentElement.clientWidth;
14421		windowHeight = document.documentElement.clientHeight;
14422	} else if (document.body) {
14423		windowWidth = document.body.clientWidth;
14424		windowHeight = document.body.clientHeight;
14425	}
14426
14427	if(yScroll < windowHeight){
14428		PageHeight = windowHeight;
14429	} else {
14430		PageHeight = yScroll;
14431	}
14432
14433	if(xScroll < windowWidth){
14434		PageWidth = windowWidth;
14435	} else {
14436		PageWidth = xScroll;
14437	}
14438	if (Ret) {
14439		var ToReturn = new Object() ;
14440
14441		ToReturn.PageWidth = PageWidth ;
14442		ToReturn.xScroll = xScroll ;
14443		ToReturn.windowWidth = windowWidth ;
14444		ToReturn.PageHeight = PageHeight ;
14445		ToReturn.windowHeight = windowHeight ;
14446		ToReturn.yScroll = yScroll ;
14447
14448		if(typeof(window.pageYOffset) == 'number') {
14449			ToReturn.XOffset = window.pageXOffset;
14450			ToReturn.YOffset = window.pageYOffset;
14451		} else if(document.body && (document.body.scrollLeft || document.body.scrollTop)) {
14452			ToReturn.XOffset = document.body.scrollLeft;
14453			ToReturn.YOffset = document.body.scrollTop;
14454		} else if(document.documentElement) {
14455			ToReturn.XOffset = document.documentElement.scrollLeft;
14456			ToReturn.YOffset = document.documentElement.scrollTop;
14457		}
14458
14459		return ToReturn ;
14460	}
14461}
14462
14463// Nova funkcija za prikaz waiterja znotraj posameznega block elementa
14464function dwm_showWaitInElement(iElement) {
14465	if ($D(iElement)) {
14466		var IzbraniElement = $(iElement);
14467		waitElementId = $(iElement).id + "_newWaiter" ;
14468
14469		IzbraniElement.insert({top: '<div align="center" valign="center" id="'+waitElementId+'" style="position:absolute; z-index:65535; background-image: url(/P/DeskWM/Mask.gif);" class="ico_mask ico_wait ico_special"></div>'})
14470
14471		var NewImage = $(waitElementId) ;
14472
14473		IzbraniElement.waitOn = NewImage ;
14474		IzbraniElement.style.cursor="wait" ;
14475	}
14476}
14477
14478function dwm_hideWaitInElement(iElement) {
14479	console.log("dwm_hideWaitInElement: "+iElement) ;
14480	if ($D(iElement)) {
14481		waitElementId = $(iElement).id + "_newWaiter" ;
14482		Element.remove(waitElementId) ;
14483		$(iElement).style.cursor="" ;
14484	}
14485}
14486
14487function ShowWaitInElement(iElement,waitElementId) {
14488	if ($D(iElement)) {
14489		console.error("SHOW WAITER IN") ;
14490		console.warn(iElement) ;
14491
14492		var IzbraniElement = $(iElement);
14493
14494		// Kreiramo "spinning circle" element in ga pozicioniramo čez izbarni element
14495		if (typeof(waitElementId) != "undefined") {
14496			if ($D(waitElementId)) {
14497				var NewImage = $(waitElementId) ;
14498			} else {
14499				IzbraniElement.insert({after: '<div align="center" valign="center" id="'+waitElementId+'" style="position:absolute; display:none;" class="ico_mask ico_wait ico_special"></div>'})
14500				var NewImage = $(waitElementId) ;
14501			}
14502		} else if ($D("MaskaDelamDWMjr")) {
14503			var NewImage = $("MaskaDelamDWMjr") ;
14504		} else if ($D("MaskaDelamStran")) {
14505			var NewImage = $("MaskaDelam") ;
14506		} else if ($D("MaskaDelam")) {
14507			var NewImage = $("MaskaDelam") ;
14508		} else if ($D("MaskaDelamDWMjr")) {
14509			// Nimamo Wait elementa, torej naredimo enega splošnega in ga uporabimo - seveda, če ga najdemo
14510			IzbraniElement.insert({after: '<div align="center" valign="center" id="'+waitElementId+'" style="position:absolute; display:none;" class="ico_mask ico_wait ico_special"></div>'})
14511			var NewImage = $("MaskaDelamDWMjr") ;
14512		} else {
14513			console.log("Element MaskaDelamDWMjr ni definiran !") ;
14514		}
14515
14516		if (NewImage) {
14517			Element.clonePosition(NewImage,IzbraniElement) ;
14518			NewImage.style.zIndex = 65535 ;
14519			NewImage.style.display = "" ;
14520			IzbraniElement.waitOn = NewImage ;
14521		}
14522
14523		// Ura cursor
14524		IzbraniElement.style.cursor="wait" ;
14525	}
14526}
14527
14528function HideWaitInElement(iElement,waitElementId) {
14529	if ($D(iElement)) {
14530		console.error("HIDE WAITER IN") ;
14531		console.warn(iElement) ;
14532		var IzbraniElement = $(iElement);
14533		if (IzbraniElement.waitOn) {
14534			IzbraniElement.waitOn.style.display = "none" ;
14535		}
14536		// Ura cursor
14537		IzbraniElement.style.cursor="" ;
14538	}
14539}
14540
14541function ShowWait(waitElementId) {
14542	if (document.getElementById(waitElementId)) {
14543		if ((waitElementId == "MaskaDelamStran") && document.getElementById("MaskaDelamStran")) {
14544			getPageDimensions() ;
14545			$('MaskaDelamStran').style.height = PageHeight ;
14546			$('MaskaDelamStran').style.width = PageWidth ;
14547		}
14548		document.getElementById(waitElementId).style.display="" ;
14549		document.body.style.cursor="wait" ;
14550	} else if (document.getElementById("MaskaDelamPopupList")) {
14551		document.getElementById("MaskaDelamPopupList").clonePosition(document.getElementById("SpiskiMainBodyDiv")) ;
14552		document.getElementById("MaskaDelamPopupList").style.display="" ;
14553		document.body.style.cursor="wait" ;
14554	} else if (document.getElementById("MaskaDelam")) {
14555		document.getElementById("MaskaDelam").style.display="" ;
14556		document.body.style.cursor="wait" ;
14557	} else {
14558		document.body.insert({after: '<div id="MaskaDelam" style="position:absolute; display:none;" class="ico_mask"><span class="ico_wait ico_pozicija_w"></span></div>'})
14559		document.getElementById("MaskaDelam").style.display="" ;
14560		document.body.style.cursor="wait" ;
14561	}
14562}
14563
14564function HideWait(waitElementId) {
14565	
14566	if (document.getElementById(waitElementId)) {
14567		document.getElementById(waitElementId).style.display="none" ;
14568		document.body.style.cursor="" ;
14569	} else if (document.getElementById("MaskaDelamPopupList")) {
14570		document.getElementById("MaskaDelamPopupList").style.display="none" ;
14571		document.body.style.cursor="" ;
14572	} else if (document.getElementById("MaskaDelam")) {
14573		document.getElementById("MaskaDelam").style.display="none" ;
14574		document.body.style.cursor="" ;
14575	} else if(parent.document.getElementById("lightwindow_iframe")) {
14576		// NOTE OK. Se pravi imamo odprt lightWindow
14577		var iframeForm = parent.document.getElementById("lightwindow_iframe").contentWindow.document;
14578		if (iframeForm.getElementById(waitElementId)) {
14579			iframeForm.getElementById(waitElementId).style.display="none" ;
14580		} else if (iframeForm.getElementById("MaskaDelam")) {
14581			iframeForm.getElementById("MaskaDelam").style.display="none" ;
14582		}
14583		iframeForm.body.style.cursor="" ;
14584	}
14585}
14586
14587function ShowWaitSerial(Func) {
14588	WaitArr.push(Func) ;
14589	if (document.getElementById("MaskaDelam")) {
14590		document.getElementById("MaskaDelam").style.display="" ;
14591		document.body.style.cursor="wait" ;
14592	}
14593}
14594
14595function HideWaitSerial(Func) {
14596	var X = WaitArr.pop() ;
14597	if ((WaitArr.length < 1) && (document.getElementById("MaskaDelam"))) {
14598		document.getElementById("MaskaDelam").style.display="none" ;
14599		document.body.style.cursor="" ;
14600	}
14601}
14602
14603function ShowWaitSerialSmall(Func) {
14604	WaitArr.push(Func) ;
14605	if (document.getElementById("MaskaDelamSmall")) {
14606		document.getElementById("MaskaDelamSmall").style.display="" ;
14607		document.body.style.cursor="wait" ;
14608	}
14609}
14610
14611function HideWaitSerialSmall(Func) {
14612	var X = WaitArr.pop() ;
14613	if ((WaitArr.length < 1) && (document.getElementById("MaskaDelamSmall"))) {
14614		document.getElementById("MaskaDelamSmall").style.display="none" ;
14615		document.body.style.cursor="" ;
14616	}
14617}
14618
14619function Prazno() {
14620	// ShowRightClickMenu() ;
14621	return false ;
14622}
14623
14624
14625if (document.all) {
14626	CursorTip = 'hand';
14627} else {
14628	CursorTip = 'pointer';
14629}
14630
14631String.prototype.trim = function() {
14632	return this.replace(/(^\s*)|(\s*$)/g, "");
14633}
14634
14635Number.prototype.trim = function() {
14636	return String(this).replace(/(^\s*)|(\s*$)/g, "");
14637}
14638
14639String.prototype.nl2br = function() {
14640	return this.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + '<br ' + '/>' + '$2');
14641}
14642
14643String.prototype.escapeHTML = function() {
14644	var map = {
14645		'&': '&amp;',
14646		'<': '&lt;',
14647		'>': '&gt;',
14648		'"': '&quot;',
14649		"'": '&#039;'
14650	};
14651	return this.replace(/[&<>"']/g, function(m) { return map[m]; });
14652}
14653
14654document.getElementsByAttribute = function(attribute, value, tagName, parentElement) {
14655	var children = ($(parentElement) || document.body).getElementsByTagName((tagName || '*'));
14656	return $A(children).inject([], function(elements, child) {
14657		var attributeValue = child.getAttribute(attribute);
14658		if(attributeValue != null) {
14659			if(!value || attributeValue == value) {
14660				elements.push(child);
14661			}
14662		}
14663		return elements;
14664	});
14665}
14666
14667document.getElementsByDWMId = function(DWMId)
14668{
14669	var cIterate=document.getElementsByTagName('*') ;
14670	var elm ;
14671	var attr ;
14672	var i = 0 ;
14673	var aResponse=[] ;
14674
14675	while((elm=cIterate.item(i++)))
14676	{
14677		if (elm["dwm_id"])
14678		{
14679			attr = String(elm["dwm_id"]);
14680			if (attr == DWMId)
14681			{
14682				aResponse.push(elm);
14683			}
14684		}
14685	}
14686	return aResponse;
14687}
14688
14689document.getElementsByClassName = function(clsName){
14690	var retVal = new Array();
14691	var elements = document.getElementsByTagName("*");
14692	for(var i = 0;i < elements.length;i++){
14693		if (elements[i].className && elements[i].className.indexOf && (elements[i].className.indexOf(" ") >= 0)) {
14694			var classes = elements[i].className.split(" ");
14695			for(var j = 0;j < classes.length;j++){
14696				if(classes[j] == clsName)
14697					retVal.push(elements[i]);
14698			}
14699		}
14700		else if(elements[i].className == clsName)
14701			retVal.push(elements[i]);
14702	}
14703	return retVal;
14704}
14705
14706Number.prototype.LocaleNumberFormat = function() {
14707	Stevilka = String(Math.round(this)) ;
14708	StevilkaZaIzpis = "" ;
14709	Locilo = "" ;
14710	while (Stevilka.length > 0) {
14711		StevilkaZaIzpis = Stevilka.substring(Stevilka.length - 3) + Locilo + StevilkaZaIzpis ;
14712		Stevilka = Stevilka.substring(0,Stevilka.length - 3) ;
14713		Locilo = "." ;
14714	}
14715	if (StevilkaZaIzpis.substring(0,2) == "-.")
14716		StevilkaZaIzpis = "-" + StevilkaZaIzpis.substring(2) ;
14717	return StevilkaZaIzpis ;
14718}
14719
14720Number.prototype.round = function() {
14721	return Math.round(this);
14722}
14723
14724String.prototype.LocaleToNum = function() {
14725	if (this.trim() == "") {
14726		return 0
14727	} else {
14728		// Najprej preverimo, ali imamo kako ločilo - tisočice ali stotice
14729		var tmpStr = this.trim() ;
14730		var posDecLoc = tmpStr.lastIndexOf(DecLoc) ;
14731		var posTousLoc = tmpStr.lastIndexOf(TousLoc) ;
14732
14733		// console.log("Str:"+tmpStr+" DL:"+DecLoc+" DLoc:"+posDecLoc+" TL:"+TousLoc+" TLoc:"+posTousLoc) ;
14734		if ((posDecLoc > 0) && (posTousLoc > 0)) {
14735			// Da vidimo, da nimamo slučajno zamenjave ločila za decimalno in tisočice
14736			if (posDecLoc < posTousLoc) {
14737				// console.log("Obrnemo:"+Number(this.replace(LocaleRegXObr,"$1$2$4$6$8$10$12.$14"))) ;
14738				return Number(this.replace(LocaleRegXObr,"$1$2$4$6$8$10$12.$14")) ;
14739			} else {
14740				// console.log("OK:"+Number(this.replace(LocaleRegX,"$1$2$4$6$8$10$12.$14"))) ;
14741				return Number(this.replace(LocaleRegX,"$1$2$4$6$8$10$12.$14")) ;
14742			}
14743		} else if (posTousLoc > 0) {
14744			// console.log("Obrnemo-:"+Number(this.replace(LocaleRegXObr,"$1$2$4$6$8$10$12.$14"))) ;
14745			return Number(this.replace(LocaleRegXObr,"$1$2$4$6$8$10$12.$14")) ;
14746		} else if (posDecLoc > 0) {
14747			// console.log("OK-:"+Number(this.replace(LocaleRegX,"$1$2$4$6$8$10$12.$14"))) ;
14748			return Number(this.replace(LocaleRegX,"$1$2$4$6$8$10$12.$14")) ;
14749		} else {
14750			// Nimamo nobenih ločil -> vrnemo direktno število
14751			return Number(tmpStr) ;
14752		}
14753	}
14754}
14755
14756function dwm_getEventTarget(e) {
14757	if (!e) var e = window.event ;
14758	if (e.target)
14759		targ = e.target;
14760	else if (e.srcElement)
14761		targ = e.srcElement;
14762	if (targ.nodeType == 3) // defeat Safari bug
14763		targ = targ.parentNode;
14764	return targ ;
14765}
14766
14767function ListHide() {
14768	DebugJS('', 'ListHide()-START');
14769	if (typeof(ListIzbirnik) != "undefined") {
14770		if (ListIzbirnik.style.display == "") {
14771			ListIzbirnik.style.display = "none" ;
14772			ListIzbirnik.vezavaPolje = null ;
14773			ListIzbirnik.izbranaVrstica = 0 ;
14774
14775			if (targ.hasAttribute("dwm_oldValue")) {
14776				targ.value = targ.getAttribute("dwm_oldValue") ;
14777			}
14778		}
14779	}
14780	DebugJS('', 'ListHide()-END');
14781}
14782
14783function eventListHide(e) {
14784	if (!e) var e = window.event ;
14785	if (e.target) targ = e.target;
14786	else if (e.srcElement) targ = e.srcElement;
14787	if (targ.nodeType == 3) // defeat Safari bug
14788		targ = targ.parentNode;
14789
14790	if (typeof(DebugJS) == 'function') {
14791		DebugJS('', 'eventListHide('+targ.id+')-START');
14792		DebugJS('', 'eventListHide->Izbirnik:'+typeof(ListIzbirnik));
14793	}
14794	if (!targ.hasAttribute("selektorWasDowned") || (targ.getAttribute("selektorWasDowned") != "1")) {
14795		if (typeof(ListIzbirnik) != "undefined") {
14796			if (ListIzbirnik.style.display == "") {
14797				ListIzbirnik.style.display = "none" ;
14798				ListIzbirnik.vezavaPolje = null ;
14799				ListIzbirnik.izbranaVrstica = 0 ;
14800
14801				if (targ.hasAttribute("dwm_oldValue")) {
14802					targ.value = targ.getAttribute("dwm_oldValue") ;
14803				}
14804			}
14805		}
14806	} else {
14807		targ.setAttribute("selektorWasDowned","0") ;
14808	}
14809	if (typeof(DebugJS) == 'function') {
14810		DebugJS('', 'eventListHide('+targ.id+')-END') ;
14811	}
14812}
14813
14814function LokalnaCifra(Stevilka,DecCifer,DodajNule) {
14815	Stevilka = Number(Stevilka).Round(DecCifer) ;
14816	Mnozitelj = Math.pow(10,DecCifer) ;
14817
14818	// Ker delamo z absolutnimi vrednostmi, damo predznak posebej
14819	(Stevilka < 0) ? Predznak = "-" : Predznak="" ;
14820	VhodnoStevilo = Math.abs(Stevilka) ;
14821
14822	if ((VhodnoStevilo < 1000) || (TousLoc.trim()=="")) {
14823		CeliDel = parseInt(VhodnoStevilo) ;
14824		if (DecCifer <= 0 )
14825			ZaVrnitev = CeliDel ;
14826		else {
14827			DecimalniDel = VhodnoStevilo - CeliDel ;
14828			DecimalniDel = Math.abs(Math.round(DecimalniDel * Mnozitelj)/Mnozitelj) ;
14829			if (DecimalniDel == 1) {
14830				DecimalniDel = 0 ;
14831				CeliDel ++ ;
14832			}
14833			ZaVrnitev = CeliDel ;
14834			TDecDel = String(DecimalniDel).substr(2) ;
14835			SteviloCifer = DecCifer - String(TDecDel).length ;
14836			NuleZaDodat = "" ;
14837			if(DodajNule) {
14838				for (i=0; i < SteviloCifer; i++)
14839					NuleZaDodat += "0" ;
14840				ZaVrnitev += DecLoc + String(DecimalniDel).substr(2,DecCifer) + NuleZaDodat;
14841			} else {
14842				// Odstranimo vse odvečne ničle na decimalnem delu
14843				TDecDelN = Number(TDecDel) ;
14844				while (TDecDelN != 0) {
14845					if (TDecDelN % 10 != 0)
14846						break ;
14847					else
14848						TDecDelN = TDecDelN / 10 ;
14849				}
14850				if (TDecDelN != 0)
14851					TDecDel = String(TDecDelN) ;
14852				else
14853					TDecDel = "" ;
14854				if (TDecDel.trim() != "")
14855					ZaVrnitev += DecLoc + String(DecimalniDel).substr(2,DecCifer) + NuleZaDodat;
14856			}
14857		}
14858	}
14859	else
14860	{
14861		PrvoLocilo = 1000000000 ;
14862		Stevilo = VhodnoStevilo ;
14863		ZaVrnitev = "" ;
14864		Locilo = "" ;
14865
14866		// Najprej obdelamo decimalke, v kolikor se zaokrožijo na 1
14867		if (DecCifer >0)
14868		{
14869			CeliDel = parseInt(Stevilo) ;
14870			DecimalniDel = Stevilo - CeliDel ;
14871			DecimalniDel = Math.abs(Math.round(DecimalniDel * Mnozitelj)/Mnozitelj) ;
14872			if (DecimalniDel == 1)
14873			{
14874				DecimalniDel = 0 ;
14875				Stevilo ++ ;
14876			}
14877		}
14878
14879		while (PrvoLocilo >= 1)
14880		{
14881			Temp = parseInt(Stevilo / PrvoLocilo) ;
14882			Stevilo = Stevilo - Temp * PrvoLocilo ;
14883			Temp = Math.abs(Temp) ;
14884			if (Temp >= 100)
14885			{
14886				ZaVrnitev += Locilo + Temp ;
14887				Locilo = TousLoc ;
14888			}
14889			else if (Temp >= 10)
14890			{
14891				if (Locilo != "")
14892					ZaVrnitev += Locilo + "0" + Temp ;
14893				else
14894					ZaVrnitev += Temp ;
14895				Locilo = TousLoc ;
14896			}
14897			else if (Temp > 0)
14898			{
14899				if (Locilo != "")
14900					ZaVrnitev += Locilo + "00" + Temp ;
14901				else
14902					ZaVrnitev += Temp ;
14903				Locilo = TousLoc ;
14904			}
14905			else if (Locilo != "")
14906				ZaVrnitev += Locilo + "000" ;
14907
14908			PrvoLocilo /= 1000 ;
14909		}
14910		if (ZaVrnitev.trim() == "")
14911			ZaVrnitev += "0" ;
14912
14913		if (DecCifer >0)
14914		{
14915			TDecDel = String(DecimalniDel).substr(2) ;
14916			SteviloCifer = DecCifer - String(TDecDel).length ;
14917			NuleZaDodat = "" ;
14918			if(DodajNule)
14919			{
14920				for (i=0; i < SteviloCifer; i++)
14921					NuleZaDodat += "0" ;
14922				ZaVrnitev += DecLoc + String(DecimalniDel).substr(2,DecCifer) + NuleZaDodat;
14923			}
14924			else
14925			{
14926				// Odstranimo vse odvečne ničle na decimalnem delu
14927				TDecDelN = Number(TDecDel) ;
14928				while (TDecDelN != 0)
14929				{
14930					if (TDecDelN % 10 != 0)
14931						break ;
14932					else
14933						TDecDelN = TDecDelN / 10 ;
14934				}
14935				if (TDecDelN != 0)
14936					TDecDel = String(TDecDelN) ;
14937				else
14938					TDecDel = "" ;
14939				if (TDecDel.trim() != "")
14940					ZaVrnitev += DecLoc + String(DecimalniDel).substr(2,DecCifer) + NuleZaDodat;
14941			}
14942		}
14943	}
14944	return Predznak+ZaVrnitev ;
14945}
14946
14947Number.prototype.DWMLocale = function(DecCifer) {
14948	return LokalnaCifra(this,DecCifer,true) ;
14949}
14950
14951Number.prototype.DWMLocaleWZ = function(DecCifer) {
14952	return LokalnaCifra(this,DecCifer,false) ;
14953}
14954
14955Number.prototype.Round = function(DecCifer) {
14956	ZaRound = Math.pow(10,DecCifer) ;
14957	// alert("Round : "+this+" to "+(Math.round(this * ZaRound) / ZaRound)) ;
14958	return (Math.round(this * ZaRound) / ZaRound) ;
14959}
14960
14961function DWMLocaleElement(Element,DecCifer,CeloStevilcno,WZ) {
14962	if (typeof(CeloStevilcno) == 'undefined')
14963		CeloStevilcno = 0 ;
14964	if (typeof(WZ) == 'undefined')
14965		WZ = true ;
14966
14967	if (($D(Element)) && (typeof($(Element).setValue) == 'function')) {
14968		if (CeloStevilcno != 0) {
14969			var Cifra = Math.round(Number(String($(Element).getValue()).LocaleToNum())) ;
14970		} else {
14971			var Cifra = Number(String($(Element).getValue()).LocaleToNum()) ;
14972		}
14973		$(Element).setValue(LokalnaCifra(Cifra,DecCifer,WZ)) ;
14974	}
14975}
14976
14977function DWMNumber(Vnos) {
14978	TempVrednost = Number(Vnos) ;
14979	if (isNaN(TempVrednost))
14980		return 0 ;
14981	else
14982		return TempVrednost ;
14983}
14984
14985function IsIE() {
14986	if (((navigator.userAgent.indexOf('MSIE') != -1) && ((navigator.userAgent.indexOf('5.0')!=-1) || (navigator.userAgent.indexOf('5.5')!=-1) || (navigator.userAgent.indexOf('6.0')!=-1) || (navigator.userAgent.indexOf('7.0')!=-1)))) {
14987		return true ;
14988	} else {
14989		return false ;
14990	}
14991}
14992
14993function StrAddNE(TStr,TAdd) {
14994	if (TStr.trim() != "") {
14995		return TAdd ;
14996	} else {
14997		return "" ;
14998	}
14999}
15000
15001function PopUpWindowNotResize(Name,W,H)
15002{
15003	windowName="PopUp" ;
15004	properties="channelmode =  0." ;
15005	properties=properties + "directories =  0," ;
15006	properties=properties + "fullscreen =  0," ;
15007	properties=properties + "height = "+(H+100)+"px," ;
15008	properties=properties + "width = "+(W+20)+"px," ;
15009	properties=properties + "top = "+((window.screen.height - H - 20 )/2)+"," ;
15010	properties=properties + "left = "+((window.screen.width - W - 20 )/2) +"," ;
15011	properties=properties + "location =  0," ;
15012	properties=properties + "menubar =  0," ;
15013	properties=properties + "resizable =  1," ;
15014	properties=properties + "scrollbars = 1," ;
15015	properties=properties + "status =  0," ;
15016	properties=properties + "titlebar =  0," ;
15017	properties=properties + "toolbar =  0" ;
15018	window.open(Name,windowName, properties) ;
15019}
15020
15021function PopUpWindowNotIE(Name,W,H)
15022{
15023	windowName="PopUp" ;
15024	properties="channelmode =  0." ;
15025	properties=properties + "directories =  0," ;
15026	properties=properties + "fullscreen =  0," ;
15027	properties=properties + "height = "+(H+100)+"px," ;
15028	properties=properties + "width = "+(W+20)+"px," ;
15029	properties=properties + "top = "+((window.screen.height - H - 20 )/2)+"," ;
15030	properties=properties + "left = "+((window.screen.width - W - 20 )/2) +"," ;
15031	properties=properties + "location =  0," ;
15032	properties=properties + "menubar =  0," ;
15033	properties=properties + "resizable =  0," ;
15034	properties=properties + "scrollbars = 0," ;
15035	properties=properties + "status =  0," ;
15036	properties=properties + "titlebar =  0," ;
15037	properties=properties + "toolbar =  0" ;
15038	window.open(Name,windowName, properties) ;
15039}
15040
15041function PopUpWindow(Name,W,H)
15042{
15043	if (((navigator.userAgent.indexOf('MSIE') != -1) && ((navigator.userAgent.indexOf('5.5')!=-1) || (navigator.userAgent.indexOf('6.0')!=-1))))
15044	{
15045		PopUpWindowIE(Name,W,H) ;
15046	}
15047	else
15048	{
15049		PopUpWindowNotIE(Name,W,H) ;
15050	}
15051}
15052
15053function PopUpWindow1(Name,W,H)
15054{
15055	if (((navigator.userAgent.indexOf('MSIE') != -1) && ((navigator.userAgent.indexOf('5.5')!=-1) || (navigator.userAgent.indexOf('6.0')!=-1))))
15056	{
15057		PopUpWindowIE1(Name,W,H) ;
15058	}
15059	else
15060	{
15061		PopUpWindowNotIE(Name,W,H) ;
15062	}
15063}
15064
15065function PopUpWindowSm(Name,W,H,Mag)
15066{
15067	if (((navigator.userAgent.indexOf('MSIE') != -1) && ((navigator.userAgent.indexOf('5.5')!=-1) || (navigator.userAgent.indexOf('6.0')!=-1))))
15068	{
15069		PopUpWindowIE(Name,W*Mag,H*Mag) ;
15070	}
15071	else
15072	{
15073		// Tukaj trenutno še nimamo Povečave/Pomanjšave
15074		PopUpWindowNotIE(Name,W,H) ;
15075	}
15076}
15077
15078function PopUpWindowHTML(Name,W,H,HTML)
15079{
15080	if (((navigator.userAgent.indexOf('MSIE') != -1) && ((navigator.userAgent.indexOf('5.5')!=-1) || (navigator.userAgent.indexOf('6.0')!=-1))))
15081	{
15082		PopUpWindowIEHTML(Name,W,H,HTML) ;
15083	}
15084	else
15085	{
15086		// Tukaj trenutno še nimamo Povečave/Pomanjšave
15087		PopUpWindowNotIEHTML(Name,W,H,HTML) ;
15088	}
15089}
15090
15091function PopUpWindowNotIEHTML(Name,W,H,HTML)
15092{
15093  var generator=window.open('',Name,'height='+(H*2)+',width='+W);
15094
15095  generator.document.write(HTML);
15096  generator.document.write('<p><a href="javascript:self.close()">Zapri</a></p>');
15097  generator.document.close();
15098}
15099
15100function PopUpWindowIEHTML(Name,W,H,HTML)
15101{
15102	var NewTable = document.createElement("table");
15103	document.body.insertAdjacentElement("BeforeEnd",NewTable);
15104
15105	Id = TempId++ ;
15106	NewTable.border=2;
15107	NewTable.height=H+20;
15108	NewTable.width=W+20;
15109	NewTable.name="Floater";
15110	NewTable.className="Floater";
15111	NewTable.cellPadding=3;
15112	NewTable.cellSpacing=3;
15113	NewTable.id="PopUp"+Id;
15114	if (typeof(PopUpLight)=="undefined")
15115	{
15116		NewTable.borderColorLight="#a9a9a9" ;
15117		NewTable.borderColorDark="#727272" ;
15118		NewTable.bgColor="#f1f1f1" ;
15119	}
15120	else
15121	{
15122		NewTable.borderColorLight=PopUpLight ;
15123		NewTable.borderColorDark=PopUpDark ;
15124		NewTable.bgColor=PopUpBg ;
15125	}
15126	NewTable.attachEvent("onmousemove",Vleci);
15127	NewTable.attachEvent("onmouseup",KonecVlecenja);
15128	NewTable.style.position="absolute";
15129	NewTable.style.zIndex=99;
15130	NewTable.style.cursor="default";
15131	NewTable.style.left=((document.body.offsetWidth - W - 10) / 2 );
15132	NewTable.style.top=(document.body.scrollTop+((document.body.offsetHeight - H - 10) / 2 ));
15133	NewTable.style.display="" ;
15134	NewRow=NewTable.insertRow();
15135	NewCell=NewRow.insertCell();
15136	NewCell.style.borderWidth=1;
15137	NewCell.height=H-12;
15138	NewCell.width=W;
15139	NewCell.align="center";
15140	NewCell.vAlign="top";
15141	NewCell.id="DLVsebina"+Id;
15142	NewCell.style.behavior = "url('#default#download')";
15143	NewCell.innerHTML="<table width=100%><tr><td>"+HTML +"</td></tr></table>" ;
15144	NewRow=NewTable.insertRow();
15145	NewCell=NewRow.insertCell();
15146	NewCell.style.borderWidth=0;
15147	NewCell.height=12;
15148	NewCell.width=W;
15149	NewCell.align="center";
15150	NewCell.innerHTML="<SPAN style='cursor:hand;' class=PicTitle onclick='PopUp"+Id+".removeNode()'>Zapri komentar</SPAN>" ;
15151}
15152
15153// Podvojena funkcija v Menu.js
15154function PopUpWindowIE(Name,W,H)
15155{
15156	var NewTable = document.createElement("table");
15157	document.body.insertAdjacentElement("BeforeEnd",NewTable);
15158
15159	Id = TempId++ ;
15160	NewTable.border=2;
15161	NewTable.height=H+10;
15162	NewTable.width=W+10;
15163	NewTable.name="Floater";
15164	NewTable.cellPadding=3;
15165	NewTable.cellSpacing=3;
15166	NewTable.id="PopUp"+Id;
15167	if (typeof(PopUpLight)=="undefined")
15168	{
15169		NewTable.borderColorLight="#a9a9a9" ;
15170		NewTable.borderColorDark="#727272" ;
15171		NewTable.bgColor="#f1f1f1" ;
15172	}
15173	else
15174	{
15175		NewTable.borderColorLight=PopUpLight ;
15176		NewTable.borderColorDark=PopUpDark ;
15177		NewTable.bgColor=PopUpBg ;
15178	}
15179	NewTable.attachEvent("onmousemove",Vleci);
15180	NewTable.attachEvent("onmouseup",KonecVlecenja);
15181	NewTable.style.position="absolute";
15182	NewTable.style.zIndex=99;
15183	NewTable.style.cursor="default";
15184	NewTable.style.left=((document.body.offsetWidth - W - 5) / 2 );
15185	NewTable.style.top=(document.body.scrollTop+((document.body.offsetHeight - H - 5) / 2 ));
15186	NewTable.style.display="" ;
15187	NewRow=NewTable.insertRow();
15188	NewCell=NewRow.insertCell();
15189	NewCell.style.borderWidth=0;
15190	NewCell.height=H+12;
15191	NewCell.width=W;
15192	NewCell.align="center";
15193	NewCell.id="DLVsebina"+Id;
15194	NewCell.style.behavior = "url('#default#download')";
15195	NewCell.innerHTML="<IMG onmousedown='ZacniVlecenje()' width="+(W-20)+" height="+(H-20)+" src="+Name+"><BR><SPAN style='cursor:hand;' class=PicTitle onclick='PopUp"+Id+".removeNode()'>Zapri komentar</SPAN>" ;
15196}
15197
15198function PopUpWindowIE1(Name,W,H)
15199{
15200	var NewTable = document.createElement("table");
15201	document.body.insertAdjacentElement("BeforeEnd",NewTable);
15202
15203	Id = TempId++ ;
15204	NewTable.border=2;
15205	NewTable.height=H+20;
15206	NewTable.width=W+20;
15207	NewTable.name="Floater";
15208	NewTable.cellPadding=3;
15209	NewTable.cellSpacing=3;
15210	NewTable.id="PopUp"+Id;
15211	if (typeof(PopUpLight)=="undefined")
15212	{
15213		NewTable.borderColorLight="#a9a9a9" ;
15214		NewTable.borderColorDark="#727272" ;
15215		NewTable.bgColor="#f1f1f1" ;
15216	}
15217	else
15218	{
15219		NewTable.borderColorLight=PopUpLight ;
15220		NewTable.borderColorDark=PopUpDark ;
15221		NewTable.bgColor=PopUpBg ;
15222	}
15223	NewTable.attachEvent("onmousemove",Vleci);
15224	NewTable.attachEvent("onmouseup",KonecVlecenja);
15225	NewTable.style.position="absolute";
15226	NewTable.style.zIndex=99;
15227	NewTable.style.cursor="default";
15228	NewTable.style.left=((document.body.offsetWidth - W - 10) / 2 );
15229	NewTable.style.top=(document.body.scrollTop+((document.body.offsetHeight - H - 10) / 2 ));
15230	NewTable.style.display="" ;
15231	NewRow=NewTable.insertRow();
15232	NewCell=NewRow.insertCell();
15233	NewCell.style.borderWidth=0;
15234	NewCell.height=H+12;
15235	NewCell.width=W;
15236	NewCell.align="center";
15237	NewCell.id="DLVsebina"+Id;
15238	NewCell.style.behavior = "url('#default#download')";
15239	NewCell.innerHTML="<IMG onmousedown='ZacniVlecenje()' src="+Name+"><BR><SPAN style='cursor:hand;' class=PicTitle onclick='PopUp"+Id+".removeNode()'>Zapri</SPAN>" ;
15240}
15241
15242function ZacniVlecenje()
15243{
15244	odmikXHeaderAbs=0;
15245	odmikYHeaderAbs=0;
15246	IskaniElement=event.srcElement;
15247	while (IskaniElement.name!="Floater")
15248	{
15249		if ((IskaniElement.tagName!="TR") & (IskaniElement.tagName!="TBODY"))
15250		{
15251			odmikYHeaderAbs=odmikYHeaderAbs+IskaniElement.offsetTop;
15252			odmikXHeaderAbs=odmikXHeaderAbs+IskaniElement.offsetLeft;
15253		}
15254		IskaniElement=IskaniElement.parentNode;
15255	}
15256	odmikXHeader=window.event.offsetX+odmikXHeaderAbs;
15257	odmikYHeader=window.event.offsetY+odmikYHeaderAbs;
15258	if (event.srcElement.tagName=="MARQUEE")
15259	{
15260		odmikXHeader=odmikXHeader-event.srcElement.clientWidth;
15261	}
15262	IskaniElement.setCapture();
15263	PremikanjeHeader=true;
15264}
15265
15266function Vleci()
15267{
15268	if (PremikanjeHeader)
15269	{
15270		IskaniElement.style.left=window.event.x - odmikXHeader + document.body.scrollLeft;
15271		IskaniElement.style.top=window.event.y - odmikYHeader + document.body.scrollTop;
15272	}
15273}
15274function KonecVlecenja()
15275{
15276	if (PremikanjeHeader)
15277	{
15278		IskaniElement.releaseCapture();
15279		PremikanjeHeader=false;
15280	}
15281}
15282
15283function DWMErrorHandler()
15284{
15285	TEvent = window.event ;
15286	return true ;
15287}
15288
15289function RevealElement(Objekt,samoTip) {
15290	if (!samoTip)
15291		samoTip = "" ;
15292	else
15293		samoTip = String(samoTip).trim() ;
15294	
15295	var tStrings = new Array() ;
15296	var tNumbers = new Array() ;
15297	var tBooleans = new Array() ;
15298	var tOthers = new Array() ;
15299	
15300	TText = "" ;
15301	TI = 0 ;
15302	for (TE in Objekt) {
15303		var tyOf = typeof(Objekt[TE]) ;
15304		
15305		if ((TE != "outerHTML") && (TE != "outerText") && (TE != "innerHTML") && (TE != "innerText") && (tyOf != "function")) {
15306			if (( samoTip == "") || (tyOf == samoTip)) {
15307				switch (tyOf) {
15308					case "string"  : tStrings.push(TE + " : "+Objekt[TE]) ;
15309									 break ;
15310					case "number"  : tNumbers.push(TE + " : "+Objekt[TE]) ;
15311									 break ;
15312					case "boolean" : tBooleans.push(TE + " : "+Objekt[TE]) ;
15313									 break ;
15314					default		   : tOthers.push(TE + " : "+Objekt[TE]) ;
15315									 break ;
15316				}
15317			}
15318		}
15319	}
15320	// Posortiramo arraye
15321	if (tStrings.length > 0) {
15322		tStrings.sort() ;
15323		TText += "\n\nSTRINGS:\n" ;
15324		tStrings.each(function(item) {
15325			TText += item + "\n" ;
15326		});
15327	}
15328	if (tNumbers.length > 0) {
15329		tNumbers.sort() ;
15330		TText += "\n\nNUMBERS:\n" ;
15331		tNumbers.each(function(item) {
15332			TText += item + "\n" ;
15333		});
15334	}
15335	if (tBooleans.length > 0) {
15336		tBooleans.sort() ;
15337		TText += "\n\nBOOLEANS:\n" ;
15338		tBooleans.each(function(item) {
15339			TText += item + "\n" ;
15340		});
15341	}
15342	if (tOthers.length > 0) {
15343		tOthers.sort() ;
15344		TText += "\n\nOTHERS:\n" ;
15345		tOthers.each(function(item) {
15346			TText += item + "\n" ;
15347		});
15348	}
15349	alert (TText) ;
15350}
15351
15352function PhoneValidNonEmpty(Value)
15353{
15354	if ((PhoneValid(Value)) && (Value.trim() != ""))
15355	{
15356		return true ;
15357	} else {
15358		return false ;
15359	}
15360}
15361
15362function PhoneValid(Value)
15363{
15364	if (Value.trim() == "")
15365	{
15366		return true ;
15367	}
15368	else
15369	{
15370		var RegPhone=new RegExp ("^(\\+|)\\d{2}[\\d\\/\\-\\040]*$","i") ;
15371		if (RegPhone.test(Value))
15372		{
15373			return true ;
15374		}
15375		else
15376		{
15377			return false ;
15378		}
15379	}
15380}
15381
15382function EMailValidNonEmpty(Value)
15383{
15384	if ((EmailValid(Value)) && (Value.trim() != ""))
15385	{
15386		return true ;
15387	} else {
15388		return false ;
15389	}
15390}
15391
15392function EmailValid(Value)
15393{
15394	if (Value.trim() == "")
15395	{
15396		return true ;
15397	} else {
15398		var RegMail=new RegExp ("^([\\w-]+(?:\\.[\\w-]+)*)@((?:[\\w-]+\\.)*\\w[\\w-]{0,66})\\.([a-z]{2,6}(?:\\.[a-z]{2})?)$","i") ;
15399
15400		if (RegMail.test(Value))
15401		{
15402			return true ;
15403		} else {
15404			return false ;
15405		}
15406	}
15407}
15408
15409function DateHourValid(Objekt) {
15410	// console.log("DateHourValid:"+Objekt.value) ;
15411	if (typeof(Objekt) == "object") {
15412		var Datum = new Object() ;
15413		var Ura = new Object() ;
15414		var Value = Objekt.value.trim() ;
15415		if (Value != '') {
15416			// console.log("VALUE: "+Value+": "+Value.indexOf(" ")) ;
15417			if (Value.indexOf(" ") != -1) {
15418				var DatumCas = Value.split(" ") ;
15419				Datum.value = DatumCas[0] ;
15420				Ura.value = DatumCas[1] ;
15421				DateValid(Datum) ;
15422				HourValid(Ura) ;
15423			} else {
15424				// console.log(Objekt) ;
15425				if (DateValid(Objekt)) {
15426					// console.log("Obdelano:"+Objekt.value) ;
15427					// Če pridemo tule čez, potem smo imeli samo datum - ker pa rabimo tudi uro, jo po potrebi dodamo in sicer 00:00
15428					var Value = Objekt.value.trim() ;
15429					if ((Value.indexOf(" ") == -1) && (Value != "CURRENT")) {
15430						Objekt.value += " 00:00" ;
15431					}
15432				}
15433			}
15434		}
15435	}
15436}
15437
15438function HourValid(Objekt) {
15439	// console.log("HourValid:"+Objekt.value) ;
15440	UraPravilna = true ;
15441	var Value="" ;
15442	if (typeof(Objekt) == "object") {
15443		Value=Objekt.value ;
15444	} else if (typeof(Objekt) == "string") {
15445		Value=Objekt ;
15446	}
15447	if (Value.trim()!="") {
15448		/* Samo ura ? */
15449		var RegDate=new RegExp ("^\\d{1,2}$","") ;
15450		if (RegDate.test(Value)) {
15451			if (Number(Value) < 24) {
15452				Value += ":00:00" ;
15453				Objekt.value=Value ;
15454				UraPravilna = Value ;
15455			} else {
15456				UraPravilna = false ;
15457			}
15458		} else {
15459			/* Ure in minute ? */
15460			var RegDate=new RegExp ("^(\\d{1,2})(,|:)(\\d{1,2})$","") ;
15461			if (RegDate.test(Value)) {
15462				if ((Number(RegExp.$1) < 24) && (Number(RegExp.$3) < 60)) {
15463					var TempUra = RegExp.$1+":" ;
15464					if (String(RegExp.$3).length == 1)
15465						TempUra += "0"+RegExp.$3+":00" ;
15466					else
15467						TempUra += RegExp.$3+":00" ;
15468					Objekt.value=TempUra ;
15469					UraPravilna = Value ;
15470				} else {
15471					UraPravilna = false ;
15472				}
15473			} else {
15474				/* Kompletni zapis ? */
15475				var RegDate=new RegExp ("^(\\d{1,2})(,|:)(\\d{1,2})(,|:)(\\d{1,2})$","") ;
15476				if (RegDate.test(Value)) {
15477					if ((Number(RegExp.$1) < 24) && (Number(RegExp.$3) < 60) && (Number(RegExp.$5) < 60)) {
15478						var TempUra = RegExp.$1+":" ;
15479						if (String(RegExp.$3).length == 1)
15480							TempUra += "0"+RegExp.$3+":" ;
15481						else
15482							TempUra += RegExp.$3+":" ;
15483						if (String(RegExp.$5).length == 1)
15484							TempUra += "0"+RegExp.$5 ;
15485						else
15486							TempUra += RegExp.$5 ;
15487						Objekt.value=TempUra ;
15488						UraPravilna = Value ;
15489					} else {
15490						UraPravilna = false ;
15491					}
15492				} else {
15493					/* Napačen zapis časa ! */
15494					UraPravilna = false ;
15495				}
15496			}
15497		}
15498	}
15499	if (!UraPravilna) {
15500		alert ("Napačna oblika ure !\n\nPodprte oblike zapisa ure :\nhh\nhh:mm\nhh:mm:ss\nhh.mm\nhh,mm,ss\n") ;
15501		if (typeof(Objekt) == "object") {
15502			Objekt.value="" ;
15503		}
15504	}
15505	return UraPravilna ;
15506}
15507
15508function TrajanjeValid(Objekt) {
15509	UraPravilna = true ;
15510	var Value = "" ;
15511	if (typeof(Objekt) == "object") {
15512		Value = Objekt.value ;
15513	} else if (typeof(Objekt) == "string") {
15514		Value = Objekt ;
15515	}
15516	if (Value.trim() != "") {
15517		/* Samo ura ? */
15518		var RegDate=new RegExp ("^\\d+$","") ;
15519		if (RegDate.test(Value)) {
15520			Value += ":00:00" ;
15521			Objekt.value=Value ;
15522			UraPravilna = Value ;
15523		} else {
15524			/* Ure in minute ? */
15525			var RegDate=new RegExp ("^(\\d+)(,|:)(\\d{1,2})$","") ;
15526			if (RegDate.test(Value)) {
15527				var RegVez=new RegExp (",","") ;
15528				Value = Value.replace(RegVez,":")+":00" ;
15529				Objekt.value=Value ;
15530				UraPravilna = Value ;
15531			} else {
15532				/* Kompletni zapis ? */
15533				var RegDate=new RegExp ("^(\\d+)(,|:)(\\d{1,2})(,|:)(\\d{1,2})$","") ;
15534				if (RegDate.test(Value)) {
15535					var RegVez=new RegExp (",","") ;
15536					Value = Value.replace(RegVez,":") ;
15537					Value = Value.replace(RegVez,":") ;
15538					Objekt.value=Value ;
15539					UraPravilna = Value ;
15540				} else {
15541					/* Napačen zapis časa ! */
15542					UraPravilna = false ;
15543				}
15544			}
15545		}
15546	}
15547	if (!UraPravilna) {
15548		alert ("Napačna oblika trajanja !\n\nPodprte oblike zapisa trajanja v urah so :\nhhh\nhhh:mm\nhhh:mm:ss\nhhh.mm\nhhh,mm,ss\n") ;
15549		if (typeof(Objekt) == "object") {
15550			Objekt.value="" ;
15551		}
15552	}
15553	return UraPravilna ;
15554}
15555
15556function DateValid(Objekt) {
15557	var Value="" ;
15558	if (typeof(Objekt) == "object") {
15559		Value=Objekt.value ;
15560	} else if (typeof(Objekt) == "string") {
15561		Value=Objekt ;
15562	}
15563	if (Value.trim()=="") {
15564		return true ;
15565	} else {
15566		/// Pogledamo, ali imamo slučajno podan datum kot D ali D+x
15567		if ((Value.substr(0,1) == "d") || (Value.substr(0,1) == "D")) {
15568			DD = new Date() ;
15569			/* Ali imamo slučajno dodano še + nekaj ? */
15570			if ((Value.substr(1,1) == "+") || (Value.substr(1,1) == "-"))
15571			{
15572				DodanoDni = Number(Value.substr(2)) ;
15573				if (DodanoDni != "NaN")
15574				{
15575					if (Value.substr(1,1) == "+")
15576						DDD = new Date(DD.valueOf() + (DodanoDni * 24 * 60 * 60 * 1000)) ;
15577					else
15578						DDD = new Date(DD.valueOf() - (DodanoDni * 24 * 60 * 60 * 1000)) ;
15579					DD = DDD ;
15580				}
15581			}
15582			Objekt.value=DD.getDate()+"."+(DD.getMonth()+1)+"."+DD.getFullYear() ;
15583			Value = Objekt.value ;
15584		} else if ((Value.substr(0,1) == "w") || (Value.substr(0,1) == "W")) {
15585			/// Dan v tednu - prvi naslednji
15586			DD = new Date() ;
15587			var tretnutniDan = DD.getDay() ;
15588			var zeljeniDan = Number(Value.substr(1,1)) ;
15589			if (isNaN(zeljeniDan))
15590				zeljeniDan = 0 ;
15591			if (zeljeniDan > 6)
15592				zeljeniDan = 6 ;
15593			if (tretnutniDan > zeljeniDan)
15594				DDD = new Date(DD.valueOf() + ((7+zeljeniDan-tretnutniDan) * 24 * 60 * 60 * 1000)) ;
15595			else
15596				DDD = new Date(DD.valueOf() + ((zeljeniDan-tretnutniDan) * 24 * 60 * 60 * 1000)) ;
15597			DD = DDD ;
15598			Objekt.value=DD.getDate()+"."+(DD.getMonth()+1)+"."+DD.getFullYear() ;
15599			Value = Objekt.value ;
15600		} else if ((Value.substr(0,7) == "current") || (Value.substr(0,7) == "CURRENT")) {
15601			return true ; // Special value !!!
15602		}
15603
15604		/* Samo dan ? -> Dodamo trenutni mesec in leto */
15605		var RegDate=new RegExp ("^\\d{1,2}$","") ;
15606		if (RegDate.test(Value))
15607		{
15608			DD = new Date() ;
15609			Objekt.value=Value+"."+(DD.getMonth()+1)+"."+DD.getFullYear() ;
15610			Value = Objekt.value ;
15611			// return true ;
15612		}
15613		/* Samo dan in mesec ? -> Dodamo trenutno leto */
15614		var RegDate=new RegExp ("^([0123]\\d|\\d)(\\.|-|\\/|,)((0|)\\d|10|11|12)$","") ;
15615		if (RegDate.test(Value))
15616		{
15617			var TReg=new RegExp ("\\.","") ;
15618			if (TReg.test(Value))
15619				TVez = "." ;
15620			else
15621			{
15622				var TReg=new RegExp ("-","") ;
15623				if (TReg.test(Value))
15624					TVez = "-" ;
15625				else
15626				{
15627					var TReg=new RegExp (",","") ;
15628					if (TReg.test(Value))
15629						TVez = "," ;
15630					else
15631						TVez = "/" ;
15632				}
15633			}
15634
15635			DD = new Date() ;
15636			Objekt.value=Value+TVez+DD.getFullYear() ;
15637			Value = Objekt.value ;
15638			// return true ;
15639		}
15640
15641		/* Sedaj pa naredimo dejansko preverbo datuma */
15642		ReturnedDate = GetDateDMY(Value) ;
15643		if (ReturnedDate == false) {
15644			alert ("NAPAČNA OBLIKA DATUMA\nALI\nDATUM NE OBSTAJA !\n\nDatum je lahko le oblike :	Pravilne oblike datuma so :\nyyyymmdd\nyyyy.mm.dd\nyyyy-mm-dd\nyyyy/mm/dd\nyyyy,mm,dd\ndd.mm.yyyy\ndd-mm-yyyy\ndd/mm/yyyy\ndd,mm,yyyy\nmm.dd.yyyy\nmm-dd-yyyy\nmm/dd/yyyy\nmm,dd,yyyy\n" ) ;
15645			Objekt.focus() ;
15646			return false ;
15647		} else {
15648			TempDate = new Date(ReturnedDate.Leto,ReturnedDate.Mesec,ReturnedDate.Dan) ;
15649			// Objekt.value = TempDate.getDate()+"."+(TempDate.getMonth()+1)+"."+TempDate.getYear() ;
15650			Objekt.value = TempDate.getDate()+"."+(TempDate.getMonth()+1)+"."+TempDate.getFullYear() ;
15651			return true ;
15652		}
15653	}
15654}
15655
15656function PreveriStevilo(Ime)
15657{
15658	LocRegX = new RegExp ("(-|)(\\d*)(\\.|)(\\d*)(\\.|)(\\d*)(\\.|)(\\d*)(\\.|)(\\,|)(\\d*)","") ;
15659
15660	Stevilo = Number(document.getElementById("D"+Ime).value.replace(LocRegX,"$1$2$4$6$8.$11")) ;
15661	OldStevilo = Number(document.getElementById(Ime).value) ;
15662
15663	if (isNaN(Stevilo))
15664	{
15665		alert ("Vpisana številka je lahko le oblike :\n\nddd.ddd,dd \nali\n dddddd,dd\nali\ndddddd") ;
15666		document.getElementById("D"+Ime).value = OldStevilo.toLocaleString() ;
15667	}
15668	else
15669	{
15670		document.getElementById("D"+Ime).value = Stevilo.toLocaleString() ;
15671		document.getElementById(Ime).value = Stevilo ;
15672	}
15673}
15674
15675/* ********************************** */
15676/*   Dodano zaradi updejta editorja   */
15677/* ********************************** */
15678
15679/* Pogledamo, kateri Browser imamo */
15680function CheckBrowser()
15681{
15682	Navi = navigator.userAgent.toLowerCase();
15683	/* Opera ? */
15684	if (Navi.indexOf("opera") != -1)
15685	{
15686		return 3 ;
15687	}
15688	else if ((Navi.indexOf("msie") != -1) && (Navi.indexOf("mac") == -1)) /* IE */
15689	{
15690		/* IE - Ali je prava verzija ? */
15691		if ((Navi.indexOf('5.5')!=-1) || (Navi.indexOf('6.0')!=-1))
15692		{
15693			return 1 ;
15694		}
15695		else
15696		{
15697			return 4 ;
15698		}
15699	}
15700	else
15701	{
15702		/* Ali je Mozilla in je prava verzija ? */
15703		// Rx = /rv:1\.[3456789](.*?)Gecko/i ;
15704		Rx = new RegExp ("rv:1\\.[3456789](.*?)Gecko","i") ;
15705		if (Rx.test(Navi))
15706		{
15707			return 2 ;
15708		}
15709		else
15710		{
15711			return 5 ; /* Ostali browserji */
15712		}
15713	}
15714}
15715
15716function GetDateDMY(Value) {
15717	// Preverimo najprej, če imamo slučajno datum in uro ( iz izbirnika za datume ) 
15718	
15719	// YYYYmmdd
15720	var RegDate=new RegExp ("^\\d{8}$","") ;
15721	TRet = new Object() ;
15722	if (RetArr = Value.match(RegDate)) {
15723		TRet.Leto = Value.substr(0,4) ;
15724		TRet.Mesec = Number(Value.substr(4,2))-1 ;
15725		TRet.Dan = Value.substr(6,2) ;
15726		return TRet ;
15727	} else {
15728		// YYYY.mm.dd
15729		RegDate=new RegExp ("^([12]\\d\\d\\d)(\\.|-|,|\\/)((0|)\\d|10|11|12)(\\.|-|,|\\/)([0123]\\d|\\d)$","") ;
15730		if (RetArr = Value.match(RegDate)) {
15731			TRet.Dan = RetArr[5] ;
15732			TRet.Mesec = Number(RetArr[3])-1 ;
15733			TRet.Leto = RetArr[1] ;
15734			return TRet ;
15735		} else {
15736			// dd.mm.YYYY
15737			RegDate=new RegExp ("^([0123]\\d|\\d)(\\.|-|,|\\/)((0|)\\d|10|11|12)(\\.|-|,|\\/)([12]\\d\\d\\d)$","") ;
15738			if (RetArr = Value.match(RegDate)) {
15739				TRet.Dan = RetArr[1] ;
15740				TRet.Mesec = Number(RetArr[3]-1) ;
15741				TRet.Leto = RetArr[6] ;
15742				return TRet ;
15743			} else {
15744				// mm.dd.YYYY
15745				RegDate=new RegExp ("^((0|)\\d|10|11|12)(\\.|-|,|\\/)([0123]\\d|\\d)(\\.|-|,|\\/)([12]\\d\\d\\d)$","") ;
15746				if (RetArr = Value.match(RegDate)) {
15747					TRet.Dan = RetArr[5] ;
15748					TRet.Mesec = Number(RetArr[1]-1) ;
15749					TRet.Leto = RetArr[3] ;
15750					return TRet ;
15751				} else {
15752					// Poskusimo še z morebitnimi JS metodami
15753					var d = new Date(Value) ;
15754					if (d != "Invalid Date") {
15755						TRet.Dan = d.getDate() ;
15756						TRet.Mesec = d.getMonth() ;
15757						TRet.Leto = d.getFullYear() ;
15758						return TRet ;
15759					} else {
15760						// dd.mm.YYYY H:i
15761						RegDate=new RegExp ("^([0123]\\d|\\d)(\\.|-|,|\\/)((0|)\\d|10|11|12)(\\.|-|,|\\/)([12]\\d\\d\\d) \\d{1,2}:\\d{1,2}$","") ;
15762						if (RetArr = Value.match(RegDate)) {
15763							TRet.Dan = RetArr[1] ;
15764							TRet.Mesec = Number(RetArr[3]-1) ;
15765							TRet.Leto = RetArr[6] ;
15766							return TRet ;
15767						} else {
15768							return false ;
15769						}
15770					}
15771				}
15772			}
15773		}
15774	}
15775}
15776
15777var GetDatumFunkcija = "" ;
15778var GetDatumPolje = "" ;
15779
15780function GetDatum(Polje,Funkcija)
15781{
15782	GetDatumFunkcija = Funkcija ;
15783	GetDatumPolje = Polje ;
15784	TrenDatum = String(document.getElementById(Polje).value) ;
15785	if (TrenDatum.trim() != "")
15786	{
15787		RetDatum = GetDateDMY(TrenDatum) ;
15788		Dan = RetDatum.Dan ;
15789		Mesec = RetDatum.Mesec+1 ;
15790		Leto = RetDatum.Leto ;
15791	}
15792	else
15793	{
15794		TDate = new Date() ;
15795		Dan = TDate.getDate() ;
15796		Mesec = TDate.getMonth()+1 ;
15797		Leto = TDate.getYear() ;
15798	}
15799	AllSmallWindowDialog(190,240,"/DeskWMDialog.php?Izbira=IzberiDatumOkv&D="+Dan+"&M="+Mesec+"&L="+Leto,"VrniDatum") ;
15800	// TRetVal = NewSmallWindowDialog(190,240,"DeskWMDialog.php?Izbira=IzberiDatumOkv&D="+Dan+"&M="+Mesec+"&L="+Leto) ;
15801	//if (typeof(TRetVal)=="object")
15802	//{
15803	//	if(TRetVal!=null)
15804	//	{
15805	//		document.getElementById(Polje).value=TRetVal.Datum ;
15806	//		eval(Funkcija+"(document.getElementById(Polje))") ; ;
15807	//	}
15808	//}
15809}
15810
15811function VrniDatum(RetObj)
15812{
15813	if (typeof(RetObj) == "object")
15814	{
15815		document.getElementById(GetDatumPolje).value=RetObj.Datum ;
15816		eval(GetDatumFunkcija+"(document.getElementById(GetDatumPolje))") ; ;
15817	}
15818}
15819
15820var Slike = new Array ;
15821
15822function SlikaPreload(Id, onslika, offslika)
15823{
15824	Slike[Id] = new Object;
15825	Slike[Id].on = new Image();
15826	Slike[Id].on.src = onslika;
15827	Slike[Id].off = new Image();
15828	Slike[Id].off.src = offslika;
15829}
15830
15831function onPic(Id)
15832{
15833	document.getElementById("RollOver"+Id).src = Slike[Id].on.src;
15834}
15835
15836function offPic(Id)
15837{
15838	document.getElementById("RollOver"+Id).src = Slike[Id].off.src;
15839}
15840
15841
15842function checkFocus()
15843{
15844	if (modalWin!=null && !modalWin.closed)
15845	{
15846		self.blur();
15847		modalWin.focus();
15848	}
15849}
15850
15851function AllSmallWindowDialog(h,w,fileName,Funkcija)
15852{
15853	if (Funkcija.trim() == "")
15854	{
15855		alert ("Dialog okno zahteva funkcijo za obdelavo vrnjenih podatkov !") ;
15856	}
15857	else
15858	{
15859		Args = new Object ;
15860		Args.Funkcija = Funkcija;
15861
15862		if (window.showModalDialog)
15863		{
15864			sFeatures ="dialogHeight: " + h + "px;";
15865			sFeatures+="dialogWidth: " + w + "px;";
15866			sFeatures+="resizable: 0;" ;
15867			sFeatures+="scroll: 0;";
15868			sFeatures+="status: 0;";
15869			sFeatures+="titlebar: 0;";
15870			sFeatures+="toolbar: 0;";
15871			X = window.showModalDialog(fileName, Args, sFeatures) ;
15872
15873			HideWait() ;
15874			ReturnFunction(X) ;
15875		}
15876		else
15877		{
15878			properties ="channelmode=0," ;
15879			properties+="directories=0,";
15880			properties+="fullscreen=0,";
15881			properties+="height="+h+"px,";
15882			properties+="left="+(window.screen.width - w - 20 ) +",";
15883			properties+="location=0,";
15884			properties+="menubar=0,";
15885			properties+="resizable=1," ;
15886			properties+="scrollbars=1,";
15887			properties+="status=0,";
15888			properties+="titlebar=0,";
15889			properties+="toolbar=0,";
15890			properties+="top=20,";
15891			properties+="width="+w+"," ;
15892			properties+="modal=yes";
15893
15894			modalWin=window.open(fileName,"",properties);
15895			modalWin.dialogArguments=Args;
15896		}
15897	}
15898}
15899
15900function AllSmallWindowNeDialog(h,w,fileName,Funkcija)
15901{
15902	if (Funkcija.trim() == "")
15903	{
15904		alert ("Dialog okno zahteva funkcijo za obdelavo vrnjenih podatkov !") ;
15905	}
15906	else
15907	{
15908		Args = new Object ;
15909		Args.Funkcija = Funkcija;
15910
15911		properties="channelmode =  0." ;
15912		properties=properties + "directories =  0,";
15913		properties=properties + "fullscreen =  0,";
15914		properties=properties + "height = "+h+"px ,";
15915		properties=properties + "left = "+(window.screen.width - w - 20 ) +",";
15916		properties=properties + "location =  0,";
15917		properties=properties + "menubar =  0,";
15918		properties=properties + "resizable =  1," ;
15919		properties=properties + "scrollbars = 1,";
15920		properties=properties + "status =  0,";
15921		properties=properties + "titlebar =  0,";
15922		properties=properties + "toolbar =  0,";
15923		properties=properties + "top = 20,";
15924		properties=properties + "width = "+w+"," ;
15925
15926		modalWin=window.open(fileName,"",properties);
15927		modalWin.dialogArguments=Args;
15928	}
15929}
15930
15931function GetDatumStran(Polje,Funkcija)
15932{
15933	TrenDatum = document.getElementById(Polje).value ;
15934	if (TrenDatum.trim() != "")
15935	{
15936		RetDatum = GetDateDMY(TrenDatum) ;
15937		Dan = RetDatum.Dan ;
15938		Mesec = RetDatum.Mesec+1 ;
15939		Leto = RetDatum.Leto ;
15940	}
15941	else
15942	{
15943		TDate = new Date() ;
15944		Dan = TDate.getDate() ;
15945		Mesec = TDate.getMonth()+1 ;
15946		Leto = TDate.getYear() ;
15947	}
15948	AllSmallWindowDialog(180,240,"/Dialog.php?Izbira=IzberiDatumOkv&D="+Dan+"&M="+Mesec+"&L="+Leto+"&Func="+Funkcija+"&Polje="+Polje,"GetDatumReturn") ;
15949}
15950
15951function GetDatumReturn(RetObj)
15952{
15953	if (typeof(RetObj)=="object")
15954	{
15955		if(RetObj!=null)
15956		{
15957			if (RetObj.Polje.trim() != "")
15958			{
15959				document.getElementById(RetObj.Polje).value=RetObj.Datum ;
15960				eval(RetObj.Funkcija+"(document.getElementById(RetObj.Polje))") ; ;
15961			}
15962		}
15963	}
15964}
15965
15966function ReturnFunction(RetObj)
15967{
15968	if ((typeof(RetObj)=="object") && (RetObj!=null))
15969		eval(RetObj.Izvedi+"(RetObj) ;") ;
15970}
15971
15972
15973/* Dodamo OnMouseOver in OnMouseOut evente vsem DIV in IMG objektom na strani */
15974function DodajTitleHelpFuncs()
15975{
15976	HTMLElementi = document.getElementsByTagName("DIV") ;
15977	for (var i=0; i < HTMLElementi.length; i++)
15978	{
15979		var Telement = HTMLElementi[i];
15980		if (String(Telement.title).trim() != "")
15981		{
15982			if (Telement.onMouseOver != null)
15983			{
15984				Telement.onMouseOver = function () {
15985					IconButtonMouseOver(Telement) ;
15986					Telement.onMouseOver() ;
15987				}
15988			}
15989			else
15990				Telement.onMouseOver = IconButtonMouseOver(Telement) ;
15991
15992			if (Telement.onMouseOut != null)
15993			{
15994				Telement.onMouseOut = function () {
15995					IconButtonMouseOver(Telement) ;
15996					Telement.onMouseOut() ;
15997				}
15998			}
15999			else
16000				Telement.onMouseOut = HideDescriptionHelp(Telement) ;
16001		}
16002	}
16003
16004	HTMLElementi = document.getElementsByTagName("IMG") ;
16005	for (var i=0; i < HTMLElementi.length; i++)
16006	{
16007		var Telement = HTMLElementi[i];
16008		if (String(Telement.title).trim() != "")
16009		{
16010			if (Telement.onMouseOver != null)
16011			{
16012				Telement.onMouseOver = function () {
16013					IconButtonMouseOver(Telement) ;
16014					Telement.onMouseOver() ;
16015				}
16016			}
16017			else
16018				Telement.onMouseOver = IconButtonMouseOver(Telement) ;
16019
16020			if (Telement.onMouseOut != null)
16021			{
16022				Telement.onMouseOut = function () {
16023					IconButtonMouseOver(Telement) ;
16024					Telement.onMouseOut() ;
16025				}
16026			}
16027			else
16028				Telement.onMouseOut = HideDescriptionHelp(Telement) ;
16029		}
16030	}
16031}
16032
16033function ShowDescriptionHelpTitle(Objekt)
16034{
16035	if (window.top.document.getElementById("DescriptionField") != null)
16036	{
16037		window.top.document.getElementById("DescriptionField").innerHTML = Objekt.title ;
16038	}
16039	else
16040	{
16041		if (document.getElementById("DescriptionField") != null)
16042		{
16043			document.getElementById("DescriptionField").innerHTML = Objekt.title ;
16044		}
16045	}
16046}
16047
16048function ShowDescriptionHelp(ObjektValue)
16049{
16050	if (window.top.document.getElementById("DescriptionField") != null)
16051	{
16052		window.top.document.getElementById("DescriptionField").innerHTML = ObjektValue ;
16053	}
16054	else
16055	{
16056		if (document.getElementById("DescriptionField") != null)
16057		{
16058			document.getElementById("DescriptionField").innerHTML = ObjektValue ;
16059		}
16060	}
16061}
16062
16063function HideDescriptionHelp()
16064{
16065	if (window.top.document.getElementById("DescriptionField") != null)
16066	{
16067		window.top.document.getElementById("DescriptionField").innerHTML = "&nbsp;" ;
16068	}
16069	else
16070	{
16071		if (document.getElementById("DescriptionField") != null)
16072		{
16073			document.getElementById("DescriptionField").innerHTML = "&nbsp;" ;
16074		}
16075	}
16076}
16077
16078function IconButtonMouseOver(Button) {
16079	Button.className ="IconButtonOver" ;
16080	if (window.top.document.getElementById("DescriptionField")) {
16081		window.top.document.getElementById("DescriptionField").innerHTML = Button.title ;
16082	} else if (document.getElementById("DescriptionField")) {
16083		document.getElementById("DescriptionField").innerHTML = Button.title ;
16084	}
16085}
16086
16087function IconButtonMouseOut(Button) {
16088	Button.className ="IconButton" ;
16089	if (window.top.document.getElementById("DescriptionField")) {
16090		window.top.document.getElementById("DescriptionField").innerHTML = "&nbsp;" ;
16091	} else if (document.getElementById("DescriptionField") != null) {
16092		document.getElementById("DescriptionField").innerHTML = "&nbsp;" ;
16093	}
16094}
16095
16096function IconButtonMouseDown(Button) {
16097	Button.className ="IconButtonDown" ;
16098	if (typeof(FloaterHelpDIVObj) != "undefined")
16099		FloaterHelpDIVObj.style.display="none" ;
16100}
16101
16102function IconButtonMouseUp(Button) {
16103	Button.className ="IconButtonOver" ;
16104}
16105
16106function StartMenuInterval()
16107{
16108	TimeOutRightClickMenu = window.setTimeout(SkrijRightClickMenu,1000) ;
16109}
16110function StopMenuInterval()
16111{
16112	window.clearTimeout(TimeOutRightClickMenu);
16113}
16114
16115function ClearRows(TTable)
16116{
16117	StRows = TTable.rows.length ;
16118	for (i=0; i < StRows; i++)
16119		TTable.deleteRow(0) ;
16120}
16121
16122function getObjectPosX(Objekt)
16123{
16124	var tempX = 0;
16125	if (Objekt.offsetParent)
16126	{
16127		while (Objekt.offsetParent)
16128		{
16129			tempX += Objekt.offsetLeft
16130			Objekt = Objekt.offsetParent;
16131		}
16132	}
16133	else if (Objekt.x)
16134		tempX += Objekt.x;
16135	return tempX;
16136}
16137
16138function getObjectPosY(Objekt)
16139{
16140	var tempY = 0;
16141	if (Objekt.offsetParent)
16142	{
16143		while (Objekt.offsetParent)
16144		{
16145			tempY += Objekt.offsetTop
16146			Objekt = Objekt.offsetParent;
16147		}
16148	}
16149	else if (Objekt.y)
16150		tempY += Objekt.y;
16151	return tempY;
16152}
16153
16154function DivHelpFloaterHide()
16155{
16156	if (typeof(FloaterHelpDIVObj) != "undefined")
16157		FloaterHelpDIVObj.style.display='none';
16158}
16159
16160var VsebinaPoljaOld = "" ;
16161var FocusiranoPolje = new Object ;
16162
16163function FocusPolje(e)
16164{
16165	if (!e) var e = window.event ;
16166
16167	if (e.target) targ = e.target;
16168	else if (e.srcElement) targ = e.srcElement;
16169	if (targ.nodeType == 3) // defeat Safari bug
16170		targ = targ.parentNode;
16171
16172	if (((targ.tagName == "INPUT") || (targ.tagName == "TEXTAREA")) && (FocusiranoPolje != targ))
16173	{
16174		VsebinaPoljaOld = targ.value ;
16175		FocusiranoPolje = targ ;
16176	}
16177}
16178
16179function SubmitLogout()
16180{
16181	window.location="Odjava.php" ;
16182}
16183
16184var NaVrhBehavior = {
16185	mo: null,
16186	x: 0,
16187	y: 0,
16188
16189	onmousedown: function (e)
16190	{
16191		e = e || window.event;
16192		var src = jcl.FindBehaviourElement(e.srcElement, NaVrhBehavior);
16193		src.NaVrh(e);
16194	},
16195
16196	NaVrh: function (e)
16197	{
16198		var mo = this;
16199		while ((mo != null) && (mo.className != "ZavihekArtikla"))
16200			mo = mo.parentNode;
16201
16202		if (mo == null)
16203			return; // don't move
16204		MoverBehaviour.mo = mo;
16205
16206		// Dodamo zamenjavo zIndex-a - postavimo zavihek na vrh
16207		var VsiZavihki = jcl.getElementsByClassName(document.getElementById("OsnovnaForma"),"ZavihekArtikla") ;
16208		var TObjzIndex = mo.style.zIndex ;
16209		for (var i = 0; i < VsiZavihki.length; i++)
16210			if (VsiZavihki[i].style.zIndex > TObjzIndex)
16211				VsiZavihki[i].style.zIndex -= 1 ;
16212		mo.style.zIndex = 90 ;
16213	} // NaVrh
16214} ;
16215
16216var MoverBehaviour = {
16217	mo: null,
16218	x: 0,
16219	y: 0,
16220	xx : 0,
16221	yy : 0,
16222
16223	onmousedown: function (e)
16224	{
16225		e = e || window.event;
16226		var src = jcl.FindBehaviourElement(e.srcElement, MoverBehaviour);
16227		src.MoveStart(e);
16228	},
16229
16230	_onmousemove: function (e)
16231	{
16232		e = e || window.event;
16233		MoverBehaviour.MoveIt(e);
16234	},
16235
16236
16237	_onmouseup: function (e)
16238	{
16239		e = e || window.event;
16240		MoverBehaviour.MoveEnd(e);
16241	},
16242
16243	MoveStart: function (e)
16244	{
16245		var mo = this;
16246		while ((mo != null) && (mo.className != "ZavihekArtikla"))
16247			mo = mo.parentNode;
16248
16249		if (mo == null)
16250			return; // don't move
16251		MoverBehaviour.mo = mo;
16252
16253		// Dodamo zamenjavo zIndex-a - postavimo zavihek na vrh
16254		var VsiZavihki = jcl.getElementsByClassName(document.getElementById("OsnovnaForma"),"ZavihekArtikla") ;
16255		var TObjzIndex = mo.style.zIndex ;
16256		for (var i = 0; i < VsiZavihki.length; i++)
16257			if (VsiZavihki[i].style.zIndex > TObjzIndex)
16258				VsiZavihki[i].style.zIndex -= 1 ;
16259		mo.style.zIndex = 90 ;
16260
16261		// calculate mousepointer-object distance
16262		mo.x = mo.y = 0;
16263		obj = mo;
16264		while (obj != null)
16265		{
16266			mo.x += obj.offsetLeft;
16267			mo.y += obj.offsetTop;
16268			obj = obj.offsetParent;
16269		} // while
16270		mo.x = e.clientX - mo.x;
16271		mo.y = e.clientY - mo.y;
16272
16273		// make the moving object globally evailable when mouse is leaving this object.
16274		jcl.AttachEvent(document, "onmousemove", this._onmousemove);
16275		jcl.AttachEvent(document, "onmouseup", this._onmouseup);
16276	}, // MoveStart
16277
16278
16279	MoveIt: function (e)
16280	{
16281		var mo = MoverBehaviour.mo;
16282		if (mo != null)
16283		{
16284			var tt = (e.clientX - mo.x);
16285			if (tt < 0) tt = 0 ;
16286			var p = tt + "px";
16287			if (p != mo.style.left)
16288			{
16289				mo.style.left = p;
16290				this.xx = (e.clientX - mo.x) ;
16291			}
16292			tt = (e.clientY - mo.y) ;
16293			if (tt < 60) tt = 60 ;
16294			p = tt + "px";
16295			if (p != mo.style.top)
16296			{
16297				mo.style.top = p;
16298				this.yy = (e.clientY - mo.y) ;
16299			}
16300		} // if
16301		// cancel selecting anything
16302		e.cancelBubble = true;
16303		e.returnValue = false;
16304	}, // MoveIt
16305
16306
16307	MoveEnd: function ()
16308	{
16309		var mo = MoverBehaviour.mo;
16310		if (mo != null)
16311		{
16312			MoverBehaviour.mo = null;
16313			jcl.DetachEvent(document, "onmousemove", this._onmousemove);
16314			jcl.DetachEvent(document, "onmouseup", this._onmouseup);
16315			// Zapišemo na server v Session zadnjo pozicijo
16316			DWMAJ_RequestXMLV2("DeskWMServer.php?Objekt=AJAX&SubKorak=ZapisiPozicijoZavihka&Zav="+mo.id+"&y="+this.yy+"&x="+this.xx+"&z="+mo.style.zIndex+"&d="+mo.style.display,NoOp) ;
16317		} // if
16318	} // MoveEnd
16319
16320} // MoverBehaviour
16321
16322function NoOp()
16323{
16324}
16325
16326var VsiBannerji = new Array ;
16327var BannerTimer = new Array ;
16328var BannerRun = new Array ;
16329var BannerCurTxt = new Array ;
16330
16331function PremakniBannerCSS(BanId,TxtId) {
16332	var TDebug = false ;
16333	var DebugBannerObj = null ;
16334
16335	if ($D('DebugBanner'))
16336		DebugBannerObj = $('DebugBanner') ;
16337	else
16338		TDebug = false ; // Izključimo TDebug, če slučajno nimamo HTML elementa za DEBUG
16339
16340	if (TxtId == -1) {
16341		if (TDebug) DebugBannerObj.innerHTML = DebugBannerObj.innerHTML + 'Avtomatsko premikanje :'+TxtId+'<br>' ;
16342		// Avtomatsko premikanje - ali je vključeno ?
16343		if (BannerRun[BanId]) {
16344			if (TDebug) DebugBannerObj.innerHTML = DebugBannerObj.innerHTML + 'Naslednji - Running:'+BannerRun[BanId]+' Current:'+BannerCurTxt[BanId]+' Length:'+VsiBannerji[BanId].length+'<br>' ;
16345			if (BannerCurTxt[BanId] >= VsiBannerji[BanId].length-1)
16346				TxtId = 0 ;
16347			else
16348				TxtId = BannerCurTxt[BanId] + 1 ;
16349		}
16350	} else {
16351		// Ročni premik - izklopimo avtomatsko menjavo
16352		if (BannerRun[BanId])
16353			StartStopBanner(BanId) ;
16354	}
16355	if (TxtId >= 0) {
16356		if ((!$('BanVseb'+BanId+'_'+BannerCurTxt[BanId]).inEffect) && (!$('BanVseb'+BanId+'_'+TxtId).inEffect)) {
16357			if ( BannerCurTxt[BanId] != TxtId ) {
16358				// Naredimo dejansko zamenjavo bannerja
16359				var VsebinaBan = $('VsebinaBanner'+BanId) ;
16360				if (TDebug) DebugBannerObj.innerHTML = DebugBannerObj.innerHTML + 'Fadeout :'+BannerCurTxt[BanId]+'<br>' ;
16361				$('BanVseb'+BanId+'_'+BannerCurTxt[BanId]).className = $('BanVseb'+BanId+'_'+BannerCurTxt[BanId]).getAttribute("banOffClass") ;
16362
16363				// Ugasnemo ikono, če obstaja
16364				if($D("Ban"+BanId+"Im"+BannerCurTxt[BanId])) {
16365					var tmpButon = $("Ban"+BanId+"Im"+BannerCurTxt[BanId]) ;
16366					if (tmpButon.hasAttribute("offImage")) {
16367						tmpButon.src = tmpButon.getAttribute("offImage") ;
16368					}
16369				}
16370				if (TDebug) DebugBannerObj.innerHTML = DebugBannerObj.innerHTML + 'FadeIn :'+TxtId+'<br>' ;
16371				$('BanVseb'+BanId+'_'+BannerCurTxt[BanId]).inEffect = false ;
16372				
16373				$('BanVseb'+BanId+'_'+TxtId).inEffect = true ;
16374				$('BanVseb'+BanId+'_'+TxtId).className = $('BanVseb'+BanId+'_'+TxtId).getAttribute("banOnClass") ;
16375				
16376				// Prižgemo ikono, če obstaja
16377				if($D("Ban"+BanId+"Im"+TxtId)) {
16378					var tmpButon = $("Ban"+BanId+"Im"+TxtId) ;
16379					if (tmpButon.hasAttribute("onImage")) {
16380						tmpButon.src = tmpButon.getAttribute("onImage") ;
16381					}
16382				}
16383				BannerCurTxt[BanId] = TxtId ;
16384				$('BanVseb'+BanId+'_'+TxtId).inEffect = false ;
16385			} else {
16386				StartStopBanner(BanId) ;
16387			}
16388		}
16389	}
16390}
16391
16392function PremakniBanner(BanId,TxtId) {
16393	var TDebug = false ;
16394	var DebugBannerObj = null ;
16395	if ($D('DebugBanner'))
16396		DebugBannerObj = $('DebugBanner') ;
16397	else
16398		TDebug = false ; // Izključimo TDebug, če slučajno nimamo HTML elementa za DEBUG
16399
16400	if (TxtId == -1) {
16401		if (TDebug) DebugBannerObj.innerHTML = DebugBannerObj.innerHTML + 'Avtomatsko premikanje :'+TxtId+'<br>' ;
16402		// Avtomatsko premikanje - ali je vključeno ?
16403		if (BannerRun[BanId]) {
16404			if (TDebug) DebugBannerObj.innerHTML = DebugBannerObj.innerHTML + 'Naslednji - Running:'+BannerRun[BanId]+' Current:'+BannerCurTxt[BanId]+' Length:'+VsiBannerji[BanId].length+'<br>' ;
16405			if (BannerCurTxt[BanId] >= VsiBannerji[BanId].length-1)
16406				TxtId = 0 ;
16407			else
16408				TxtId = BannerCurTxt[BanId] + 1 ;
16409		}
16410	} else {
16411		// Ročni premik - izklopimo avtomatsko menjavo
16412		if (BannerRun[BanId])
16413			StartStopBanner(BanId) ;
16414	}
16415	if (TxtId >= 0) {
16416		if ((!$('BanVseb'+BanId+'_'+BannerCurTxt[BanId]).inEffect) && (!$('BanVseb'+BanId+'_'+TxtId).inEffect)) {
16417			if ( BannerCurTxt[BanId] != TxtId ) {
16418				// Naredimo dejansko zamenjavo bannerja
16419				var VsebinaBan = $('VsebinaBanner'+BanId) ;
16420				// console.log('Fadeout '+BanId+':'+BannerCurTxt[BanId]) ;
16421				var tFadeoutObj = $('BanVseb'+BanId+'_'+BannerCurTxt[BanId]) ;
16422				var tTransPosition = "" ;
16423				// Ali imamo na objektu nastavljeno, kateri "position" se uporablja med tranzicijo ( za kompatibilnost s starimi objekti za banner izmenjevalce
16424// 				if (tFadeoutObj.hasAttribute("dwm_bannerTransPosition"))
16425// 					tTransPosition = tFadeoutObj.getAttribute("dwm_bannerTransPosition") ;
16426				// console.log("FadeOut "+tFadeoutObj.style.position+":"+tTransPosition) ;
16427				tFadeoutObj.inEffect = true ;
16428				tFadeoutObj.bckPosition = tFadeoutObj.style.position ;
16429				tFadeoutObj.style.position = tTransPosition ;
16430// 				if (BanId == 0) {
16431// 					var tHeightOut = Element.getHeight(tFadeoutObj) ;
16432// 					tFadeoutObj.style.top = "-"+tHeightOut+"px" ;
16433// 				}
16434				// Position.absolutize($('BanVseb'+BanId+'_'+BannerCurTxt[BanId])) ;
16435				Effect.Fade('BanVseb'+BanId+'_'+BannerCurTxt[BanId],{duration:1, afterFinish:function(effect) { console.log("Finish fadeOut:"+effect.element.id+" : "+effect.element.bckPosition+":"+effect.element.style.position ); effect.element.style.top = '0px'; effect.element.style.position = effect.element.bckPosition; }}) ;
16436				// Ugasnemo ikono, če obstaja
16437				if($D("Ban"+BanId+"Im"+BannerCurTxt[BanId])) {
16438					var tmpButon = $("Ban"+BanId+"Im"+BannerCurTxt[BanId]) ;
16439					if (tmpButon.hasAttribute("offImage")) {
16440						tmpButon.src = tmpButon.getAttribute("offImage") ;
16441					}
16442				}
16443				tFadeoutObj.inEffect = false ;
16444
16445				console.log('FadeIn '+BanId+':'+TxtId) ;
16446				var tFadeInObj = $('BanVseb'+BanId+'_'+TxtId) ;
16447				tTransPosition = "" ;
16448				// Ali imamo na objektu nastavljeno, kateri "position" se uporablja med tranzicijo ( za kompatibilnost s starimi objekti za banner izmenjevalce
16449// 				if (tFadeInObj.hasAttribute("dwm_bannerTransPosition"))
16450// 					tTransPosition = tFadeInObj.getAttribute("dwm_bannerTransPosition") ;
16451				console.log("FadeIn "+tFadeInObj.style.position+":"+tTransPosition) ;
16452				tFadeInObj.inEffect = true ;
16453				tFadeInObj.bckPosition = tFadeInObj.style.position ;
16454				tFadeInObj.style.position = tTransPosition ;
16455// 				if (TxtId != 0) {
16456// 					var tHeightIn = Element.getHeight(tFadeInObj) ;
16457// 					tFadeInObj.style.top = "-"+tHeightIn+"px" ;
16458// 				}
16459				// Position.absolutize($('BanVseb'+BanId+'_'+TxtId)) ;
16460				Effect.Appear('BanVseb'+BanId+'_'+TxtId,{duration:1.0, from:0.0, to:1.0, afterFinish:function(effect) { console.log("Finish fadein:"+effect.element.id+" : "+effect.element.bckPosition+":"+effect.element.style.position ); effect.element.style.top = '0px'; effect.element.style.position = effect.element.bckPosition; }}) ;
16461				// Prižgemo ikono, če obstaja
16462				if($D("Ban"+BanId+"Im"+TxtId)) {
16463					var tmpButon = $("Ban"+BanId+"Im"+TxtId) ;
16464					if (tmpButon.hasAttribute("onImage")) {
16465						tmpButon.src = tmpButon.getAttribute("onImage") ;
16466					}
16467				}
16468				BannerCurTxt[BanId] = TxtId ;
16469				tFadeInObj.inEffect = false ;
16470			} else {
16471				StartStopBanner(BanId) ;
16472			}
16473		}
16474	}
16475}
16476
16477function StartStopBanner(BanId) {
16478	if (BannerRun[BanId]) {
16479		BannerRun[BanId] = false ;
16480		$('BanStop'+BanId).style.display = "" ;
16481		$('BanRun'+BanId).style.display = "none" ;
16482	} else {
16483		BannerRun[BanId] = true ;
16484		$('BanStop'+BanId).style.display = "none" ;
16485		$('BanRun'+BanId).style.display = "" ;
16486	}
16487}
16488
16489
16490function GetViewPort() {
16491	// the more standards compliant browsers (mozilla/netscape/opera/IE7) use window.innerWidth and window.innerHeight
16492	if (typeof window.innerWidth != 'undefined') {
16493		viewportwidth = window.innerWidth,
16494		viewportheight = window.innerHeight
16495	} else if (typeof document.documentElement != 'undefined'
16496		&& typeof document.documentElement.clientWidth !=
16497		'undefined' && document.documentElement.clientWidth != 0)
16498	{
16499		// IE6 in standards compliant mode (i.e. with a valid doctype as the first line in the document)
16500		viewportwidth = document.documentElement.clientWidth,
16501		viewportheight = document.documentElement.clientHeight
16502	} else {
16503		// older versions of IE
16504		viewportwidth = document.getElementsByTagName('body')[0].clientWidth,
16505		viewportheight = document.getElementsByTagName('body')[0].clientHeight
16506	}
16507}
16508
16509function fireEvent(element,event){
16510	if (Prototype.Browser.IE && document.documentMode < 9){
16511		// dispatch for IE
16512		var evt = document.createEventObject();
16513		return element.fireEvent('on'+event,evt)
16514	} else {
16515		// dispatch for firefox + others
16516		var evt = document.createEvent("HTMLEvents");
16517		evt.initEvent(event, true, true ); // event type,bubbling,cancelable
16518		return !element.dispatchEvent(evt);
16519	}
16520}
16521
16522function dwm_statusiApp() {
16523	dwm_sessionRequest(true) ;
16524	dwm_updateRequest() ;
16525	dwm_externalSessionStatus() ;
16526}
16527
16528var kontaktSessionCache = {
16529	StSporocil: 0,
16530	StNeprSporocil: 0,
16531	StOpomnik: 0,
16532	StJobov: 0,
16533	StKlicev: 0,
16534	StSms: 0
16535};
16536
16537var windowPopUpOpen = false;
16538
16539function dwm_popupPozeniMakro(MakroId) {
16540	if (typeof(MakroId) != 'undefined') {
16541		var url = '/AJAX.php?C=dwmMacros_PopupPozeniMakro&Id='+encodeURIComponent(Number(MakroId)) ;
16542		lightWindowStack.openWindow({
16543			href: url,
16544			title: '',
16545			author: '',
16546			caption: '',
16547			iframeEmbed: false,
16548			loadingAnimation: {},
16549			width: (document.viewport.getDimensions().width * 0.95),
16550			height: (document.viewport.getDimensions().height * 0.8)
16551		}) ;
16552	}
16553}
16554
16555function dwm_externalSessionStatus() {
16556	var url = "AJAX.php?C=ExternalSessionStatus";
16557	new Ajax.Request(url, {
16558		method: 'post',
16559		onSuccess: function(transport) {
16560			var Res = transport.responseJSON ;
16561			var LastDed ;
16562
16563			if (Res.error) {
16564				alert(Res.error) ;
16565			} else {
16566				
16567				setTimeout("dwm_externalSessionStatus()",600000); // Na vsake 10 minut, da ne bo prepogosto
16568				
16569				if(Res.Login) {
16570					var Glink = Res.Link ;
16571					if(!$D('GLogin')) {
16572						var content = '<div id="GLogin" class="GLogin"><a href="javascript:dwm_OpenGoogleLogin(\''+Glink+'\')"><img src="https://c.inmaster.si/DeskWM/DwmJR/login_google.png" alt="Google login" /></a></div>';
16573						$('InfoG').insert(content) ;
16574					}
16575					if ($D('GLoginRemove'))
16576						$('GLoginRemove').hide() ;
16577				} else {
16578					if ($D('GLogin')) 
16579						$('GLogin').remove() ;
16580					if ($D('GLoginRemove'))
16581						$('GLoginRemove').show() ;
16582				}
16583				DebugJS('Session','dwm_externalSessionStatus-Ajax return') ;
16584			}
16585		},
16586		onFailure: function(transport) {
16587			DebugJS('Session','dwm_externalSessionStatus-Ajax return failed !') ;
16588			setTimeout("dwm_externalSessionStatus()",10000) ;
16589		}
16590	});
16591}
16592
16593function dwm_OpenGoogleLogin(Glink) {
16594	var popup = window.open(Glink, '_blank', 'height=600,width=800');
16595}
16596
16597var updateReqTime;
16598function dwm_updateRequest() {
16599	clearTimeout(updateReqTime);
16600	// Ali imamo polje, ki definira UpdateStatusRequest ?
16601	if ($D("updStatusRequestTime")) {
16602		var epoch = Date.now() ;
16603		if (Math.floor(epoch/1000) > Number($D("updStatusRequestTime").value)) {
16604			var url = "AJAX.php?C=UpdateStatusRequest";
16605			new Ajax.Request(url, {
16606				method: 'post',
16607				onSuccess: function(transport) {
16608					var Res = transport.responseJSON ;
16609					var LastDed ;
16610
16611					if (Res.error) {
16612						console.log(Res.error) ;
16613					} else {
16614						var content = '' ;
16615						updateReqTime = setTimeout("dwm_updateRequest()",3600000); // Na vsake 1 uro, da ne bo prepogosto
16616
16617						if (Res.UpdateApp) {
16618							if (!$D('UpdateApp')) {
16619								content += '<div id="UpdateApp" class="ico_update_app"><div class="UpdateApp"></div><a href="javascript:UpdateAppPopUp()"  class="ico_refresh_form ico_v2" alt="Update app"></a></div>';
16620								$('dwmJrStatusiApp').insert(content);
16621							}
16622						} else {
16623							if ($D('UpdateApp'))
16624								$('UpdateApp').remove();
16625						}
16626						DebugJS('Session','dwm_updateRequest-Ajax return') ;
16627					}
16628				},
16629				onFailure: function(transport) {
16630					DebugJS('Session','dwm_updateRequest-Ajax return failed !') ;
16631					updateReqTime = setTimeout("dwm_updateRequest()",10000) ;
16632				}
16633			});
16634		}
16635	}
16636}
16637
16638var gcTimeOut = 60 ;
16639
16640function dwm_localStorageGarbageCollector() {
16641	console.log("dwm_localStorageGarbageCollector") ;
16642
16643	localStorage.setItem("lastGarbageCollectorRun",Number(Date.now())/1000) ;
16644	var tTimeDayAgo = (Number(Date.now())/1000) - gcTimeOut  ;
16645
16646	for(let key in localStorage) {
16647		if (!localStorage.hasOwnProperty(key)) {
16648			continue; // skip keys like "setItem", "getItem" etc
16649		}
16650
16651		if ((String(key).substr(0,3) == "DL:") && localStorage.getItem(key) < tTimeDayAgo) {
16652			console.log("Removing: "+key) ;
16653			localStorage.removeItem(key) ;
16654		}
16655	}
16656}
16657
16658function dwm_sessionRequest() {
16659	var doRunSessionRequest = true ;
16660	var weHaveLocalStorage = false ;
16661	// Preverimo, ali imamo omogočen localStorage - če ni, teže LRQ na vseh oknih
16662	// Če je to prvi request po kliku, ga poženemo - ne glede na ostale query-e
16663	if (dwm_storageAvailable('localStorage')) {
16664		weHaveLocalStorage = true ;
16665	}
16666	if (!(arguments[0]) && weHaveLocalStorage) {
16667	    // Imamo session storage - preverimo, ali slučajno že poteka request
16668		var tmpTS = Math.floor(Date.now() / 1000) ;
16669		var whenToRun = localStorage.getItem("whenToResession") ;
16670		if (whenToRun && (whenToRun > tmpTS)) {
16671			// Imamo drugi session, ki že teče in še ni timeoutal -> ne poganjamo resessiona v tretnunem oknu
16672			doRunSessionRequest = false ;
16673		}
16674
16675		// Pogledamo, ali imamo ključ za zadnji zagon drisanja prevzetih dokumentov in kdaj   je bil izveden in ali je potrebno izvesti brisanje prevzetih dokumentov
16676		var zadnjiZagonBrisanja = localStorage.getItem("lastGarbageCollectorRun") ;
16677		// console.log("zadnjiZagonBrisanja: "+zadnjiZagonBrisanja+" tTime: "+((Number(Date.now())/1000) - gcTimeOut)+" windowPopUpOpen:"+windowPopUpOpen) ;
16678		if (!zadnjiZagonBrisanja || (zadnjiZagonBrisanja < ((Number(Date.now())/1000) - gcTimeOut))) {
16679			dwm_localStorageGarbageCollector() ;
16680		}
16681	}
16682
16683	if (doRunSessionRequest) {
16684		if (weHaveLocalStorage) {
16685			localStorage.setItem("whenToResession",tmpTS+50) ; // Long running query ima čas 45sekund, timeout tule nastavimo na 50 sekund
16686		}
16687		var url = 'AJAX.php?C=SessionStatusRequest' ;
16688		if (arguments[0]) {
16689			url += '&First=1' ;
16690			if (weHaveLocalStorage) {
16691				// Nastavimo intervalno klicanje resessiona
16692				setInterval(dwm_sessionRequest,6500) ;
16693				setTimeout(dwm_sessionRequest,100) ; // Da takoj poženemo prvi LRQ
16694			}
16695		}
16696
16697		if ($D('PageID'))
16698			url += '&PageID='+encodeURIComponent($('PageID').value) ;
16699
16700		new Ajax.Request(url, {
16701			method: 'post',
16702			onSuccess: function(transport) {
16703				// Pridobili smo podatke nazaj - zapišemo jih v localStorage in v sessionStorage, da jih bomo lahko primerjali
16704				var Res = transport.responseJSON ;
16705				localStorage.setItem("sessionJSON",JSON.stringify(Res)) ;
16706				sessionStorage.setItem("sessionJSON",JSON.stringify(Res)) ;
16707				dwm_sessionRequestStatusExec(Res,weHaveLocalStorage) ;
16708			},
16709			onFailure: function(transport) {
16710				DebugJS('Session','dwm_sessionRequest-Ajax return failed !') ;
16711				if (!weHaveLocalStorage)
16712					setTimeout("dwm_sessionRequest()",100) ;
16713			}
16714		});
16715	} else {
16716		// Samo preverimo, ali je localStorage JSON drugačen od sessionStorage JSON-a in če je, potem poženemo update statusov v oknu
16717		var ResP = localStorage.getItem("sessionJSON") ;
16718		if (ResP != null) {
16719			var Res = JSON.parse(ResP) ;
16720			var sessionResP = sessionStorage.getItem("sessionJSON") ;
16721			if (sessionResP != null) {
16722				var sessionRes = JSON.parse(sessionResP) ;
16723				if (Res.ts != sessionRes.ts) {
16724					// Imamo razliko - shranimo novi sessionStorage.JSON in poženemo funkcijo za prikaze sprememb
16725					sessionStorage.setItem("sessionJSON",JSON.stringify(Res)) ;
16726					dwm_sessionRequestStatusExec(Res,weHaveLocalStorage) ;
16727				}
16728			}
16729		}
16730	}
16731}
16732
16733function dwm_sessionRequestStatusExec(Res,weHaveLocalStorage) {
16734	console.log("Start dwm_sessionRequestStatusExec") ;
16735	var LastDed ;
16736	var whileNum = 0 ;
16737
16738	if (Res.whileNum)
16739		whileNum = Res.whileNum ;
16740
16741	if (Res.error) {
16742		alert(Res.error) ;
16743		if (Res.redirect) {
16744			window.location = Res.redirect ;
16745		}
16746	} else if (Res.ok) {
16747		if (Res.redirect) {
16748			window.location = Res.redirect ;
16749		}
16750	} else {
16751		// Ali smo na koledarju ?
16752		if ($D("prikazniOkvirKoledarja")) {
16753			// alert(Number($("prikazniOkvirKoledarja").getAttribute("timeLoaded"))+" : "+Number(Res.Koledar)) ;
16754			if (Number($("prikazniOkvirKoledarja").getAttribute("timeLoaded")) < Number(Res.Koledar)) {
16755				// Potreben je reload koledarja
16756				if (typeof(plan_LoadOpravila)=="function")
16757					plan_LoadOpravila() ;
16758				if (typeof(loadRazporejenaOpravila)=="function") {
16759					loadRazporejenaOpravila() ;
16760					if(typeof(LoadPlanerOpravilSpisek)=="function")
16761						LoadPlanerOpravilSpisek();
16762				}
16763			}
16764		}
16765
16766		var content = "";
16767		var statNeedsUpdate = false ;
16768		var image;
16769
16770		// Preverimo ali imamo vklopljeno snemanje makrojev v aplikaciji
16771		if (Res.MacroRecording) {
16772			content += '<div id="MacroRecordingApp" class="ico_macrorecord_app"><div class="MacroRecordApp"></div><a href="javascript:dwmjr_macroRecord_Stop({\'goToMacro\':\'1\'})" class="ico_status_zamujen ico_v4"></a></div>' ;
16773			statNeedsUpdate = true;
16774		} else {
16775			if ($D('MacroRecordingApp'))
16776				$('MacroRecordingApp').remove() ;
16777		}
16778
16779		// Preverimo ali imamo kakšno novo sporočilo v aplikaciji
16780		if ((Number(kontaktSessionCache.StSporocil) != Number(Res.StSporocil)) || (Number(kontaktSessionCache.StNeprSporocil) != Number(Res.StNeprSporocil))) {
16781			kontaktSessionCache.StSporocil = Number(Res.StSporocil) ;
16782			kontaktSessionCache.StNeprSporocil = Number(Res.StNeprSporocil) ;
16783			statNeedsUpdate = true ;
16784		}
16785		if((Res.StSporocil > 0) || (Res.StNeprSporocil > 0)) {
16786			image = '<span class="ico_mail ico_v2" alt="Messages"></span>';
16787			content = '<div class="ico_status_mail_con"><div class="ico_status_mail"></div><a href="javascript:dwmjr_AppSporocila(1)" title="'+Res.Sporocilo+'">'+image ;
16788			if (Number(Res.StSporocil) > 0)
16789				content += '<span class="topNumber">'+Res.StSporocil+'</span>' ;
16790			if (Number(Res.StNeprSporocil) > 0)
16791				content += '<span class="bottomNumber">'+Res.StNeprSporocil+'</span>' ;
16792			content += '</a></div>';
16793		}
16794
16795		// Preverimo ali trenutno traja kakšen klic v aplikaciji
16796		if(Number(kontaktSessionCache.StKlicev) != Number(Res.StKlicevVApp)) {
16797			kontaktSessionCache.StKlicev = Number(Res.StKlicevVApp) ;
16798			statNeedsUpdate = true ;
16799		}
16800
16801		if(Res.StKlicevVApp > 0) {
16802			image = '<span class="ico_stat_telefon ico_v2" alt="Calls"></span>';
16803			content += '<div class="ico_status_klici_con"><div class="ico_status_klici"></div><a href="javascript:dwmjr_AppTelKlici()" title="'+Res.SporociloKlic+'">'+image ;
16804			if (Number(Res.StKlicevVApp) > 0)
16805				content += '<span class="topNumber">'+Res.StKlicevVApp+'</span>' ;
16806			content += '</a></div>';
16807
16808			if (Res.AsteriskPrikaziPopup) { dwmjr_AppTelKlici(); }
16809
16810		}
16811
16812		// Preverimo ali imamo kakšen nov opomnik v aplikaciji
16813		if(Number(kontaktSessionCache.StOpomnik) != Number(Res.StOpomnik)) {
16814			kontaktSessionCache.StOpomnik = Number(Res.StOpomnik) ;
16815			statNeedsUpdate = true ;
16816		}
16817		if(Res.StOpomnik > 0) {
16818			image = '<span class="ico_opomnik_add ico_v2" alt="Reminders"></span>';
16819			content += '<div class="ico_status_opomnik_con"><div class="ico_status_opomnik"></div><a href="javascript:dwmjr_opomnikKoledar(\'1\')" title="'+Res.Opomnik+'">'+image+'<span class="topNumber">'+Res.StOpomnik+'</span></a></div>';
16820		}
16821
16822		// Preverimo ali imamo kakšen nov job v aplikaciji
16823		if(Number(kontaktSessionCache.StJobov) != Number(Res.StJobov)) {
16824			kontaktSessionCache.StJobov = Number(Res.StJobov) ;
16825			statNeedsUpdate = true ;
16826		}
16827		if(Number(Res.StJobov) > 0 || Number(Res.StJobovVDelu) > 0) {
16828			image = '<span class="ico_stat_job_done ico_v2" alt="Jobs"></span>';
16829			content += '<div class="ico_status_job_con"><div class="ico_status_job"></div><a href="javascript:dwmjr_AppSpisekJob()" title="'+Res.JobText+'">'+image ;
16830			if (Number(Res.StJobov) > 0)
16831				content += '<span class="topNumber">'+Res.StJobov+'</span>' ;
16832			if (Number(Res.StJobovVDelu) > 0)
16833				content += '<span class="bottomNumber">'+Res.StJobovVDelu+'</span>' ;
16834			content += '</a></div>';
16835
16836			// Sedaj pa pogledamo ali je potrebno izvesti kakršn koli task
16837			console.log("Test st. jobov: "+Res.JobPrenesi) ;
16838			if (typeof(Res.JobPrenesi) != "undefined") {
16839				if (Res.JobPrenesi.length > 0) {
16840					Res.JobPrenesi.each(function(prenos) {
16841						console.log("Job prenosi: "+prenos) ;
16842						// Imamo kakšen dokument za DL ?
16843						if ($("DownloadData") != null) {
16844							// Ali je bil dokument že dan v DL ?
16845							console.log("weHaveLocalStorage: "+weHaveLocalStorage) ;
16846							alreadyDL = localStorage.getItem("DL:"+prenos) ;
16847							console.log(alreadyDL) ;
16848							if (weHaveLocalStorage && alreadyDL) {
16849								// Nothing to do
16850								console.log("File "+prenos+" already served!") ;
16851							} else {
16852								if (weHaveLocalStorage) {
16853									// Označimo, da smo datoteko že servirali
16854									console.log("Serving file "+prenos+"!") ;
16855									localStorage.setItem("DL:"+prenos,Number(Date.now())/1000) ;
16856								}
16857								var url = prenos;
16858								var iframeForm = document.getElementById('DownloadData').contentWindow.document.getElementById("SendDownloadRequest");
16859								iframeForm.setAttribute("action",url);
16860								iframeForm.submit();
16861							}
16862						}
16863					});
16864				}
16865			}
16866
16867			if(typeof(Res.JobJS) != "undefined") {
16868				if(Res.JobJS.length > 0) {
16869					Res.JobJS.each(function(callFunc) {
16870						// Tukaj napišemo custom javascripte, ki se lahko izvajajo
16871						switch(Number(callFunc)) {
16872							default: "";
16873						}
16874					});
16875				}
16876			}
16877
16878			if(typeof(Res.JobMsg) != "undefined") {
16879				if(Res.JobMsg.length > 0) {
16880					var MsgContent = "";
16881					Res.JobMsg.each(function(JobMsg) {
16882						MsgContent += JobMsg;
16883					});
16884					alert(MsgContent);
16885				}
16886			}
16887			//image = '<span class="ico_stat_job_done ico_v2" alt="Jobs"></span>';
16888			//content += '<div class="ico_status_job_con"><div class="ico_status_job"></div><a href="javascript:dwmjr_AppSpisekJob()" title="'+Res.JobText+'">'+image+'<span class="topNumber">'+Res.StJobov+'</span></a></div>';
16889		}
16890
16891		if(Res.NumSms) {
16892			if(Number(kontaktSessionCache.StSms) != Number(Res.NumSms)) {
16893				content += '<div class="ico_status_sms_con" title="'+Res.SmsStatus+'">' +
16894								'<div class="ico_status_sms"></div>' +
16895								'<span class="lowSms">' +
16896									'<span class="ico_stat_sms ico_v2" alt="SMSStatus"></span>' +
16897									'<span class="topNumber">'+Res.NumSms+'</span>' +
16898								'</span>' +
16899							'</div>';
16900				statNeedsUpdate = true;
16901			}
16902		} else {
16903			if(Number(kontaktSessionCache.StSms) >= 0 && kontaktSessionCache.StSms != false) {
16904				statNeedsUpdate = true;
16905				kontaktSessionCache.StSms = false;
16906			}
16907		}
16908
16909		if(Number(Res.StOpomnikovPopUp) > 0) {
16910			// Odpremo popup z opomniki
16911			var url = "/AJAX.php?C=alertOpomnikPopUp";
16912			kontaktSessionCache.isOpenAlert = lightWindowStack.openWindow({
16913				href: url,
16914				title: Res.OpomNaslovPopUp,
16915				author: '',
16916				caption: Res.OpomNaslovPopUp,
16917				iframeEmbed: false,
16918				loadingAnimation: {},
16919				width: 700,
16920				height: 400,
16921				onClose: function() {
16922					//B windowPopUpOpen = false;
16923				}
16924			});
16925			//B windowPopUpOpen = true;
16926		}
16927
16928		// Preverimo, če imamo kakšno PopUp sporočilo in če je, jih prikažemo
16929		// NOTE - Tole bi bilo fino, če bi bila posebna funkcija, ki bi vsako PopUp sporočilo kazala v svojem okviru
16930		//      - Trenutno samo odpremo sporočila
16931
16932		// Preprečimo, da bi se ob kliku na sporočilo okno znova naložilo sporočilo označilo kot prebrano
16933		// Vrednost pridobimo vsakokrat iz SessionStatusRequest
16934		if(Res.prikazStPopUpUpSporocil == false) {
16935			//B windowPopUpOpen = false ;
16936		}
16937		//alert(windowPopUpOpen) ;
16938		if(Res.StPopUpSporocil && windowPopUpOpen == false) {
16939			//B windowPopUpOpen = true ;
16940			dwmjr_AppSporocila() ;
16941		}
16942
16943		if(statNeedsUpdate) {
16944			// V primeru, da imamo postavljeno ikono za update jo bomo morali po osvežitvi ikon še enkrat postaviti
16945			var osveziUpdateIco = false;
16946			if($D("UpdateApp"))
16947				osveziUpdateIco = true;
16948			// Naredimo update vseh icon
16949			$("dwmJrStatusiApp").update(content);
16950			// Osvežiti je potrebno še update status ikono
16951			if(osveziUpdateIco) { dwm_updateRequest(); }
16952		}
16953
16954		if(Number(Res.CheckOut) == 1) { window.location = "Odjava.php"; }
16955		// Ponovno naložimo povezane lastnosti - Trenutno naredimo request 1x na 3 sekunde
16956		console.log('dwm_sessionRequest('+whileNum+')-Ajax return') ;
16957	}
16958	if (!weHaveLocalStorage)
16959		setTimeout("dwm_sessionRequest()",100) ;
16960}
16961
16962//Potrebujemo ID kontakta, da preverimo nastavitve potrjevanja brisanja, obdelati in vrniti je potrebno tudi argumente,
16963//v nasprotnem primeru se brisanje izvede šele ob drugem kliku, če vrednost nastavitve ni v spremenljivki
16964function initKontaktStatusRequest(argumenti) {
16965	var url = "AJAX.php?C=FilterUserKontaktID" ;
16966	new Ajax.Request(url, {
16967		method: 'post',
16968		onSuccess: function(transport) {
16969			var Res = transport.responseJSON ;
16970			if (Res.error) {
16971				console.log(Res.error) ;
16972			} else {
16973				window.kontaktID = Res.kontaktID ;
16974				kontaktID = window.kontaktID ;
16975				window.vrednostKon = Res.vrednostKon ;
16976				vrednostKon = window.vrednostKon ;
16977				window.alertText = Res.alertText ;
16978				alertText = window.alertText ;
16979				//poskrbimo za argumente
16980				var args = "" ;
16981				for( var i = 0; i < argumenti.length; i++ ) {
16982					args += "'"+argumenti[i]+"'" ;
16983					if (i != (argumenti.length-1)) {
16984						args += "," ;
16985					}
16986				} ;
16987				setTimeout("pocistiPolja("+args+")",50) ;
16988			}
16989		},
16990
16991		onFailure: function(transport) {
16992			DebugJS('Session','dwm_-Ajax return failed !') ;
16993			setTimeout("initKontaktStatusRequest()",1000) ;
16994		}
16995	});
16996}
16997
16998function pocistiPolja() {
16999	//RevealElement(arguments) ;
17000	var canDelete = false ;
17001	if ((!window.kontaktID) && (typeof(window.kontaktID) != 'number')) {
17002		initKontaktStatusRequest(arguments) ;
17003	} else {
17004		kontaktID = window.kontaktID ;
17005		vrednostKon = window.vrednostKon ;
17006		alertText = window.alertText ;
17007
17008		//Dodatek za potrjevanje brisanja osnovnih podatkov
17009		if(vrednostKon == 1) {
17010			if(confirm(alertText))
17011				canDelete = true ;
17012		} else {
17013			canDelete = true ;
17014		}
17015
17016		if(canDelete) {
17017			for( var i = 0; i < arguments.length; i++ ) {
17018				if ($D(arguments[i]))
17019					$(arguments[i]).value = "" ;
17020
17021				// HACK Dodamo še onchange funkcijo v primeru, če praznimo polje
17022				if($(arguments[i]).hasAttribute("dwmOnChangeFunc")) {
17023					var changeFunction = $(arguments[i]).getAttribute("dwmOnChangeFunc");
17024					if(changeFunction != "")
17025						window[changeFunction]();
17026				}
17027			}
17028		}
17029		if (typeof(PodatekSpremenjen) == "function")
17030			PodatekSpremenjen() ;
17031	}
17032}
17033
17034function TrenutniCas(DatumPolje,CasPolje,autoSave,minusMinutes) {
17035	var d = new Date() ;
17036	var msDate = d.getTime() ;
17037
17038	if(typeof(minusMinutes) == "undefined")
17039		minusMinutes = 0;
17040
17041	if (minusMinutes != 0) {
17042		d = new Date(msDate - (minusMinutes * 60000)) ;
17043	}
17044
17045	Datum = d.getDate()+"."+(d.getMonth()+1)+"."+d.getFullYear() ;
17046	Cas = "" ;
17047
17048	(d.getHours() < 10) ? Cas += "0"+d.getHours() : Cas += d.getHours() ;
17049	Cas += ":" ;
17050	(d.getMinutes() < 10) ? Cas += "0"+d.getMinutes() : Cas += d.getMinutes() ;
17051	Cas += ":" ;
17052	(d.getSeconds() < 10) ? Cas += "0"+d.getSeconds() : Cas += d.get
17052Seconds() ;
17053
17054	if ($(DatumPolje)) {
17055		$(DatumPolje).value = Datum ;
17056	}
17057	if ($(CasPolje)) {
17058		$(CasPolje).value = Cas ;
17059	}
17060	if (autoSave && (typeof(autoSave) != "undefined")) {
17061		Shrani();
17062	} else {
17063		PodatekSpremenjen() ;
17064	}
17065}
17066
17067dwm_sessionObj = new Object() ;
17068
17069//Funkciji za slide
17070
17071function OpenDwmSlide(ThisTag,Tag,Speed){
17072	var Element = "";
17073	Element = ThisTag.down(Tag);
17074	
17075	if(typeof(Speed) == "undefined")
17076		Speed = 0.5;
17077	if(typeof(Element) == "undefined")
17078		Element = ThisTag.next(Tag);
17079
17080	new Effect.toggle(Element,'blind',{duration:Speed});
17081}
17082
17083function CloseDwmSlide(ThisNextTag,NextTag,Speed){
17084	var NextElement = "";
17085	NextElement = ThisNextTag.previous(NextTag);
17086
17087	if(typeof(Speed) == "undefined")
17088		Speed = 0.5;
17089	if(typeof(NextElement) == "undefined")
17090		NextElement = ThisNextTag.up(NextTag);
17091
17092	new Effect.toggle(NextElement,'blind',{duration:Speed});
17093}
17094
17095/* Go to cart */
17096function GoToCart(Artikel,pgId) {
17097	var Cart = new Object() ;
17098	var url = "AJAX.php?C=DodajVKosarico" ;
17099
17100	// Artikel
17101	if (($D("ArtikelSID"+Artikel)) && (Artikel != false)) {
17102		Cart.Artikel = $("ArtikelSID"+Artikel).value ;
17103		if ($D("PageToGo"+Artikel)) {
17104			if (Number($("PageToGo"+Artikel).value) != -1) {
17105				url += "&Pgd="+encodeURIComponent($("PageToGo"+Artikel).value) ;
17106			}
17107		}
17108	} else if ($D("ArtikelSID")) {
17109		Cart.Artikel = $("ArtikelSID").value ;
17110	} else {
17111		Cart.Artikel = Number(Artikel) ;
17112	}
17113
17114	// Morebitna opomba pri artiklu?
17115	if ($D("Opomba"+Cart.Artikel)) {
17116		Cart.Opomba = $("Opomba"+Cart.Artikel).value ;
17117	}
17118
17119	// Količina
17120	if ($D("Kolicina"+Artikel)) {
17121		Cart.Kolicina = $("Kolicina"+Artikel).value ;
17122	} else if ($D("Kolicina")) {
17123		Cart.Kolicina = $("Kolicina").value ;
17124	} else {
17125		Cart.Kolicina = 1 ;
17126	}
17127	Cart.Kolicina = String(Cart.Kolicina).LocaleToNum() ;
17128
17129	// EnotaMere - HACK - Za spiske
17130	if ($D("ArtikelEnota"+Artikel)) {
17131		Cart.Enota = $("ArtikelEnota"+Artikel).value ;
17132	} else if ($D("ArtikelEnota1_"+Artikel)) {
17133		Cart.Enota = $("ArtikelEnota1_"+Artikel).value ;
17134	} else if ($D("ArtikelEnota2_"+Artikel)) {
17135		Cart.Enota = $("ArtikelEnota2_"+Artikel).value ;
17136	} else if ($D("ArtikelEnota3_"+Artikel)) {
17137		Cart.Enota = $("ArtikelEnota3_"+Artikel).value ;
17138	} else if ($D("ArtikelEnota")) {
17139		Cart.Enota = $("ArtikelEnota").value ;
17140	} else {
17141		Cart.Enota = -1 ;
17142	}
17143
17144	if (typeof(pgId) != "undefined")
17145		url += "&PageID="+encodeURIComponent(pgId);
17146	
17147	// Preverimo še vse morebitne obkljukane povezane storitve
17148	var zapStPovStor = 0 ;
17149	$(document.body).select('input.addStorExtra').each( function(e) {
17150		if (e.checked) {
17151			url += "&iVs["+zapStPovStor+"]="+e.value ;
17152			zapStPovStor++ ;
17153		}
17154	} );
17155
17156	new Ajax.Request(url, {
17157		method: 'post',
17158		parameters: 'json='+encodeURIComponent(Object.toJSON(Cart)),
17159		onSuccess: function(transport) {
17160			var Res = transport.responseJSON ;
17161			if (Res.error) {
17162				alert(Res.error) ;
17163			} else {
17164				if ($D("ArtikelSID"+Artikel) && ($("ArtikelSID"+Artikel).hasAttribute("after_cart"))) {
17165					eval($("ArtikelSID"+Artikel).getAttribute("after_cart")) ;
17166				}
17167				if (Res.notice)
17168					alert(Res.notice) ;
17169
17170				var checker = -1;
17171				if ($D("PageToGo"+Artikel))
17172					checker = Number($("PageToGo"+Artikel).value);
17173				
17174				if (checker == -1 || Number(Res.PopUpKosarica) == 1) {
17175					$("CartContent").update("");
17176					$("NumProduct").update(Res.StProduktov);
17177					$("CartContent").LoadKosarica(true);
17178
17179					if (typeof(afterCartChange) == "function") {
17180						afterCartChange(Res) ;
17181					}
17182				} else {
17183					window.location = Res.CartRelocate;
17184				}
17185			}
17186
17187		}
17188	});
17189}
17190
17191function WWWPovprasevanje(Artikel){
17192
17193	// Odpremo okno za urejanje
17194	var PopUpWindow = new Control.Window($("WWWPovprasevanje"),{
17195		afterOpen: function() {
17196			$("ClosePovprasevanje").observe('click',this.closeHandler);
17197		},
17198		closeOnClick: $("ClosePovprasevanje"),
17199		afterClose: function() {
17200			var element = $(this.container.id);
17201			var elIframe = $(this.container.id).next('iframe');
17202
17203			element.remove();
17204			elIframe.remove();
17205			$("PovprasevanjeCon").style.display = "none";
17206		},
17207		//draggable: "WWWPovprasevanje",
17208		position: 'center',
17209		className: 'simple_window1',
17210		method: 'get',
17211		parameters: {"Art": Artikel},
17212		offsetLeft: 0,
17213		offsetTop: 0
17214	});
17215	$("PovprasevanjeCon").style.display = "";
17216	PopUpWindow.open() ;
17217}
17218
17219function WWWPosljiPovprasevanje(Artikel) {
17220	
17221	var SendMail = new Object();
17222	
17223	SendMail.ImeNaziv = $("WWWImePriimek").value;
17224	SendMail.Naslov = $("WWWNaslov").value;
17225	SendMail.Posta = $("WWWPosta").value;
17226	SendMail.KontaktnaOseb = $("WWWKontaktnaOseb").value;
17227	SendMail.Gsm = $("WWWGsm").value;
17228	SendMail.Email = $("WWWEmail").value;
17229	SendMail.Sporocilo = $("WWWSporocilo").value;
17230	SendMail.Sifra = $("ArtFormaSIF").value;
17231	SendMail.Podjetje = $("ArtIsPodjetje").value;
17232
17233	var url = "AJAX.php?C=PosljiPovprasevanje&Art="+encodeURIComponent(Artikel) ;
17234	new Ajax.Request(url, {
17235		method: 'post',
17236		parameters: 'json='+encodeURIComponent(Object.toJSON(SendMail)),
17237		onSuccess: function(transport) {
17238			var Res = transport.responseJSON ;
17239			if (Res.error) {
17240				alert(Res.error) ;
17241				$(Res.get_focus).focus();
17242			} else {
17243				alert(Res.msg);
17244			}
17245		}
17246	});
17247}
17248
17249function WWWCheckField(e){
17250	if (!e) var e = window.event ;
17251	if (e.target) targ = e.target;
17252	else if (e.srcElement) targ = e.srcElement;
17253	if (targ.nodeType == 3) // defeat Safari bug
17254		targ = targ.parentNode;
17255
17256	var element = $(targ.id).previous('span');
17257	
17258	if($(targ.id).value == "" || targ.id == "WWWEmail" && !EmailValid($(targ.id).value))
17259		element.setAttribute("class","WWWFormError");
17260	else
17261		element.setAttribute("class","");
17262}
17263
17264function globalPodatekSPremenjen() {
17265	PodatekSpremenjen() ;
17266}
17267
17268//Galerija iz Thumbnail
17269var ThumbSlider = function(options){
17270	
17271	var TSSettings = Object.extend({
17272		widththumb: 128,
17273		auto: true,
17274		time: 3000,
17275		duration: 1.0
17276	}, options || {});
17277	
17278	
17279	var StopAuto = false;
17280	var ShowElement = true;
17281	var PosOffset = $('UlNavCon').viewportOffset().left;
17282	
17283	var ElementId = $("SlideConteiner").down("li");
17284	var ShowImage = ElementId.id;
17285
17286	if(TSSettings.auto) {
17287		$(ShowImage).appear();
17288		if(!StopAuto) {
17289			var TimeOut = setTimeout(function() {
17290				AutoSlide(TSSettings.time);
17291			},TSSettings.time);
17292		}
17293		
17294	} else {
17295		$(ShowImage).appear();
17296	}
17297	
17298	function AutoSlide(Time){
17299		var NextShowImage = "";
17300		$(ShowImage).fade();
17301		
17302		if(typeof($(ShowImage).next()) == "undefined")
17303			NextShowImage = $("SlideConteiner").down("li").id;
17304		else
17305			NextShowImage = $(ShowImage).next().id;
17306
17307		NextShowImage = "b_"+NextShowImage.substr(2);
17308		ShowImage = NextShowImage;
17309		$(NextShowImage).appear();
17310		TimeOut = setTimeout(function() {
17311			AutoSlide(Time);
17312		},Time);
17313	}
17314	
17315	function ClearAuto(Clear){
17316		if(TSSettings.auto) {
17317			if(!StopAuto || Clear) {
17318				StopAuto = true;
17319				clearTimeout(TimeOut);
17320				$("AutoPlayGumb").setAttribute("class","AutoPlayGumb AutoPlayOff");
17321			} else {
17322				$("AutoPlayGumb").setAttribute("class","AutoPlayGumb AutoPlayOn");
17323				StopAuto = false;
17324				TimeOut = setTimeout(function() {
17325					AutoSlide(TSSettings.time);
17326				},TSSettings.time);
17327			}
17328		}
17329	}
17330
17331	$("AfterSlider").observe("click", function(event){
17332		ClearAuto(true);
17333		var NextShowImage = event.target.up("a").id;
17334		var OldImage = "s_"+ShowImage.substr(2)
17335		if(NextShowImage != OldImage) {
17336			$(ShowImage).fade();
17337			NextShowImage = "b_"+NextShowImage.substr(2);
17338			ShowImage = NextShowImage;
17339			$(NextShowImage).appear();
17340		}
17341		
17342		var ThumbWidth = $('s_'+NextShowImage.substr(2)).getWidth()/2;
17343		var ThumbCoord = ($('s_'+NextShowImage.substr(2)).viewportOffset().left - PosOffset)+ThumbWidth;
17344		var ContWidth = $("SliderNav").getWidth();
17345		var UlWidth = ($('UlNavCon').getWidth() - ContWidth) + (ThumbWidth-15); //Odstopanje puščic
17346		var UlPos = $('UlNavCon').viewportOffset().left - PosOffset;
17347		var CenterCon = ContWidth/2;
17348		//Izračunamo najprej če je pozicija pozitivna
17349		MoveThumb = UlPos - (ThumbCoord - CenterCon);
17350		//Pogledamo ali treba premikat še kaj v desno
17351		if(MoveThumb > 0)
17352			MoveThumb = 0;
17353		//Izračunamo koliko slik je še do konca sliderja
17354		if(MoveThumb < -UlWidth)
17355			MoveThumb = -(UlWidth);
17356		
17357		if(MoveThumb <= 0)
17358			new Effect.Move('UlNavCon', { x: MoveThumb, y: 0, mode: 'absolute', duration: TSSettings.duration });
17359	});
17360	
17361	$("RightSlideNav").observe("click", function(event){
17362		var Element = $('UlNavCon').viewportOffset().left - PosOffset;
17363		var WidthElement = $('UlNavCon').getWidth();
17364		var InnerElement = $('AfterSlider').getWidth();
17365		var TmpWidth = 0;
17366		var TmpMinus = 0;
17367		
17368		TmpWidth = InnerElement - WidthElement;
17369		TmpMinus = Element - TSSettings.widththumb;
17370		
17371		if(TmpMinus < TmpWidth) {
17372			TmpMinus = TmpWidth - Element;
17373			TmpMinus = Element + TmpMinus;
17374		}
17375		
17376		if(Element > TmpWidth)
17377			new Effect.Move('UlNavCon', { x: TmpMinus, y: 0, mode: 'absolute', duration: TSSettings.duration });
17378	});
17379	
17380	$("LeftSlideNav").observe("click", function(event){
17381		var Element = $('UlNavCon').viewportOffset().left - PosOffset;
17382		var WidthElement = $('UlNavCon').getWidth();
17383		var TmpMinus = 0;
17384		
17385		TmpMinus = Element + TSSettings.widththumb;
17386		if(TmpMinus > 0){
17387			TmpMinus = 0;
17388		}
17389		
17390		if(TmpMinus <= 0)
17391			new Effect.Move('UlNavCon', { x: TmpMinus, y: 0, mode: 'absolute', duration: TSSettings.duration });
17392	});
17393	
17394	if(TSSettings.auto) {
17395		$("AutoPlayGumb").observe("click", function(event){
17396			ClearAuto();
17397		});
17398	}
17399}
17400
17401// Galerija 52
17402var WinGallery = function(options) {
17403	
17404	// Najprej poiščemo prvi element in ga prikažemo
17405	var autoPlayTime;
17406	var animationFrame;
17407	var WGElement = Object.extend({
17408		id: 'MultiGallery',
17409		arrownav: true,
17410		dotnav: true,
17411		numnav: false,
17412		duration: 1.0,
17413		thumb: true,
17414		thumbWidth: 128,
17415		thumbHeight: 96,
17416		autoplay: false,
17417		autoTime: 7000,
17418		circle: true,
17419		showTitle:false,
17420		showDesc:false,
17421		overlayPosTB:'bottom',
17422		overlayPosLR:'left',
17423		overlayDimTB:0,
17424		overlayDimLR:0,
17425		overlayAnim:'slide',
17426		textDuration: 0.4
17427	}, options || {});
17428	
17429	$(WGElement.id).down(1).style.display = "";
17430	
17431	// Ali moramo generirati puščice za premik thumbnailov
17432	if(WGElement.thumb === true) {
17433		if($("MGSlider")) {
17434			$("MGSlider").insert({after:'<div id="IMThumbArrNav" class="IMThumbNav"><a id="IMPrevThumb" class="prevThumb"></a><a id="IMNextThumb" class="nextThumb"></a></div>'});
17435
17436			Element.absolutize($("IMThumbArrNav"));
17437			$("IMThumbArrNav").clonePosition($("MGSlider"),{setLeft:false,setTop:true,setWidth:false,setHeight:false});
17438			
17439			// Pridobimo dimenzije prvega thumbnaila
17440			var premikOkvirja = 0;
17441			var thumbDim = $("MGSliderStrip").down("ul").down(0).getDimensions();
17442			var numThumbs = $("MGSlider").readAttribute("name");
17443
17444			// Pridobimo vse padding in margine, če obstajajo - za li
17445			var leftLiPadding = $("MGSliderStrip").down("ul").down(0).getStyle("paddingLeft");
17446			var rightLiPadding = $("MGSliderStrip").down("ul").down(0).getStyle("paddingRight");
17447			var leftLiMargin = $("MGSliderStrip").down("ul").down(0).getStyle("marginLeft");
17448			var rightLiMargin = $("MGSliderStrip").down("ul").down(0).getStyle("marginRight");
17449
17450			if(typeof(leftLiPadding) != "string")
17451				leftLiPadding = '0px';
17452			if(typeof(rightLiPadding) != "string")
17453				rightLiPadding = '0px';
17454				
17455			var racPadding = Number(leftLiPadding.substr(0,leftLiPadding.length - 2)) + Number(rightLiPadding.substr(0,rightLiPadding.length - 2)) ;
17456		
17457			if(typeof(leftLiMargin) != "string")
17458				leftLiMargin = '0px';
17459			if(typeof(rightLiMargin) != "string")
17460				rightLiMargin = '0px';
17461				
17462			var racMargin = Number(leftLiMargin.substr(0,leftLiMargin.length - 2)) + Number(rightLiMargin.substr(0,rightLiMargin.length - 2)) ;
17463			
17464			var thumbWithPadMar = Number(WGElement.thumbWidth) + Number(racPadding) + Number(racMargin);
17465			var maxPosMove = (Number(numThumbs) * Number(thumbWithPadMar)) - Number($("MGSlider").getWidth());
17466			
17467			
17468			// Pripravimo overlay, če je potreben
17469			if(WGElement.showTitle || WGElement.showDesc) {
17470				$$('div.DiscPanel').each(function(e) {
17471					
17472					if(WGElement.showTitle)
17473						$(e).down('h2').setStyle({'display':'block'});
17474					if(WGElement.showDesc)
17475						$(e).down('span').setStyle({'display':'block'});
17476					
17477					// Naredimo preračun pozicije
17478					var imageDim = $(e).up('div').down('img').getDimensions();
17479					var overlayDim = $(e).getDimensions();
17480					var topPos = 0;
17481					var leftPos = 0;
17482					
17483					if(WGElement.overlayPosTB == "bottom") {
17484						// Preračun za bottom
17485						topPos = Number(imageDim.height) - (Number(overlayDim.height) + Number(WGElement.overlayDimTB));
17486					} else {
17487						topPos += Number(WGElement.overlayDimTB);
17488					}
17489					
17490					if(WGElement.overlayPosLR == "right") {
17491						leftPos = Number(imageDim.width) - (Number(overlayDim.width) + Number(WGElement.overlayDimLR));
17492					} else {
17493						leftPos += Number(WGElement.overlayDimLR);
17494					}
17495					
17496					if(WGElement.overlayAnim == "none") {
17497						$(e).setStyle({
17498							'display':'block',
17499							'top':topPos+'px',
17500							'left':leftPos+'px'
17501						});
17502					} else {
17503						// Naredimo observer
17504						$(e).up('div').observe("mouseenter", function(e){
17505							
17506							if(WGElement.overlayAnim == "fade") {
17507								$(this).down('div').setStyle({
17508									'top':topPos+'px',
17509									'left':leftPos+'px'
17510								});
17511								
17512								$(this).down('div').appear({ duration: WGElement.textDuration });
17513							} else if(WGElement.overlayAnim == "slide") {
17514								$(this).down('div').setStyle({
17515									'display':'block',
17516									'top':topPos+'px',
17517									'left':leftPos+'px',
17518									'height':'0px',
17519									'opacity':1
17520								});
17521
17522								var effectTransition = -overlayDim.height;
17523								
17524								if(WGElement.overlayPosTB == "top")
17525									effectTransition = overlayDim.height;
17526								
17527								animationFrame = new Effect.Move($(this).down('div'), {
17528													x: 0, 
17529													y: effectTransition, 
17530													mode: 'relative',
17531													transition: Effect.Transitions.spring,
17532													duration:WGElement.textDuration
17533												});
17534							}
17535						});
17536						
17537						var elem = $(e).up('div');
17538						
17539						$(e).up('div').observe("mouseleave",function(e,t) {
17540							if(WGElement.overlayAnim == "fade") {
17541								$(this).down('div').fade({ duration: 0.1 });
17542							} else if(WGElement.overlayAnim == "slide") {
17543								animationFrame.cancel(); 
17544								if(WGElement.overlayPosTB == "top") {
17545									var elementAnim = $(this).down('div');
17546									animationFrame = new Effect.Move($(this).down('div'), {
17547													x: 0, 
17548													y: -overlayDim.height, 
17549													mode: 'relative',
17550													transition: Effect.Transitions.spring,
17551													duration:0.15,
17552													afterFinish: function(event) {
17553														elementAnim.fade({ duration: 0.1 });
17554													}
17555												});
17556								} else
17557									Effect.DropOut($(this).down('div'), {duration:0.1});
17558							}
17559						});
17560						
17561					}
17562				}) ;
17563			}
17564			
17565			
17566			// Postavimo še margine in padinge za UL
17567			$("MGSliderStrip").down("ul").setStyle({
17568				'marginLeft':'0px',
17569				'marginRight':'0px',
17570				'paddingLeft':'0px',
17571				'paddingRight':'0px'
17572			});
17573			
17574			$$("img.thumbImages").each(function(e){
17575				$(e).setStyle({
17576					'width':WGElement.thumbWidth+'px',
17577					'height':WGElement.thumbHeight+'px'
17578				});
17579			});
17580			
17581			$("MGSlider").setStyle({'height':WGElement.thumbHeight+'px'});
17582			
17583			$("IMNextThumb").observe("click", function(event){
17584				var izracunPremika = Number(premikOkvirja) - ($("MGSliderStrip").getWidth());
17585				// Pogledamo ali lahko premaknemo toliko slider
17586				if(izracunPremika > (-maxPosMove)) {
17587					// Premaknemo slider za polno dolžino - v levo
17588					premikOkvirja = izracunPremika;
17589				} else {
17590					// Slider premaknemo samo še za toliko kolikor je ostalo sličic
17591					premikOkvirja = (-maxPosMove);
17592				}
17593				
17594				new Effect.Move($("MGSliderStrip").down(0), { x: premikOkvirja, y: 0, mode: 'absolute' });
17595			});
17596			
17597			$("IMPrevThumb").observe("click", function(event){
17598				var izracunPremika = Number(premikOkvirja) + ($("MGSliderStrip").getWidth());
17599				
17600				if(izracunPremika <= 0) {
17601					// Premaknemo slider za polno dolžino - v desno
17602					premikOkvirja = izracunPremika;
17603				} else {
17604					// Slider premaknemo samo še za toliko kolikor je ostalo do ničerlne točke
17605					premikOkvirja = 0;
17606				}
17607				
17608				new Effect.Move($("MGSliderStrip").down(0), { x: premikOkvirja, y: 0, mode: 'absolute' });
17609			});
17610		}
17611	}
17612	
17613	// Naredimo še observe na hover -> stop animacija
17614	$(WGElement.id).down(0).observe("mouseover",function() {
17615		clearTimeout(autoPlayTime);
17616	});
17617	
17618	$(WGElement.id).down(0).observe("mouseout",function() {
17619		if(WGElement.autoplay === true) {
17620			setTransaction();
17621		}
17622	});
17623	
17624	$(WGElement.id).select('div.MultiContainer').each(function(e,key){
17625		// Odpremo navigacijo iz puščicami
17626		if(WGElement.arrownav === true) {
17627			if(!$("IMArrowNav")) {
17628				$(WGElement.id).insert('<div id="IMArrowNav" class="IMNav"><a id="IMNextPrev" class="prevNav"></a><a id="IMNextNav" class="nextNav"></a></div>');
17629				
17630				// Naredimo observer
17631				$("IMNextPrev").observe("click",function() {
17632					getPrevNextSlide("prev");
17633					
17634					// Pogledamo še ali imamo vklopljen auto premik
17635					if(WGElement.autoplay === true) {
17636						clearTimeout(autoPlayTime);
17637						setTransaction();
17638					}
17639				});
17640				
17641				$("IMNextNav").observe("click",function() {
17642					getPrevNextSlide("next");
17643					
17644					// Pogledamo še ali imamo vklopljen auto premik
17645					if(WGElement.autoplay === true) {
17646						clearTimeout(autoPlayTime);
17647						setTransaction();
17648					}
17649				});
17650				
17651			}
17652		}
17653		
17654		
17655		// Pogledamo ali je potrebno dodati navigacijo iz pikami
17656		if(WGElement.dotnav == true) {
17657			if(!$("IMDotNav")) 
17658				$(WGElement.id).insert('<div id="IMDotNav"></div>');
17659			
17660			// V primru, če je key 0 ga postavimo za aktivnega
17661			var ActiveSlide = "NavDot";
17662			if(Number(key) == 0)
17663				ActiveSlide = "NavDotActive";
17664			
17665			$("IMDotNav").insert('<a id="DotNav'+key+'" class="NavDot '+ActiveSlide+'" rel="'+key+'"></a>');
17666			
17667			// Sedaj pa je potrebno postaviti observerje na klik
17668			$("DotNav"+key).observe("click",function() {
17669				GetSlide($(this).readAttribute("rel"));
17670				
17671				// Pogledamo še ali imamo vklopljen auto premik
17672				if(WGElement.autoplay === true) {
17673					clearTimeout(autoPlayTime);
17674					setTransaction();
17675				}
17676				
17677			});
17678		} else if(WGElement.numnav === true) {
17679			
17680			if(typeof($("IMNumNav")) != "undefined") 
17681				$(WGElement.id).insert('<div id="IMNumNav"></div>');
17682			
17683			// V primru, če je key 0 ga postavimo za aktivnega
17684			var ActiveSlide = "";
17685			if(Number(key) == 0)
17686				ActiveSlide = "NavNumActive";
17687			
17688			$("IMNumNav").insert('<a id="NumNav'+key+'" class="NavNum '+ActiveSlide+'" rel="'+key+'">'+(Number(key) + 1)+'</a>');
17689			
17690			// Sedaj pa je potrebno postaviti observerje na klik
17691			$("NumNav"+key).observe("click",function() {
17692				GetSlide($(this).readAttribute("rel"));
17693				
17694				// Pogledamo še ali imamo vklopljen auto premik
17695				if(WGElement.autoplay === true) {
17696					clearTimeout(autoPlayTime);
17697					setTransaction();
17698				}
17699				
17700			});
17701		}
17702		
17703	});
17704	
17705	// Pogledamo ali imamo autoTransition vklopljen
17706	if(WGElement.autoplay === true) {
17707		setTransaction();
17708	}
17709
17710	function setTransaction(GetNext) {
17711		if(GetNext === true)
17712			getPrevNextSlide("next");
17713		
17714		autoPlayTime = setTimeout(function() {
17715			setTransaction(true);
17716		},WGElement.autoTime);
17717	}
17718
17719	
17720	function GetSlide(Slide) {
17721		// Poiščemo trenutno aktiven slide
17722		$$("div.MSlideActive").each(function(e) {
17723			if(Number($(e).readAttribute("name")) != Number(Slide)) {
17724				// Naredimo relocate activnih slidov
17725				$(e).removeClassName("MSlideActive");
17726				$("MGallery"+Slide).addClassName("MSlideActive");
17727				
17728				// V primeru, da imamo navigacijo iz pikam spremenimo aktivne pike
17729				if($("IMDotNav")) {
17730					$$("a.NavDot").each(function(e) {
17731						$(e).removeClassName("NavDotActive");
17732						$("DotNav"+Slide).addClassName("NavDotActive");
17733					});
17734				}
17735				
17736				if($("IMNumNav")) {
17737					$$("a.NavNum").each(function(e) {
17738						$(e).removeClassName("NavNumActive");
17739						$("NumNav"+Slide).addClassName("NavNumActive");
17740					});
17741				}
17742				
17743				$(e).fade({ duration: 0.1 });
17744				$("MGallery"+Slide).appear({ duration: WGElement.duration });
17745			}
17746		});
17747	}
17748	
17749	function getPrevNextSlide(TipSlide) {
17750		if(String(TipSlide) == "next") {
17751			$$("div.MSlideActive").each(function(e) {
17752				// Najprej je potrebno pogledati ali imamo naslednji slider
17753				var slideNum = $(e).readAttribute("name");
17754				var nextSlide = Number(slideNum) + 1;
17755				var goToSlide = 0;
17756				
17757				if(WGElement.circle === true) {
17758					// Pogledamo naslednji slide
17759					if($("MGallery"+nextSlide))
17760						goToSlide = nextSlide;
17761				} else {
17762					goToSlide = -1;
17763					if($("MGallery"+nextSlide))
17764						goToSlide = nextSlide;
17765				}
17766				
17767				if(Number(goToSlide) >= 0)
17768					GetSlide(goToSlide);
17769				
17770			});
17771		} else if(String(TipSlide) == "prev") {
17772			$$("div.MSlideActive").each(function(e) {
17773				// Najprej je potrebno pogledati ali imamo naslednji slider
17774				var slideNum = $(e).readAttribute("name");
17775				var prevSlide = Number(slideNum) - 1;
17776				var goToSlide = $(e).up("div").readAttribute("name");
17777				
17778				if(WGElement.circle === true) {
17779					// Pogledamo naslednji slide
17780					if($("MGallery"+prevSlide)) {
17781						goToSlide = prevSlide;
17782					}
17783				} else {
17784					goToSlide = -1;
17785					if($("MGallery"+prevSlide))
17786						goToSlide = prevSlide;
17787				}
17788
17789				if(Number(goToSlide) >= 0)
17790					GetSlide(goToSlide);
17791			});
17792		}
17793	}
17794}
17795
17796var contentSlider = Class.create({
17797	
17798	initialize: function(id,options) {
17799		this.elSlider = $(id);
17800		this.elOffset = this.elSlider.down("div.conSliderWrap").viewportOffset();
17801		
17802		this.settings = Object.extend({
17803			arrownav: true,
17804			dotnav: true,
17805			duration: 1.0,
17806			width: 200,
17807			responsive: false,
17808			autoplay: false,
17809			autoTime: 7000,
17810			circle: true,
17811			showTitle:false,
17812			showDesc:false,
17813			content: "inner",
17814			clickedNav: false,
17815			beforeAnim: false,
17816			finishedAnim: false, 
17817			beforeNavClicked: false,
17818			userNavClicked: false,
17819			onElementHover: false,
17820			onElementLeave: false,
17821		}, options || {});
17822		
17823		this.elSlider.down("div.thumbsSlider ul").setStyle({left:0 + 'px'});
17824		this.startTransition = false;
17825
17826		this.calcSliderDim();
17827		this.setObservers();
17828	},
17829	
17830	calcSliderDim: function() {
17831
17832		var thisEl = this;
17833		var ic = 0;
17834		this.dimLI = this.leftOff = this.currentPos = this.orgWidth = this.anMove = this.widthDim = 0;
17835		this.dotCount = izr = 1;
17836		this.numEl = this.elSlider.select("div.thumbsSlider ul li").length ;
17837		
17838		if(this.numEl > 0) {
17839			if(this.settings.responsive) {
17840				this.elSlider.down("div.conSliderWrap").setStyle({width:'100%'});
17841				// Postavimo slider na polno dolžino
17842				this.sliderWidth = Number(this.elSlider.down("div.conSliderWrap").getWidth());
17843
17844				this.elSlider.select("div.thumbsSlider ul li").each(function(el) {
17845					if($(el).getStyle("display") != "none") {
17846						var elPadding = Number($(el).getStyle("paddingLeft").replace("px","")) + Number($(el).getStyle("paddingRight").replace("px",""));
17847						var elMargin = Number($(el).getStyle("marginLeft").replace("px","")) + Number($(el).getStyle("marginRight").replace("px",""));
17848						thisEl.dimLI = thisEl.settings.width + elPadding + elMargin;
17849						thisEl.widthDim += thisEl.settings.width + elPadding + elMargin;
17850
17851						$(el).setStyle({
17852							width:thisEl.settings.width + 'px'
17853						});
17854
17855						$(el).writeAttribute("slide-number",thisEl.widthDim);
17856						
17857						// Pridobimo število slik, ki jih lahko prikažemo
17858						if(Number(thisEl.sliderWidth) > Number(thisEl.widthDim)) {
17859							// Preračunamo sredino sliderja
17860							thisEl.leftOff = (Number(thisEl.sliderWidth) - thisEl.widthDim) / 2;
17861							thisEl.elSlider.down("div.thumbsSlider").setStyle({left: thisEl.leftOff + 'px',width: thisEl.widthDim + 'px'});
17862							thisEl.orgWidth = thisEl.anMove = thisEl.widthDim;
17863							
17864							// Pripravimo število pik
17865							ic++;
17866						}
17867					}
17868				}) ;
17869				
17870				izr = Math.floor((this.numEl / ic));
17871				if((this.numEl % ic) > 0) 
17872					izr++;
17873				
17874				this.dotCount = izr;
17875				
17876				/*if(this.settings.dotnav) 
17877					this.setBullets();*/
17878				
17879				this.setDimensions();
17880			} else {
17881				this.sliderWidth = Number(this.elSlider.down("div.conSliderWrap").getWidth());
17882
17883				this.elSlider.select("div.thumbsSlider ul li").each(function(el) {
17884					if($(el).getStyle("display") != "none") {
17885						var elPadding = Number($(el).getStyle("paddingLeft").replace("px","")) + Number($(el).getStyle("paddingRight").replace("px",""));
17886						var elMargin = Number($(el).getStyle("marginLeft").replace("px","")) + Number($(el).getStyle("marginRight").replace("px",""));
17887						thisEl.dimLI = thisEl.settings.width + elPadding + elMargin;
17888						thisEl.widthDim += thisEl.settings.width + elPadding + elMargin;
17889
17890						$(el).setStyle({
17891							width:thisEl.settings.width + 'px'
17892						});
17893						
17894						$(el).addClassName("Slider_"+(thisEl.widthDim - (thisEl.settings.width + elPadding + elMargin)));
17895						$(el).writeAttribute("slide-item",(thisEl.widthDim - (thisEl.settings.width + elPadding + elMargin)));
17896						
17897						// Pridobimo število slik, ki jih lahko prikažemo
17898						if(Number(thisEl.sliderWidth) > Number(thisEl.widthDim)) {
17899							// Preračunamo sredino sliderja
17900							thisEl.leftOff = (Number(thisEl.sliderWidth) - thisEl.widthDim) / 2;
17901							thisEl.elSlider.down("div.thumbsSlider").setStyle({left: thisEl.leftOff + 'px',width: thisEl.widthDim + 'px'});
17902							thisEl.orgWidth = thisEl.anMove = thisEl.widthDim;
17903							
17904							// Pripravimo število pik
17905							ic++;
17906						}
17907					}
17908				}) ;
17909				
17910				this.elSlider.down("div.thumbsSlider ul").setStyle({width:this.widthDim + 'px'});
17911			}
17912		}
17913	},
17914	
17915	calculateMove: function(aType,moveBy,justCalc) {
17916		
17917		var sliderMove = 0;
17918		this.tmpCurrentPos = Number(this.currentPos);
17919		
17920		//console.log("Tip: "+aType+" Position: "+this.currentPos+" TMP: "+this.tmpCurrentPos);
17921		if(aType == "next") {
17922			this.tmpCalc = this.widthDim - (this.tmpCurrentPos + this.anMove) ;
17923			if(this.tmpCalc > 0) {
17924				// Pogledamno ali lahko premaknemo za celoten slide
17925				if(this.tmpCalc > this.anMove) {
17926					this.tmpCurrentPos += this.anMove;
17927				} else {
17928					this.tmpCurrentPos += this.tmpCalc;
17929				}
17930				
17931				sliderMove = -(this.tmpCurrentPos);
17932			} else {
17933				this.tmpCurrentPos = sliderMove = 0;
17934			}
17935		} else if(aType == "prev") {
17936			
17937			if(this.tmpCurrentPos <= 0) {
17938				
17939				this.tmpCurrentPos = this.widthDim - this.tmpCurrentPos - this.anMove ;
17940				//console.log("TMpCurrentPOS - move back: "+this.tmpCurrentPos+" Move: "+this.anMove);
17941			} else {
17942				//console.log("TMpCurrentPOS - is null: "+this.tmpCurrentPos);
17943				this.tmpCurrentPos = this.tmpCurrentPos - this.anMove ; 
17944				
17945				if(Number(this.tmpCurrentPos) < 0)
17946					this.tmpCurrentPos = 0;
17947			}
17948			
17949			sliderMove = -(this.tmpCurrentPos);
17950		} else if(aType == "move") {
17951			if(!isNaN(moveBy)) {
17952				this.tmpCurrentPos = moveBy;
17953				sliderMove = -(this.tmpCurrentPos);
17954			}
17955		}
17956		
17957		// Če ne gre samo kalkulacijo zapišemo tmpPozicijo v pozicijo
17958		if(justCalc !== true)
17959			this.currentPos = Number(this.tmpCurrentPos);
17960		
17961		//console.log("After Position: "+this.currentPos+" TMP: "+this.tmpCurrentPos+" JustCal: "+justCalc);
17962		
17963		return sliderMove;
17964	},
17965	
17966	moveAnimSlider: function(aType,moveBy) {
17967		
17968		var thisEl = this;
17969		var sliderMove = this.calculateMove(aType,moveBy);
17970		var duration = this.settings.duration;
17971				
17972		//this.elSlider.down("div.thumbsSlider ul").setStyle({left: sliderMove + 'px'});
17973		new Effect.Morph(this.elSlider.down("div.thumbsSlider ul"), {
17974			style: 'left:'+sliderMove+'px;', // CSS Properties
17975			duration: duration,
17976			transition: Effect.Transitions.spring,
17977			beforeStart: function(item) {
17978				//RevealElement(item.element);
17979				thisEl.startTransition = true;
17980				
17981				if(typeof(thisEl.settings.beforeAnim) == "function" && aType != "move") {
17982					thisEl.settings.beforeAnim(item,thisEl.currentPos);
17983				}
17984			},
17985			afterFinish: function(item) {
17986				if(typeof(thisEl.settings.finishedAnim) == "function" && aType != "move") {
17987					thisEl.settings.finishedAnim(item,thisEl.currentPos);
17988				} else
17989					thisEl.startTransition = false;
17990			}
17991		});
17992	},
17993	
17994	setDimensions: function() {
17995		this.w=window;
17996		this.d=document;
17997		this.e=this.d.documentElement;
17998		this.g=this.d.getElementsByTagName('body')[0];
17999		this.x=this.w.innerWidth||this.e.clientWidth||this.g.clientWidth;
18000		this.y=this.w.innerHeight||this.e.clientHeight||this.g.clientHeight;
18001
18002		if(Number(this.sliderWidth) > (Number(this.x) - this.elOffset.left)) {
18003
18004			this.anMove = 0;
18005			var tmpMove = 0;
18006			
18007			while(tmpMove >= 0) {
18008				tmpMove = this.x - this.elOffset.left - this.anMove - 60;
18009				//console.log("Width of slide: "+tmpMove);
18010				if(tmpMove >= 0 && tmpMove > Number(this.dimLI))
18011					this.anMove += Number(this.dimLI);
18012				else
18013					tmpMove = -1;
18014			}
18015			
18016			if(this.anMove < Number(this.dimLI))
18017				this.anMove = Number(this.dimLI);
18018
18019			this.elSlider.down("div.thumbsSlider").setStyle({width:this.anMove + 'px'});
18020
18021			var calcZamik = ((this.x - this.elOffset.left) - this.anMove) / 2;
18022			if(calcZamik > 40)
18023				this.elSlider.down("div.thumbsSlider").setStyle({left: calcZamik + 'px'});
18024			
18025			this.elSlider.down("div.conSliderWrap").setStyle({width: (this.anMove + (2 * calcZamik)) + 'px'});
18026			
18027		} else {
18028			this.anMove = this.orgWidth;
18029			this.elSlider.setStyle({width:100 + '%'});
18030			this.elSlider.down("div.conSliderWrap").setStyle({width:this.sliderWidth + 'px'});
18031			this.elSlider.down("div.thumbsSlider").setStyle({width:this.anMove + 'px'});
18032			this.elSlider.down("div.thumbsSlider ul").setStyle({width:this.widthDim + 'px'});
18033		}
18034	},
18035	
18036	setBullets: function() {
18037		if(this.settings.dotnav) {
18038			for(var i = 0; i < Number(this.dotCount); i++) 
18039					this.elSlider.down("div.bulletsSlider").insert('<span class="bullet"></span>');
18040
18041			if(this.elSlider.select("span.bulletActive").length != 1)
18042				this.elSlider.down("div.bulletsSlider").firstChild.addClassName("bulletActive");
18043		}
18044	},
18045	
18046	setObservers: function() {
18047		var thisEl = this;
18048		this.elSlider.down("div.arrowsSlider").down("div.arrow_left").observe("click",function (el) {
18049			if(!thisEl.startTransition) {
18050				if(typeof(thisEl.settings.userNavClicked) == "function") {
18051					thisEl.settings.userNavClicked(el,"prev");
18052				} else {
18053					if(typeof(thisEl.settings.beforeNavClicked) == "function") 
18054						thisEl.settings.beforeNavClicked(el,"prev");
18055					
18056					thisEl.moveAnimSlider("prev");
18057					if(typeof(thisEl.settings.clickedNav) == "function" ) {
18058						thisEl.settings.clickedNav(thisEl.elSlider.down("div.thumbsSlider ul"));
18059					}
18060				}
18061			}
18062		});
18063		
18064		this.elSlider.down("div.arrowsSlider").down("div.arrow_right").observe("click",function (el) {
18065			if(!thisEl.startTransition) {
18066				if(typeof(thisEl.settings.userNavClicked) == "function") {
18067					thisEl.settings.userNavClicked(el,"next");
18068				} else {
18069					if(typeof(thisEl.settings.beforeNavClicked) == "function")  
18070						thisEl.settings.beforeNavClicked(el,"next");
18071					
18072					thisEl.moveAnimSlider("next");
18073					if(typeof(thisEl.settings.clickedNav) == "function") {
18074						thisEl.settings.clickedNav(thisEl.elSlider.down("div.thumbsSlider ul"));
18075					}
18076				}
18077			}
18078		});
18079
18080		thisEl.elSlider.down("div.thumbsSlider ul").select("a").each(function(el) {
18081			$(el).observe("mouseenter",function(hover) {
18082				if(typeof(thisEl.settings.onElementHover) == "function") {
18083					thisEl.settings.onElementHover(el,hover);
18084				}
18085			});
18086		});
18087		
18088		
18089		this.elSlider.down("div.thumbsSlider ul").select("a").each(function(el) {
18090			$(el).observe("mouseleave",function(hover) {
18091				if(typeof(thisEl.settings.onElementLeave) == "function") {
18092					thisEl.settings.onElementLeave(el,hover);
18093				}
18094			});
18095		});
18096		
18097		
18098		this.elSlider.down("div.bulletsSlider").childElements().invoke("observe", "click", function () {
18099			if(!this.hasClassName("bulletActive")) {
18100				alert("move slider - bullet");
18101			}
18102		});
18103		
18104		if(this.settings.responsive) {
18105			Event.observe(window, 'resize', function() {
18106				thisEl.calcSliderDim();
18107			});
18108		}
18109	}
18110});
18111
18112function dwmViewport() {
18113	var e = window, a = 'inner';
18114	if(!('innerWidth' in window)) {
18115		a = 'client';
18116		e = document.documentElement || document.body;
18117	}
18118	return { width : e[ a+'Width' ] , height : e[ a+'Height' ] }
18119}
18120
18121function dwm_odpriVimeo(VimeoLink) {
18122	
18123	var url = "/AJAX.php?C=VimeoHelpLink&NavodiloLink="+encodeURIComponent(VimeoLink) ;
18124	
18125	lightWindowStack.openWindow({
18126		href: url,
18127		title: '',
18128		author: 'Boogie in Klemen',
18129		caption: '',
18130		iframeEmbed: false,
18131		loadingAnimation: {},
18132		width: 850,
18133		height: 500
18134	}) ;
18135}
18136
18137function getStyleSheet(unique_title) {
18138	for(var i=0; i<document.styleSheets.length; i++) {
18139		var sheet = document.styleSheets[i];
18140			if(sheet.title == unique_title) {
18141			return sheet;
18142		}
18143	}
18144}
18145// Zapri okno - za vse popupe	
18146function zapriPopUp(){
18147	lightWindowStack.closeWindow() ;
18148}
18149
18150var t_LookupTable_Count = 0 ;
18151var t_LookupTable_ReturnFunkcija = new Array() ;
18152var t_LookupTable_Options = new Array() ;
18153function LookupTable(TabelaId,ReturnFunkcija,options) {
18154	/*
18155	 * Tole smo preselili zgoraj v osnovno odpiranje za lightWindow
18156	if ((typeof(myLightWindow) == "undefined") || (myLightWindow == null)) {
18157		t_LookupTable_Count++ ;
18158		t_LookupTable_ReturnFunkcija[t_LookupTable_Count] = ReturnFunkcija ;
18159		t_LookupTable_Options[t_LookupTable_Count] = options ;
18160		setTimeout('LookupTable('+TabelaId+',t_LookupTable_ReturnFunkcija['+t_LookupTable_Count+'],t_LookupTable_Options['+t_LookupTable_Count+'])',50) ;
18161	} else */
18162	{
18163		var default_args = {
18164			'Title' 		:	'Izbirnik',
18165			'Caption' 		:	'Izbirnik',
18166			'Width'			:	900,
18167			'Height'		:	500,
18168			'DodatniFiltri'	: '',
18169			'onClose'		: function(){}
18170		}
18171
18172		lwObj = {} ;
18173
18174		for(var index in default_args) {
18175			if(typeof options[index] == "undefined")
18176				options[index] = default_args[index];
18177		}
18178
18179		if (typeof(ReturnFunkcija) == "function") {
18180			if (typeof(options["IdDodatno"]) != "undefined") {
18181				if ($D("IdDodatno")) {
18182					$("IdDodatno").value = options["IdDodatno"];
18183				}
18184			}
18185			lwObj.retFunction = ReturnFunkcija ;
18186		} else if ((typeof(ReturnFunkcija) == "object") && (ReturnFunkcija.activate)) {
18187			if (typeof(options["IdDodatno"]) != "undefined") {
18188				if ($D("IdDodatno")) {
18189					$("IdDodatno").value = options["IdDodatno"];
18190				}
18191			}
18192			lwObj.retFunction = ReturnFunkcija.activate ;
18193		} else {
18194			lwObj.retFunction = function(Objekt) {
18195				// HACK - Ker imamo nekje polja "s_id" namesto "id", tule to nadomestimo
18196				if (ReturnFunkcija.id == "s_id") {
18197					ReturnFunkcija.id = "id" ;
18198					ReturnFunkcija.Polja["id"] = ReturnFunkcija.Polja["s_id"] ;
18199				}
18200
18201				// Splošna funkcija za vrnitev
18202				if (Objekt[ReturnFunkcija.id] != ReturnFunkcija.id_field.value) {
18203					// Imamo spremembo elementa
18204					// Napolnimo vsa potrebna polja
18205					for (var index in ReturnFunkcija.Polja) { // nastavi vsa polja
18206						if (typeof(ReturnFunkcija.Polja[index]) == "string") {
18207							if ((index == "s_id") && (typeof(Objekt[index]) == "undefined")) {
18208								$(ReturnFunkcija.Polja[index]).value = Objekt["id"] ;
18209							} else {
18210								$(ReturnFunkcija.Polja[index]).value = Objekt[index] ;
18211							}
18212						}
18213					}
18214					// Sedaj na vseh teh poljih sprožimo onChange event
18215					for (var index in ReturnFunkcija.Polja) { // nastavi vsa polja
18216						if (typeof(ReturnFunkcija.Polja[index]) == "string") {
18217							fireEvent($(ReturnFunkcija.Polja[index]),"change") ;
18218						}
18219					}
18220				}
18221
18222				if(typeof(ReturnFunkcija.OnChangeEvent) == "function") {
18223					Objekt.vrsId = ReturnFunkcija.vrsId;
18224					Objekt.tableid = TabelaId;
18225					
18226					if(typeof(options.extraData) != "undefined") {
18227						// Vrnemo dodatna polja v return funkcijo
18228						for(var index in options.extraData) {
18229							Objekt[index] = options.extraData[index];
18230						}
18231					}
18232
18233					ReturnFunkcija.OnChangeEvent(Objekt);
18234				} else {
18235					if(typeof(PodatekSpremenjen) == "function") {
18236						PodatekSpremenjen() ;
18237					}
18238				}
18239			}
18240		}
18241
18242		if(typeof(options['Multiple']) != "undefined") {
18243			lwObj.Multiple = options['Multiple'];
18244			lwObj.MultipleAdd = options['Multiple'];
18245		}
18246		if(typeof(options['MultipleAdd']) != "undefined") {
18247			lwObj.MultipleAdd = options['MultipleAdd'];
18248		}
18249
18250		//afterClose
18251		if(typeof(options['MultiFilterPolje']) != "undefined") {
18252			MultiFilterPolje = options['MultiFilterPolje'];
18253			options['onClose'] = ReloadList;
18254		}
18255
18256		if ((!$D(ReturnFunkcija)) || (!$D(ReturnFunkcija.id_field)) || ($(ReturnFunkcija.id_field).readOnly === false)) {
18257			var tlwObj = Object.assign({
18258				href: '/AJAX.php?C=Lookup&T='+TabelaId+options['DodatniFiltri'],
18259				title: options['Title'],
18260				author: '',
18261				caption: options['Caption'],
18262				iframeEmbed: false,
18263				loadingAnimation: {},
18264				width: options['Width'],
18265				height: options['Height'],
18266				onClose: options['onClose']
18267			},lwObj) ;
18268			lightWindowStack.openWindow(tlwObj,true) ;
18269		}
18270	}
18271}
18272
18273function PoisciInNapolniKopijePolja(Polje) {
18274	if (($D(Polje)) && (typeof($(Polje).hasAttribute) != "undefined") && ($(Polje).hasAttribute("dwm_poljekopija"))) {
18275		var Vrednost = String($(Polje).value) ;
18276		var PoljeKopija = $(Polje).getAttribute("dwm_poljekopija") ;
18277		switch (String(Polje.type).trim()) {
18278			case "text":
18279				var eachPolje = "input" ;
18280				break;
18281			case "textarea":
18282				var eachPolje = "textarea" ;
18283				break;
18284		}
18285		$$(eachPolje).each(function(inptPolje){
18286			if (($(inptPolje).hasAttribute("dwm_poljekopija")) && ((String($(inptPolje).getAttribute("dwm_poljekopija")).trim()) == PoljeKopija)) {
18287				$(inptPolje).value = Vrednost ;
18288			}
18289		}) ;
18290	}
18291}
18292
18293function PodatekSpremenjen(FunkcijaPredSpremembo,Polje) {
18294	if ((typeof(form_loading) != 'undefined') && (form_loading == false)) {
18295		// Če je potrebno kaj preračunati ob spremembi polja, to naredimo tule
18296		if (FunkcijaPredSpremembo && (typeof(FunkcijaPredSpremembo) == "function")) {
18297			FunkcijaPredSpremembo() ;
18298		}
18299		if (Polje && (typeof(Polje) != "undefined")) {
18300			PoisciInNapolniKopijePolja(Polje) ;
18301		}
18302		// Ali imamo nastavljeno, da se podatki shranjujeo takoj ob spremembi polja, al
18302i šele, ko uporabnik stisne "Shrani" ?
18303		if (PodatekShraniObSpremembiPolja) {
18304			if (typeof(CustomFormaShrani) == 'function') {
18305				CustomFormaShrani() ;
18306			} else {
18307				Shrani() ;
18308			}
18309		} else {
18310			if ($D('IkonaPodatekNiShranjen')) {
18311				$('IkonaPodatekNiShranjen').style.display = "" ;
18312			}
18313			
18314			if($D("DWMPovrniPodatke")) {
18315				$('DWMPovrniPodatke').style.display = "" ;
18316			}
18317			PodatekNiShranjen = true ;
18318		}
18319	}
18320}
18321
18322// attach the .equals method to Array's prototype to call it on any array
18323Array.prototype.equals = function(array) {
18324	// if the other array is a falsy value, return
18325	if (!array) {
18326		return false ;
18327	}
18328
18329	// compare lengths - can save a lot of time 
18330	if (this.length != array.length) {
18331		return false ;
18332	}
18333
18334	for (var i = 0, l=this.length; i < l; i++) {
18335		// Check if we have nested arrays
18336		if (this[i] instanceof Array && array[i] instanceof Array) {
18337			// recurse into the nested arrays
18338			if (!this[i].equals(array[i])) {
18339				return false ;
18340			}
18341		} else if (this[i] != array[i]) {
18342			// Warning - two different object instances will never be equal: {x:20} != {x:20}
18343			return false ;
18344		}
18345	}
18346	return true ;
18347}
18348function dwmjr_reIndexTBL(type) {
18349	if(type == 1) 
18350		var Tabela = $('IdPodatka').value;
18351	else
18352		var Tabela = 0;
18353	
18354	if(Tabela == 0) {
18355			alert("Reindeksiranje tabel lahko poteka dolog časa !");
18356	}
18357	
18358		var url = "/AJAX.php?C=ReindexTabele&T="+Tabela;
18359		new Ajax.Request(url, {
18360			method: 'post',
18361			onSuccess: function(transport) {
18362				var Res = transport.responseJSON ;
18363				HideWait() ;
18364				if (Res.error) {
18365					alert(Res.error) ;
18366				} else {
18367					alert(Res.ok)
18368				}
18369			},
18370			onFailure: function() {
18371				HideWait() ;
18372			}
18373		});
18374
18375}
18376
18377function Linkify(inputText) {
18378	//URLs starting with http://, https://, or ftp://
18379	var replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
18380	var replacedText = inputText.replace(replacePattern1, '<a href="$1" target="_blank">$1</a>');
18381
18382	//URLs starting with www. (without // before it, or it'd re-link the ones done above)
18383	var replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
18384	var replacedText = replacedText.replace(replacePattern2, '$1<a href="http://$2" target="_blank">$2</a>');
18385
18386	//Change email addresses to mailto:: links
18387	var replacePattern3 = /(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim;
18388	var replacedText = replacedText.replace(replacePattern3, '<a href="mailto:$1">$1</a>');
18389
18390	return replacedText
18391}
18392
18393function dateTimeFieldChanged() {
18394	if ((typeof(PodatekSpremenjen) == "function") && (this.value != this.readAttribute("dwm_oldvalue"))) {
18395		PodatekSpremenjen() ;
18396	}
18397	if (typeof(DatePickerOnChange) == "function") {
18398		DatePickerOnChange() ;
18399	}
18400}
18401
18402function openPopUp(urlToOpen,winTitle,winOptions,errText) {
18403	var popup_window=window.open(urlToOpen,winTitle,winOptions);            
18404	try {
18405		popup_window.focus();   
18406		return true ;
18407	}
18408	catch (e) {
18409		if (errText)
18410			alert(errText) ;
18411		return false ;
18412	}
18413}
18414
18415function SPLVrsticeElementa_Delete(e) {
18416	if (!e) var e = window.event ;
18417	if (e.target) targ = e.target;
18418	else if (e.srcElement) targ = e.srcElement;
18419	if (targ.nodeType == 3) // defeat Safari bug
18420		targ = targ.parentNode;
18421
18422	if (typeof($(targ).up('.DivLoadVrstice')) != 'undefined')
18423		var DivLoadVrstice = $(targ).up('.DivLoadVrstice') ;
18424
18425	if (typeof($(targ).up('.SPL_Vrstica_Container')) != 'undefined') {
18426		var fEvent = new Object() ;
18427		fEvent.target = $(targ).up('.Tabela_SPL_Vrstice_Body') ;
18428
18429		$(targ).up('.SPL_Vrstica_Container').remove() ;
18430		PodatekSpremenjen() ;
18431		// sprožimo preračun skupnih vrednosti vrstic
18432		SPLVrsticeElementa_OnChange(fEvent) ;
18433
18434		if (typeof(DivLoadVrstice) != 'undefined')
18435			DivLoadVrstice.SPLVE_Save() ;
18436	}
18437}
18438
18439function SPLVrsticeElementa_OnChange(e) {
18440	if (!e) var e = window.event ;
18441	if (e.target) targ = e.target;
18442	else if (e.srcElement) targ = e.srcElement;
18443	if (targ.nodeType == 3) // defeat Safari bug
18444		targ = targ.parentNode;
18445
18446	if (typeof($(targ).up('.SPL_Vrstica_Container')) != 'undefined') {
18447		$(targ).value = Number(String($(targ).value).trim().LocaleToNum()).DWMLocale(ValutaDecimalk) ;
18448
18449		var TargetTR = $(targ).up('.SPL_Vrstica_Container') ;
18450		if (typeof(TargetTR.down('input[name="SUM_VRS"]')) != 'undefined') {
18451			var SumVrsInput = TargetTR.down('input[name="SUM_VRS"]') ;
18452
18453			var rezultat = 1 ;
18454
18455			if (typeof(TargetTR.down('.SPL_Vrstica_Element')) != 'undefined') {
18456				var VrsticaElement = TargetTR.down('.SPL_Vrstica_Element') ;
18457				var vsiElementi = false ;
18458				while (vsiElementi === false) {
18459					if (typeof(VrsticaElement) == 'undefined') {
18460						vsiElementi = true ;
18461					} else {
18462						VrsticaInput = VrsticaElement.down('input') ;
18463						var vsiInputi = false ;
18464						while (vsiInputi === false) {
18465							if (typeof(VrsticaInput) == 'undefined') {
18466								vsiInputi = true ;
18467							} else {
18468								if ((VrsticaInput.hasAttribute('sum')) && (Number(VrsticaInput.getAttribute('sum')) == 1)) {
18469									rezultat *= String(VrsticaInput.value).trim().LocaleToNum() ;
18470								}
18471								VrsticaInput = VrsticaInput.next('input') ;
18472							}
18473						}
18474
18475						VrsticaElement = VrsticaElement.next('.SPL_Vrstica_Element') ;
18476					}
18477				}
18478			}
18479
18480			SumVrsInput.value = Number(rezultat).DWMLocale(ValutaDecimalk) ;
18481		}
18482	}
18483
18484	// če imamo polje za skupno vrednost seštejemo vse skupne vrednosti vrstic
18485	if ((typeof($(targ).up('.DivLoadVrstice')) != 'undefined') && (typeof($(targ).up('.DivLoadVrstice').down('input[name="SPL_Vrstice_Skupaj"]')) != 'undefined')) {
18486		var SkupajSestevek = 0 ;
18487		$$('input[name="SUM_VRS"]').each(function(SumVrs){
18488			SkupajSestevek += String(SumVrs.value).trim().LocaleToNum() ;
18489		}) ;
18490
18491		$(targ).up('.DivLoadVrstice').down('input[name="SPL_Vrstice_Skupaj"]').value = Number(SkupajSestevek).DWMLocale(ValutaDecimalk) ;
18492	}
18493}
18494
18495var page_loading = true;
18496var dwm_inSelector = false ;
18497var dwm_bodyClicked = false ;
18498
18499document.observe("dom:loaded", function(){
18500	document.observe("click", function() {
18501		console.log("BODY-Click:"+dwm_inSelector) ;
18502		dwm_bodyClicked = true ;
18503		if (dwm_inSelector) {
18504			// Ker imamo odprt selektor, ga zapremo
18505			// FIXME - Tule bo treba zadnjo vrednost shranit nazaj v polje
18506			// RevealElement(ListIzbirnik) ;
18507			if (typeof(ListIzbirnik) == "object") {
18508				ListIzbirnik.dwmClose() ;
18509				HideWait() ;
18510			}
18511		}
18512	}) ;
18513	page_loading = false;
18514}) ;
18515
18516function dwm_enableKolChanger() {
18517	$$(".kolChanger").invoke('observe', 'click', function(e) {
18518		if (this.hasAttribute("kolField")) {
18519			if ($D(this.getAttribute("kolField"))) {
18520				var kolicinaPolje = $(this.getAttribute("kolField")) ;
18521				var kolicina = Number(String(kolicinaPolje.value).LocaleToNum()) ;
18522				var minKolicina = (kolicinaPolje.hasAttribute("minValue") ? Number(kolicinaPolje.getAttribute("minValue")) : 1) ;
18523				var maxKolicina = (kolicinaPolje.hasAttribute("maxValue") ? Number(kolicinaPolje.getAttribute("maxValue")) : 999999999) ;
18524				var zapSt = kolicinaPolje.getAttribute("zapSt") ;
18525				var tipVrs = kolicinaPolje.getAttribute("tipVrs") ;
18526				var idPodatka = kolicinaPolje.getAttribute("idPodatka") ;
18527				var staraKolicina = kolicina ;
18528				var stDecimalk = kolicinaPolje.getAttribute("stDec") ;
18529				if (isNaN(Number(stDecimalk))) stDecimalk = 2 ;
18530
18531				if (isNaN(kolicina)) kolicina = 1 ;
18532
18533				if (this.hasAttribute("minusKorak")) {
18534					var minusKorak = Number(this.getAttribute("minusKorak")) ;
18535					if (!isNaN(minusKorak)) {
18536						kolicina = kolicina - minusKorak ;
18537						if (kolicina < minKolicina)
18538							kolicina = minKolicina ;
18539					}
18540				} else if (this.hasAttribute("plusKorak")) {
18541					var plusKorak = Number(this.getAttribute("plusKorak")) ;
18542					if (!isNaN(plusKorak)) {
18543						kolicina = kolicina + plusKorak ;
18544						if ((maxKolicina != 0) && (kolicina > maxKolicina))
18545							kolicina = maxKolicina ;
18546					}
18547				}
18548				kolicinaPolje.value = kolicina.DWMLocale(stDecimalk) ;
18549				// Če imamo spremenjeno količino in obstaja JS funkcija "updateKolicinVKosarici", potem jo poženemo
18550				if ((kolicina != staraKolicina) && (typeof(updateKolicinaVKosarici) == "function")) {
18551					updateKolicinaVKosarici(idPodatka,tipVrs,zapSt) ;
18552				}
18553			}
18554		}
18555	});
18556}
18557
18558function dwm_enableKolCheck() {
18559	$$(".kolCheck").invoke('observe', 'change', function(e) {
18560		var kolicinaPolje = $(this) ;
18561		var kolicina = Number(String(kolicinaPolje.value).LocaleToNum()) ;
18562		var minKolicina = (kolicinaPolje.hasAttribute("minValue") ? Number(kolicinaPolje.getAttribute("minValue")) : 1) ;
18563		var maxKolicina = (kolicinaPolje.hasAttribute("maxValue") ? Number(kolicinaPolje.getAttribute("maxValue")) : 999999999) ;
18564		var zapSt = kolicinaPolje.getAttribute("zapSt") ;
18565		var tipVrs = kolicinaPolje.getAttribute("tipVrs") ;
18566		var idPodatka = kolicinaPolje.getAttribute("idPodatka") ;
18567
18568		if (isNaN(kolicina)) kolicina = 1 ;
18569		if (kolicina < minKolicina)
18570			kolicina = minKolicina ;
18571		else if ((maxKolicina != 0) && (kolicina > maxKolicina))
18572			kolicina = maxKolicina ;
18573		kolicinaPolje.value = kolicina.DWMLocale(2) ;
18574		if (typeof(updateKolicinaVKosarici) == "function") {
18575			updateKolicinaVKosarici(idPodatka,tipVrs,zapSt) ;
18576		}
18577	}) ;
18578}
18579
18580function dwm_enableOpombaChange() {
18581	$$(".opombaChange").invoke('observe', 'change', function(e) {
18582		var opombaPolje = $(this) ;
18583		var opomba = String(opombaPolje.value) ;
18584		var zapSt = opombaPolje.getAttribute("zapSt") ;
18585		var tipVrs = opombaPolje.getAttribute("tipVrs") ;
18586		var idPodatka = opombaPolje.getAttribute("idPodatka") ;
18587
18588		if (typeof(updateOpombaVKosarici) == "function") {
18589			updateOpombaVKosarici(idPodatka,tipVrs,zapSt) ;
18590		}
18591	}) ;
18592}
18593
18594function dwm_skrivanjePostnine() {
18595	$(document.body).select('.nacinDP').each( function(e) {
18596		if (e.down('.cenaDostave')) {
18597			if (String(e.down('.cenaDostave').innerText).substr(0,4) == '0,00') {
18598				e.hide() ;
18599			} else {
18600				e.show() ;
18601			}
18602		}
18603	});
18604}
18605
18606function dwm_storageAvailable(type) {
18607	try {
18608		var storage = window[type],
18609			x = 'test';
18610		storage.setItem(x, x);
18611		storage.removeItem(x);
18612		return true;
18613	}
18614	catch(e) {
18615		return e instanceof DOMException && (
18616			// everything except Firefox
18617			e.code === 22 ||
18618			// Firefox
18619			e.code === 1014 ||
18620			// test name field too, because code might not be present
18621			// everything except Firefox
18622			e.name === 'QuotaExceededError' ||
18623			// Firefox
18624			e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
18625			// acknowledge QuotaExceededError only if there's something already stored
18626			storage.length !== 0;
18627	}
18628}
18629
18630function dwn_ajaxCall( opt ) {
18631	if (typeof(opt) != "object") {
18632		console.log('ERR: dwn_ajaxCall requres an object as parameter!') ;
18633	} else if ((typeof(opt.url) != "string") || (String(opt.url).trim() == "")) {
18634		console.log('ERR: url is required and cannot be empty!') ;
18635	} else if (typeof(opt.onResult) != "function") {
18636		console.log('ERR: "onResult" function is required!') ;
18637	} else {
18638		if ((opt.element != null) && $D(opt.element))
18639			ShowWaitInElement(opt.element, opt.waiterEl) ;
18640
18641		// Set default "opt" options, if they are not set
18642		var default_options = {
18643			method: 'get',
18644			parameters: null,
18645			debug: false,
18646			show_error: true,
18647			show_notice: true,
18648			redirect: true,         // TODO
18649			element: null,          // HTML element, where we show "waiter"
18650			waiterEl: null, 		// HTML Waiter element
18651			onError: null,          // function, that runs, if AJAX returns error
18652			onConnError: null,      // function, that runs on connection error
18653			onEmpty: function() { console.log("No JSON returned!"); }
18654		}
18655
18656		for (var index in default_options) {
18657			if (typeof opt[index] == "undefined")
18658				opt[index] = default_options[index];
18659		}
18660
18661		// TODO - Pretvorimo v REST klic
18662		new Ajax.Request(opt.url, {
18663			method: opt.method,
18664			parameters: opt. parameters,
18665			onSuccess: function(transport) {
18666				var Res = transport.responseJSON ;
18667				console.log(Res) ;
18668				HideWaitInElement(opt.element, opt.waiterEl) ;
18669				if (typeof(Res) != "object") {
18670					if (opt.debug)
18671						console.log("Running onEmpty!") ;
18672					opt.onEmpty(Res) ;
18673				} else {
18674					if (opt.debug) {
18675						console.log("Returned result:") ;
18676						console.log(Res) ;
18677					}
18678					if (Res.error) {
18679						if (opt.show_error) alert(Res.error) ;
18680						if (typeof(opt.onError) == "function") {
18681							if (opt.debug)
18682								console.log("Running onConnError!") ;
18683							opt.onError(Res) ;
18684						}
18685					} else {
18686						if ((Res.notice) && (opt.show_notice)) alert(Res.notice) ;
18687						if (opt.debug) {
18688							console.log("Running onResult for "+opt.url+" !") ;
18689							console.debug(Res) ;
18690						}
18691						opt.onResult(Res) ;
18692					}
18693				}
18694			},
18695			onFailure: function() {
18696				if ((opt.element != null) && $D(opt.element))
18697					HideWaitInElement(opt.element, opt.waiterEl) ;
18698				if (opt.show_error) alert("Error connecting to server") ;
18699				console.log("ERR: Server connection failed");
18700				if (typeof(opt.onConnError) == "function") {
18701					if (opt.debug)
18702						console.log("Running onConnError!") ;
18703					opt.onConnError() ;
18704				}
18705			}
18706		});
18707	}
18708}
18709
18710/**
18711 * Event.simulate(@element, eventName[, options]) -> Element
18712 *
18713 * - @element: element to fire event on
18714 * - eventName: name of event to fire (only MouseEvents and HTMLEvents interfaces are supported)
18715 * - options: optional object to fine-tune event properties - pointerX, pointerY, ctrlKey, etc.
18716 *
18717 *    $('foo').simulate('click'); // => fires "click" event on an element with id=foo
18718 *
18719 **/
18720(function(){
18721
18722	var eventMatchers = {
18723		'HTMLEvents': /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,
18724 'MouseEvents': /^(?:click|mouse(?:down|up|over|move|out))$/
18725	}
18726	var defaultOptions = {
18727		pointerX: 0,
18728 pointerY: 0,
18729 button: 0,
18730 ctrlKey: false,
18731 altKey: false,
18732 shiftKey: false,
18733 metaKey: false,
18734 bubbles: true,
18735 cancelable: true
18736	}
18737
18738	Event.simulate = function(element, eventName) {
18739		var options = Object.extend(defaultOptions, arguments[2] || { });
18740		var oEvent, eventType = null;
18741
18742		element = $(element);
18743
18744		for (var name in eventMatchers) {
18745			if (eventMatchers[name].test(eventName)) { eventType = name; break; }
18746		}
18747
18748		if (!eventType)
18749			throw new SyntaxError('Only HTMLEvents and MouseEvents interfaces are supported');
18750
18751		if (document.createEvent) {
18752			oEvent = document.createEvent(eventType);
18753			if (eventType == 'HTMLEvents') {
18754				oEvent.initEvent(eventName, options.bubbles, options.cancelable);
18755			}
18756			else {
18757				oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, document.defaultView,
18758									  options.button, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
18759						  options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, element);
18760			}
18761			element.dispatchEvent(oEvent);
18762		}
18763		else {
18764			options.clientX = options.pointerX;
18765			options.clientY = options.pointerY;
18766			oEvent = Object.extend(document.createEventObject(), options);
18767			element.fireEvent('on' + eventName, oEvent);
18768		}
18769		return element;
18770	}
18771
18772	Element.addMethods({ simulate: Event.simulate });
18773})()
18774Hash.prototype.without = function() {
18775    var values = $A(arguments);
18776	var retHash = $H();
18777    this.each(function(entry) {
18778		if(!values.include(entry.key))
18779			retHash.set(entry.key, entry.value);
18780    });
18781	return retHash;
18782}
18783
18784Element.insertAfter = function(insert, element) {
18785	if (element.nextSibling) element.parentNode.insertBefore(insert, element.nextSibling);
18786	else element.parentNode.appendChild(insert);
18787}
18788
18789// Fix exceptions thrown thrown when removing an element with no parent
18790Element._remove = Element.remove;
18791Element.remove = function(element) {
18792	element = $(element);
18793	if (element.parentNode)
18794		return Element._remove(element);
18795}
18796DateFormat = Class.create();
18797Object.extend(DateFormat, {
18798	MONTH_NAMES: ['January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
18799	DAY_NAMES: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat'],
18800	LZ: function(x) {return(x<0||x>9?"":"0")+x},
18801	compareDates: function(date1,dateformat1,date2,dateformat2) {
18802		var d1=DateFormat.parseFormat(date1,dateformat1);
18803		var d2=DateFormat.parseFormat(date2,dateformat2);
18804		if (d1==0 || d2==0) return -1;
18805		else if (d1 > d2) return 1;
18806		return 0;
18807	},
18808	format: function(date,format) {
18809		format=format+"";
18810		var result="";
18811		var i_format=0;
18812		var c="";
18813		var token="";
18814		var y=date.getYear()+"";
18815		var M=date.getMonth()+1;
18816		var d=date.getDate();
18817		var E=date.getDay();
18818		var H=date.getHours();
18819		var m=date.getMinutes();
18820		var s=date.getSeconds();
18821		var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
18822		// Convert real date parts into formatted versions
18823		var value=new Object();
18824		if (y.length < 4) {y=""+(y-0+1900);}
18825		value["y"]=""+y;
18826		value["yyyy"]=y;
18827		value["yy"]=y.substring(2,4);
18828		value["M"]=M;
18829		value["MM"]=DateFormat.LZ(M);
18830		value["MMM"]=DateFormat.MONTH_NAMES[M-1];
18831		value["NNN"]=DateFormat.MONTH_NAMES[M+11];
18832		value["d"]=d;
18833		value["dd"]=DateFormat.LZ(d);
18834		value["E"]=DateFormat.DAY_NAMES[E+7];
18835		value["EE"]=DateFormat.DAY_NAMES[E];
18836		value["H"]=H;
18837		value["HH"]=DateFormat.LZ(H);
18838		if (H==0){value["h"]=12;}
18839		else if (H>12){value["h"]=H-12;}
18840		else {value["h"]=H;}
18841		value["hh"]=DateFormat.LZ(value["h"]);
18842		if (H>11){value["K"]=H-12;} else {value["K"]=H;}
18843		value["k"]=H+1;
18844		value["KK"]=DateFormat.LZ(value["K"]);
18845		value["kk"]=DateFormat.LZ(value["k"]);
18846		if (H > 11) { value["a"]="PM"; }
18847		else { value["a"]="AM"; }
18848		value["m"]=m;
18849		value["mm"]=DateFormat.LZ(m);
18850		value["s"]=s;
18851		value["ss"]=DateFormat.LZ(s);
18852		while (i_format < format.length) {
18853			c=format.charAt(i_format);
18854			token="";
18855			while ((format.charAt(i_format)==c) && (i_format < format.length))
18856				token += format.charAt(i_format++);
18857			if (value[token] != null) result += value[token];
18858			else result += token;
18859		}
18860		return result;
18861	},
18862	_isInteger: function(val) {
18863		var digits="1234567890";
18864		for (var i=0; i < val.length; i++)
18865			if (digits.indexOf(val.charAt(i))==-1) return false;
18866		return true;
18867	},
18868	_getInt: function(str,i,minlength,maxlength) {
18869		for (var x=maxlength; x>=minlength; x--) {
18870			var token=str.substring(i,i+x);
18871			if (token.length < minlength) return null;
18872			if (DateFormat._isInteger(token)) return token;
18873		}
18874		return null;
18875	},
18876	parseFormat: function(val,format) {
18877		val=val+"";
18878		format=format+"";
18879		var i_val=0;
18880		var i_format=0;
18881		var c="";
18882		var token="";
18883		var token2="";
18884		var x,y;
18885		var now=new Date();
18886		var year=now.getYear();
18887		var month=now.getMonth()+1;
18888		var date=1;
18889		var hh=now.getHours();
18890		var mm=now.getMinutes();
18891		var ss=now.getSeconds();
18892		var ampm="";
18893		
18894		while (i_format < format.length) {
18895			// Get next token from format string
18896			c=format.charAt(i_format);
18897			token="";
18898			while ((format.charAt(i_format)==c) && (i_format < format.length))
18899				token += format.charAt(i_format++);
18900			// Extract contents of value based on format token
18901			if (token=="yyyy" || token=="yy" || token=="y") {
18902				if (token=="yyyy") x=4;y=4;
18903				if (token=="yy") x=2;y=2;
18904				if (token=="y") x=2;y=4;
18905				year=DateFormat._getInt(val,i_val,x,y);
18906				if (year==null) return 0;
18907				i_val += year.length;
18908				if (year.length==2) {
18909					if (year > 70) year=1900+(year-0);
18910					else year=2000+(year-0);
18911				}
18912			} else if (token=="MMM"||token=="NNN") {
18913				month=0;
18914				for (var i=0; i<DateFormat.MONTH_NAMES.length; i++) {
18915					var month_name=DateFormat.MONTH_NAMES[i];
18916					if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
18917						if (token=="MMM"||(token=="NNN"&&i>11)) {
18918							month=i+1;
18919							if (month>12) month -= 12;
18920							i_val += month_name.length;
18921							break;
18922						}
18923					}
18924				}
18925				if ((month < 1)||(month>12)) return 0;
18926			} else if (token=="EE"||token=="E") {
18927				for (var i=0; i<DateFormat.DAY_NAMES.length; i++) {
18928					var day_name=DateFormat.DAY_NAMES[i];
18929					if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
18930						i_val += day_name.length;
18931						break;
18932					}
18933				}
18934			} else if (token=="MM"||token=="M") {
18935				month=DateFormat._getInt(val,i_val,token.length,2);
18936				if(month==null||(month<1)||(month>12)) return 0;
18937				i_val+=month.length;
18938			} else if (token=="dd"||token=="d") {
18939				date=DateFormat._getInt(val,i_val,token.length,2);
18940				if(date==null||(date<1)||(date>31)) return 0;
18941				i_val+=date.length;
18942			} else if (token=="hh"||token=="h") {
18943				hh=DateFormat._getInt(val,i_val,token.length,2);
18944				if(hh==null||(hh<1)||(hh>12)) return 0;
18945				i_val+=hh.length;
18946			} else if (token=="HH"||token=="H") {
18947				hh=DateFormat._getInt(val,i_val,token.length,2);
18948				if(hh==null||(hh<0)||(hh>23)) return 0;
18949				i_val+=hh.length;
18950			} else if (token=="KK"||token=="K") {
18951				hh=DateFormat._getInt(val,i_val,token.length,2);
18952				if(hh==null||(hh<0)||(hh>11)) return 0;
18953				i_val+=hh.length;
18954			} else if (token=="kk"||token=="k") {
18955				hh=DateFormat._getInt(val,i_val,token.length,2);
18956				if(hh==null||(hh<1)||(hh>24)) return 0;
18957				i_val+=hh.length;hh--;
18958			} else if (token=="mm"||token=="m") {
18959				mm=DateFormat._getInt(val,i_val,token.length,2);
18960				if(mm==null||(mm<0)||(mm>59)) return 0;
18961				i_val+=mm.length;
18962			} else if (token=="ss"||token=="s") {
18963				ss=DateFormat._getInt(val,i_val,token.length,2);
18964				if(ss==null||(ss<0)||(ss>59)) return 0;
18965				i_val+=ss.length;
18966			} else if (token=="a") {
18967				if (val.substring(i_val,i_val+2).toLowerCase()=="am") ampm="AM";
18968				else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") ampm="PM";
18969				else return 0;
18970				i_val+=2;
18971			} else {
18972				if (val.substring(i_val,i_val+token.length)!=token) return 0;
18973				else i_val+=token.length;
18974			}
18975		}
18976		// If there are any trailing characters left in the value, it doesn't match
18977		if (i_val != val.length) return 0;
18978		// Is date valid for month?
18979		if (month==2) {
18980			// Check for leap year
18981			if (((year%4==0)&&(year%100 != 0)) || (year%400==0)) { // leap year
18982				if (date > 29) return 0;
18983			} else if (date > 28) {
18984				return 0;
18985			}
18986		}
18987		if ((month==4)||(month==6)||(month==9)||(month==11))
18988			if (date > 30) return 0;
18989		// Correct hours value
18990		if (hh<12 && ampm=="PM") hh=hh-0+12;
18991		else if (hh>11 && ampm=="AM") hh-=12;
18992		var newdate=new Date(year,month-1,date,hh,mm,ss);
18993		return newdate;
18994	},
18995	parse: function(val, format) {
18996		if (format) {
18997			return DateFormat.parseFormat(val, format);
18998		} else {
18999			var preferEuro=(arguments.length==2)?arguments[1]:false;
19000			var generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d');
19001			var monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d');
19002			var dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M');
19003			var checkList=[generalFormats,preferEuro?dateFirst:monthFirst,preferEuro?monthFirst:dateFirst];
19004			var d=null;
19005			for (var i=0; i<checkList.length; i++) {
19006				var l=checkList[i];
19007				for (var j=0; j<l.length; j++) {
19008					d=DateFormat.parseFormat(val,l[j]);
19009					if (d!=0) return new Date(d);
19010				}
19011			}
19012			return null;
19013		}
19014	}
19015});
19016
19017DateFormat.prototype = {
19018	initialize: function(format) { this.format = format; },
19019	parse: function(value) { return DateFormat.parseFormat(value, this.format); },
19020	format: function(value) { return DateFormat.format(value, this.format); }
19021}
19022
19023Date.prototype.format = function(format) {
19024	return DateFormat.format(this, format);
19025}
19026/*
19027 * Control.DatePicker
19028 *
19029 * Transforms an ordinary input textbox into an interactive date picker.
19030 * When the textbox is clicked (or the down arrow is pressed), a calendar
19031 * appears that the user can browse through and select a date.
19032 *
19033 * Features:
19034 *  - Allows user to specify a date format
19035 *  - Easy to localize
19036 *  - Customizable by CSS
19037 *
19038 * Written and maintained by Jeremy Jongsma ([email protected])
19039 */
19040if (window.Control == undefined) Control = {};
19041
19042Control.DatePicker = Class.create();
19043Control.DatePicker.activePicker = null;
19044Control.DatePicker.prototype = {
19045	initialize: function(element, options) {
19046		this.element = $(element);
19047		this.i18n = new Control.DatePicker.i18n(options && options.locale ? options.locale : 'eu_US');
19048		options = this.i18n.inheritOptions(options);
19049		options = Object.extend({
19050						datePicker: true,
19051						timePicker: false
19052					}, options || {});
19053
19054		this.handlers = { onClick: options.onClick,
19055				onHover: options.onHover,
19056				onSelect: options.onSelect };
19057
19058		this.options = Object.extend(options || {}, {
19059				onClick: this.pickerClicked.bind(this),
19060				onHover: this.dateHover.bind(this),
19061				onSelect: this.datePicked.bind(this)
19062			});
19063
19064		if (this.options.timePicker && this.options.datePicker)
19065			this.options.currentFormat = this.options.dateTimeFormat;
19066		else if (this.options.timePicker)
19067			this.options.currentFormat = this.options.timeFormat;
19068		else
19069			this.options.currentFormat = this.options.dateFormat;
19070		
19071		this.options.currentFormat == this.options.timePicker ? this.options.dateTimeFormat : this.options.dateFormat;
19072		this.options.date = DateFormat.parseFormat(this.element.value, this.options.currentFormat);
19073		
19074		// Lazy load to avoid excessive CPU usage with lots of controls on one page
19075		this.datepicker = null;
19076
19077		this.originalValue = null;
19078		this.hideTimeout = null;
19079
19080		if (this.options.icon) {
19081			this.element.style.background = 'url('+this.options.icon+') right center no-repeat #FFF';
19082			// Prevent text writing over icon
19083			this.element.style.paddingRight = '20px';
19084		}
19085		
19086		// Popravek Tomaž
19087		if(this.options.dblClick)
19088			Event.observe(this.element, 'dblclick', this.togglePicker.bindAsEventListener(this));
19089		else
19090			Event.observe(this.element, 'click', this.togglePicker.bindAsEventListener(this));
19091
19092		this.hidePickerListener = this.delayedHide.bindAsEventListener(this);
19093		Event.observe(this.element, 'keydown', this.keyHandler.bindAsEventListener(this));
19094		Event.observe(document, 'keydown', this.docKeyHandler.bindAsEventListener(this));
19095
19096		// Boogie - dodamo event observerje za formatiranje datumov in časov
19097		if ((this.options.datePicker) && (!this.options.timePicker)) {
19098			// Datumsko polje
19099			// alert(this.element.tagName+":"+this.element.id) ;
19100			Event.observe(this.element, 'change', function() { DateValid(this); });
19101		} else if ((!this.options.datePicker) && (this.options.timePicker)) {
19102			// Časovno polje
19103			Event.observe(this.element, 'change', function () {HourValid(this); });
19104		} else if ((this.options.datePicker) && (this.options.timePicker)) {
19105			// FIXME Event se požene dvakrat, bi bilo fino preveriti zakaj.
19106			Event.observe(this.element, 'change', function () {DateHourValid(this); });
19107		}
19108
19109		this.pickerActive = false;
19110	},
19111	tr: function(str) {
19112		return this.i18n.tr(str);
19113	},
19114	delayedHide: function(e) {
19115		this.hideTimeout = setTimeout(this.hide.bind(this), 100);
19116	},
19117	pickerClicked: function() {
19118		if (this.hideTimeout) {
19119			clearTimeout(this.hideTimeout);
19120			this.hideTimeout = null;
19121		}
19122		if (this.handlers.onClick)
19123			this.handlers.onClick();
19124	},
19125	datePicked: function(date) {
19126		this.element.value = DateFormat.format(date, this.options.currentFormat);
19127		
19128		this.element.focus();
19129		this.hide();
19130		if (this.handlers.onSelect)
19131			this.handlers.onSelect(date);
19132		if (this.element.onchange)
19133			this.element.onchange();
19134	},
19135	dateHover: function(date) {
19136		if (this.hideTimeout) {
19137			clearTimeout(this.hideTimeout);
19138			this.hideTimeout = null;
19139		}
19140		if (this.pickerActive) {
19141			this.element.value = DateFormat.format(date, this.options.currentFormat);
19142			if (this.handlers.onHover)
19143				this.handlers.onHover(date);
19144		}
19145	},
19146	togglePicker: function(e) {
19147		if (this.pickerActive) {
19148			this.element.value = this.originalValue;
19149			this.hide();
19150		} else {
19151			this.show();
19152		}
19153		Event.stop(e);
19154		return false;
19155	},
19156	docKeyHandler: function(e) {
19157		if (e.keyCode == Event.KEY_ESC)
19158			if (this.pickerActive) {
19159				this.element.value = this.originalValue;
19160				this.hide();
19161			}
19162
19163	},
19164	keyHandler: function(e) {
19165		switch (e.keyCode) {
19166			case Event.KEY_ESC:
19167				if (this.pickerActive)
19168					this.element.value = this.originalValue;
19169			case Event.KEY_TAB:
19170				this.hide();
19171				return;
19172			case Event.KEY_DOWN:
19173				if (!this.pickerActive) {
19174					this.show();
19175					Event.stop(e);
19176				}
19177		}
19178		if (this.pickerActive)
19179			return false;
19180	},
19181	hide: function() {
19182		if(this.pickerActive && !this.element.disabled) {
19183			this.datepicker.releaseKeys();
19184			Element.remove(this.datepicker.element);
19185			Event.stopObserving(document, 'click', this.hidePickerListener, true);
19186			this.pickerActive = false;
19187			Control.DatePicker.activePicker = null;
19188		}
19189	},
19190	scrollOffset: function(element) {
19191		var valueT = 0, valueL = 0;
19192		do {
19193			if (element.tagName == 'BODY') break;
19194			valueT += element.scrollTop  || 0;
19195			valueL += element.scrollLeft || 0;
19196			element = element.parentNode;
19197		} while (element);
19198		return Element._returnOffset(valueL, valueT);
19199	},
19200	show: function () {
19201		if (!this.pickerActive && !this.element.disabled && !this.element.readOnly) {
19202			if (Control.DatePicker.activePicker)
19203				Control.DatePicker.activePicker.hide();
19204			this.element.focus();
19205			if (!this.datepicker)
19206				this.datepicker = new Control.DatePickerPanel(this.options);
19207			this.originalValue = this.element.value;
19208
19209			// Find real page position
19210			/*
19211			var pos = this.element.cumulativeOffset();
19212			if (!/MSIE 8/.test(navigator.userAgent)) {
19213				// IE seems to account for scrollTop in offsetTop already
19214				var scroll = this.scrollOffset(this.element);
19215				pos[0] -= scroll[0] + document.body.scrollTop;
19216				pos[1] -= scroll[1] + document.body.scrollLeft;
19217			}
19218			*/
19219			var pos = Position.positionedOffset(this.element);
19220			var dim = Element.getDimensions(this.element);
19221			var pickerTop = /MSIE/.test(navigator.userAgent) ? (pos[1] + dim.height) + 'px' : (pos[1] + dim.height - 1) + 'px';
19222			this.datepicker.element.style.position = 'absolute';
19223			this.datepicker.element.style.top = pickerTop;
19224			this.datepicker.element.style.left = pos[0] + 'px';
19225			this.datepicker.element.style.zIndex = '60001';
19226			this.datepicker.selectDate(DateFormat.parseFormat(this.element.value, this.options.currentFormat));
19227			this.datepicker.captureKeys();
19228
19229			this.element.parentNode.appendChild(this.datepicker.element);
19230			Event.observe(document, 'click', this.hidePickerListener, true);
19231			this.pickerActive = true;
19232			Control.DatePicker.activePicker = this;
19233			this.pickerClicked();
19234		}
19235	}
19236};
19237
19238Control.DatePicker.i18n = Class.create();
19239Object.extend(Control.DatePicker.i18n, {
19240	baseLocales: {
19241		'us': {
19242			dateTimeFormat: 'MM-dd-yyyy HH:mm',
19243			dateFormat: 'MM-dd-yyyy',
19244			firstWeekDay: 0,
19245			weekend: [0,6],
19246			timeFormat: 'HH:mm'
19247		},
19248		'eu': {
19249			dateTimeFormat: 'dd.MM.yyyy HH:mm',
19250			dateFormat: 'dd.MM.yyyy',
19251			firstWeekDay: 1,
19252			weekend: [0,6],
19253			timeFormat: 'HH:mm'
19254		},
19255		'iso8601': {
19256			dateTimeFormat: 'yyyy-MM-dd HH:mm',
19257			dateFormat: 'yyyy-MM-dd',
19258			firstWeekDay: 1,
19259			weekend: [0,6],
19260			timeFormat: 'HH:mm'
19261		}
19262	},
19263	createLocale: function(base, lang) {
19264		return Object.extend(Object.clone(Control.DatePicker.i18n.baseLocales[base]), {'language': lang});
19265	}
19266});
19267Control.DatePicker.i18n.prototype = {
19268	initialize: function(code) {
19269		var lang = code.charAt(2) == '_' ? code.substring(0,2) : code;
19270		var locale = (Control.DatePicker.Locale[code] || Control.DatePicker.Locale[lang]);
19271		this.opts = Object.clone(locale || {});
19272		var language = locale ? Control.DatePicker.Language[locale.language] : null;
19273		if (language) Object.extend(this.opts, language);
19274	},
19275	opts: null,
19276	inheritOptions: function(options) {
19277		if (!this.opts) this.setLocale('en_US');
19278		return Object.extend(this.opts, options || {});
19279	},
19280	tr: function(str) {
19281		return this.opts && this.opts.strings ? this.opts.strings[str] || str : str;
19282	}
19283};
19284
19285Control.DatePicker.Locale = {};
19286with (Control.DatePicker) {
19287	// Full locale definitions not needed if countries use the language default format
19288	// Datepicker will fallback to the language default; i.e. 'es_AR' will use 'es'
19289	Locale['sl'] = i18n.createLocale('eu', 'sl');
19290	Locale['es'] = i18n.createLocale('eu', 'es');
19291	Locale['en'] = i18n.createLocale('us', 'en');
19292	Locale['en_GB'] = i18n.createLocale('eu', 'en');
19293	Locale['en_AU'] = Locale['en_GB'];
19294	Locale['de'] = i18n.createLocale('eu', 'de');
19295	Locale['es_iso8601'] = i18n.createLocale('iso8601', 'es');
19296	Locale['en_iso8601'] = i18n.createLocale('iso8601', 'en');
19297	Locale['de_iso8601'] = i18n.createLocale('iso8601', 'de');
19298}
19299
19300Control.DatePicker.Language = {
19301	'es': {
19302		months: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Augosto', '
19302Septiembre', 'Octubre', 'Novimbre', 'Diciembre'],
19303		days: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sa'],
19304		strings: {
19305			'Now': 'Ahora',
19306			'Today': 'Hoy',
19307			'Time': 'Hora',
19308			'Exact minutes': 'Minuto exacto',
19309			'Select Date and Time': 'Selecciona Dia y Hora',
19310			'Select Time': 'Selecciona Hora',
19311			'Open calendar': 'Abre calendario'
19312		}
19313	},
19314	'de': {
19315		months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
19316		days: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
19317		strings: {
19318			'Now': 'Jetzt',
19319			'Today': 'Heute',
19320			'Time': 'Zeit',
19321			'Exact minutes': 'Exakte minuten',
19322			'Select Date and Time': 'Zeit und Datum Auswählen',
19323			'Select Time': 'Zeit Auswählen',
19324			'Open calendar': 'Kalender öffnen'
19325		}
19326	},
19327	'sl': {
19328		months: ['Januar', 'Februar', 'Marec', 'April', 'Maj', 'Junij', 'Julij', 'Avgust', 'September', 'Oktober', 'November', 'December'],
19329		days: ['Ne', 'Po', 'To', 'Sr', 'Če', 'Pe', 'So'],
19330		strings: {
19331			'Now': 'Sedaj',
19332			'Today': 'Danes',
19333			'Time': 'Čas',
19334			'Exact minutes': 'Natančno minut',
19335			'Select Date and Time': 'Izberi datum in čas',
19336			'Select Time': 'Izberi čas',
19337			'Open calendar': 'Odpri koledar'
19338		}
19339	}
19340};
19341
19342Control.DatePickerPanel = Class.create();
19343Object.extend(Control.DatePickerPanel.prototype, {
19344	initialize: function(options) {
19345		this.i18n = new Control.DatePicker.i18n(options && options.locale ? options.locale : 'en_US');
19346		options = this.i18n.inheritOptions(options);
19347		this.options = Object.extend({
19348						className: 'datepickerControl',
19349						closeOnToday: true,
19350						selectToday: true,
19351						showOnFocus: false,
19352						datePicker: true,
19353						timePicker: false,
19354						use24hrs: false,
19355						firstWeekDay: 0,
19356						weekend: [0,6],
19357						months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
19358						days: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']
19359					}, options || {});
19360		// Make sure first weekday is in the correct range
19361		with (this.options)
19362			if (isNaN(firstWeekDay*1)) firstWeekDay = 0;
19363			else firstWeekDay = firstWeekDay % 7;
19364
19365		this.keysCaptured = false;
19366		this.calendarCont = null;
19367		this.currentDate = this.options.date ? this.options.date : new Date();
19368		this.dayOfWeek = 0;
19369		this.minInterval = 5;
19370
19371		this.selectedDay = null;
19372		this.selectedHour = null;
19373		this.selectedMinute = null;
19374		this.selectedAmPm = null;
19375
19376		this.currentDays = [];
19377		this.hourCells = [];
19378		this.minuteCells = [];
19379		this.otherMinutes = null;
19380		this.amCell = null;
19381		this.pmCell = null;
19382
19383		this.element = this.createPicker();
19384		this.selectDate(this.currentDate);
19385	},
19386	createPicker: function() {
19387		var elt = document.createElement('div');
19388		elt.style.position = 'absolute';
19389		elt.className = this.options.className;
19390		this.calendarCont = this.drawCalendar(elt, this.currentDate);
19391
19392		Event.observe(elt, 'click', this.clickHandler.bindAsEventListener(this));
19393		Event.observe(elt, 'dblclick', this.dblClickHandler.bindAsEventListener(this));
19394		this.documentKeyListener = this.keyHandler.bindAsEventListener(this);
19395		if (this.options.captureKeys)
19396			this.captureKeys();
19397
19398		return elt;
19399	},
19400	tr: function(str) {
19401		return this.i18n.tr(str);
19402	},
19403	captureKeys: function() {
19404		Event.observe(document, 'keydown', this.documentKeyListener, true);
19405		this.keysCaptured = true;
19406	},
19407	releaseKeys: function() {
19408		Event.stopObserving(document, 'keydown', this.documentKeyListener, true);
19409		this.keysCaptured = false;
19410	},
19411	setDate: function(date) {
19412		if (date) {
19413			// Clear container
19414			while (this.element.firstChild)
19415				this.element.removeChild(this.element.firstChild);
19416			this.calendarCont = this.drawCalendar(this.element, date);
19417		}
19418	},
19419	drawCalendar: function(container, date) {
19420		var calCont = container;
19421		if (!this.options.datePicker) {
19422			var calTable =  document.createElement('table');
19423			calTable.cellSpacing = 0;
19424			calTable.cellPadding = 0;
19425			calTable.border = 0;
19426		} else {
19427			var calTable = this.createCalendar(date);
19428		}
19429
19430		var rowwidth = this.options.use24hrs ? 6 : 7;
19431		if (this.options.timePicker) {
19432			var timeTable;
19433			if (this.options.timePickerAdjacent && this.options.datePicker) {
19434				var rows = 0;
19435
19436				var adjTable = document.createElement('table');
19437				adjTable.cellSpacing = 0;
19438				adjTable.cellPadding = 0;
19439				adjTable.border = 0;
19440
19441				row = adjTable.insertRow(0);
19442
19443				cell = row.insertCell(0);
19444				cell.vAlign = 'top';
19445				cell.appendChild(calTable);
19446				calCont = cell;
19447
19448				cell = row.insertCell(1);
19449				cell.style.width = '5px';
19450
19451				cell = row.insertCell(2);
19452				cell.vAlign = 'top';
19453				timeTable = document.createElement('table');
19454				timeTable.cellSpacing = 0;
19455				timeTable.cellPadding = 0;
19456				timeTable.border = 0;
19457				cell.appendChild(timeTable);
19458
19459				container.appendChild(adjTable);
19460
19461				row = timeTable.insertRow(rows++);
19462				row.className = 'monthLabel';
19463				cell = row.insertCell(0);
19464				cell.colSpan = rowwidth;
19465				cell.innerHTML = this.tr('Time');
19466
19467				row = timeTable.insertRow(rows++);
19468				cell = row.insertCell(0);
19469				cell.colSpan = rowwidth;
19470				cell.style.height = '1px';
19471
19472			} else {
19473				container.appendChild(calTable);
19474				timeTable = calTable;
19475				var rows = calTable.rows.length;
19476
19477				if (this.options.datePicker) {
19478					row = timeTable.insertRow(rows++);
19479					cell = row.insertCell(0);
19480					cell.colSpan = rowwidth;
19481
19482					var hr = document.createElement('hr');
19483					Element.setStyle(hr, {'color': 'gray', 'backgroundColor': 'gray', 'height': '1px', 'border': '0', 'marginTop': '3px', 'marginBottom': '3px', 'padding': '0'});
19484					cell.appendChild(hr);
19485				}
19486			}
19487
19488			var hourrows = this.options.use24hrs ? 4 : 2;
19489			for (var j = 0; j < hourrows; ++j) {
19490				row = timeTable.insertRow(rows++);
19491				for (var i = 0; i < 6; ++i){
19492					cell = row.insertCell(i);
19493					cell.className = 'hour';
19494					cell.width = '14%';
19495					cell.innerHTML = (j*6)+i+(this.options.use24hrs?0:1);
19496					cell.onclick = this.hourClickedListener((j*6)+i+(this.options.use24hrs?0:1));
19497					this.hourCells[(j*6)+i] = cell;
19498				}
19499				if (!this.options.use24hrs) {
19500					cell = row.insertCell(i);
19501					cell.className = 'ampm';
19502					cell.width = '14%';
19503					if (j) {
19504						cell.innerHTML = this.tr('PM');
19505						cell.onclick = this.pmClickedListener();
19506						this.pmCell = cell;
19507					} else {
19508						cell.innerHTML = this.tr('AM');
19509						cell.onclick = this.amClickedListener();
19510						this.amCell = cell;
19511					}
19512				}
19513			}
19514
19515			row = timeTable.insertRow(rows++);
19516			cell = row.insertCell(0);
19517			cell.colSpan = 6;
19518
19519			var hr = document.createElement('hr');
19520			Element.setStyle(hr, {'color': '#CCCCCC', 'backgroundColor': '#CCCCCC', 'height': '1px', 'border': '0', 'marginTop': '2px', 'marginBottom': '2px', 'padding': '0'});
19521			cell.appendChild(hr);
19522			// cell = row.insertCell(1);
19523
19524			for (var j = 0; j < (10/this.minInterval); ++j) {
19525				row = timeTable.insertRow(rows++);
19526				for (var i = 0; i < 6; ++i){
19527					cell = row.insertCell(i);
19528					cell.className = 'minute';
19529					cell.width = '14%';
19530					var minval = ((j*6+i)*this.minInterval);
19531					if (minval < 10) minval = '0'+minval;
19532					cell.innerHTML = ':'+minval;
19533					cell.onclick = this.minuteClickedListener(minval);
19534					this.minuteCells[(j*6)+i] = cell;
19535				}
19536				if (!this.options.use24hrs) {
19537					cell = row.insertCell(i);
19538					cell.width = '14%';
19539				}
19540			}
19541
19542			row = timeTable.insertRow(rows++);
19543			cell = row.insertCell(0);
19544			cell.style.textAlign = 'right';
19545			cell.colSpan = 5;
19546			cell.innerHTML = '<i>'+this.tr('Exact minutes')+':</i>';
19547
19548			cell = row.insertCell(1);
19549			cell.className = 'otherminute';
19550			var otherInput = document.createElement('input');
19551			otherInput.type = 'text';
19552			otherInput.maxLength = 2;
19553			otherInput.style.width = '2em';
19554			var inputTimeout = null;
19555			otherInput.onkeyup = function(e) {
19556						if (!isNaN(otherInput.value)) {
19557							inputTimeout = setTimeout(function() {
19558									this.currentDate.setMinutes(otherInput.value);
19559									this.dateChanged(this.currentDate);
19560								}.bind(this), 500);
19561						}
19562					}.bindAsEventListener(this);
19563			otherInput.onkeydown = function(e) {
19564						if (e.keyCode == Event.KEY_RETURN)
19565							if (this.options.onSelect) this.options.onSelect(this.currentDate);
19566						if (inputTimeout)
19567							clearTimeout(inputTimeout)
19568					}.bindAsEventListener(this);
19569			// Remove event key capture to allow use of arrow keys
19570			otherInput.onclick = otherInput.select;
19571			otherInput.onfocus = this.releaseKeys.bindAsEventListener(this);
19572			otherInput.onblur = this.captureKeys.bindAsEventListener(this);
19573			this.otherMinutes = otherInput;
19574			cell.appendChild(otherInput);
19575			// Padding cell
19576			if (!this.options.use24hrs)
19577				cell = row.insertCell(2);
19578
19579			row = timeTable.insertRow(rows++);
19580			cell = row.insertCell(0);
19581			cell.colSpan = rowwidth;
19582
19583			hr = document.createElement('hr');
19584			Element.setStyle(hr, {'color': 'gray', 'backgroundColor': 'gray', 'height': '1px', 'border': '0', 'marginTop': '3px', 'marginBottom': '3px', 'padding': '0'});
19585			cell.appendChild(hr);
19586
19587			row = timeTable.insertRow(rows++);
19588			cell = row.insertCell(0);
19589			cell.colSpan = rowwidth;
19590
19591			selectButton = document.createElement('input');
19592			selectButton.type = 'button';
19593			if (this.options.datePicker)
19594				selectButton.value = this.tr('Select Date and Time');
19595			else
19596				selectButton.value = this.tr('Select Time');
19597			selectButton.onclick = function(e) {
19598						this.options.onSelect && this.options.onSelect(this.currentDate);
19599					}.bindAsEventListener(this);
19600			cell.appendChild(selectButton);
19601
19602		} else {
19603			calCont.appendChild(calTable);
19604		}
19605
19606		return calCont;
19607
19608	},
19609	createCalendar: function(date) {
19610		this.currentDate = date;
19611		this.currentDays = [];
19612
19613		var today = new Date();
19614		var previousYear = new Date(date.getFullYear() - 1, date.getMonth(), 1)
19615		var previousMonth = new Date(date.getFullYear(), date.getMonth() - 1, 1)
19616		var nextMonth = new Date(date.getFullYear(), date.getMonth() + 1, 1)
19617		var nextYear = new Date(date.getFullYear() + 1, date.getMonth(), 1)
19618
19619		var row;
19620		var cell;
19621		var rows = 0;
19622
19623		var calTable = document.createElement('table');
19624		calTable.cellSpacing = 0;
19625		calTable.cellPadding = 0;
19626		calTable.border = 0;
19627
19628		row = calTable.insertRow(rows++);
19629		row.className = 'monthLabel';
19630		cell = row.insertCell(0);
19631		cell.colSpan = 7;
19632		cell.innerHTML = this.monthName(date.getMonth()) + ' ' + date.getFullYear();
19633
19634		row = calTable.insertRow(rows++);
19635		row.className = 'navigation';
19636
19637		cell = row.insertCell(0);
19638		cell.className = 'navbutton';
19639		cell.title = this.monthName(previousYear.getMonth()) + ' ' + previousYear.getFullYear();
19640		cell.onclick = this.movePreviousYearListener();
19641		cell.innerHTML = '&lt;&lt;';
19642
19643		cell = row.insertCell(1);
19644		cell.className = 'navbutton';
19645		cell.title = this.monthName(previousMonth.getMonth()) + ' ' + previousMonth.getFullYear();
19646		cell.onclick = this.movePreviousMonthListener();
19647		cell.innerHTML = '&lt;';
19648
19649		cell = row.insertCell(2);
19650		cell.colSpan = 3;
19651		cell.className = 'navbutton';
19652		cell.title = today.getDate() + ' ' + this.monthName(today.getMonth()) + ' ' + today.getFullYear();
19653		cell.onclick = this.dateClickedListener(today, true);
19654		if (this.options.timePicker)
19655			cell.innerHTML = this.tr('Now');
19656		else
19657			cell.innerHTML = this.tr('Today');
19658
19659		cell = row.insertCell(3);
19660		cell.className = 'navbutton';
19661		cell.title = this.monthName(nextMonth.getMonth()) + ' ' + nextMonth.getFullYear();
19662		cell.onclick = this.moveNextMonthListener();
19663		cell.innerHTML = '&gt;';
19664
19665		cell = row.insertCell(4);
19666		cell.className = 'navbutton';
19667		cell.title = this.monthName(nextYear.getMonth()) + ' ' + nextYear.getFullYear();
19668		cell.onclick = this.moveNextYearListener();
19669		cell.innerHTML = '&gt;&gt;';
19670
19671		row = calTable.insertRow(rows++);
19672		row.className = 'dayLabel';
19673		for (var i = 0; i < 7; ++i){
19674			cell = row.insertCell(i);
19675			cell.width = '14%';
19676			cell.innerHTML = this.dayName((this.options.firstWeekDay + i) % 7);
19677		}
19678
19679		row = null;
19680		var workDate = new Date(date.getFullYear(), date.getMonth(), 1);
19681		var day = workDate.getDay();
19682		var j = 0;
19683
19684		// Pad with previous month
19685		if (day != this.options.firstWeekDay) {
19686			row = calTable.insertRow(rows++);
19687			row.className = 'calendarRow';
19688			workDate.setDate(workDate.getDate() - ((day - this.options.firstWeekDay + 7) % 7));
19689			day = workDate.getDay();
19690			while (workDate.getMonth() != date.getMonth()) {
19691				cell = row.insertCell(row.cells.length);
19692				this.assignDayClasses(cell, 'dayothermonth', workDate);
19693				cell.innerHTML = workDate.getDate();
19694				cell.onclick = this.dateClickedListener(workDate);
19695				workDate.setDate(workDate.getDate() + 1);
19696				day = workDate.getDay();
19697			}
19698		}
19699
19700		// Display days
19701		while (workDate.getMonth() == date.getMonth()) {
19702			if (day == this.options.firstWeekDay) {
19703				row = calTable.insertRow(rows++);
19704				row.className = 'calendarRow';
19705			}
19706			cell = row.insertCell(row.cells.length);
19707			this.assignDayClasses(cell, 'day', workDate);
19708			cell.innerHTML = workDate.getDate();
19709			cell.onclick = this.dateClickedListener(workDate);
19710			this.currentDays[workDate.getDate()] = cell;
19711			workDate.setDate(workDate.getDate() + 1);
19712			day = workDate.getDay();
19713		}
19714
19715		// Pad with next month
19716		if (day != this.options.firstWeekDay)
19717			do {
19718				cell = row.insertCell(row.cells.length);
19719				this.assignDayClasses(cell, 'dayothermonth', workDate);
19720				cell.innerHTML = workDate.getDate();
19721				var thisDate = new Date(workDate.getTime());
19722				cell.onclick = this.dateClickedListener(workDate);
19723				workDate.setDate(workDate.getDate() + 1);
19724				day = workDate.getDay();
19725			} while (workDate.getDay() != this.options.firstWeekDay);
19726
19727		return calTable;
19728	},
19729	movePreviousMonthListener: function() {
19730		return function(e) {
19731				var prevMonth = new Date(
19732						this.currentDate.getFullYear(),
19733						this.currentDate.getMonth() - 1,
19734						this.currentDate.getDate(),
19735						this.currentDate.getHours(),
19736						this.currentDate.getMinutes());
19737				if (prevMonth.getMonth() != (this.currentDate.getMonth() + 11) % 12) prevMonth.setDate(0);
19738				this.selectDate(prevMonth);
19739			}.bindAsEventListener(this);
19740	},
19741	moveNextMonthListener: function() {
19742		return function(e) {
19743				var nextMonth = new Date(
19744						this.currentDate.getFullYear(),
19745						this.currentDate.getMonth() + 1,
19746						this.currentDate.getDate(),
19747						this.currentDate.getHours(),
19748						this.currentDate.getMinutes());
19749				if (nextMonth.getMonth() != (this.currentDate.getMonth() + 1) % 12) nextMonth.setDate(0);
19750				this.selectDate(nextMonth);
19751			}.bindAsEventListener(this);
19752	},
19753	moveNextYearListener: function() {
19754		return function(e) {
19755				var nextYear = new Date(
19756						this.currentDate.getFullYear() + 1,
19757						this.currentDate.getMonth(),
19758						this.currentDate.getDate(),
19759						this.currentDate.getHours(),
19760						this.currentDate.getMinutes());
19761				if (nextYear.getMonth() != this.currentDate.getMonth()) nextYear.setDate(0);
19762				this.selectDate(nextYear);
19763			}.bindAsEventListener(this);
19764	},
19765	movePreviousYearListener: function() {
19766		return function(e) {
19767				var prevYear = new Date(
19768						this.currentDate.getFullYear() - 1,
19769						this.currentDate.getMonth(),
19770						this.currentDate.getDate(),
19771						this.currentDate.getHours(),
19772						this.currentDate.getMinutes());
19773				if (prevYear.getMonth() != this.currentDate.getMonth()) prevYear.setDate(0);
19774				this.selectDate(prevYear);
19775			}.bindAsEventListener(this);
19776	},
19777	dateClickedListener: function(date, timeOverride) {
19778		var dateCopy = new Date(date.getTime());
19779		return function(e) {
19780				if (!timeOverride) {
19781					dateCopy.setHours(this.currentDate.getHours());
19782					dateCopy.setMinutes(this.currentDate.getMinutes());
19783				}
19784				this.dateClicked(dateCopy);
19785			}.bindAsEventListener(this);
19786	},
19787	hourClickedListener: function(hour) {
19788		return function(e) {
19789				this.hourClicked(hour);
19790			}.bindAsEventListener(this);
19791	},
19792	minuteClickedListener: function(minutes) {
19793		return function(e) {
19794				this.currentDate.setMinutes(minutes);
19795				this.dateClicked(this.currentDate);
19796			}.bindAsEventListener(this);
19797	},
19798	amClickedListener: function() {
19799		return function(e) {
19800				if (this.selectedAmPm == this.pmCell) {
19801					this.currentDate.setHours(this.currentDate.getHours()-12);
19802					this.dateClicked(this.currentDate);
19803				}
19804			}.bindAsEventListener(this);
19805	},
19806	pmClickedListener: function() {
19807		return function(e) {
19808				if (this.selectedAmPm == this.amCell) {
19809					this.currentDate.setHours(this.currentDate.getHours()+12);
19810					this.dateClicked(this.currentDate);
19811				}
19812			}.bindAsEventListener(this);
19813	},
19814	assignDayClasses: function(cell, baseClass, date) {
19815		var today = new Date();
19816		Element.addClassName(cell, baseClass);
19817		if (date.getFullYear() == today.getFullYear() && date.getMonth() == today.getMonth() && date.getDate() == today.getDate())
19818			Element.addClassName(cell, 'today');
19819		if (this.options.weekend.include(date.getDay()))
19820			Element.addClassName(cell, 'weekend');
19821	},
19822	monthName: function(month) {
19823		return this.options.months[month];
19824	},
19825	dayName: function(day) {
19826		return this.options.days[day];
19827	},
19828	dblClickHandler: function(e) {
19829		if(this.options.onSelect) {
19830			this.options.onSelect(this.currentDate);
19831		}
19832		Event.stop(e);
19833	},
19834	clickHandler: function(e) {
19835		if(this.options.onClick)
19836			this.options.onClick();
19837		Event.stop(e);
19838	},
19839	hoverHandler: function(e) {
19840		if(this.options.onHover)
19841			this.options.onHover(date);
19842	},
19843	keyHandler: function(e) {
19844		var days = 0;
19845		switch (e.keyCode){
19846			case Event.KEY_RETURN:
19847				if (this.options.onSelect) this.options.onSelect(this.currentDate);
19848				break;
19849			case Event.KEY_LEFT:
19850				days = -1;
19851				break;
19852			case Event.KEY_UP:
19853				days = -7;
19854				break;
19855			case Event.KEY_RIGHT:
19856				days = 1;
19857				break;
19858			case Event.KEY_DOWN:
19859				days = 7;
19860				break;
19861			case 33: // PgUp
19862				var lastMonth = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() - 1, this.currentDate.getDate());
19863				days = -this.getDaysOfMonth(lastMonth);
19864				break;
19865			case 34: // PgDn
19866				days = this.getDaysOfMonth(this.currentDate);
19867				break;
19868			case 13: // enter-key (forms without submit buttons)
19869				this.dateClicked(this.currentDate);
19870				break;
19871			default:
19872				return;
19873		}
19874		if (days != 0) {
19875			var moveDate = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), this.currentDate.getDate() + days);
19876			moveDate.setHours(this.currentDate.getHours());
19877			moveDate.setMinutes(this.currentDate.getMinutes());
19878			this.selectDate(moveDate);
19879		}
19880		Event.stop(e);
19881		return false;
19882	},
19883	getDaysOfMonth: function(date) {
19884		var lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0);
19885		return lastDay.getDate();
19886	},
19887	getNextMonth: function(month, year, increment) {
19888		if (p_Month == 11) return [0, year + 1];
19889		else return [month + 1, year];
19890	},
19891	getPrevMonth: function(month, year, increment) {
19892		if (p_Month == 0) return [11, year - 1];
19893		else return [month - 1, year];
19894	},
19895	dateClicked: function(date) {
19896		if (date) {
19897			if (!this.options.timePicker && this.options.onSelect)
19898				this.options.onSelect(date);
19899			this.selectDate(date);
19900		}
19901	},
19902	dateChanged: function(date) {
19903		if (date) {
19904			if ((!this.options.timePicker || !this.options.datePicker) && this.options.onHover)
19905				this.options.onHover(date);
19906			this.selectDate(date);
19907		}
19908	},
19909	hourClicked: function(hour) {
19910		if (!this.options.use24hrs) {
19911			if (hour == 12) {
19912				if (this.selectedAmPm == this.amCell)
19913					hour = 0;
19914			} else if (this.selectedAmPm == this.pmCell) {
19915				hour += 12;
19916			}
19917		}
19918		this.currentDate.setHours(hour);
19919		this.dateClicked(this.currentDate);
19920	},
19921	selectDate: function(date) {
19922		if (date) {
19923			if (this.options.datePicker) {
19924				if (date.getMonth() != this.currentDate.getMonth()
19925					|| date.getFullYear() != this.currentDate.getFullYear())
19926					this.setDate(date);
19927				else
19928					this.currentDate = date;
19929
19930				if (date.getDate() < this.currentDays.length) {
19931					if (this.selectedDay)
19932						Element.removeClassName(this.selectedDay, 'current');
19933					this.selectedDay = this.currentDays[date.getDate()];
19934					Element.addClassName(this.selectedDay, 'current');
19935				}
19936			}
19937
19938			if (this.options.timePicker) {
19939				var hours = date.getHours();
19940				if (this.selectedHour)
19941					Element.removeClassName(this.selectedHour, 'current');
19942				if (this.options.use24hrs)
19943					this.selectedHour = this.hourCells[hours];
19944				else
19945					this.selectedHour = this.hourCells[hours % 12 ? (hours % 12) - 1 : 11];
19946				Element.addClassName(this.selectedHour, 'current');
19947
19948				if (this.selectedAmPm)
19949					Element.removeClassName(this.selectedAmPm, 'current');
19950				this.selectedAmPm = (hours < 12 ? this.amCell : this.pmCell);
19951				Element.addClassName(this.selectedAmPm, 'current');
19952
19953				var minutes = date.getMinutes();
19954				if (this.selectedMinute)
19955					Element.removeClassName(this.selectedMinute, 'current');
19956				Element.removeClassName(this.otherMinutes, 'current');
19957				if (minutes % this.minInterval == 0) {
19958					this.otherMinutes.value = '';
19959					this.selectedMinute = this.minuteCells[minutes / this.minInterval];
19960					Element.addClassName(this.selectedMinute, 'current');
19961				} else {
19962					this.otherMinutes.value = minutes;
19963					Element.addClassName(this.otherMinutes, 'current');
19964				}
19965			}
19966
19967			if (this.options.onHover)
19968				this.options.onHover(date);
19969		}
19970	}
19971});
19972/**
19973* @author Ryan Johnson <http://syntacticx.com/>
19974* @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
19975* @package LivePipe UI
19976* @license MIT
19977* @url http://livepipe.net/core
19978* @require prototype.js
19979*/
19980
19981if(typeof(Control) == 'undefined')
19982	Control = {};
19983
19984var $proc = function(proc){
19985	return typeof(proc) == 'function' ? proc : function(){return proc};
19986};
19987
19988var $value = function(value){
19989	return typeof(value) == 'function' ? value() : value;
19990};
19991
19992Object.Event = {
19993	extend: function(object){
19994		object._objectEventSetup = function(event_name){
19995			this._observers = this._observers || {};
19996			this._observers[event_name] = this._observers[event_name] || [];
19997		};
19998		object.observe = function(event_name,observer){
19999			if(typeof(event_name) == 'string' && typeof(observer) != 'undefined'){
20000				this._objectEventSetup(event_name);
20001				if(!this._observers[event_name].include(observer))
20002					this._observers[event_name].push(observer);
20003			}else
20004				for(var e in event_name)
20005					this.observe(e,event_name[e]);
20006		};
20007		object.stopObserving = function(event_name,observer){
20008			this._objectEventSetup(event_name);
20009			if(event_name && observer)
20010				this._observers[event_name] = this._observers[event_name].without(observer);
20011			else if(event_name)
20012				this._observers[event_name] = [];
20013			else
20014				this._observers = {};
20015		};
20016		object.observeOnce = function(event_name,outer_observer){
20017			var inner_observer = function(){
20018				outer_observer.apply(this,arguments);
20019				this.stopObserving(event_name,inner_observer);
20020			}.bind(this);
20021			this._objectEventSetup(event_name);
20022			this._observers[event_name].push(inner_observer);
20023		};
20024		object.notify = function(event_name){
20025			this._objectEventSetup(event_name);
20026			var collected_return_values = [];
20027			var args = $A(arguments).slice(1);
20028			try{
20029				for(var i = 0; i < this._observers[event_name].length; ++i)
20030					collected_return_values.push(this._observers[event_name][i].apply(this,args) || null);
20031			}catch(e){
20032				if(e == $break)
20033					return false;
20034				else
20035					throw e;
20036			}
20037			return collected_return_values;
20038		};
20039		if(object.prototype){
20040			object.prototype._objectEventSetup = object._objectEventSetup;
20041			object.prototype.observe = object.observe;
20042			object.prototype.stopObserving = object.stopObserving;
20043			object.prototype.observeOnce = object.observeOnce;
20044			object.prototype.notify = function(event_name){
20045				if(object.notify){
20046					var args = $A(arguments).slice(1);
20047					args.unshift(this);
20048					args.unshift(event_name);
20049					object.notify.apply(object,args);
20050				}
20051				this._objectEventSetup(event_name);
20052				var args = $A(arguments).slice(1);
20053				var collected_return_values = [];
20054				try{
20055					if(this.options && this.options[event_name] && typeof(this.options[event_name]) == 'function')
20056						collected_return_values.push(this.options[event_name].apply(this,args) || null);
20057					var callbacks_copy = this._observers[event_name]; // since original array will be modified after observeOnce calls
20058					for(var i = 0; i < callbacks_copy.length; ++i)
20059						collected_return_values.push(callbacks_copy[i].apply(this,args) || null);
20060				}catch(e){
20061					if(e == $break)
20062						return false;
20063					else
20064						throw e;
20065				}
20066				return collected_return_values;
20067			};
20068		}
20069	}
20070};
20071
20072/* Begin Core Extensions */
20073
20074//Element.observeOnce
20075Element.addMethods({
20076	observeOnce: function(element,event_name,outer_callback){
20077		var inner_callback = function(){
20078			outer_callback.apply(this,arguments);
20079			Element.stopObserving(element,event_name,inner_callback);
20080		};
20081		Element.observe(element,event_name,inner_callback);
20082	}
20083});
20084
20085//mouse:wheel
20086(function(){
20087	function wheel(event){
20088		var delta, element, custom_event;
20089		// normalize the delta
20090		if (event.wheelDelta) { // IE & Opera
20091			delta = event.wheelDelta / 120;
20092		} else if (event.detail) { // W3C
20093			delta =- event.detail / 3;
20094		}
20095		if (!delta) { return; }
20096		element = Event.extend(event).target;
20097		element = Element.extend(element.nodeType === Node.TEXT_NODE ? element.parentNode : element);
20098		custom_event = element.fire('mouse:wheel',{ delta: delta });
20099		if (custom_event.stopped) {
20100			Event.stop(event);
20101			return false;
20102		}
20103	}
20104	document.observe('mousewheel',wheel);
20105	document.observe('DOMMouseScroll',wheel);
20106})();
20107
20108/* End Core Extensions */
20109
20110//from PrototypeUI
20111var IframeShim = Class.create({
20112	initialize: function() {
20113		this.element = new Element('iframe',{
20114			style: 'position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);display:none',
20115			src: 'javascript:void(0);',
20116			frameborder: 0
20117		});
20118		$(document.body).insert(this.element);
20119	},
20120	hide: function() {
20121		this.element.hide();
20122		return this;
20123	},
20124	show: function() {
20125		this.element.show();
20126		return this;
20127	},
20128	positionUnder: function(element) {
20129		var element = $(element);
20130		var offset = element.cumulativeOffset();
20131		var dimensions = element.getDimensions();
20132		this.element.setStyle({
20133			left: offset[0] + 'px',
20134			top: offset[1] + 'px',
20135			width: dimensions.width + 'px',
20136			height: dimensions.height + 'px',
20137			zIndex: element.getStyle('zIndex') - 1
20138		}).show();
20139		return this;
20140	},
20141	setBounds: function(bounds) {
20142		for(prop in bounds)
20143			bounds[prop] += 'px';
20144		this.element.setStyle(bounds);
20145		return this;
20146	},
20147	destroy: function() {
20148		if(this.element)
20149			this.element.remove();
20150		return this;
20151	}
20152});
20153/**
20154* @author Ryan Johnson <http://syntacticx.com/>
20155* @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
20156* @package LivePipe UI
20157* @license MIT
20158* @url http://livepipe.net/control/window
20159* @require prototype.js, effects.js, draggable.js, resizable.js, livepipe.js
20160*/
20161
20162//adds onDraw and constrainToViewport option to draggable
20163if(typeof(Draggable) != 'undefined'){
20164	//allows the point to be modified with an onDraw callback
20165	Draggable.prototype.draw = function(point) {
20166		var pos = Position.cumulativeOffset(this.element);
20167		if(this.options.ghosting) {
20168			var r = Position.realOffset(this.element);
20169			pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
20170		}
20171
20172		var d = this.currentDelta();
20173		pos[0] -= d[0]; pos[1] -= d[1];
20174
20175		if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
20176			pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
20177			pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
20178		}
20179
20180		var p = [0,1].map(function(i){
20181			return (point[i]-pos[i]-this.offset[i])
20182		}.bind(this));
20183
20184		if(this.options.snap) {
20185			if(typeof this.options.snap == 'function') {
20186				p = this.options.snap(p[0],p[1],this);
20187			} else {
20188				if(this.options.snap instanceof Array) {
20189					p = p.map( function(v, i) {return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this))
20190				} else {
20191					p = p.map( function(v) {return Math.round(v/this.options.snap)*this.options.snap }.bind(this))
20192				}
20193			}
20194		}
20195
20196		if(this.options.onDraw)
20197			this.options.onDraw.bind(this)(p);
20198		else{
20199			var style = this.element.style;
20200			if(this.options.constrainToViewport){
20201				var viewport_dimensions = document.viewport.getDimensions();
20202				var container_dimensions = this.element.getDimensions();
20203				var margin_top = parseInt(this.element.getStyle('margin-top'));
20204				var margin_left = parseInt(this.element.getStyle('margin-left'));
20205				var boundary = [[
20206					0 - margin_left,
20207					0 - margin_top
20208				],[
20209					(viewport_dimensions.width - container_dimensions.width) - margin_left,
20210					(viewport_dimensions.height - container_dimensions.height) - margin_top
20211				]];
20212				if((!this.options.constraint) || (this.options.constraint=='horizontal')){
20213					if((p[0] >= boundary[0][0]) && (p[0] <= boundary[1][0]))
20214						this.element.style.left = p[0] + "px";
20215					else
20216						this.element.style.left = ((p[0] < boundary[0][0]) ? boundary[0][0] : boundary[1][0]) + "px";
20217				}
20218				if((!this.options.constraint) || (this.options.constraint=='vertical')){
20219					if((p[1] >= boundary[0][1] ) && (p[1] <= boundary[1][1]))
20220						this.element.style.top = p[1] + "px";
20221				else
20222						this.element.style.top = ((p[1] <= boundary[0][1]) ? boundary[0][1] : boundary[1][1]) + "px";
20223				}
20224			}else{
20225				if((!this.options.constraint) || (this.options.constraint=='horizontal'))
20226				style.left = p[0] + "px";
20227				if((!this.options.constraint) || (this.options.constraint=='vertical'))
20228				style.top     = p[1] + "px";
20229			}
20230			if(style.visibility=="hidden")
20231				style.visibility = ""; // fix gecko rendering
20232		}
20233	};
20234}
20235
20236if(typeof(Prototype) == "undefined")
20237	throw "Control.Window requires Prototype to be loaded.";
20238if(typeof(IframeShim) == "undefined")
20239	throw "Control.Window requires IframeShim to be loaded.";
20240if(typeof(Object.Event) == "undefined")
20241	throw "Control.Window requires Object.Event to be loaded.";
20242/*
20243	known issues:
20244		- when iframe is clicked is does not gain focus
20245		- safari can't open multiple iframes properly
20246		- constrainToViewport: body must have no margin or padding for this to work properly
20247		- iframe will be mis positioned during fade in
20248		- document.viewport does not account for scrollbars (this will eventually be fixed in the prototype core)
20249	notes
20250		- setting constrainToViewport only works when the page is not scrollable
20251		- setting draggable: true will negate the effects of position: center
20252*/
20253Control.Window = Class.create({
20254	initialize: function(container,options){
20255		Control.Window.windows.push(this);
20256
20257		//attribute initialization
20258		this.container = false;
20259		this.isOpen = false;
20260		this.href = false;
20261		this.sourceContainer = false; //this is optionally the container that will open the window
20262		this.ajaxRequest = false;
20263		this.remoteContentLoaded = false; //this is set when the code to load the remote content is run, onRemoteContentLoaded is fired when the connection is closed
20264		this.numberInSequence = Control.Window.windows.length + 1; //only useful for the effect scoping
20265		this.indicator = false;
20266		this.effects = {
20267			fade: false,
20268			appear: false
20269		};
20270		this.indicatorEffects = {
20271			fade: false,
20272			appear: false
20273		};
20274
20275		//options
20276		this.options = Object.extend({
20277			//lifecycle
20278			relativeAnchor: null,
20279			beforeOpen: Prototype.emptyFunction,
20280			afterOpen: Prototype.emptyFunction,
20281			beforeClose: Prototype.emptyFunction,
20282			afterClose: Prototype.emptyFunction,
20283			//dimensions and modes
20284			height: null,
20285			width: null,
20286			className: false,
20287			position: 'center', //'center', 'center_once', 'relative', [x,y], [function(){return x;},function(){return y;}]
20288			offsetLeft: 0, //available only for anchors opening the window, or windows set to position: hover
20289			offsetTop: 0, //""
20290			iframe: false, //if the window has an href, this will display the href as an iframe instead of requesting the url as an an Ajax.Request
20291			hover: false, //element object to hover over, or if "true" only available for windows with sourceContainer (an anchor or any element already on the page with an href attribute)
20292			indicator: false, //element to show or hide when ajax requests, images and iframes are loading
20293			closeOnClick: false, //does not work with hover,can be: true (click anywhere), 'container' (will refer to this.container), or element (a specific element)
20294			iframeshim: true, //whether or not to position an iFrameShim underneath the window
20295			//effects
20296			fade: false,
20297			fadeDuration: 0.75,
20298			//draggable
20299			draggable: false,
20300			onDrag: Prototype.emptyFunction,
20301			//resizable
20302			resizable: false,
20303			minHeight: false,
20304			minWidth: false,
20305			maxHeight: false,
20306			maxWidth: false,
20307			onResize: Prototype.emptyFunction,
20308			//draggable and resizable
20309			constrainToViewport: false,
20310			//ajax
20311			method: 'post',
20312			parameters: {},
20313			onComplete: Prototype.emptyFunction,
20314			onSuccess: Prototype.emptyFunction,
20315			onFailure: Prototype.emptyFunction,
20316			onException: Prototype.emptyFunction,
20317			//any element with an href (image,iframe,ajax) will call this after it is done loading
20318			onRemoteContentLoaded: Prototype.emptyFunction,
20319			insertRemoteContentAt: false //false will set this to this.container, can be string selector (first returned will be selected), or an Element that must be a child of this.container
20320		},options || {});
20321
20322		//container setup
20323		this.indicator = this.options.indicator ? $(this.options.indicator) : false;
20324		if(container){
20325			if(typeof(container) == "string" && container.match(Control.Window.uriRegex))
20326				this.href = container;
20327			else{
20328				this.container = $(container);
20329				//need to create the container now for tooltips (or hover: element with no container already on the page)
20330				//second call made below will not create the container since the check is done inside createDefaultContainer()
20331				this.createDefaultContainer(container);
20332				//if an element with an href was passed in we use it to activate the window
20333				if(this.container && ((this.container.readAttribute('href') && this.container.readAttribute('href') != '') || (this.options.hover && this.options.hover !== true))){
20334					if(this.options.hover && this.options.hover !== true)
20335						this.sourceContainer = $(this.options.hover);
20336					else{
20337						this.sourceContainer = this.container;
20338						this.href = this.container.readAttribute('href');
20339						var rel = this.href.match(/^#(.+)$/);
20340						if(rel && rel[1]){
20341							this.container = $(rel[1]);
20342							this.href = false;
20343						}else
20344							this.container = false;
20345					}
20346					//hover or click handling
20347					this.sourceContainerOpenHandler = function(event){
20348						this.open(event);
20349						event.stop();
20350						return false;
20351					}.bindAsEventListener(this);
20352					this.sourceContainerCloseHandler = function(event){
20353						this.close(event);
20354					}.bindAsEventListener(this);
20355					this.sourceContainerMouseMoveHandler = function(event){
20356						this.position(event);
20357					}.bindAsEventListener(this);
20358					if(this.options.hover) {
20359						this.sourceContainer.observe('mouseenter',this.sourceContainerOpenHandler);
20360						this.sourceContainer.observe('mouseleave',this.sourceContainerCloseHandler);
20361						if(this.options.position == 'mouse')
20362							this.sourceContainer.observe('mousemove',this.sourceContainerMouseMoveHandler);
20363					} else if (this.options.dblclick) { // BOOGIE - Podpora za doubleclick odpiranje
20364						this.sourceContainer.observe('dblclick',this.sourceContainerOpenHandler);
20365					} else {
20366						this.sourceContainer.observe('click',this.sourceContainerOpenHandler);
20367					}
20368				}
20369			}
20370		}
20371		this.createDefaultContainer(container);
20372		if(this.options.insertRemoteContentAt === false)
20373			this.options.insertRemoteContentAt = this.container;
20374		var styles = {
20375			margin: 0,
20376			position: 'absolute',
20377			zIndex: Control.Window.initialZIndexForWindow()
20378		};
20379		if(this.options.width)
20380			styles.width = $value(this.options.width) + 'px';
20381		if(this.options.height)
20382			styles.height = $value(this.options.height) + 'px';
20383		this.container.setStyle(styles);
20384		if(this.options.className)
20385			this.container.addClassName(this.options.className);
20386		this.positionHandler = this.position.bindAsEventListener(this);
20387		this.outOfBoundsPositionHandler = this.ensureInBounds.bindAsEventListener(this);
20388		this.bringToFrontHandler = this.bringToFront.bindAsEventListener(this);
20389		this.container.observe('mousedown',this.bringToFrontHandler);
20390		this.container.hide();
20391		this.closeHandler = this.close.bindAsEventListener(this);
20392		//iframeshim setup
20393		if(this.options.iframeshim){
20394			this.iFrameShim = new IframeShim();
20395			this.iFrameShim.hide();
20396		}
20397		//resizable support
20398		this.applyResizable();
20399		//draggable support
20400		this.applyDraggable();
20401
20402		//makes sure the window can't go out of bounds
20403		Event.observe(window,'resize',this.outOfBoundsPositionHandler);
20404
20405		this.notify('afterInitialize');
20406	},
20407	open: function(event){
20408		if(this.isOpen){
20409			this.bringToFront();
20410			return false;
20411		}
20412		if(this.notify('beforeOpen') === false)
20413			return false;
20414		//closeOnClick
20415		if(this.options.closeOnClick){
20416			if(this.options.closeOnClick === true)
20417				this.closeOnClickContainer = $(document.body);
20418			else if(this.options.closeOnClick == 'container')
20419				this.closeOnClickContainer = this.container;
20420			else if (this.options.closeOnClick == 'overlay'){
20421				Control.Overlay.load();
20422				this.closeOnClickContainer = Control.Overlay.container;
20423			}else
20424				this.closeOnClickContainer = $(this.options.closeOnClick);
20425			this.closeOnClickContainer.observe('click',this.closeHandler);
20426		}
20427		if(this.href && !this.options.iframe && !this.remoteContentLoaded){
20428			//link to image
20429			this.remoteContentLoaded = true;
20430			if(this.href.match(/\.(jpe?g|gif|png|tiff?)$/i)){
20431				var img = new Element('img');
20432				img.observe('load',function(img){
20433					this.getRemoteContentInsertionTarget().insert(img);
20434					this.position();
20435					if(this.notify('onRemoteContentLoaded') !== false){
20436						if(this.options.indicator)
20437							this.hideIndicator();
20438						this.finishOpen();
20439					}
20440				}.bind(this,img));
20441				img.writeAttribute('src',this.href);
20442			}else{
20443				//if this is an ajax window it will only open if the request is successful
20444				if(!this.ajaxRequest){
20445					if(this.options.indicator)
20446						this.showIndicator();
20447					this.ajaxRequest = new Ajax.Request(this.href,{
20448						method: this.options.method,
20449						parameters: this.options.parameters,
20450						onComplete: function(request){
20451							this.notify('onComplete',request);
20452							this.ajaxRequest = false;
20453						}.bind(this),
20454						onSuccess: function(request){
20455							this.getRemoteContentInsertionTarget().insert(request.responseText);
20456							this.notify('onSuccess',request);
20457							if(this.notify('onRemoteContentLoaded') !== false){
20458								if(this.options.indicator)
20459									this.hideIndicator();
20460								this.finishOpen();
20461							}
20462						}.bind(this),
20463						onFailure: function(request){
20464							this.notify('onFailure',request);
20465							if(this.options.indicator)
20466								this.hideIndicator();
20467						}.bind(this),
20468						onException: function(request,e){
20469							this.notify('onException',request,e);
20470							if(this.options.indicator)
20471								this.hideIndicator();
20472						}.bind(this)
20473					});
20474				}
20475			}
20476			return true;
20477		}else if(this.options.iframe && !this.remoteContentLoaded){
20478			//iframe
20479			this.remoteContentLoaded = true;
20480			if(this.options.indicator)
20481				this.showIndicator();
20482			this.getRemoteContentInsertionTarget().insert(Control.Window.iframeTemplate.evaluate({
20483				href: this.href
20484			}));
20485			var iframe = this.container.down('iframe');
20486			iframe.onload = function(){
20487				this.notify('onRemoteContentLoaded');
20488				if(this.options.indicator)
20489					this.hideIndicator();
20490				iframe.onload = null;
20491			}.bind(this);
20492		}
20493		this.finishOpen(event);
20494		return true
20495	},
20496	close: function(event){ //event may or may not be present
20497		if(!this.isOpen || this.notify('beforeClose',event) === false)
20498			return false;
20499		if(this.options.closeOnClick)
20500			this.closeOnClickContainer.stopObserving('click',this.closeHandler);
20501		if(this.options.fade){
20502			this.effects.fade = new Effect.Fade(this.container,{
20503				queue: {
20504					position: 'front',
20505					scope: 'Control.Window' + this.numberInSequence
20506				},
20507				from: 1,
20508				to: 0,
20509				duration: this.options.fadeDuration / 2,
20510				afterFinish: function(){
20511					if(this.iFrameShim)
20512						this.iFrameShim.hide();
20513					this.isOpen = false;
20514					this.notify('afterClose');
20515				}.bind(this)
20516			});
20517		}else{
20518			this.container.hide();
20519			if(this.iFrameShim)
20520				this.iFrameShim.hide();
20521		}
20522		if(this.ajaxRequest)
20523			this.ajaxRequest.transport.abort();
20524		if(!(this.options.draggable || this.options.resizable) && this.options.position == 'center')
20525			Event.stopObserving(window,'resize',this.positionHandler);
20526		if(!this.options.draggable && this.options.position == 'center')
20527			Event.stopObserving(window,'scroll',this.positionHandler);
20528		if(this.options.indicator)
20529			this.hideIndicator();
20530		if(!this.options.fade){
20531			this.isOpen = false;
20532			this.notify('afterClose');
20533		}
20534		return true;
20535	},
20536	position: function(event){
20537		//this is up top for performance reasons
20538		if(this.options.position == 'mouse'){
20539			var xy = [Event.pointerX(event),Event.pointerY(event)];
20540			this.container.setStyle({
20541				top: xy[1] + $value(this.options.offsetTop) + 'px',
20542				left: xy[0] + $value(this.options.offsetLeft) + 'px'
20543			});
20544			return;
20545		}
20546		var container_dimensions = this.container.getDimensions();
20547		var viewport_dimensions = document.viewport.getDimensions();
20548		Position.prepare();
20549		var offset_left = (Position.deltaX + Math.floor((viewport_dimensions.width - container_dimensions.width) / 2));
20550		var offset_top = (Position.deltaY + ((viewport_dimensions.height > container_dimensions.height) ? Math.floor((viewport_dimensions.height - container_dimensions.height) / 2) : 0));
20551		offset_top += $value(this.options.offsetTop);
20552		offset_left += $value(this.options.offsetLeft);
20553		if(this.options.position == 'center' || this.options.position == 'center_once'){
20554			this.container.setStyle({
20555				top: (container_dimensions.height <= viewport_dimensions.height) ? ((offset_top != null && offset_top > 0) ? offset_top : 0) + 'px' : 0,
20556				left: (container_dimensions.width <= viewport_dimensions.width) ? ((offset_left != null && offset_left > 0) ? offset_left : 0) + 'px' : 0
20557			});
20558		}else if(this.options.position == 'relative'){
20559			var xy = this.sourceContainer.cumulativeOffset();
20560			var top = xy[1] + $value(this.options.offsetTop);
20561			var left = xy[0] + $value(this.options.offsetLeft);
20562			this.container.setStyle({
20563				top: (container_dimensions.height <= viewport_dimensions.height) ? (this.options.constrainToViewport ? Math.max(0,Math.min(viewport_dimensions.height - (container_dimensions.height),top)) : top) + 'px' : 0,
20564									left: (container_dimensions.width <= viewport_dimensions.width) ? (this.options.constrainToViewport ? Math.max(0,Math.min(viewport_dimensions.width - (container_dimensions.width),left)) : left) + 'px' : 0
20565			});
20566		}else if(this.options.position == 'relativeDWM'){ // BOOGIE
20567			var xy = this.options.relativeAnchor.cumulativeOffset();
20568			var top = xy[1] + $value(this.options.offsetTop);
20569			var left = xy[0] + $value(this.options.offsetLeft);
20570			this.container.setStyle({
20571				top: (container_dimensions.height <= viewport_dimensions.height) ? (this.options.constrainToViewport ? Math.max(0,Math.min(viewport_dimensions.height - (container_dimensions.height),top)) : top) + 'px' : 0,
20572									left: (container_dimensions.width <= viewport_dimensions.width) ? (this.options.constrainToViewport ? Math.max(0,Math.min(viewport_dimensions.width - (container_dimensions.width),left)) : left) + 'px' : 0
20573			});
20574		}else if(this.options.position.length){
20575			var top = $value(this.options.position[1]) + $value(this.options.offsetTop);
20576			var left = $value(this.options.position[0]) + $value(this.options.offsetLeft);
20577			this.container.setStyle({
20578				top: (container_dimensions.height <= viewport_dimensions.height) ? (this.options.constrainToViewport ? Math.max(0,Math.min(viewport_dimensions.height - (container_dimensions.height),top)) : top) + 'px' : 0,
20579				left: (container_dimensions.width <= viewport_dimensions.width) ? (this.options.constrainToViewport ? Math.max(0,Math.min(viewport_dimensions.width - (container_dimensions.width),left)) : left) + 'px' : 0
20580			});
20581		}
20582		if(this.iFrameShim)
20583			this.updateIFrameShimZIndex();
20584	},
20585	ensureInBounds: function(){
20586		if(!this.isOpen)
20587			return;
20588		var viewport_dimensions = document.viewport.getDimensions();
20589		var container_offset = this.container.cumulativeOffset();
20590		var container_dimensions = this.container.getDimensions();
20591		if(container_offset.left + container_dimensions.width > viewport_dimensions.width){
20592			this.container.setStyle({
20593				left: (Math.max(0,viewport_dimensions.width - container_dimensions.width)) + 'px'
20594			});
20595		}
20596		if(container_offset.top + container_dimensions.height > viewport_dimensions.height){
20597			this.container.setStyle({
20598				top: (Math.max(0,viewport_dimensions.height - container_dimensions.height)) + 'px'
20599			});
20600		}
20601	},
20602	bringToFront: function(){
20603		Control.Window.bringToFront(this);
20604		this.notify('bringToFront');
20605	},
20606	destroy: function(){
20607		this.container.stopObserving('mousedown',this.bringToFrontHandler);
20608		if(this.draggable){
20609			Draggables.removeObserver(this.container);
20610			this.draggable.handle.stopObserving('mousedown',this.bringToFrontHandler);
20611			this.draggable.destroy();
20612		}
20613		if(this.resizable){
20614			Resizables.removeObserver(this.container);
20615			this.resizable.handle.stopObserving('mousedown',this.bringToFrontHandler);
20616			this.resizable.destroy();
20617		}
20618		if(this.container && !this.sourceContainer)
20619			this.container.remove();
20620		if(this.sourceContainer){
20621			if(this.options.hover){
20622				this.sourceContainer.stopObserving('mouseenter',this.sourceContainerOpenHandler);
20623				this.sourceContainer.stopObserving('mouseleave',this.sourceContainerCloseHandler);
20624				if(this.options.position == 'mouse')
20625					this.sourceContainer.stopObserving('mousemove',this.sourceContainerMouseMoveHandler);
20626			}else
20627				this.sourceContainer.stopObserving('click',this.sourceContainerOpenHandler);
20628		}
20629		if(this.iFrameShim)
20630			this.iFrameShim.destroy();
20631		Event.stopObserving(window,'resize',this.outOfBoundsPositionHandler);
20632		Control.Window.windows = Control.Window.windows.without(this);
20633		this.notify('afterDestroy');
20634	},
20635	//private
20636	applyResizable: function(){
20637		if(this.options.resizable){
20638			if(typeof(Resizable) == "undefined")
20639				throw "Control.Window requires resizable.js to be loaded.";
20640			var resizable_handle = null;
20641			if(this.options.resizable === true){
20642				resizable_handle = new Element('div',{
20643					className: 'resizable_handle'
20644				});
20645				this.container.insert(resizable_handle);
20646			}else
20647				resizable_handle = $(this.options.resziable);
20648			this.resizable = new Resizable(this.container,{
20649				handle: resizable_handle,
20650				minHeight: this.options.minHeight,
20651				minWidth: this.options.minWidth,
20652				maxHeight: this.options.constrainToViewport ? function(element){
20653					//viewport height - top - total border height
20654					return (document.viewport.getDimensions().height - parseInt(element.style.top || 0)) - (element.getHeight() - parseInt(element.style.height || 0
20654));
20655				} : this.options.maxHeight,
20656				maxWidth: this.options.constrainToViewport ? function(element){
20657					//viewport width - left - total border width
20658					return (document.viewport.getDimensions().width - parseInt(element.style.left || 0)) - (element.getWidth() - parseInt(element.style.width || 0));
20659				} : this.options.maxWidth
20660			});
20661			this.resizable.handle.observe('mousedown',this.bringToFrontHandler);
20662			Resizables.addObserver(new Control.Window.LayoutUpdateObserver(this,function(){
20663				if(this.iFrameShim)
20664					this.updateIFrameShimZIndex();
20665				this.notify('onResize');
20666			}.bind(this)));
20667		}
20668	},
20669	applyDraggable: function(){
20670		if(this.options.draggable){
20671			if(typeof(Draggables) == "undefined")
20672				throw "Control.Window requires dragdrop.js to be loaded.";
20673			var draggable_handle = null;
20674			if(this.options.draggable === true){
20675				draggable_handle = new Element('div',{
20676					className: 'draggable_handle'
20677				});
20678				this.container.insert(draggable_handle);
20679			}else
20680				draggable_handle = $(this.options.draggable);
20681			this.draggable = new Draggable(this.container,{
20682				handle: draggable_handle,
20683				constrainToViewport: this.options.constrainToViewport,
20684				zindex: this.container.getStyle('z-index'),
20685				starteffect: function(){
20686					if(Prototype.Browser.IE){
20687						this.old_onselectstart = document.onselectstart;
20688						document.onselectstart = function(){
20689							return false;
20690						};
20691					}
20692				}.bind(this),
20693				endeffect: function(){
20694					document.onselectstart = this.old_onselectstart;
20695				}.bind(this)
20696			});
20697			this.draggable.handle.observe('mousedown',this.bringToFrontHandler);
20698			Draggables.addObserver(new Control.Window.LayoutUpdateObserver(this,function(){
20699				if(this.iFrameShim)
20700					this.updateIFrameShimZIndex();
20701				this.notify('onDrag');
20702			}.bind(this)));
20703		}
20704	},
20705	createDefaultContainer: function(container){
20706		if(!this.container){
20707			//no container passed or found, create it
20708			this.container = new Element('div',{
20709				id: 'control_window_' + this.numberInSequence
20710			});
20711			$(document.body).insert(this.container);
20712			if(typeof(container) == "string" && $(container) == null && !container.match(/^#(.+)$/) && !container.match(Control.Window.uriRegex))
20713				this.container.update(container);
20714		}
20715	},
20716	finishOpen: function(event){
20717		this.bringToFront();
20718		if(this.options.fade){
20719			if(typeof(Effect) == "undefined")
20720				throw "Control.Window requires effects.js to be loaded."
20721			if(this.effects.fade)
20722				this.effects.fade.cancel();
20723			this.effects.appear = new Effect.Appear(this.container,{
20724				queue: {
20725					position: 'end',
20726					scope: 'Control.Window.' + this.numberInSequence
20727				},
20728				from: 0,
20729				to: 1,
20730				duration: this.options.fadeDuration / 2,
20731				afterFinish: function(){
20732					if(this.iFrameShim)
20733						this.updateIFrameShimZIndex();
20734					this.isOpen = true;
20735					this.notify('afterOpen');
20736				}.bind(this)
20737			});
20738		}else
20739			this.container.show();
20740		this.position(event);
20741		if(!(this.options.draggable || this.options.resizable) && this.options.position == 'center')
20742			Event.observe(window,'resize',this.positionHandler,false);
20743		if(!this.options.draggable && this.options.position == 'center')
20744			Event.observe(window,'scroll',this.positionHandler,false);
20745		if(!this.options.fade){
20746			this.isOpen = true;
20747			this.notify('afterOpen');
20748		}
20749		return true;
20750	},
20751	showIndicator: function(){
20752		this.showIndicatorTimeout = window.setTimeout(function(){
20753			if(this.options.fade){
20754				this.indicatorEffects.appear = new Effect.Appear(this.indicator,{
20755					queue: {
20756						position: 'front',
20757						scope: 'Control.Window.indicator.' + this.numberInSequence
20758					},
20759					from: 0,
20760					to: 1,
20761					duration: this.options.fadeDuration / 2
20762				});
20763			}else
20764				this.indicator.show();
20765		}.bind(this),Control.Window.indicatorTimeout);
20766	},
20767	hideIndicator: function(){
20768		if(this.showIndicatorTimeout)
20769			window.clearTimeout(this.showIndicatorTimeout);
20770		this.indicator.hide();
20771	},
20772	getRemoteContentInsertionTarget: function(){
20773		return typeof(this.options.insertRemoteContentAt) == "string" ? this.container.down(this.options.insertRemoteContentAt) : $(this.options.insertRemoteContentAt);
20774	},
20775	updateIFrameShimZIndex: function(){
20776		if(this.iFrameShim)
20777			this.iFrameShim.positionUnder(this.container);
20778	}
20779});
20780//class methods
20781Object.extend(Control.Window,{
20782	windows: [],
20783	baseZIndex: 1000,
20784	indicatorTimeout: 250,
20785	iframeTemplate: new Template('<iframe src="#{href}" width="100%" height="100%" frameborder="0"></iframe>'),
20786	uriRegex: /^(\/|\#|https?\:\/\/|[\w]+\/)/,
20787	bringToFront: function(w){
20788		Control.Window.windows = Control.Window.windows.without(w);
20789		Control.Window.windows.push(w);
20790		Control.Window.windows.each(function(w,i){
20791			var z_index = Control.Window.baseZIndex + i;
20792			w.container.setStyle({
20793				zIndex: z_index
20794			});
20795			if(w.isOpen){
20796				if(w.iFrameShim)
20797				w.updateIFrameShimZIndex();
20798			}
20799			if(w.options.draggable)
20800				w.draggable.options.zindex = z_index;
20801		});
20802	},
20803	open: function(container,options){
20804		var w = new Control.Window(container,options);
20805		w.open();
20806		return w;
20807	},
20808	//protected
20809	initialZIndexForWindow: function(w){
20810		return Control.Window.baseZIndex + (Control.Window.windows.length - 1);
20811	}
20812});
20813Object.Event.extend(Control.Window);
20814
20815//this is the observer for both Resizables and Draggables
20816Control.Window.LayoutUpdateObserver = Class.create({
20817	initialize: function(w,observer){
20818		this.w = w;
20819		this.element = $(w.container);
20820		this.observer = observer;
20821	},
20822	onStart: Prototype.emptyFunction,
20823	onEnd: function(event_name,instance){
20824		if(instance.element == this.element && this.iFrameShim)
20825			this.w.updateIFrameShimZIndex();
20826	},
20827	onResize: function(event_name,instance){
20828		if(instance.element == this.element)
20829			this.observer(this.element);
20830	},
20831	onDrag: function(event_name,instance){
20832		if(instance.element == this.element)
20833			this.observer(this.element);
20834	}
20835});
20836
20837//overlay for Control.Modal
20838Control.Overlay = {
20839	id: 'control_overlay',
20840	loaded: false,
20841	container: false,
20842	lastOpacity: 0,
20843	getStyles: function() {
20844		return {
20845			position: 'fixed',
20846			top: 0,
20847			left: 0,
20848			width: '100%',
20849			height: '100%',
20850			zIndex: Control.Window.baseZIndex - 1
20851		};
20852	},
20853	getIeStyles: function() {
20854		return {
20855			position: 'absolute',
20856			top: 0,
20857			left: 0,
20858			zIndex: Control.Window.baseZIndex - 1
20859		};
20860	},
20861	effects: {
20862		fade: false,
20863		appear: false
20864	},
20865	load: function(){
20866		if(Control.Overlay.loaded)
20867			return false;
20868		Control.Overlay.loaded = true;
20869		Control.Overlay.container = new Element('div',{
20870			id: Control.Overlay.id
20871		});
20872		$(document.body).insert(Control.Overlay.container);
20873		if(Prototype.Browser.IE){
20874			Control.Overlay.container.setStyle(Control.Overlay.getIeStyles());
20875			Event.observe(window,'scroll',Control.Overlay.positionOverlay);
20876			Event.observe(window,'resize',Control.Overlay.positionOverlay);
20877			Control.Overlay.observe('beforeShow',Control.Overlay.positionOverlay);
20878		}else
20879			Control.Overlay.container.setStyle(Control.Overlay.getStyles());
20880		Control.Overlay.iFrameShim = new IframeShim();
20881		Control.Overlay.iFrameShim.hide();
20882		Event.observe(window,'resize',Control.Overlay.positionIFrameShim);
20883		Control.Overlay.container.hide();
20884		return true;
20885	},
20886	unload: function(){
20887		if(!Control.Overlay.loaded)
20888			return false;
20889		Event.stopObserving(window,'resize',Control.Overlay.positionOverlay);
20890		Control.Overlay.stopObserving('beforeShow',Control.Overlay.positionOverlay);
20891		Event.stopObserving(window,'resize',Control.Overlay.positionIFrameShim);
20892		Control.Overlay.iFrameShim.destroy();
20893		Control.Overlay.container.remove();
20894		Control.Overlay.loaded = false;
20895		return true;
20896	},
20897	show: function(opacity,fade){
20898		if(Control.Overlay.notify('beforeShow') === false)
20899			return false;
20900		Control.Overlay.lastOpacity = opacity;
20901		Control.Overlay.positionIFrameShim();
20902		Control.Overlay.iFrameShim.show();
20903		if(fade){
20904			if(typeof(Effect) == "undefined")
20905				throw "Control.Window requires effects.js to be loaded."
20906			if(Control.Overlay.effects.fade)
20907				Control.Overlay.effects.fade.cancel();
20908			Control.Overlay.effects.appear = new Effect.Appear(Control.Overlay.container,{
20909				queue: {
20910					position: 'end',
20911					scope: 'Control.Overlay'
20912				},
20913				afterFinish: function(){
20914					Control.Overlay.notify('afterShow');
20915				},
20916				from: 0,
20917				to: Control.Overlay.lastOpacity,
20918				duration: (fade === true ? 0.75 : fade) / 2
20919			});
20920		}else{
20921			Control.Overlay.container.setStyle({
20922				opacity: opacity || 1
20923			});
20924			Control.Overlay.container.show();
20925			Control.Overlay.notify('afterShow');
20926		}
20927		return true;
20928	},
20929	hide: function(fade){
20930		if(Control.Overlay.notify('beforeHide') === false)
20931			return false;
20932		if(Control.Overlay.effects.appear)
20933			Control.Overlay.effects.appear.cancel();
20934		Control.Overlay.iFrameShim.hide();
20935		if(fade){
20936			Control.Overlay.effects.fade = new Effect.Fade(Control.Overlay.container,{
20937				queue: {
20938					position: 'front',
20939					scope: 'Control.Overlay'
20940				},
20941				afterFinish: function(){
20942					Control.Overlay.notify('afterHide');
20943				},
20944				from: Control.Overlay.lastOpacity,
20945				to: 0,
20946				duration: (fade === true ? 0.75 : fade) / 2
20947			});
20948		}else{
20949			Control.Overlay.container.hide();
20950			Control.Overlay.notify('afterHide');
20951		}
20952		return true;
20953	},
20954	positionIFrameShim: function(){
20955		if(Control.Overlay.container.visible())
20956			Control.Overlay.iFrameShim.positionUnder(Control.Overlay.container);
20957	},
20958	//IE only
20959	positionOverlay: function(){
20960		Control.Overlay.container.setStyle({
20961			width: document.body.clientWidth + 'px',
20962			height: document.body.clientHeight + 'px'
20963		});
20964	}
20965};
20966Object.Event.extend(Control.Overlay);
20967
20968Control.ToolTip = Class.create(Control.Window,{
20969	initialize: function($super,container,tooltip,options){
20970		$super(tooltip,Object.extend(Object.extend(Object.clone(Control.ToolTip.defaultOptions),options || {}),{
20971			position: 'mouse',
20972			hover: container
20973		}));
20974	}
20975});
20976Object.extend(Control.ToolTip,{
20977	defaultOptions: {
20978		offsetLeft: 10
20979	}
20980});
20981
20982Control.Modal = Class.create(Control.Window,{
20983	initialize: function($super,container,options){
20984		Control.Modal.InstanceMethods.beforeInitialize.bind(this)();
20985		$super(container,Object.extend(Object.clone(Control.Modal.defaultOptions),options || {}));
20986	},
20987	closeWithoutOverlay: function(){
20988		this.keepOverlay = true;
20989		this.close();
20990	}
20991});
20992Object.extend(Control.Modal,{
20993	defaultOptions: {
20994		overlayOpacity: 0.5,
20995		closeOnClick: 'overlay'
20996	},
20997	current: false,
20998	open: function(container,options){
20999		var modal = new Control.Modal(container,options);
21000		modal.open();
21001		return modal;
21002	},
21003	close: function(){
21004		if(Control.Modal.current)
21005			Control.Modal.current.close();
21006	},
21007	InstanceMethods: {
21008		beforeInitialize: function(){
21009			Control.Overlay.load();
21010			this.observe('beforeOpen',Control.Modal.Observers.beforeOpen.bind(this));
21011			this.observe('afterOpen',Control.Modal.Observers.afterOpen.bind(this));
21012			this.observe('afterClose',Control.Modal.Observers.afterClose.bind(this));
21013		}
21014	},
21015	Observers: {
21016		beforeOpen: function(){
21017			Control.Window.windows.without(this).each(function(w){
21018				if(w.closeWithoutOverlay && w.isOpen){
21019					w.closeWithoutOverlay();
21020				}else{
21021					w.close();
21022				}
21023			});
21024			if(!Control.Overlay.overlayFinishedOpening){
21025				Control.Overlay.observeOnce('afterShow',function(){
21026					Control.Overlay.overlayFinishedOpening = true;
21027					this.open();
21028				}.bind(this));
21029				Control.Overlay.show(this.options.overlayOpacity,this.options.fade ? this.options.fadeDuration : false);
21030				throw $break;
21031			}
21032		},
21033		afterOpen: function(){
21034			Control.Overlay.show(this.options.overlayOpacity);
21035			Control.Overlay.overlayFinishedOpening = true;
21036			Control.Modal.current = this;
21037		},
21038		afterClose: function(){
21039			if(!this.keepOverlay){
21040				Control.Overlay.hide(this.options.fade ? this.options.fadeDuration : false);
21041				Control.Overlay.overlayFinishedOpening = false;
21042			}
21043			this.keepOverlay = false;
21044			Control.Modal.current = false;
21045		}
21046	}
21047});
21048
21049Control.LightBox = Class.create(Control.Window,{
21050	initialize: function($super,container,options){
21051		this.allImagesLoaded = false;
21052		if(options.modal){
21053			var options = Object.extend(Object.clone(Control.LightBox.defaultOptions),options || {});
21054			options = Object.extend(Object.clone(Control.Modal.defaultOptions),options);
21055			options = Control.Modal.InstanceMethods.beforeInitialize.bind(this)(options);
21056			$super(container,options);
21057		}else
21058			$super(container,Object.extend(Object.clone(Control.LightBox.defaultOptions),options || {}));
21059		this.hasRemoteContent = this.href && !this.options.iframe;
21060		if(this.hasRemoteContent)
21061			this.observe('onRemoteContentLoaded',Control.LightBox.Observers.onRemoteContentLoaded.bind(this));
21062		else
21063			this.applyImageObservers();
21064		this.observe('beforeOpen',Control.LightBox.Observers.beforeOpen.bind(this));
21065	},
21066	applyImageObservers:function(){
21067		var images = this.getImages();
21068		this.numberImagesToLoad = images.length;
21069		this.numberofImagesLoaded = 0;
21070		images.each(function(image){
21071			image.observe('load',function(image){
21072				++this.numberofImagesLoaded;
21073				if(this.numberImagesToLoad == this.numberofImagesLoaded){
21074					this.allImagesLoaded = true;
21075					this.onAllImagesLoaded();
21076				}
21077			}.bind(this,image));
21078			image.hide();
21079		}.bind(this));
21080	},
21081	onAllImagesLoaded: function(){
21082		this.getImages().each(function(image){
21083			this.showImage(image);
21084		}.bind(this));
21085		if(this.hasRemoteContent){
21086			if(this.options.indicator)
21087				this.hideIndicator();
21088			this.finishOpen();
21089		}else
21090			this.open();
21091	},
21092	getImages: function(){
21093		return this.container.select(Control.LightBox.imageSelector);
21094	},
21095	showImage: function(image){
21096		image.show();
21097	}
21098});
21099Object.extend(Control.LightBox,{
21100	imageSelector: 'img',
21101	defaultOptions: {},
21102	Observers: {
21103		beforeOpen: function(){
21104			if(!this.hasRemoteContent && !this.allImagesLoaded)
21105				throw $break;
21106		},
21107		onRemoteContentLoaded: function(){
21108			this.applyImageObservers();
21109			if(!this.allImagesLoaded)
21110				throw $break;
21111		}
21112	}
21113});
21114var window_factory = function(container,options){
21115	var window_header = new Element('div',{
21116		className: 'window_header'
21117	});
21118	var window_title = new Element('div',{
21119		className: 'window_title'
21120		});
21121	var window_close = new Element('div',{
21122		className: 'window_close'
21123		});
21124	var window_contents = new Element('div',{
21125		className: 'window_contents'
21126		});
21127	var w = new Control.Window(container,Object.extend({
21128		className: 'window',
21129		closeOnClick: window_close,
21130		draggable: window_header,
21131		insertRemoteContentAt: window_contents,
21132		afterOpen: function(){
21133			window_title.update(container.readAttribute('title'))
21134		}
21135	},options || {}));
21136	w.container.insert(window_header);
21137	window_header.insert(window_title);
21138	window_header.insert(window_close);
21139	w.container.insert(window_contents);
21140	return w;
21141};
21142
21143
21144// script.aculo.us Resizables.js
21145
21146// Copyright(c) 2007 - Orr Siloni, Comet Information Systems http://www.comet.co.il/en/
21147//
21148// Resizable.js is freely distributable under the terms of an MIT-style license.
21149// For details, see the script.aculo.us web site: http://script.aculo.us/
21150
21151var Resizables = {
21152	instances: [],
21153	observers: [],
21154
21155	register: function(resizable) {
21156		if(this.instances.length == 0) {
21157			this.eventMouseUp   = this.endResize.bindAsEventListener(this);
21158			this.eventMouseMove = this.updateResize.bindAsEventListener(this);
21159
21160			Event.observe(document, "mouseup", this.eventMouseUp);
21161			Event.observe(document, "mousemove", this.eventMouseMove);
21162		}
21163		this.instances.push(resizable);
21164	},
21165
21166	unregister: function(resizable) {
21167		this.instances = this.instances.reject(function(d) { return d==resizable });
21168		if(this.instances.length == 0) {
21169			Event.stopObserving(document, "mouseup", this.eventMouseUp);
21170			Event.stopObserving(document, "mousemove", this.eventMouseMove);
21171		}
21172	},
21173
21174	activate: function(resizable) {
21175		if(resizable.options.delay) {
21176			this._timeout = setTimeout(function() {
21177				Resizables._timeout = null;
21178				Resizables.activeResizable = resizable;
21179			}.bind(this), resizable.options.delay);
21180		} else {
21181			this.activeResizable = resizable;
21182		}
21183	},
21184
21185	deactivate: function() {
21186		this.activeResizable = null;
21187	},
21188
21189	updateResize: function(event) {
21190		if(!this.activeResizable) return;
21191		var pointer = [Event.pointerX(event), Event.pointerY(event)];
21192		// Mozilla-based browsers fire successive mousemove events with
21193		// the same coordinates, prevent needless redrawing (moz bug?)
21194		if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
21195		this._lastPointer = pointer;
21196		this.activeResizable.updateResize(event, pointer);
21197	},
21198
21199	endResize: function(event) {
21200		if(this._timeout) {
21201		clearTimeout(this._timeout);
21202		this._timeout = null;
21203		}
21204		if(!this.activeResizable) return;
21205		this._lastPointer = null;
21206		this.activeResizable.endResize(event);
21207		this.activeResizable = null;
21208	},
21209
21210	addObserver: function(observer) {
21211		this.observers.push(observer);
21212		this._cacheObserverCallbacks();
21213	},
21214
21215	removeObserver: function(element) {  // element instead of observer fixes mem leaks
21216		this.observers = this.observers.reject( function(o) { return o.element==element });
21217		this._cacheObserverCallbacks();
21218	},
21219
21220	notify: function(eventName, resizable, event) {  // 'onStart', 'onEnd', 'onResize'
21221		if(this[eventName+'Count'] > 0)
21222			this.observers.each( function(o) {
21223				if(o[eventName]) o[eventName](eventName, resizable, event);
21224			});
21225		if(resizable.options[eventName]) resizable.options[eventName](resizable, event);
21226	},
21227
21228	_cacheObserverCallbacks: function() {
21229		['onStart','onEnd','onResize'].each( function(eventName) {
21230			Resizables[eventName+'Count'] = Resizables.observers.select(
21231				function(o) { return o[eventName]; }
21232			).length;
21233		});
21234	}
21235}
21236
21237var Resizable = Class.create();
21238Resizable._resizing = {};
21239
21240Resizable.prototype = {
21241	initialize: function(element){
21242		var defaults = {
21243			handle: false,
21244			snap: false,  // false, or xy or [x,y] or function(x,y){ return [x,y] }
21245			delay: 0,
21246			minHeight: false,
21247			minwidth: false,
21248			maxHeight: false,
21249			maxWidth: false
21250		}
21251
21252		this.element = $(element);
21253
21254		var options = Object.extend(defaults, arguments[1] || {});
21255		if(options.handle && typeof options.handle == 'string')
21256			this.handle = $(options.handle);
21257		else if(options.handle)
21258			this.handle = options.handle;
21259
21260		if(!this.handle) this.handle = this.element;
21261
21262		this.options  = options;
21263		this.dragging = false;
21264
21265		this.eventMouseDown = this.initResize.bindAsEventListener(this);
21266		Event.observe(this.handle, "mousedown", this.eventMouseDown);
21267
21268		Resizables.register(this);
21269	},
21270
21271	destroy: function() {
21272		Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
21273	},
21274
21275	currentDelta: function() {
21276		return([
21277			parseInt(Element.getStyle(this.element,'width') || '0'),
21278			parseInt(Element.getStyle(this.element,'height') || '0')]);
21279	},
21280
21281	initResize: function(event) {
21282		if(typeof Resizable._resizing[this.element] != 'undefined' &&
21283			Resizable._resizing[this.element]) return;
21284		if(Event.isLeftClick(event)) {
21285			// abort on form elements, fixes a Firefox issue
21286			var src = Event.element(event);
21287			if((tag_name = src.tagName.toUpperCase()) && (
21288				tag_name=='INPUT' || tag_name=='SELECT' || tag_name=='OPTION' ||
21289				tag_name=='BUTTON' || tag_name=='TEXTAREA')) return;
21290
21291			this.pointer = [Event.pointerX(event), Event.pointerY(event)];
21292			this.size = [parseInt(this.element.getStyle('width')) || 0, parseInt(this.element.getStyle('height')) || 0];
21293
21294			Resizables.activate(this);
21295			Event.stop(event);
21296		}
21297	},
21298
21299	startResize: function(event) {
21300		this.resizing = true;
21301		if(this.options.zindex) {
21302			this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
21303			this.element.style.zIndex = this.options.zindex;
21304		}
21305		Resizables.notify('onStart', this, event);
21306		Resizable._resizing[this.element] = true;
21307	},
21308
21309	updateResize: function(event, pointer) {
21310		if(!this.resizing) this.startResize(event);
21311
21312		Resizables.notify('onResize', this, event);
21313
21314		// console.log("R->updateResize X:"+pointer[0]+" Y:"+pointer[1]) ;
21315		// console.log("N:"+Number($("sifra").getWidth())+" F:"+Number($("fltStolpec_sifra").getWidth())+" FI:"+Number($("TabelaSpiski_Fsifra").getWidth())+" V:"+Number($("Vrs7833").down("td").getWidth())) ;
21316		
21317		this.draw(pointer);
21318		if(this.options.change) this.options.change(this);
21319
21320		// fix AppleWebKit rendering
21321		if(Prototype.Browser.WebKit) window.scrollBy(0,0);
21322		Event.stop(event);
21323	},
21324
21325	finishResize: function(event, success) {
21326		this.resizing = false;
21327		Resizables.notify('onEnd', this, event);
21328		if(this.options.zindex) this.element.style.zIndex = this.originalZ;
21329		Resizable._resizing[this.element] = false;
21330		Resizables.deactivate(this);
21331	},
21332
21333	endResize: function(event) {
21334		if(!this.resizing) return;
21335		this.finishResize(event, true);
21336		Event.stop(event);
21337	},
21338
21339	draw: function(point) {
21340		var p = [0,1].map(function(i){
21341			return (this.size[i] + point[i] - this.pointer[i]);
21342		}.bind(this));
21343
21344		if(this.options.snap) {
21345			if(typeof this.options.snap == 'function') {
21346				p = this.options.snap(p[0],p[1],this);
21347			} else {
21348				if(this.options.snap instanceof Array) {
21349				p = p.map( function(v, i) {
21350				return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this))
21351			} else {
21352				p = p.map( function(v) {
21353				return Math.round(v/this.options.snap)*this.options.snap }.bind(this))
21354			}
21355		}}
21356
21357		var minWidth = (typeof(this.options.minWidth) == 'function') ? this.options.minWidth(this.element) : this.options.minWidth;
21358		var maxWidth = (typeof(this.options.maxWidth) == 'function') ? this.options.maxWidth(this.element) : this.options.maxWidth;
21359		var minHeight = (typeof(this.options.minHeight) == 'function') ? this.options.minHeight(this.element) : this.options.minHeight;
21360		var maxHeight = (typeof(this.options.maxHeight) == 'function') ? this.options.maxHeight(this.element) : this.options.maxHeight;
21361
21362		var debugLog = "MinW:"+minWidth+" MaxW:"+maxWidth+" p0:"+p[0] ;
21363		
21364		if (minWidth && p[0] <= minWidth) p[0] = minWidth;
21365		if (maxWidth && p[0] >= maxWidth) p[0] = maxWidth;
21366		if (minHeight && p[1] <= minHeight) p[1] = minHeight;
21367		if (maxHeight && p[1] >= maxHeight) p[1] = maxHeight;
21368
21369		var style = this.element.style;
21370		if((!this.options.constraint) || (this.options.constraint=='horizontal')){
21371			style.width = p[0] + "px";
21372		}
21373		if((!this.options.constraint) || (this.options.constraint=='vertical')){
21374			style.height = p[1] + "px";
21375		}
21376
21377		if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
21378		
21379		console.log(debugLog+" Np0:"+p[0]) ;
21380	}
21381};
21382/*
21383 * flowplayer.js 3.2.4. The Flowplayer API
21384 *
21385 * Copyright 2009 Flowplayer Oy
21386 *
21387 * This file is part of Flowplayer.
21388 *
21389 * Flowplayer is free software: you can redistribute it and/or modify
21390 * it under the terms of the GNU General Public License as published by
21391 * the Free Software Foundation, either version 3 of the License, or
21392 * (at your option) any later version.
21393 *
21394 * Flowplayer is distributed in the hope that it will be useful,
21395 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21396 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21397 * GNU General Public License for more details.
21398 *
21399 * You should have received a copy of the GNU General Public License
21400 * along with Flowplayer.  If not, see <http://www.gnu.org/licenses/>.
21401 *
21402 * Date: 2010-08-25 12:48:46 +0000 (Wed, 25 Aug 2010)
21403 * Revision: 551
21404 */
21405(function(){function g(o){console.log("$f.fireEvent",[].slice.call(o))}function k(q){if(!q||typeof q!="object"){return q}var o=new q.constructor();for(var p in q){if(q.hasOwnProperty(p)){o[p]=k(q[p])}}return o}function m(t,q){if(!t){return}var o,p=0,r=t.length;if(r===undefined){for(o in t){if(q.call(t[o],o,t[o])===false){break}}}else{for(var s=t[0];p<r&&q.call(s,p,s)!==false;s=t[++p]){}}return t}function c(o){return document.getElementById(o)}function i(q,p,o){if(typeof p!="object"){return q}if(q&&p){m(p,function(r,s){if(!o||typeof s!="function"){q[r]=s}})}return q}function n(s){var q=s.indexOf(".");if(q!=-1){var p=s.slice(0,q)||"*";var o=s.slice(q+1,s.length);var r=[];m(document.getElementsByTagName(p),function(){if(this.className&&this.className.indexOf(o)!=-1){r.push(this)}});return r}}function f(o){o=o||window.event;if(o.preventDefault){o.stopPropagation();o.preventDefault()}else{o.returnValue=false;o.cancelBubble=true}return false}function j(q,o,p){q[o]=q[o]||[];q[o].push(p)}function e(){return"_"+(""+Math.random()).slice(2,10)}var h=function(t,r,s){var q=this,p={},u={};q.index=r;if(typeof t=="string"){t={url:t}}i(this,t,true);m(("Begin*,Start,Pause*,Resume*,Seek*,Stop*,Finish*,LastSecond,Update,BufferFull,BufferEmpty,BufferStop").split(","),function(){var v="on"+this;if(v.indexOf("*")!=-1){v=v.slice(0,v.length-1);var w="onBefore"+v.slice(2);q[w]=function(x){j(u,w,x);return q}}q[v]=function(x){j(u,v,x);return q};if(r==-1){if(q[w]){s[w]=q[w]}if(q[v]){s[v]=q[v]}}});i(this,{onCuepoint:function(x,w){if(arguments.length==1){p.embedded=[null,x];return q}if(typeof x=="number"){x=[x]}var v=e();p[v]=[x,w];if(s.isLoaded()){s._api().fp_addCuepoints(x,r,v)}return q},update:function(w){i(q,w);if(s.isLoaded()){s._api().fp_updateClip(w,r)}var v=s.getConfig();var x=(r==-1)?v.clip:v.playlist[r];i(x,w,true)},_fireEvent:function(v,y,w,A){if(v=="onLoad"){m(p,function(B,C){if(C[0]){s._api().fp_addCuepoints(C[0],r,B)}});return false}A=A||q;if(v=="onCuepoint"){var z=p[y];if(z){return z[1].call(s,A,w)}}if(y&&"onBeforeBegin,onMetaData,onStart,onUpdate,onResume".indexOf(v)!=-1){i(A,y);if(y.metaData){if(!A.duration){A.duration=y.metaData.duration}else{A.fullDuration=y.metaData.duration}}}var x=true;m(u[v],function(){x=this.call(s,A,y,w)});return x}});if(t.onCuepoint){var o=t.onCuepoint;q.onCuepoint.apply(q,typeof o=="function"?[o]:o);delete t.onCuepoint}m(t,function(v,w){if(typeof w=="function"){j(u,v,w);delete t[v]}});if(r==-1){s.onCuepoint=this.onCuepoint}};var l=function(p,r,q,t){var o=this,s={},u=false;if(t){i(s,t)}m(r,function(v,w){if(typeof w=="function"){s[v]=w;delete r[v]}});i(this,{animate:function(y,z,x){if(!y){return o}if(typeof z=="function"){x=z;z=500}if(typeof y=="string"){var w=y;y={};y[w]=z;z=500}if(x){var v=e();s[v]=x}if(z===undefined){z=500}r=q._api().fp_animate(p,y,z,v);return o},css:function(w,x){if(x!==undefined){var v={};v[w]=x;w=v}r=q._api().fp_css(p,w);i(o,r);return o},show:function(){this.display="block";q._api().fp_showPlugin(p);return o},hide:function(){this.display="none";q._api().fp_hidePlugin(p);return o},toggle:function(){this.display=q._api().fp_togglePlugin(p);return o},fadeTo:function(y,x,w){if(typeof x=="function"){w=x;x=500}if(w){var v=e();s[v]=w}this.display=q._api().fp_fadeTo(p,y,x,v);this.opacity=y;return o},fadeIn:function(w,v){return o.fadeTo(1,w,v)},fadeOut:function(w,v){return o.fadeTo(0,w,v)},getName:function(){return p},getPlayer:function(){return q},_fireEvent:function(w,v,x){if(w=="onUpdate"){var z=q._api().fp_getPlugin(p);if(!z){return}i(o,z);delete o.methods;if(!u){m(z.methods,function(){var B=""+this;o[B]=function(){var C=[].slice.call(arguments);var D=q._api().fp_invoke(p,B,C);return D==="undefined"||D===undefined?o:D}});u=true}}var A=s[w];if(A){var y=A.apply(o,v);if(w.slice(0,1)=="_"){delete s[w]}return y}return o}})};function b(q,G,t){var w=this,v=null,D=false,u,s,F=[],y={},x={},E,r,p,C,o,A;i(w,{id:function(){return E},isLoaded:function(){return(v!==null&&v.fp_play!==undefined&&!D)},getParent:function(){return q},hide:function(H){if(H){q.style.height="0px"}if(w.isLoaded()){v.style.height="0px"}return w},show:function(){q.style.height=A+"px";if(w.isLoaded()){v.style.height=o+"px"}return w},isHidden:function(){return w.isLoaded()&&parseInt(v.style.height,10)===0},load:function(J){if(!w.isLoaded()&&w._fireEvent("onBeforeLoad")!==false){var H=function(){u=q.innerHTML;if(u&&!flashembed.isSupported(G.version)){q.innerHTML=""}if(J){J.cached=true;j(x,"onLoad",J)}
21405flashembed(q,G,{config:t})};var I=0;m(a,function(){this.unload(function(K){if(++I==a.length){H()}})})}return w},unload:function(J){if(this.isFullscreen()&&/WebKit/i.test(navigator.userAgent)){if(J){J(false)}return w}if(u.replace(/\s/g,"")!==""){if(w._fireEvent("onBeforeUnload")===false){if(J){J(false)}return w}D=true;try{if(v){v.fp_close();w._fireEvent("onUnload")}}catch(H){}var I=function(){v=null;q.innerHTML=u;D=false;if(J){J(true)}};setTimeout(I,50)}else{if(J){J(false)}}return w},getClip:function(H){if(H===undefined){H=C}return F[H]},getCommonClip:function(){return s},getPlaylist:function(){return F},getPlugin:function(H){var J=y[H];if(!J&&w.isLoaded()){var I=w._api().fp_getPlugin(H);if(I){J=new l(H,I,w);y[H]=J}}return J},getScreen:function(){return w.getPlugin("screen")},getControls:function(){return w.getPlugin("controls")._fireEvent("onUpdate")},getLogo:function(){try{return w.getPlugin("logo")._fireEvent("onUpdate")}catch(H){}},getPlay:function(){return w.getPlugin("play")._fireEvent("onUpdate")},getConfig:function(H){return H?k(t):t},getFlashParams:function(){return G},loadPlugin:function(K,J,M,L){if(typeof M=="function"){L=M;M={}}var I=L?e():"_";w._api().fp_loadPlugin(K,J,M,I);var H={};H[I]=L;var N=new l(K,null,w,H);y[K]=N;return N},getState:function(){return w.isLoaded()?v.fp_getState():-1},play:function(I,H){var J=function(){if(I!==undefined){w._api().fp_play(I,H)}else{w._api().fp_play()}};if(w.isLoaded()){J()}else{if(D){setTimeout(function(){w.play(I,H)},50)}else{w.load(function(){J()})}}return w},getVersion:function(){var I="flowplayer.js 3.2.4";if(w.isLoaded()){var H=v.fp_getVersion();H.push(I);return H}return I},_api:function(){if(!w.isLoaded()){throw"Flowplayer "+w.id()+" not loaded when calling an API method"}return v},setClip:function(H){w.setPlaylist([H]);return w},getIndex:function(){return p},_swfHeight:function(){return v.clientHeight}});m(("Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,ClipAdd,Fullscreen*,FullscreenExit,Error,MouseOver,MouseOut").split(","),function(){var H="on"+this;if(H.indexOf("*")!=-1){H=H.slice(0,H.length-1);var I="onBefore"+H.slice(2);w[I]=function(J){j(x,I,J);return w}}w[H]=function(J){j(x,H,J);return w}});m(("pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffer
21405ing,stopBuffering,isFullscreen,toggleFullscreen,reset,close,setPlaylist,addClip,playFeed,setKeyboardShortcutsEnabled,isKeyboardShortcutsEnabled").split(","),function(){var H=this;w[H]=function(J,I){if(!w.isLoaded()){return w}var K=null;if(J!==undefined&&I!==undefined){K=v["fp_"+H](J,I)}else{K=(J===undefined)?v["fp_"+H]():v["fp_"+H](J)}return K==="undefined"||K===undefined?w:K}});w._fireEvent=function(Q){if(typeof Q=="string"){Q=[Q]}var R=Q[0],O=Q[1],M=Q[2],L=Q[3],K=0;if(t.debug){g(Q)}if(!w.isLoaded()&&R=="onLoad"&&O=="player"){v=v||c(r);o=w._swfHeight();m(F,function(){this._fireEvent("onLoad")});m(y,function(S,T){T._fireEvent("onUpdate")});s._fireEvent("onLoad")}if(R=="onLoad"&&O!="player"){return}if(R=="onError"){if(typeof O=="string"||(typeof O=="number"&&typeof M=="number")){O=M;M=L}}if(R=="onContextMenu"){m(t.contextMenu[O],function(S,T){T.call(w)});return}if(R=="onPluginEvent"||R=="onBeforePluginEvent"){var H=O.name||O;var I=y[H];if(I){I._fireEvent("onUpdate",O);return I._fireEvent(M,Q.slice(3))}return}if(R=="onPlaylistReplace"){F=[];var N=0;m(O,function(){F.push(new h(this,N++,w))})}if(R=="onClipAdd"){if(O.isInStream){return}O=new h(O,M,w);F.splice(M,0,O);for(K=M+1;K<F.length;K++){F[K].index++}}var P=true;if(typeof O=="number"&&O<F.length){C=O;var J=F[O];if(J){P=J._fireEvent(R,M,L)}if(!J||P!==false){P=s._fireEvent(R,M,L,J)}}m(x[R],function(){P=this.call(w,O,M);if(this.cached){x[R].splice(K,1)}if(P===false){return false}K++});return P};function B(){if($f(q)){$f(q).getParent().innerHTML="";p=$f(q).getIndex();a[p]=w}else{a.push(w);p=a.length-1}A=parseInt(q.style.height,10)||q.clientHeight;E=q.id||"fp"+e();r=G.id||E+"_api";G.id=r;t.playerId=E;if(typeof t=="string"){t={clip:{url:t}}}if(typeof t.clip=="string"){t.clip={url:t.clip}}t.clip=t.clip||{};if(q.getAttribute("href",2)&&!t.clip.url){t.clip.url=q.getAttribute("href",2)}s=new h(t.clip,-1,w);t.playlist=t.playlist||[t.clip];var I=0;m(t.playlist,function(){var K=this;if(typeof K=="object"&&K.length){K={url:""+K}}m(t.clip,function(L,M){if(M!==undefined&&K[L]===undefined&&typeof M!="function"){K[L]=M}});t.playlist[I]=K;K=new h(K,I,w);F.push(K);I++});m(t,function(K,L){if(typeof L=="function"){if(s[K]){s[K](L)}else{j(x,K,L)}delete t[K]}});m(t.plugins,function(K,L){if(L){y[K]=new l(K,L,w)}});if(!t.plugins||t.plugins.controls===undefined){y.controls=new l("controls",null,w)}y.canvas=new l("canvas",null,w);u=q.innerHTML;function J(L){var K=w.hasiPadSupport&&w.hasiPadSupport();if(/iPad|iPhone|iPod/i.test(navigator.userAgent)&&!/.flv$/i.test(F[0].url)&&!K){return true}if(!w.isLoaded()&&w._fireEvent("onBeforeClick")!==false){w.load()}return f(L)}function H(){if(u.replace(/\s/g,"")!==""){if(q.addEventListener){q.addEventListener("click",J,false)}else{if(q.attachEvent){q.attachEvent("onclick",J)}}}else{if(q.addEventListener){q.addEventListener("click",f,false)}w.load()}}setTimeout(H,0)}if(typeof q=="string"){var z=c(q);if(!z){throw"Flowplayer cannot access element: "+q}q=z;B()}else{B()}}var a=[];function d(o){this.length=o.length;this.each=function(p){m(o,p)};this.size=function(){return o.length}}window.flowplayer=window.$f=function(){var p=null;var o=arguments[0];if(!arguments.length){m(a,function(){if(this.isLoaded()){p=this;return false}});return p||a[0]}if(arguments.length==1){if(typeof o=="number"){return a[o]}else{if(o=="*"){return new d(a)}m(a,function(){if(this.id()==o.id||this.id()==o||this.getParent()==o){p=this;return false}});return p}}if(arguments.length>1){var t=arguments[1],q=(arguments.length==3)?arguments[2]:{};if(typeof t=="string"){t={src:t}}t=i({bgcolor:"#000000",version:[9,0],expressInstall:"http://static.flowplayer.org/swf/expressinstall.swf",cachebusting:true},t);if(typeof o=="string"){if(o.indexOf(".")!=-1){var s=[];m(n(o),function(){s.push(new b(this,k(t),k(q)))});return new d(s)}else{var r=c(o);return new b(r!==null?r:o,t,q)}}else{if(o){return new b(o,t,q)}}}return null};i(window.$f,{fireEvent:function(){var o=[].slice.call(arguments);var q=$f(o[0]);return q?q._fireEvent(o.slice(1)):null},addPlugin:function(o,p){b.prototype[o]=p;return $f},each:m,extend:i});if(typeof jQuery=="function"){jQuery.fn.flowplayer=function(q,p){if(!arguments.length||typeof arguments[0]=="number"){var o=[];this.each(function(){var r=$f(this);if(r){o.push(r)}});return arguments.length?o[arguments[0]]:new d(o)}return this.each(function(){$f(this,k(q),p?k(p):{})})}}})();(function(){var h=document.all,j="http://www.adobe.com/go/getflashplayer",c=typeof jQuery=="function",e=/(\d+)[^\d]+(\d+)[^\d]*(\d*)/,b={width:"100%",height:"100%",id:"_"+(""+Math.random()).slice(9),allowfullscreen:true,allowscriptaccess:"always",quality:"high",version:[3,0],onFail:null,expressInstall:null,w3c:false,cachebusting:false};if(window.attachEvent){window.attachEvent("onbeforeunload",function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){}})}function i(m,l){if(l){for(var f in l){if(l.hasOwnProperty(f)){m[f]=l[f]}}}return m}function a(f,n){var m=[];for(var l in f){if(f.hasOwnProperty(l)){m[l]=n(f[l])}}return m}window.flashembed=function(f,m,l){if(typeof f=="string"){f=document.getElementById(f.replace("#",""))}if(!f){return}if(typeof m=="string"){m={src:m}}return new d(f,i(i({},b),m),l)};var g=i(window.flashembed,{conf:b,getVersion:function(){var m,f;try{f=navigator.plugins["Shockwave Flash"].description.slice(16)}catch(o){try{m=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");f=m&&m.GetVariable("$version")}catch(n){try{m=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");f=m&&m.GetVariable("$version")}catch(l){}}}f=e.exec(f);return f?[f[1],f[3]]:[0,0]},asString:function(l){if(l===null||l===undefined){return null}var f=typeof l;if(f=="object"&&l.push){f="array"}switch(f){case"string":l=l.replace(new RegExp('(["\\\\])',"g"),"\\$1");l=l.replace(/^\s?(\d+\.?\d+)%/,"$1pct");return'"'+l+'"';case"array":return"["+a(l,function(o){return g.asString(o)}).join(",")+"]";case"function":return'"function()"';case"object":var m=[];for(var n in l){if(l.hasOwnProperty(n)){m.push('"'+n+'":'+g.asString(l[n]))}}return"{"+m.join(",")+"}"}return String(l).replace(/\s/g," ").replace(/\'/g,'"')},getHTML:function(o,l){o=i({},o);var n='<object width="'+o.width+'" height="'+o.height+'" id="'+o.id+'" name="'+o.id+'"';if(o.cachebusting){o.src+=((o.src.indexOf("?")!=-1?"&":"?")+Math.random())}if(o.w3c||!h){n+=' data="'+o.src+'" type="application/x-shockwave-flash"'}else{n+=' classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'}n+=">";if(o.w3c||h){n+='<param name="movie" value="'+o.src+'" />'}o.width=o.height=o.id=o.w3c=o.src=null;o.onFail=o.version=o.expressInstall=null;for(var m in o){if(o[m]){n+='<param name="'+m+'" value="'+o[m]+'" />'}}var p="";if(l){for(var f in l){if(l[f]){var q=l[f];p+=f+"="+(/function|object/.test(typeof q)?g.asString(q):q)+"&"}}p=p.slice(0,-1);n+='<param name="flashvars" value=\''+p+"' />"}n+="</object>";return n},isSupported:function(f){return k[0]>f[0]||k[0]==f[0]&&k[1]>=f[1]}});var k=g.getVersion();function d(f,n,m){if(g.isSupported(n.version)){f.innerHTML=g.getHTML(n,m)}else{if(n.expressInstall&&g.isSupported([6,65])){f.innerHTML=g.getHTML(i(n,{src:n.expressInstall}),{MMredirectURL:location.href,MMplayerType:"PlugIn",MMdoctitle:document.title})}else{if(!f.innerHTML.replace(/\s/g,"")){f.innerHTML="<h2>Flash version "+n.version+" or greater is required</h2><h3>"+(k[0]>0?"Your version is "+k:"You have no flash plugin installed")+"</h3>"+(f.tagName=="A"?"<p>Click here to download latest version</p>":"<p>Download latest version from <a href='"+j+"'>here</a></p>");
21405if(f.tagName=="A"){f.onclick=function(){location.href=j}}}if(n.onFail){var l=n.onFail.call(this);if(typeof l=="string"){f.innerHTML=l}}}}if(h){window[n.id]=document.getElementById(n.id)}i(this,{getRoot:function(){return f},getOptions:function(){return n},getConf:function(){return m},getApi:function(){return f.firstChild}})}if(c){jQuery.tools=jQuery.tools||{version:"3.2.4"};jQuery.tools.flashembed={conf:b};jQuery.fn.flashembed=function(l,f){return this.each(function(){$(this).data("flashembed",flashembed(this,l,f))})}}})();
21406/*!
21407Chosen, a Select Box Enhancer for jQuery and Prototype
21408by Patrick Filler for Harvest, http://getharvest.com
21409
21410Version 1.6.2
21411Full source at https://github.com/harvesthq/chosen
21412Copyright (c) 2011-2016 Harvest http://getharvest.com
21413
21414MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
21415This file is generated by `grunt build`, do not edit it by hand.
21416*/
21417
21418(function() {
21419  var AbstractChosen, SelectParser, _ref,
21420    __hasProp = {}.hasOwnProperty,
21421    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
21422
21423  SelectParser = (function() {
21424    function SelectParser() {
21425      this.options_index = 0;
21426      this.parsed = [];
21427    }
21428
21429    SelectParser.prototype.add_node = function(child) {
21430      if (child.nodeName.toUpperCase() === "OPTGROUP") {
21431        return this.add_group(child);
21432      } else {
21433        return this.add_option(child);
21434      }
21435    };
21436
21437    SelectParser.prototype.add_group = function(group) {
21438      var group_position, option, _i, _len, _ref, _results;
21439      group_position = this.parsed.length;
21440      this.parsed.push({
21441        array_index: group_position,
21442        group: true,
21443        label: this.escapeExpression(group.label),
21444        title: group.title ? group.title : void 0,
21445        children: 0,
21446        disabled: group.disabled,
21447        classes: group.className
21448      });
21449      _ref = group.childNodes;
21450      _results = [];
21451      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
21452        option = _ref[_i];
21453        _results.push(this.add_option(option, group_position, group.disabled));
21454      }
21455      return _results;
21456    };
21457
21458    SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
21459      if (option.nodeName.toUpperCase() === "OPTION") {
21460        if (option.text !== "") {
21461          if (group_position != null) {
21462            this.parsed[group_position].children += 1;
21463          }
21464          this.parsed.push({
21465            array_index: this.parsed.length,
21466            options_index: this.options_index,
21467            value: option.value,
21468            text: option.text,
21469            html: option.innerHTML,
21470            title: option.title ? option.title : void 0,
21471            selected: option.selected,
21472            disabled: group_disabled === true ? group_disabled : option.disabled,
21473            group_array_index: group_position,
21474            group_label: group_position != null ? this.parsed[group_position].label : null,
21475            classes: option.className,
21476            style: option.style.cssText
21477          });
21478        } else {
21479          this.parsed.push({
21480            array_index: this.parsed.length,
21481            options_index: this.options_index,
21482            empty: true
21483          });
21484        }
21485        return this.options_index += 1;
21486      }
21487    };
21488
21489    SelectParser.prototype.escapeExpression = function(text) {
21490      var map, unsafe_chars;
21491      if ((text == null) || text === false) {
21492        return "";
21493      }
21494      if (!/[\&\<\>\"\'\`]/.test(text)) {
21495        return text;
21496      }
21497      map = {
21498        "<": "&lt;",
21499        ">": "&gt;",
21500        '"': "&quot;",
21501        "'": "&#x27;",
21502        "`": "&#x60;"
21503      };
21504      unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g;
21505      return text.replace(unsafe_chars, function(chr) {
21506        return map[chr] || "&amp;";
21507      });
21508    };
21509
21510    return SelectParser;
21511
21512  })();
21513
21514  SelectParser.select_to_array = function(select) {
21515    var child, parser, _i, _len, _ref;
21516    parser = new SelectParser();
21517    _ref = select.childNodes;
21518    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
21519      child = _ref[_i];
21520      parser.add_node(child);
21521    }
21522    return parser.parsed;
21523  };
21524
21525  AbstractChosen = (function() {
21526    function AbstractChosen(form_field, options) {
21527      this.form_field = form_field;
21528      this.options = options != null ? options : {};
21529      if (!AbstractChosen.browser_is_supported()) {
21530        return;
21531      }
21532      this.is_multiple = this.form_field.multiple;
21533      this.set_default_text();
21534      this.set_default_values();
21535      this.setup();
21536      this.set_up_html();
21537      this.register_observers();
21538      this.on_ready();
21539    }
21540
21541    AbstractChosen.prototype.set_default_values = function() {
21542      var _this = this;
21543      this.click_test_action = function(evt) {
21544        return _this.test_active_click(evt);
21545      };
21546      this.activate_action = function(evt) {
21547        return _this.activate_field(evt);
21548      };
21549      this.active_field = false;
vendor: 13,148 bytes, lines 21550-21909
21550      this.mouse_on_container = false;
21551      this.results_showing = false;
21552      this.result_highlighted = null;
21553      this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
21554      this.disable_search_threshold = this.options.disable_search_threshold || 0;
21555      this.disable_search = this.options.disable_search || false;
21556      this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
21557      this.group_search = this.options.group_search != null ? this.options.group_search : true;
21558      this.search_contains = this.options.search_contains || false;
21559      this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true;
21560      this.max_selected_options = this.options.max_selected_options || Infinity;
21561      this.inherit_select_classes = this.options.inherit_select_classes || false;
21562      this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true;
21563      this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true;
21564      this.include_group_label_in_selected = this.options.include_group_label_in_selected || false;
21565      this.max_shown_results = this.options.max_shown_results || Number.POSITIVE_INFINITY;
21566      return this.case_sensitive_search = this.options.case_sensitive_search || false;
21567    };
21568
21569    AbstractChosen.prototype.set_default_text = function() {
21570      if (this.form_field.getAttribute("data-placeholder")) {
21571        this.default_text = this.form_field.getAttribute("data-placeholder");
21572      } else if (this.is_multiple) {
21573        this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
21574      } else {
21575        this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
21576      }
21577      return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text;
21578    };
21579
21580    AbstractChosen.prototype.choice_label = function(item) {
21581      if (this.include_group_label_in_selected && (item.group_label != null)) {
21582        return "<b class='group-name'>" + item.group_label + "</b>" + item.html;
21583      } else {
21584        return item.html;
21585      }
21586    };
21587
21588    AbstractChosen.prototype.mouse_enter = function() {
21589      return this.mouse_on_container = true;
21590    };
21591
21592    AbstractChosen.prototype.mouse_leave = function() {
21593      return this.mouse_on_container = false;
21594    };
21595
21596    AbstractChosen.prototype.input_focus = function(evt) {
21597      var _this = this;
21598      if (this.is_multiple) {
21599        if (!this.active_field) {
21600          return setTimeout((function() {
21601            return _this.container_mousedown();
21602          }), 50);
21603        }
21604      } else {
21605        if (!this.active_field) {
21606          return this.activate_field();
21607        }
21608      }
21609    };
21610
21611    AbstractChosen.prototype.input_blur = function(evt) {
21612      var _this = this;
21613      if (!this.mouse_on_container) {
21614        this.active_field = false;
21615        return setTimeout((function() {
21616          return _this.blur_test();
21617        }), 100);
21618      }
21619    };
21620
21621    AbstractChosen.prototype.results_option_build = function(options) {
21622      var content, data, data_content, shown_results, _i, _len, _ref;
21623      content = '';
21624      shown_results = 0;
21625      _ref = this.results_data;
21626      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
21627        data = _ref[_i];
21628        data_content = '';
21629        if (data.group) {
21630          data_content = this.result_add_group(data);
21631        } else {
21632          data_content = this.result_add_option(data);
21633        }
21634        if (data_content !== '') {
21635          shown_results++;
21636          content += data_content;
21637        }
21638        if (options != null ? options.first : void 0) {
21639          if (data.selected && this.is_multiple) {
21640            this.choice_build(data);
21641          } else if (data.selected && !this.is_multiple) {
21642            this.single_set_selected_text(this.choice_label(data));
21643          }
21644        }
21645        if (shown_results >= this.max_shown_results) {
21646          break;
21647        }
21648      }
21649      return content;
21650    };
21651
21652    AbstractChosen.prototype.result_add_option = function(option) {
21653      var classes, option_el;
21654      if (!option.search_match) {
21655        return '';
21656      }
21657      if (!this.include_option_in_results(option)) {
21658        return '';
21659      }
21660      classes = [];
21661      if (!option.disabled && !(option.selected && this.is_multiple)) {
21662        classes.push("active-result");
21663      }
21664      if (option.disabled && !(option.selected && this.is_multiple)) {
21665        classes.push("disabled-result");
21666      }
21667      if (option.selected) {
21668        classes.push("result-selected");
21669      }
21670      if (option.group_array_index != null) {
21671        classes.push("group-option");
21672      }
21673      if (option.classes !== "") {
21674        classes.push(option.classes);
21675      }
21676      option_el = document.createElement("li");
21677      option_el.className = classes.join(" ");
21678      option_el.style.cssText = option.style;
21679      option_el.setAttribute("data-option-array-index", option.array_index);
21680      option_el.innerHTML = option.search_text;
21681      if (option.title) {
21682        option_el.title = option.title;
21683      }
21684      return this.outerHTML(option_el);
21685    };
21686
21687    AbstractChosen.prototype.result_add_group = function(group) {
21688      var classes, group_el;
21689      if (!(group.search_match || group.group_match)) {
21690        return '';
21691      }
21692      if (!(group.active_options > 0)) {
21693        return '';
21694      }
21695      classes = [];
21696      classes.push("group-result");
21697      if (group.classes) {
21698        classes.push(group.classes);
21699      }
21700      group_el = document.createElement("li");
21701      group_el.className = classes.join(" ");
21702      group_el.innerHTML = group.search_text;
21703      if (group.title) {
21704        group_el.title = group.title;
21705      }
21706      return this.outerHTML(group_el);
21707    };
21708
21709    AbstractChosen.prototype.results_update_field = function() {
21710      this.set_default_text();
21711      if (!this.is_multiple) {
21712        this.results_reset_cleanup();
21713      }
21714      this.result_clear_highlight();
21715      this.results_build();
21716      if (this.results_showing) {
21717        return this.winnow_results();
21718      }
21719    };
21720
21721    AbstractChosen.prototype.reset_single_select_options = function() {
21722      var result, _i, _len, _ref, _results;
21723      _ref = this.results_data;
21724      _results = [];
21725      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
21726        result = _ref[_i];
21727        if (result.selected) {
21728          _results.push(result.selected = false);
21729        } else {
21730          _results.push(void 0);
21731        }
21732      }
21733      return _results;
21734    };
21735
21736    AbstractChosen.prototype.results_toggle = function() {
21737      if (this.results_showing) {
21738        return this.results_hide();
21739      } else {
21740        return this.results_show();
21741      }
21742    };
21743
21744    AbstractChosen.prototype.results_search = function(evt) {
21745      if (this.results_showing) {
21746        return this.winnow_results();
21747      } else {
21748        return this.results_show();
21749      }
21750    };
21751
21752    AbstractChosen.prototype.winnow_results = function() {
21753      var escapedSearchText, option, regex, results, results_group, searchText, startpos, text, zregex, _i, _len, _ref;
21754      this.no_results_clear();
21755      results = 0;
21756      searchText = this.get_search_text();
21757      escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
21758      zregex = new RegExp(escapedSearchText, 'i');
21759      regex = this.get_search_regex(escapedSearchText);
21760      _ref = this.results_data;
21761      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
21762        option = _ref[_i];
21763        option.search_match = false;
21764        results_group = null;
21765        if (this.include_option_in_results(option)) {
21766          if (option.group) {
21767            option.group_match = false;
21768            option.active_options = 0;
21769          }
21770          if ((option.group_array_index != null) && this.results_data[option.group_array_index]) {
21771            results_group = this.results_data[option.group_array_index];
21772            if (results_group.active_options === 0 && results_group.search_match) {
21773              results += 1;
21774            }
21775            results_group.active_options += 1;
21776          }
21777          option.search_text = option.group ? option.label : option.html;
21778          if (!(option.group && !this.group_search)) {
21779            option.search_match = this.search_string_match(option.search_text, regex);
21780            if (option.search_match && !option.group) {
21781              results += 1;
21782            }
21783            if (option.search_match) {
21784              if (searchText.length) {
21785                startpos = option.search_text.search(zregex);
21786                text = option.search_text.substr(0, startpos + searchText.length) + '</em>' + option.search_text.substr(startpos + searchText.length);
21787                option.search_text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
21788              }
21789              if (results_group != null) {
21790                results_group.group_match = true;
21791              }
21792            } else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) {
21793              option.search_match = true;
21794            }
21795          }
21796        }
21797      }
21798      this.result_clear_highlight();
21799      if (results < 1 && searchText.length) {
21800        this.update_results_content("");
21801        return this.no_results(searchText);
21802      } else {
21803        this.update_results_content(this.results_option_build());
21804        return this.winnow_results_set_highlight();
21805      }
21806    };
21807
21808    AbstractChosen.prototype.get_search_regex = function(escaped_search_string) {
21809      var regex_anchor, regex_flag;
21810      regex_anchor = this.search_contains ? "" : "^";
21811      regex_flag = this.case_sensitive_search ? "" : "i";
21812      return new RegExp(regex_anchor + escaped_search_string, regex_flag);
21813    };
21814
21815    AbstractChosen.prototype.search_string_match = function(search_string, regex) {
21816      var part, parts, _i, _len;
21817      if (regex.test(search_string)) {
21818        return true;
21819      } else if (this.enable_split_word_search && (search_string.indexOf(" ") >= 0 || search_string.indexOf("[") === 0)) {
21820        parts = search_string.replace(/\[|\]/g, "").split(" ");
21821        if (parts.length) {
21822          for (_i = 0, _len = parts.length; _i < _len; _i++) {
21823            part = parts[_i];
21824            if (regex.test(part)) {
21825              return true;
21826            }
21827          }
21828        }
21829      }
21830    };
21831
21832    AbstractChosen.prototype.choices_count = function() {
21833      var option, _i, _len, _ref;
21834      if (this.selected_option_count != null) {
21835        return this.selected_option_count;
21836      }
21837      this.selected_option_count = 0;
21838      _ref = this.form_field.options;
21839      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
21840        option = _ref[_i];
21841        if (option.selected) {
21842          this.selected_option_count += 1;
21843        }
21844      }
21845      return this.selected_option_count;
21846    };
21847
21848    AbstractChosen.prototype.choices_click = function(evt) {
21849      evt.preventDefault();
21850      if (!(this.results_showing || this.is_disabled)) {
21851        return this.results_show();
21852      }
21853    };
21854
21855    AbstractChosen.prototype.keyup_checker = function(evt) {
21856      var stroke, _ref;
21857      stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
21858      this.search_field_scale();
21859      switch (stroke) {
21860        case 8:
21861          if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) {
21862            return this.keydown_backstroke();
21863          } else if (!this.pending_backstroke) {
21864            this.result_clear_highlight();
21865            return this.results_search();
21866          }
21867          break;
21868        case 13:
21869          evt.preventDefault();
21870          if (this.results_showing) {
21871            return this.result_select(evt);
21872          }
21873          break;
21874        case 27:
21875          if (this.results_showing) {
21876            this.results_hide();
21877          }
21878          return true;
21879        case 9:
21880        case 38:
21881        case 40:
21882        case 16:
21883        case 91:
21884        case 17:
21885        case 18:
21886          break;
21887        default:
21888          return this.results_search();
21889      }
21890    };
21891
21892    AbstractChosen.prototype.clipboard_event_checker = function(evt) {
21893      var _this = this;
21894      return setTimeout((function() {
21895        return _this.results_search();
21896      }), 50);
21897    };
21898
21899    AbstractChosen.prototype.container_width = function() {
21900      if (this.options.width != null) {
21901        return this.options.width;
21902      } else {
21903        return "" + this.form_field.offsetWidth + "px";
21904      }
21905    };
21906
21907    AbstractChosen.prototype.include_option_in_results = function(option) {
21908      if (this.is_multiple && (!this.display_selected_options && option.selected)) {
21909        return false;
21910      }
21911      if (!this.display_disabled_options && option.disabled) {
21912        return false;
21913      }
21914      if (option.empty) {
21915        return false;
21916      }
21917      return true;
21918    };
21919
21920    AbstractChosen.prototype.search_results_touchstart = function(evt) {
21921      this.touch_started = true;
21922      return this.search_results_mouseover(evt);
21923    };
21924
21925    AbstractChosen.prototype.search_results_touchmove = function(evt) {
21926      this.touch_started = false;
21927      return this.search_results_mouseout(evt);
21928    };
21929
21930    AbstractChosen.prototype.search_results_touchend = function(evt) {
21931      if (this.touch_started) {
21932        return this.search_results_mouseup(evt);
21933      }
21934    };
21935
21936    AbstractChosen.prototype.outerHTML = function(element) {
21937      var tmp;
21938      if (element.outerHTML) {
21939        return element.outerHTML;
21940      }
21941      tmp = document.createElement("div");
21942      tmp.appendChild(element);
21943      return tmp.innerHTML;
21944    };
21945
21946    AbstractChosen.browser_is_supported = function() {
21947      if ("Microsoft Internet Explorer" === window.navigator.appName) {
21948        return document.documentMode >= 8;
21949      }
21950      if (/iP(od|hone)/i.test(window.navigator.userAgent) || /IEMobile/i.test(window.navigator.userAgent) || /Windows Phone/i.test(window.navigator.userAgent) || /BlackBerry/i.test(window.navigator.userAgent) || /BB10/i.test(window.navigator.userAgent) || /Android.*Mobile/i.test(window.navigator.userAgent)) {
21951        return false;
21952      }
21953      return true;
21954    };
21955
21956    AbstractChosen.default_multiple_text = "Select Some Options";
21957
21958    AbstractChosen.default_single_text = "Select an Option";
21959
21960    AbstractChosen.default_no_result_text = "No results match";
21961
21962    return AbstractChosen;
21963
21964  })();
21965
21966  this.Chosen = (function(_super) {
21967    __extends(Chosen, _super);
21968
21969    function Chosen() {
21970      _ref = Chosen.__super__.constructor.apply(this, arguments);
21971      return _ref;
21972    }
21973
21974    Chosen.prototype.setup = function() {
21975      this.current_selectedIndex = this.form_field.selectedIndex;
21976      return this.is_rtl = this.form_field.hasClassName("chosen-rtl");
21977    };
21978
21979    Chosen.prototype.set_default_values = function() {
21980      Chosen.__super__.set_default_values.call(this);
21981      this.single_temp = new Template('<a class="chosen-single chosen-default"><span>#{default}</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>');
21982      this.multi_temp = new Template('<ul class="chosen-choices"><li class="search-field"><input type="text" value="#{default}" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>');
21983      return this.no_results_temp = new Template('<li class="no-results">' + this.results_none_found + ' "<span>#{terms}</span>"</li>');
21984    };
21985
21986    Chosen.prototype.set_up_html = function() {
21987      var container_classes, container_props;
21988      container_classes = ["chosen-container"];
21989      container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single"));
21990      if (this.inherit_select_classes && this.form_field.className) {
21991        container_classes.push(this.form_field.className);
21992      }
21993      if (this.is_rtl) {
21994        container_classes.push("chosen-rtl");
21995      }
21996      container_props = {
21997        'class': container_classes.join(' '),
21998        'style': "width: " + (this.container_width()) + ";",
21999        'title': this.form_field.title
22000      };
22001      if (this.form_field.id.length) {
22002        container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen";
22003      }
22004      this.container = this.is_multiple ? new Element('div', container_props).update(this.multi_temp.evaluate({
22005        "default": this.default_text
22006      })) : new Element('div', container_props).update(this.single_temp.evaluate({
22007        "default": this.default_text
22008      }));
22009      this.form_field.hide().insert({
22010        after: this.container
22011      });
22012      this.dropdown = this.container.down('div.chosen-drop');
22013      this.search_field = this.container.down('input');
22014      this.search_results = this.container.down('ul.chosen-results');
22015      this.search_field_scale();
22016      this.search_no_results = this.container.down('li.no-results');
22017      if (this.is_multiple) {
22018        this.search_choices = this.container.down('ul.chosen-choices');
22019        this.search_container = this.container.down('li.search-field');
22020      } else {
22021        this.search_container = this.container.down('div.chosen-search');
22022        this.selected_item = this.container.down('.chosen-single');
22023      }
22024      this.results_build();
22025      this.set_tab_index();
22026      return this.set_label_behavior();
22027    };
22028
22029    Chosen.prototype.on_ready = function() {
22030      return this.form_field.fire("chosen:ready", {
22031        chosen: this
22032      });
22033    };
22034
22035    Chosen.prototype.register_observers = function() {
22036      var _this = this;
22037      this.container.observe("touchstart", function(evt) {
22038        _this.container_mousedown(evt);
22039        return evt.preventDefault();
22040      });
22041      this.container.observe("touchend", function(evt) {
22042        _this.container_mouseup(evt);
22043        return evt.preventDefault();
22044      });
22045      this.container.observe("mousedown", function(evt) {
22046        return _this.container_mousedown(evt);
22047      });
22048      this.container.observe("mouseup", function(evt) {
22049        return _this.container_mouseup(evt);
22050      });
22051      this.container.observe("mouseenter", function(evt) {
22052        return _this.mouse_enter(evt);
22053      });
22054      this.container.observe("mouseleave", function(evt) {
22055        return _this.mouse_leave(evt);
22056      });
22057      this.search_results.observe("mouseup", function(evt) {
22058        return _this.search_results_mouseup(evt);
22059      });
22060      this.search_results.observe("mouseover", function(evt) {
22061        return _this.search_results_mouseover(evt);
22062      });
22063      this.search_results.observe("mouseout", function(evt) {
22064        return _this.search_results_mouseout(evt);
22065      });
22066      this.search_results.observe("mousewheel", function(evt) {
22067        return _this.search_results_mousewheel(evt);
22068      });
22069      this.search_results.observe("DOMMouseScroll", function(evt) {
22070        return _this.search_results_mousewheel(evt);
22071      });
22072      this.search_results.observe("touchstart", function(evt) {
22073        return _this.search_results_touchstart(evt);
22074      });
22075      this.search_results.observe("touchmove", function(evt) {
22076        return _this.search_results_touchmove(evt);
22077      });
22078      this.search_results.observe("touchend", function(evt) {
22079        return _this.search_results_touchend(evt);
22080      });
22081      this.form_field.observe("chosen:updated", function(evt) {
22082        return _this.results_update_field(evt);
22083      });
22084      this.form_field.observe("chosen:activate", function(evt) {
22085        return _this.activate_field(evt);
22086      });
22087      this.form_field.observe("chosen:open", function(evt) {
22088        return _this.container_mousedown(evt);
22089      });
22090      this.form_field.observe("chosen:close", function(evt) {
22091        return _this.input_blur(evt);
22092      });
22093      this.search_field.observe("blur", function(evt) {
22094        return _this.input_blur(evt);
22095      });
22096      this.search_field.observe("keyup", function(evt) {
22097        return _this.keyup_checker(evt);
22098      });
22099      this.search_field.observe("keydown", function(evt) {
22100        return _this.keydown_checker(evt);
22101      });
22102      this.search_field.observe("focus", function(evt) {
22103        return _this.input_focus(evt);
22104      });
22105      this.search_field.observe("cut", function(evt) {
22106        return _this.clipboard_event_checker(evt);
22107      });
22108      this.search_field.observe("paste", function(evt) {
22109        return _this.clipboard_event_checker(evt);
22110      });
22111      if (this.is_multiple) {
22112        return this.search_choices.observe("click", function(evt) {
22113          return _this.choices_click(evt);
22114        });
22115      } else {
22116        return this.container.observe("click", function(evt) {
22117          return evt.preventDefault();
22118        });
22119      }
22120    };
22121
22122    Chosen.prototype.destroy = function() {
22123      this.container.ownerDocument.stopObserving("click", this.click_test_action);
22124      this.form_field.stopObserving();
22125      this.container.stopObserving();
22126      this.search_results.stopObserving();
22127      this.search_field.stopObserving();
22128      if (this.form_field_label != null) {
22129        this.form_field_label.stopObserving();
22130      }
22131      if (this.is_multiple) {
22132        this.search_choices.stopObserving();
22133        this.container.select(".search-choice-close").each(function(choice) {
22134          return choice.stopObserving();
22135        });
22136      } else {
22137        this.selected_item.stopObserving();
22138      }
22139      if (this.search_field.tabIndex) {
22140        this.form_field.tabIndex = this.search_field.tabIndex;
22141      }
22142      this.container.remove();
22143      return this.form_field.show();
22144    };
22145
22146    Chosen.prototype.search_field_disabled = function() {
22147      this.is_disabled = this.form_field.disabled;
22148      if (this.is_disabled) {
22149        this.container.addClassName('chosen-disabled');
22150        this.search_field.disabled = true;
22151        if (!this.is_multiple) {
22152          this.selected_item.stopObserving("focus", this.activate_action);
22153        }
22154        return this.close_field();
22155      } else {
22156        this.container.removeClassName('chosen-disabled');
22157        this.search_field.disabled = false;
vendor: 14,973 bytes, lines 22158-22598
22158        if (!this.is_multiple) {
22159          return this.selected_item.observe("focus", this.activate_action);
22160        }
22161      }
22162    };
22163
22164    Chosen.prototype.container_mousedown = function(evt) {
22165      if (!this.is_disabled) {
22166        if (evt && evt.type === "mousedown" && !this.results_showing) {
22167          evt.stop();
22168        }
22169        if (!((evt != null) && evt.target.hasClassName("search-choice-close"))) {
22170          if (!this.active_field) {
22171            if (this.is_multiple) {
22172              this.search_field.clear();
22173            }
22174            this.container.ownerDocument.observe("click", this.click_test_action);
22175            this.results_show();
22176          } else if (!this.is_multiple && evt && (evt.target === this.selected_item || evt.target.up("a.chosen-single"))) {
22177            this.results_toggle();
22178          }
22179          return this.activate_field();
22180        }
22181      }
22182    };
22183
22184    Chosen.prototype.container_mouseup = function(evt) {
22185      if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
22186        return this.results_reset(evt);
22187      }
22188    };
22189
22190    Chosen.prototype.search_results_mousewheel = function(evt) {
22191      var delta;
22192      delta = evt.deltaY || -evt.wheelDelta || evt.detail;
22193      if (delta != null) {
22194        evt.preventDefault();
22195        if (evt.type === 'DOMMouseScroll') {
22196          delta = delta * 40;
22197        }
22198        return this.search_results.scrollTop = delta + this.search_results.scrollTop;
22199      }
22200    };
22201
22202    Chosen.prototype.blur_test = function(evt) {
22203      if (!this.active_field && this.container.hasClassName("chosen-container-active")) {
22204        return this.close_field();
22205      }
22206    };
22207
22208    Chosen.prototype.close_field = function() {
22209      this.container.ownerDocument.stopObserving("click", this.click_test_action);
22210      this.active_field = false;
22211      this.results_hide();
22212      this.container.removeClassName("chosen-container-active");
22213      this.clear_backstroke();
22214      this.show_search_field_default();
22215      return this.search_field_scale();
22216    };
22217
22218    Chosen.prototype.activate_field = function() {
22219      this.container.addClassName("chosen-container-active");
22220      this.active_field = true;
22221      this.search_field.value = this.search_field.value;
22222      return this.search_field.focus();
22223    };
22224
22225    Chosen.prototype.test_active_click = function(evt) {
22226      if (evt.target.up('.chosen-container') === this.container) {
22227        return this.active_field = true;
22228      } else {
22229        return this.close_field();
22230      }
22231    };
22232
22233    Chosen.prototype.results_build = function() {
22234      this.parsing = true;
22235      this.selected_option_count = null;
22236      this.results_data = SelectParser.select_to_array(this.form_field);
22237      if (this.is_multiple) {
22238        this.search_choices.select("li.search-choice").invoke("remove");
22239      } else if (!this.is_multiple) {
22240        this.single_set_selected_text();
22241        if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
22242          this.search_field.readOnly = true;
22243          this.container.addClassName("chosen-container-single-nosearch");
22244        } else {
22245          this.search_field.readOnly = false;
22246          this.container.removeClassName("chosen-container-single-nosearch");
22247        }
22248      }
22249      this.update_results_content(this.results_option_build({
22250        first: true
22251      }));
22252      this.search_field_disabled();
22253      this.show_search_field_default();
22254      this.search_field_scale();
22255      return this.parsing = false;
22256    };
22257
22258    Chosen.prototype.result_do_highlight = function(el) {
22259      var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
22260      this.result_clear_highlight();
22261      this.result_highlight = el;
22262      this.result_highlight.addClassName("highlighted");
22263      maxHeight = parseInt(this.search_results.getStyle('maxHeight'), 10);
22264      visible_top = this.search_results.scrollTop;
22265      visible_bottom = maxHeight + visible_top;
22266      high_top = this.result_highlight.positionedOffset().top;
22267      high_bottom = high_top + this.result_highlight.getHeight();
22268      if (high_bottom >= visible_bottom) {
22269        return this.search_results.scrollTop = (high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0;
22270      } else if (high_top < visible_top) {
22271        return this.search_results.scrollTop = high_top;
22272      }
22273    };
22274
22275    Chosen.prototype.result_clear_highlight = function() {
22276      if (this.result_highlight) {
22277        this.result_highlight.removeClassName('highlighted');
22278      }
22279      return this.result_highlight = null;
22280    };
22281
22282    Chosen.prototype.results_show = function() {
22283      if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
22284        this.form_field.fire("chosen:maxselected", {
22285          chosen: this
22286        });
22287        return false;
22288      }
22289      this.container.addClassName("chosen-with-drop");
22290      this.results_showing = true;
22291      this.search_field.focus();
22292      this.search_field.value = this.search_field.value;
22293      this.winnow_results();
22294      return this.form_field.fire("chosen:showing_dropdown", {
22295        chosen: this
22296      });
22297    };
22298
22299    Chosen.prototype.update_results_content = function(content) {
22300      return this.search_results.update(content);
22301    };
22302
22303    Chosen.prototype.results_hide = function() {
22304      if (this.results_showing) {
22305        this.result_clear_highlight();
22306        this.container.removeClassName("chosen-with-drop");
22307        this.form_field.fire("chosen:hiding_dropdown", {
22308          chosen: this
22309        });
22310      }
22311      return this.results_showing = false;
22312    };
22313
22314    Chosen.prototype.set_tab_index = function(el) {
22315      var ti;
22316      if (this.form_field.tabIndex) {
22317        ti = this.form_field.tabIndex;
22318        this.form_field.tabIndex = -1;
22319        return this.search_field.tabIndex = ti;
22320      }
22321    };
22322
22323    Chosen.prototype.set_label_behavior = function() {
22324      var _this = this;
22325      this.form_field_label = this.form_field.up("label");
22326      if (this.form_field_label == null) {
22327        this.form_field_label = $$("label[for='" + this.form_field.id + "']").first();
22328      }
22329      if (this.form_field_label != null) {
22330        return this.form_field_label.observe("click", function(evt) {
22331          if (_this.is_multiple) {
22332            return _this.container_mousedown(evt);
22333          } else {
22334            return _this.activate_field();
22335          }
22336        });
22337      }
22338    };
22339
22340    Chosen.prototype.show_search_field_default = function() {
22341      if (this.is_multiple && this.choices_count() < 1 && !this.active_field) {
22342        this.search_field.value = this.default_text;
22343        return this.search_field.addClassName("default");
22344      } else {
22345        this.search_field.value = "";
22346        return this.search_field.removeClassName("default");
22347      }
22348    };
22349
22350    Chosen.prototype.search_results_mouseup = function(evt) {
22351      var target;
22352      target = evt.target.hasClassName("active-result") ? evt.target : evt.target.up(".active-result");
22353      if (target) {
22354        this.result_highlight = target;
22355        this.result_select(evt);
22356        return this.search_field.focus();
22357      }
22358    };
22359
22360    Chosen.prototype.search_results_mouseover = function(evt) {
22361      var target;
22362      target = evt.target.hasClassName("active-result") ? evt.target : evt.target.up(".active-result");
22363      if (target) {
22364        return this.result_do_highlight(target);
22365      }
22366    };
22367
22368    Chosen.prototype.search_results_mouseout = function(evt) {
22369      if (evt.target.hasClassName('active-result') || evt.target.up('.active-result')) {
22370        return this.result_clear_highlight();
22371      }
22372    };
22373
22374    Chosen.prototype.choice_build = function(item) {
22375      var choice, close_link,
22376        _this = this;
22377      choice = new Element('li', {
22378        "class": "search-choice"
22379      }).update("<span>" + (this.choice_label(item)) + "</span>");
22380      if (item.disabled) {
22381        choice.addClassName('search-choice-disabled');
22382      } else {
22383        close_link = new Element('a', {
22384          href: '#',
22385          "class": 'search-choice-close',
22386          rel: item.array_index
22387        });
22388        close_link.observe("click", function(evt) {
22389          return _this.choice_destroy_link_click(evt);
22390        });
22391        choice.insert(close_link);
22392      }
22393      return this.search_container.insert({
22394        before: choice
22395      });
22396    };
22397
22398    Chosen.prototype.choice_destroy_link_click = function(evt) {
22399      evt.preventDefault();
22400      evt.stopPropagation();
22401      if (!this.is_disabled) {
22402        return this.choice_destroy(evt.target);
22403      }
22404    };
22405
22406    Chosen.prototype.choice_destroy = function(link) {
22407      if (this.result_deselect(link.readAttribute("rel"))) {
22408        this.show_search_field_default();
22409        if (this.is_multiple && this.choices_count() > 0 && this.search_field.value.length < 1) {
22410          this.results_hide();
22411        }
22412        link.up('li').remove();
22413        return this.search_field_scale();
22414      }
22415    };
22416
22417    Chosen.prototype.results_reset = function() {
22418      this.reset_single_select_options();
22419      this.form_field.options[0].selected = true;
22420      this.single_set_selected_text();
22421      this.show_search_field_default();
22422      this.results_reset_cleanup();
22423      if (typeof Event.simulate === 'function') {
22424        this.form_field.simulate("change");
22425      }
22426      if (this.active_field) {
22427        return this.results_hide();
22428      }
22429    };
22430
22431    Chosen.prototype.results_reset_cleanup = function() {
22432      var deselect_trigger;
22433      this.current_selectedIndex = this.form_field.selectedIndex;
22434      deselect_trigger = this.selected_item.down("abbr");
22435      if (deselect_trigger) {
22436        return deselect_trigger.remove();
22437      }
22438    };
22439
22440    Chosen.prototype.result_select = function(evt) {
22441      var high, item;
22442      if (this.result_highlight) {
22443        high = this.result_highlight;
22444        this.result_clear_highlight();
22445        if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
22446          this.form_field.fire("chosen:maxselected", {
22447            chosen: this
22448          });
22449          return false;
22450        }
22451        if (this.is_multiple) {
22452          high.removeClassName("active-result");
22453        } else {
22454          this.reset_single_select_options();
22455        }
22456        high.addClassName("result-selected");
22457        item = this.results_data[high.getAttribute("data-option-array-index")];
22458        item.selected = true;
22459        this.form_field.options[item.options_index].selected = true;
22460        this.selected_option_count = null;
22461        if (this.is_multiple) {
22462          this.choice_build(item);
22463        } else {
22464          this.single_set_selected_text(this.choice_label(item));
22465        }
22466        if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) {
22467          this.results_hide();
22468        }
22469        this.show_search_field_default();
22470        if (typeof Event.simulate === 'function' && (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex)) {
22471          this.form_field.simulate("change");
22472        }
22473        this.current_selectedIndex = this.form_field.selectedIndex;
22474        evt.preventDefault();
22475        return this.search_field_scale();
22476      }
22477    };
22478
22479    Chosen.prototype.single_set_selected_text = function(text) {
22480      if (text == null) {
22481        text = this.default_text;
22482      }
22483      if (text === this.default_text) {
22484        this.selected_item.addClassName("chosen-default");
22485      } else {
22486        this.single_deselect_control_build();
22487        this.selected_item.removeClassName("chosen-default");
22488      }
22489      return this.selected_item.down("span").update(text);
22490    };
22491
22492    Chosen.prototype.result_deselect = function(pos) {
22493      var result_data;
22494      result_data = this.results_data[pos];
22495      if (!this.form_field.options[result_data.options_index].disabled) {
22496        result_data.selected = false;
22497        this.form_field.options[result_data.options_index].selected = false;
22498        this.selected_option_count = null;
22499        this.result_clear_highlight();
22500        if (this.results_showing) {
22501          this.winnow_results();
22502        }
22503        if (typeof Event.simulate === 'function') {
22504          this.form_field.simulate("change");
22505        }
22506        this.search_field_scale();
22507        return true;
22508      } else {
22509        return false;
22510      }
22511    };
22512
22513    Chosen.prototype.single_deselect_control_build = function() {
22514      if (!this.allow_single_deselect) {
22515        return;
22516      }
22517      if (!this.selected_item.down("abbr")) {
22518        this.selected_item.down("span").insert({
22519          after: "<abbr class=\"search-choice-close\"></abbr>"
22520        });
22521      }
22522      return this.selected_item.addClassName("chosen-single-with-deselect");
22523    };
22524
22525    Chosen.prototype.get_search_text = function() {
22526      return this.search_field.value.strip().escapeHTML();
22527    };
22528
22529    Chosen.prototype.winnow_results_set_highlight = function() {
22530      var do_high;
22531      if (!this.is_multiple) {
22532        do_high = this.search_results.down(".result-selected.active-result");
22533      }
22534      if (do_high == null) {
22535        do_high = this.search_results.down(".active-result");
22536      }
22537      if (do_high != null) {
22538        return this.result_do_highlight(do_high);
22539      }
22540    };
22541
22542    Chosen.prototype.no_results = function(terms) {
22543      this.search_results.insert(this.no_results_temp.evaluate({
22544        terms: terms
22545      }));
22546      return this.form_field.fire("chosen:no_results", {
22547        chosen: this
22548      });
22549    };
22550
22551    Chosen.prototype.no_results_clear = function() {
22552      var nr, _results;
22553      nr = null;
22554      _results = [];
22555      while (nr = this.search_results.down(".no-results")) {
22556        _results.push(nr.remove());
22557      }
22558      return _results;
22559    };
22560
22561    Chosen.prototype.keydown_arrow = function() {
22562      var next_sib;
22563      if (this.results_showing && this.result_highlight) {
22564        next_sib = this.result_highlight.next('.active-result');
22565        if (next_sib) {
22566          return this.result_do_highlight(next_sib);
22567        }
22568      } else {
22569        return this.results_show();
22570      }
22571    };
22572
22573    Chosen.prototype.keyup_arrow = function() {
22574      var actives, prevs, sibs;
22575      if (!this.results_showing && !this.is_multiple) {
22576        return this.results_show();
22577      } else if (this.result_highlight) {
22578        sibs = this.result_highlight.previousSiblings();
22579        actives = this.search_results.select("li.active-result");
22580        prevs = sibs.intersect(actives);
22581        if (prevs.length) {
22582          return this.result_do_highlight(prevs.first());
22583        } else {
22584          if (this.choices_count() > 0) {
22585            this.results_hide();
22586          }
22587          return this.result_clear_highlight();
22588        }
22589      }
22590    };
22591
22592    Chosen.prototype.keydown_backstroke = function() {
22593      var next_available_destroy;
22594      if (this.pending_backstroke) {
22595        this.choice_destroy(this.pending_backstroke.down("a"));
22596        return this.clear_backstroke();
22597      } else {
22598        next_available_destroy = this.search_container.siblings().last(
22598);
22599        if (next_available_destroy && next_available_destroy.hasClassName("search-choice") && !next_available_destroy.hasClassName("search-choice-disabled")) {
22600          this.pending_backstroke = next_available_destroy;
22601          if (this.pending_backstroke) {
22602            this.pending_backstroke.addClassName("search-choice-focus");
22603          }
22604          if (this.single_backstroke_delete) {
22605            return this.keydown_backstroke();
22606          } else {
22607            return this.pending_backstroke.addClassName("search-choice-focus");
22608          }
22609        }
22610      }
22611    };
22612
22613    Chosen.prototype.clear_backstroke = function() {
22614      if (this.pending_backstroke) {
22615        this.pending_backstroke.removeClassName("search-choice-focus");
22616      }
22617      return this.pending_backstroke = null;
22618    };
22619
22620    Chosen.prototype.keydown_checker = function(evt) {
22621      var stroke, _ref1;
22622      stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode;
22623      this.search_field_scale();
22624      if (stroke !== 8 && this.pending_backstroke) {
22625        this.clear_backstroke();
22626      }
22627      switch (stroke) {
22628        case 8:
22629          this.backstroke_length = this.search_field.value.length;
22630          break;
22631        case 9:
22632          if (this.results_showing && !this.is_multiple) {
22633            this.result_select(evt);
22634          }
22635          this.mouse_on_container = false;
22636          break;
22637        case 13:
22638          if (this.results_showing) {
22639            evt.preventDefault();
22640          }
22641          break;
22642        case 32:
22643          if (this.disable_search) {
22644            evt.preventDefault();
22645          }
22646          break;
22647        case 38:
22648          evt.preventDefault();
22649          this.keyup_arrow();
22650          break;
22651        case 40:
22652          evt.preventDefault();
22653          this.keydown_arrow();
22654          break;
22655      }
22656    };
22657
22658    Chosen.prototype.search_field_scale = function() {
22659      var div, f_width, h, style, style_block, styles, w, _i, _len;
22660      if (this.is_multiple) {
22661        h = 0;
22662        w = 0;
22663        style_block = "position:absolute; left: -1000px; top: -1000px; display:none;";
22664        styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing'];
22665        for (_i = 0, _len = styles.length; _i < _len; _i++) {
22666          style = styles[_i];
22667          style_block += style + ":" + this.search_field.getStyle(style) + ";";
22668        }
22669        div = new Element('div', {
22670          'style': style_block
22671        }).update(this.search_field.value.escapeHTML());
22672        document.body.appendChild(div);
22673        w = Element.measure(div, 'width') + 25;
22674        div.remove();
22675        f_width = this.container.getWidth();
22676        if (w > f_width - 10) {
22677          w = f_width - 10;
22678        }
22679        return this.search_field.setStyle({
22680          'width': w + 'px'
22681        });
22682      }
22683    };
22684
22685    return Chosen;
22686
22687  })(AbstractChosen);
22688
22689}).call(this);
22690/**
22691 * [js-sha256]{@link https://github.com/emn178/js-sha256}
22692 *
22693 * @version 0.5.0
22694 * @author Chen, Yi-Cyuan [[email protected]]
22695 * @copyright Chen, Yi-Cyuan 2014-2017
22696 * @license MIT
22697 */
22698/*jslint bitwise: true */
22699(function () {
22700  'use strict';
22701
22702  var root = typeof window === 'object' ? window : {};
22703  var NODE_JS = !root.JS_SHA256_NO_NODE_JS && typeof process == 'object' && process.versions && process.versions.node;
22704  if (NODE_JS) {
22705    root = global;
22706  }
22707  var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && typeof module === 'object' && module.exports;
22708  var AMD = typeof define === 'function' && define.amd;
22709  var ARRAY_BUFFER = typeof ArrayBuffer !== 'undefined';
22710  var HEX_CHARS = '0123456789abcdef'.split('');
22711  var EXTRA = [-2147483648, 8388608, 32768, 128];
22712  var SHIFT = [24, 16, 8, 0];
22713  var K = [
22714    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
22715    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
22716    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
22717    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
22718    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 
227180x81c2c92e, 0x92722c85,
22719    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
22720    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
22721    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
22722  ];
22723  var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer'];
22724
22725  var blocks = [];
22726
22727  var createOutputMethod = function (outputType, is224) {
22728    return function (message) {
22729      return new Sha256(is224, true).update(message)[outputType]();
22730    };
22731  };
22732
22733  var createMethod = function (is224) {
22734    var method = createOutputMethod('hex', is224);
22735    if (NODE_JS) {
22736      method = nodeWrap(method, is224);
22737    }
22738    method.create = function () {
22739      return new Sha256(is224);
22740    };
22741    method.update = function (message) {
22742      return method.create().update(message);
22743    };
22744    for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
22745      var type = OUTPUT_TYPES[i];
22746      method[type] = createOutputMethod(type, is224);
22747    }
22748    return method;
22749  };
22750
22751  var nodeWrap = function (method, is224) {
22752    var crypto = require('crypto');
22753    var Buffer = require('buffer').Buffer;
22754    var algorithm = is224 ? 'sha224' : 'sha256';
22755    var nodeMethod = function (message) {
22756      if (typeof message === 'string') {
22757        return crypto.createHash(algorithm).update(message, 'utf8').digest('hex');
22758      } else if (ARRAY_BUFFER && message instanceof ArrayBuffer) {
22759        message = new Uint8Array(message);
22760      } else if (message.length === undefined) {
22761        return method(message);
22762      }
22763      return crypto.createHash(algorithm).update(new Buffer(message)).digest('hex');
22764    };
22765    return nodeMethod;
22766  };
22767
22768  function Sha256(is224, sharedMemory) {
22769    if (sharedMemory) {
22770      blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
22771      blocks[4] = blocks[5] = blocks[6] = blocks[7] =
22772      blocks[8] = blocks[9] = blocks[10] = blocks[11] =
22773      blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
22774      this.blocks = blocks;
22775    } else {
22776      this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
22777    }
22778
22779    if (is224) {
22780      this.h0 = 0xc1059ed8;
22781      this.h1 = 0x367cd507;
22782      this.h2 = 0x3070dd17;
22783      this.h3 = 0xf70e5939;
22784      this.h4 = 0xffc00b31;
22785      this.h5 = 0x68581511;
22786      this.h6 = 0x64f98fa7;
22787      this.h7 = 0xbefa4fa4;
22788    } else { // 256
22789      this.h0 = 0x6a09e667;
22790      this.h1 = 0xbb67ae85;
22791      this.h2 = 0x3c6ef372;
22792      this.h3 = 0xa54ff53a;
22793      this.h4 = 0x510e527f;
22794      this.h5 = 0x9b05688c;
22795      this.h6 = 0x1f83d9ab;
22796      this.h7 = 0x5be0cd19;
22797    }
22798
22799    this.block = this.start = this.bytes = 0;
22800    this.finalized = this.hashed = false;
22801    this.first = true;
22802    this.is224 = is224;
22803  }
22804
22805  Sha256.prototype.update = function (message) {
22806    if (this.finalized) {
22807      return;
22808    }
22809    var notString = typeof(message) !== 'string';
22810    if (notString && ARRAY_BUFFER && message instanceof root.ArrayBuffer) {
22811      message = new Uint8Array(message);
22812    }
22813    var code, index = 0, i, length = message.length || 0, blocks = this.blocks;
22814
22815    while (index < length) {
22816      if (this.hashed) {
22817        this.hashed = false;
22818        blocks[0] = this.block;
22819        blocks[16] = blocks[1] = blocks[2] = blocks[3] =
22820        blocks[4] = blocks[5] = blocks[6] = blocks[7] =
22821        blocks[8] = blocks[9] = blocks[10] = blocks[11] =
22822        blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
22823      }
22824
22825      if(notString) {
22826        for (i = this.start; index < length && i < 64; ++index) {
22827          blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];
22828        }
22829      } else {
22830        for (i = this.start; index < length && i < 64; ++index) {
22831          code = message.charCodeAt(index);
22832          if (code < 0x80) {
22833            blocks[i >> 2] |= code << SHIFT[i++ & 3];
22834          } else if (code < 0x800) {
22835            blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3];
22836            blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
22837          } else if (code < 0xd800 || code >= 0xe000) {
22838            blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3];
22839            blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
22840            blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
22841          } else {
22842            code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
22843            blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3];
22844            blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3];
22845            blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
22846            blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
22847          }
22848        }
22849      }
22850
22851      this.lastByteIndex = i;
22852      this.bytes += i - this.start;
22853      if (i >= 64) {
22854        this.block = blocks[16];
22855        this.start = i - 64;
22856        this.hash();
22857        this.hashed = true;
22858      } else {
22859        this.start = i;
22860      }
22861    }
22862    return this;
22863  };
22864
22865  Sha256.prototype.finalize = function () {
22866    if (this.finalized) {
22867      return;
22868    }
22869    this.finalized = true;
22870    var blocks = this.blocks, i = this.lastByteIndex;
22871    blocks[16] = this.block;
22872    blocks[i >> 2] |= EXTRA[i & 3];
22873    this.block = blocks[16];
22874    if (i >= 56) {
22875      if (!this.hashed) {
22876        this.hash();
22877      }
22878      blocks[0] = this.block;
22879      blocks[16] = blocks[1] = blocks[2] = blocks[3] =
22880      blocks[4] = blocks[5] = blocks[6] = blocks[7] =
22881      blocks[8] = blocks[9] = blocks[10] = blocks[11] =
22882      blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
22883    }
22884    blocks[15] = this.bytes << 3;
22885    this.hash();
22886  };
22887
22888  Sha256.prototype.hash = function () {
22889    var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6,
22890      h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc;
22891
22892    for (j = 16; j < 64; ++j) {
22893      // rightrotate
22894      t1 = blocks[j - 15];
22895      s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3);
22896      t1 = blocks[j - 2];
22897      s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10);
22898      blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0;
22899    }
22900
22901    bc = b & c;
22902    for (j = 0; j < 64; j += 4) {
22903      if (this.first) {
22904        if (this.is224) {
22905          ab = 300032;
22906          t1 = blocks[0] - 1413257819;
22907          h = t1 - 150054599 << 0;
22908          d = t1 + 24177077 << 0;
22909        } else {
22910          ab = 704751109;
22911          t1 = blocks[0] - 210244248;
22912          h = t1 - 1521486534 << 0;
22913          d = t1 + 143694565 << 0;
22914        }
22915        this.first = false;
22916      } else {
22917        s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));
22918        s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));
22919        ab = a & b;
22920        maj = ab ^ (a & c) ^ bc;
22921        ch = (e & f) ^ (~e & g);
22922        t1 = h + s1 + ch + K[j] + blocks[j];
22923        t2 = s0 + maj;
22924        h = d + t1 << 0;
22925        d = t1 + t2 << 0;
22926      }
22927      s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10));
22928      s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7));
22929      da = d & a;
22930      maj = da ^ (d & b) ^ ab;
22931      ch = (h & e) ^ (~h & f);
22932      t1 = g + s1 + ch + K[j + 1] + blocks[j + 1];
22933      t2 = s0 + maj;
22934      g = c + t1 << 0;
22935      c = t1 + t2 << 0;
22936      s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10));
22937      s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7));
22938      cd = c & d;
22939      maj = cd ^ (c & a) ^ da;
22940      ch = (g & h) ^ (~g & e);
22941      t1 = f + s1 + ch + K[j + 2] + blocks[j + 2];
22942      t2 = s0 + maj;
22943      f = b + t1 << 0;
22944      b = t1 + t2 << 0;
22945      s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10));
22946      s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7));
22947      bc = b & c;
22948      maj = bc ^ (b & d) ^ cd;
22949      ch = (f & g) ^ (~f & h);
22950      t1 = e + s1 + ch + K[j + 3] + blocks[j + 3];
22951      t2 = s0 + maj;
22952      e = a + t1 << 0;
22953      a = t1 + t2 << 0;
22954    }
22955
22956    this.h0 = this.h0 + a << 0;
22957    this.h1 = this.h1 + b << 0;
22958    this.h2 = this.h2 + c << 0;
22959    this.h3 = this.h3 + d << 0;
22960    this.h4 = this.h4 + e << 0;
22961    this.h5 = this.h5 + f << 0;
22962    this.h6 = this.h6 + g << 0;
22963    this.h7 = this.h7 + h << 0;
22964  };
22965
22966  Sha256.prototype.hex = function () {
22967    this.finalize();
22968
22969    var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
22970      h6 = this.h6, h7 = this.h7;
22971
22972    var hex = HEX_CHARS[(h0 >> 28) & 0x0F] + HEX_CHARS[(h0 >> 24) & 0x0F] +
22973      HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] +
22974      HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] +
22975      HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +
22976      HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] +
22977      HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] +
22978      HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] +
22979      HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +
22980      HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] +
22981      HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] +
22982      HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] +
22983      HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +
22984      HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F] +
22985      HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] +
22986      HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] +
22987      HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +
22988      HEX_CHARS[(h4 >> 28) & 0x0F] + HEX_CHARS[(h4 >> 24) & 0x0F] +
22989      HEX_CHARS[(h4 >> 20) & 0x0F] + HEX_CHARS[(h4 >> 16) & 0x0F] +
22990      HEX_CHARS[(h4 >> 12) & 0x0F] + HEX_CHARS[(h4 >> 8) & 0x0F] +
22991      HEX_CHARS[(h4 >> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] +
22992      HEX_CHARS[(h5 >> 28) & 0x0F] + HEX_CHARS[(h5 >> 24) & 0x0F] +
22993      HEX_CHARS[(h5 >> 20) & 0x0F] + HEX_CHARS[(h5 >> 16) & 0x0F] +
22994      HEX_CHARS[(h5 >> 12) & 0x0F] + HEX_CHARS[(h5 >> 8) & 0x0F] +
22995      HEX_CHARS[(h5 >> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] +
22996      HEX_CHARS[(h6 >> 28) & 0x0F] + HEX_CHARS[(h6 >> 24) & 0x0F] +
22997      HEX_CHARS[(h6 >> 20) & 0x0F] + HEX_CHARS[(h6 >> 16) & 0x0F] +
22998      HEX_CHARS[(h6 >> 12) & 0x0F] + HEX_CHARS[(h6 >> 8) & 0x0F] +
22999      HEX_CHARS[(h6 >> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F];
23000    if (!this.is224) {
23001      hex += HEX_CHARS[(h7 >> 28) & 0x0F] + HEX_CHARS[(h7 >> 24) & 0x0F] +
23002        HEX_CHARS[(h7 >> 20) & 0x0F] + HEX_CHARS[(h7 >> 16) & 0x0F] +
23003        HEX_CHARS[(h7 >> 12) & 0x0F] + HEX_CHARS[(h7 >> 8) & 0x0F] +
23004        HEX_CHARS[(h7 >> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F];
23005    }
23006    return hex;
23007  };
23008
23009  Sha256.prototype.toString = Sha256.prototype.hex;
23010
23011  Sha256.prototype.digest = function () {
23012    this.finalize();
23013
23014    var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
23015      h6 = this.h6, h7 = this.h7;
23016
23017    var arr = [
23018      (h0 >> 24) & 0xFF, (h0 >> 16) & 0xFF, (h0 >> 8) & 0xFF, h0 & 0xFF,
23019      (h1 >> 24) & 0xFF, (h1 >> 16) & 0xFF, (h1 >> 8) & 0xFF, h1 & 0xFF,
23020      (h2 >> 24) & 0xFF, (h2 >> 16) & 0xFF, (h2 >> 8) & 0xFF, h2 & 0xFF,
23021      (h3 >> 24) & 0xFF, (h3 >> 16) & 0xFF, (h3 >> 8) & 0xFF, h3 & 0xFF,
23022      (h4 >> 24) & 0xFF, (h4 >> 16) & 0xFF, (h4 >> 8) & 0xFF, h4 & 0xFF,
23023      (h5 >> 24) & 0xFF, (h5 >> 16) & 0xFF, (h5 >> 8) & 0xFF, h5 & 0xFF,
23024      (h6 >> 24) & 0xFF, (h6 >> 16) & 0xFF, (h6 >> 8) & 0xFF, h6 & 0xFF
23025    ];
23026    if (!this.is224) {
23027      arr.push((h7 >> 24) & 0xFF, (h7 >> 16) & 0xFF, (h7 >> 8) & 0xFF, h7 & 0xFF);
23028    }
23029    return arr;
23030  };
23031
23032  Sha256.prototype.array = Sha256.prototype.digest;
23033
23034  Sha256.prototype.arrayBuffer = function () {
23035    this.finalize();
23036
23037    var buffer = new ArrayBuffer(this.is224 ? 28 : 32);
23038    var dataView = new DataView(buffer);
23039    dataView.setUint32(0, this.h0);
23040    dataView.setUint32(4, this.h1);
23041    dataView.setUint32(8, this.h2);
23042    dataView.setUint32(12, this.h3);
23043    dataView.setUint32(16, this.h4);
23044    dataView.setUint32(20, this.h5);
23045    dataView.setUint32(24, this.h6);
23046    if (!this.is224) {
23047      dataView.setUint32(28, this.h7);
23048    }
23049    return buffer;
23050  };
23051
23052  var exports = createMethod();
23053  exports.sha256 = exports;
23054  exports.sha224 = createMethod(true);
23055
23056  if (COMMON_JS) {
23057    module.exports = exports;
23058  } else {
23059    root.sha256 = exports.sha256;
23060    root.sha224 = exports.sha224;
23061    if (AMD) {
23062      define(function () {
23063        return exports;
23064      });
23065    }
23066  }
23067})();
23068/**
23069 * findAndReplaceDOMText v 0.4.6
23070 * @author James Padolsey http://james.padolsey.com
23071 * @license http://unlicense.org/UNLICENSE
23072 *
23073 * Matches the text of a DOM node against a regular expression
23074 * and replaces each match (or node-separated portions of the match)
23075 * in the specified element.
23076 */
23077 (function (root, factory) {
23078     if (typeof module === 'object' && module.exports) {
23079         // Node/CommonJS
23080         module.exports = factory();
23081     } else if (typeof define === 'function' && define.amd) {
23082         // AMD. Register as an anonymous module.
23083         define(factory);
23084     } else {
23085         // Browser globals
23086         root.findAndReplaceDOMText = factory();
23087     }
23088 }(this, function factory() {
23089
23090	var PORTION_MODE_RETAIN = 'retain';
23091	var PORTION_MODE_FIRST = 'first';
23092
23093	var doc = document;
23094	var hasOwn = {}.hasOwnProperty;
23095
23096	function escapeRegExp(s) {
23097		return String(s).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
23098	}
23099
23100	function exposed() {
23101		// Try deprecated arg signature first:
23102		return deprecated.apply(null, arguments) || findAndReplaceDOMText.apply(null, arguments);
23103	}
23104
23105	function deprecated(regex, node, replacement, captureGroup, elFilter) {
23106		if ((node && !node.nodeType) && arguments.length <= 2) {
23107			return false;
23108		}
23109		var isReplacementFunction = typeof replacement == 'function';
23110
23111		if (isReplacementFunction) {
23112			replacement = (function(original) {
23113				return function(portion, match) {
23114					return original(portion.text, match.startIndex);
23115				};
23116			}(replacement));
23117		}
23118
23119		// Awkward support for deprecated argument signature (<0.4.0)
23120		var instance = findAndReplaceDOMText(node, {
23121
23122			find: regex,
23123
23124			wrap: isReplacementFunction ? null : replacement,
23125			replace: isReplacementFunction ? replacement : '$' + (captureGroup || '&'),
23126
23127			prepMatch: function(m, mi) {
23128
23129				// Support captureGroup (a deprecated feature)
23130
23131				if (!m[0]) throw 'findAndReplaceDOMText cannot handle zero-length matches';
23132
23133				if (captureGroup > 0) {
23134					var cg = m[captureGroup];
23135					m.index += m[0].indexOf(cg);
23136					m[0] = cg;
23137				}
23138
23139				m.endIndex = m.index + m[0].length;
23140				m.startIndex = m.index;
23141				m.index = mi;
23142
23143				return m;
23144			},
23145			filterElements: elFilter
23146		});
23147
23148		exposed.revert = function() {
23149			return instance.revert();
23150		};
23151
23152		return true;
23153	}
23154
23155	/**
23156	 * findAndReplaceDOMText
23157	 *
23158	 * Locates matches and replaces with replacementNode
23159	 *
23160	 * @param {Node} node Element or Text node to search within
23161	 * @param {RegExp} options.find The regular expression to match
23162	 * @param {String|Element} [options.wrap] A NodeName, or a Node to clone
23163	 * @param {String} [options.wrapClass] A classname to append to the wrapping element
23164	 * @param {String|Function} [options.replace='$&'] What to replace each match with
23165	 * @param {Function} [options.filterElements] A Function to be called to check whether to
23166	 *	process an element. (returning true = process element,
23167	 *	returning false = avoid element)
23168	 */
23169	function findAndReplaceDOMText(node, options) {
23170		return new Finder(node, options);
23171	}
23172
23173	exposed.NON_PROSE_ELEMENTS = {
23174		br:1, hr:1, a:1,
23175		// Media / Source elements:
23176		script:1, style:1, img:1, video:1, audio:1, canvas:1, svg:1, map:1, object:1,
23177		// Input elements
23178		input:1, textarea:1, select:1, option:1, optgroup: 1, button:1
23179	};
23180
23181	exposed.FULL_NON_PROSE_ELEMENTS = {
23182		br:1, hr:1, a:1, h1:1, h2:1, h3:1, h4:1, h5:1, h6:1,
23183		// Media / Source elements:
23184		script:1, style:1, img:1, video:1, audio:1, canvas:1, svg:1, map:1, object:1,
23185		// Input elements
23186		input:1, textarea:1, select:1, option:1, optgroup: 1, button:1
23187	};
23188
23189	exposed.NON_CONTIGUOUS_PROSE_ELEMENTS = {
23190
23191		// Elements that will not contain prose or block elements where we don't
23192		// want prose to be matches across element borders:
23193
23194		// Block Elements
23195		address:1, article:1, aside:1, blockquote:1, dd:1, div:1,
23196		dl:1, fieldset:1, figcaption:1, figure:1, footer:1, form:1, h1:1, h2:1, h3:1,
23197		h4:1, h5:1, h6:1, header:1, hgroup:1, hr:1, main:1, nav:1, noscript:1, ol:1,
23198		output:1, p:1, pre:1, section:1, ul:1,
23199		// Other misc. elements that are not part of continuous inline prose:
23200		br:1, li: 1, summary: 1, dt:1, details:1, rp:1, rt:1, rtc:1, a:1,
23201		// Media / Source elements:
23202		script:1, style:1, img:1, video:1, audio:1, canvas:1, svg:1, map:1, object:1,
23203		// Input elements
23204		input:1, textarea:1, select:1, option:1, optgroup:1, button:1,
23205		// Table related elements:
23206		table:1, tbody:1, thead:1, th:1, tr:1, td:1, caption:1, col:1, tfoot:1, colgroup:1
23207
23208	};
23209
23210	exposed.NON_INLINE_PROSE = function(el) {
23211		return hasOwn.call(exposed.NON_CONTIGUOUS_PROSE_ELEMENTS, el.nodeName.toLowerCase());
23212	};
23213
23214	// Presets accessed via `options.preset` when calling findAndReplaceDOMText():
23215	exposed.PRESETS = {
23216		prose: {
23217			forceContext: exposed.NON_INLINE_PROSE,
23218			filterElements: function(el) {
23219				return !hasOwn.call(exposed.NON_PROSE_ELEMENTS, el.nodeName.toLowerCase());
23220			}
23221		},
23222		noTitles: {
23223			forceContext: exposed.NON_INLINE_PROSE,
23224			filterElements: function(el) {
23225				return !hasOwn.call(exposed.FULL_NON_PROSE_ELEMENTS, el.nodeName.toLowerCase());
23226			}
23227		}
23228	};
23229
23230	exposed.Finder = Finder;
23231
23232	/**
23233	 * Finder -- encapsulates logic to find and replace.
23234	 */
23235	function Finder(node, options) {
23236
23237		var preset = options.preset && exposed.PRESETS[options.preset];
23238
23239		options.portionMode = options.portionMode || PORTION_MODE_RETAIN;
23240
23241		if (preset) {
23242			for (var i in preset) {
23243				if (hasOwn.call(preset, i) && !hasOwn.call(options, i)) {
23244					options[i] = preset[i];
23245				}
23246			}
23247		}
23248
23249		this.node = node;
23250		this.options = options;
23251
23252		// Enable match-preparation method to be passed as option:
23253		this.prepMatch = options.prepMatch || this.prepMatch;
23254
23255		this.reverts = [];
23256
23257		this.matches = this.search();
23258
23259		if (this.matches.length) {
23260			this.processMatches();
23261		}
23262
23263	}
23264
23265	Finder.prototype = {
23266
23267		/**
23268		 * Searches for all matches that comply with the instance's 'match' option
23269		 */
23270		search: function() {
23271
23272			var match;
23273			var matchIndex = 0;
23274			var offset = 0;
23275			var regex = this.options.find;
23276			var textAggregation = this.getAggregateText();
23277			var matches = [];
23278			var self = this;
23279
23280			regex = typeof regex === 'string' ? RegExp(escapeRegExp(regex), 'g') : regex;
23281
23282			matchAggregation(textAggregation);
23283
23284			function matchAggregation(textAggregation) {
23285				for (var i = 0, l = textAggregation.length; i < l; ++i) {
23286
23287					var text = textAggregation[i];
23288
23289					if (typeof text !== 'string') {
23290						// Deal with nested contexts: (recursive)
23291						matchAggregation(text);
23292						continue;
23293					}
23294
23295					if (regex.global) {
23296						while (match = regex.exec(text)) {
23297							matches.push(self.prepMatch(match, matchIndex++, offset));
23298						}
23299					} else {
23300						if (match = text.match(regex)) {
23301							matches.push(self.prepMatch(match, 0, offset));
23302						}
23303					}
23304
23305					offset += text.length;
23306				}
23307			}
23308
23309			return matches;
23310
23311		},
23312
23313		/**
23314		 * Prepares a single match with useful meta info:
23315		 */
23316		prepMatch: function(match, matchIndex, characterOffset) {
23317
23318			if (!match[0]) {
23319				throw new Error('findAndReplaceDOMText cannot handle zero-length matches');
23320			}
23321
23322			match.endIndex = characterOffset + match.index + match[0].length;
23323			match.startIndex = characterOffset + match.index;
23324			match.index = matchIndex;
23325
23326			return match;
23327		},
23328
23329		/**
23330		 * Gets aggregate text within subject node
23331		 */
23332		getAggregateText: function() {
23333
23334			var elementFilter = this.options.filterElements;
23335			var forceContext = this.options.forceContext;
23336
23337			return getText(this.node);
23338
23339			/**
23340			 * Gets aggregate text of a node without resorting
23341			 * to broken innerText/textContent
23342			 */
23343			function getText(node) {
23344
23345				if (node.nodeType === Node.TEXT_NODE) {
23346					return [node.data];
23347				}
23348
23349				if (elementFilter && !elementFilter(node)) {
23350					return [];
23351				}
23352
23353				var txt = [''];
23354				var i = 0;
23355
23356				if (node = node.firstChild) do {
23357
23358					if (node.nodeType === Node.TEXT_NODE) {
23359						txt[i] += node.data;
23360						continue;
23361					}
23362
23363					var innerText = getText(node);
23364
23365					if (
23366						forceContext &&
23367						node.nodeType === Node.ELEMENT_NODE &&
23368						(forceContext === true || forceContext(node))
23369					) {
23370						txt[++i] = innerText;
23371						txt[++i] = '';
23372					} else {
23373						if (typeof innerText[0] === 'string') {
23374							// Bridge nested text-node data so that they're
23375							// not considered their own contexts:
23376							// I.e. ['some', ['thing']] -> ['something']
23377							txt[i] += innerText.shift();
23378						}
23379						if (innerText.length) {
23380							txt[++i] = innerText;
23381							txt[++i] = '';
23382						}
23383					}
23384				} while (node = node.nextSibling);
23385
23386				return txt;
23387
23388			}
23389
23390		},
23391
23392		/**
23393		 * Steps through the target node, looking for matches, and
23394		 * calling replaceFn when a match is found.
23395		 */
23396		processMatches: function() {
23397
23398			var matches = this.matches;
23399			var node = this.node;
23400			var elementFilter = this.options.filterElements;
23401
23402			var startPortion,
23403				endPortion,
23404				innerPortions = [],
23405				curNode = node,
23406				match = matches.shift(),
23407				atIndex = 0, // i.e. nodeAtIndex
23408				matchIndex = 0,
23409				portionIndex = 0,
23410				doAvoidNode,
23411				nodeStack = [node];
23412
23413			out: while (true) {
23414
23415				if (curNode.nodeType === Node.TEXT_NODE) {
23416
23417					if (!endPortion && curNode.length + atIndex >= match.endIndex) {
23418						// We've found the ending
23419						// (Note that, in the case of a single portion, it'll be an
23420						// endPortion, not a startPortion.)
23421						endPortion = {
23422							node: curNode,
23423							index: portionIndex++,
23424							text: curNode.data.substring(match.startIndex - atIndex, match.endIndex - atIndex),
23425
23426							// If it's the first match (atIndex==0) we should just return 0
23427							indexInMatch: atIndex === 0 ? 0 : atIndex - match.startIndex,
23428
23429							indexInNode: match.startIndex - atIndex,
23430							endIndexInNode: match.endIndex - atIndex,
23431							isEnd: true
23432						};
23433
23434					} else if (startPortion) {
23435						// Intersecting node
23436						innerPortions.push({
23437							node: curNode,
23438							index: portionIndex++,
23439							text: curNode.data,
23440							indexInMatch: atIndex - match.startIndex,
23441							indexInNode: 0 // always zero for inner-portions
23442						});
23443					}
23444
23445					if (!startPortion && curNode.length + atIndex > match.startIndex) {
23446						// We've found the match start
23447						startPortion = {
23448							node: curNode,
23449							index: portionIndex++,
23450							indexInMatch: 0,
23451							indexInNode: match.startIndex - atIndex,
23452							endIndexInNode: match.endIndex - atIndex,
23453							text: curNode.data.substring(match.startIndex - atIndex, match.endIndex - atIndex)
23454						};
23455					}
23456
23457					atIndex += curNode.data.length;
23458
23459				}
23460
23461				doAvoidNode = curNode.nodeType === Node.ELEMENT_NODE && elementFilter && !elementFilter(curNode);
23462
23463				if (startPortion && endPortion) {
23464
23465					curNode = this.replaceMatch(match, startPortion, innerPortions, endPortion);
23466
23467					// processMatches has to return the node that replaced the endNode
23468					// and then we step back so we can continue from the end of the
23469					// match:
23470
23471					atIndex -= (endPortion.node.data.length - endPortion.endIndexInNode);
23472
23473					startPortion = null;
23474					endPortion = null;
23475					innerPortions = [];
23476					match = matches.shift();
23477					portionIndex = 0;
23478					matchIndex++;
23479
23480					if (!match) {
23481						break; // no more matches
23482					}
23483
23484				} else if (
23485					!doAvoidNode &&
23486					(curNode.firstChild || curNode.nextSibling)
23487				) {
23488					// Move down or forward:
23489					if (curNode.firstChild) {
23490						nodeStack.push(curNode);
23491						curNode = curNode.firstChild;
23492					} else {
23493						curNode = curNode.nextSibling;
23494					}
23495					continue;
23496				}
23497
23498				// Move forward or up:
23499				while (true) {
23500					if (curNode.nextSibling) {
23501						curNode = curNode.nextSibling;
23502						break;
23503					}
23504					curNode = nodeStack.pop();
23505					if (curNode === node) {
23506						break out;
23507					}
23508				}
23509
23510			}
23511
23512		},
23513
23514		/**
23515		 * Reverts ... TODO
23516		 */
23517		revert: function() {
23518			// Reversion occurs backwards so as to avoid nodes subsequently
23519			// replaced during the matching phase (a forward process):
23520			for (var l = this.reverts.length; l--;) {
23521				this.reverts[l]();
23522			}
23523			this.reverts = [];
23524		},
23525
23526		prepareReplacementString: function(string, portion, match) {
23527			var portionMode = this.options.portionMode;
23528			if (
23529				portionMode === PORTION_MODE_FIRST &&
23530				portion.indexInMatch > 0
23531			) {
23532				return '';
23533			}
23534			string = string.replace(/\$(\d+|&|`|')/g, function($0, t) {
23535				var replacement;
23536				switch(t) {
23537					case '&':
23538						replacement = match[0];
23539						break;
23540					case '`':
23541						replacement = match.input.substring(0, match.startIndex);
23542						break;
23543					case '\'':
23544						replacement = match.input.substring(match.endIndex);
23545						break;
23546					default:
23547						replacement = match[+t] || '';
23548				}
23549				return replacement;
23550			});
23551
23552			if (portionMode === PORTION_MODE_FIRST) {
23553				return string;
23554			}
23555
23556			if (portion.isEnd) {
23557				return string.substring(portion.indexInMatch);
23558			}
23559
23560			return string.substring(portion.indexInMatch, portion.indexInMatch + portion.text.length);
23561		},
23562
23563		getPortionReplacementNode: function(portion, match) {
23564
23565			var replacement = this.options.replace || '$&';
23566			var wrapper = this.options.wrap;
23567			var wrapperClass = this.options.wrapClass;
23568
23569			if (wrapper && wrapper.nodeType) {
23570				// Wrapper has been provided as a stencil-node for us to clone:
23571				var clone = doc.createElement('div');
23572				clone.innerHTML = wrapper.outerHTML || new XMLSerializer().serializeToString(wrapper);
23573				wrapper = clone.firstChild;
23574			}
23575
23576			if (typeof replacement == 'function') {
23577				replacement = replacement(portion, match);
23578				if (replacement && replacement.nodeType) {
23579					return replacement;
23580				}
23581				return doc.createTextNode(String(replacement));
23582			}
23583
23584			var el = typeof wrapper == 'string' ? doc.createElement(wrapper) : wrapper;
23585
23586 			if (el && wrapperClass) {
23587				el.className = wrapperClass;
23588			}
23589
23590			replacement = doc.createTextNode(
23591				this.prepareReplacementString(
23592					replacement, portion, match
23593				)
23594			);
23595
23596			if (!replacement.data) {
23597				return replacement;
23598			}
23599
23600			if (!el) {
23601				return replacement;
23602			}
23603
23604			el.appendChild(replacement);
23605
23606			return el;
23607		},
23608
23609		replaceMatch: function(match, startPortion, innerPortions, endPortion) {
23610
23611			var matchStartNode = startPortion.node;
23612			var matchEndNode = endPortion.node;
23613
23614			var precedingTextNode;
23615			var followingTextNode;
23616
23617			if (matchStartNode === matchEndNode) {
23618
23619				var node = matchStartNode;
23620
23621				if (startPortion.indexInNode > 0) {
23622					// Add `before` text node (before the match)
23623					precedingTextNode = doc.createTextNode(node.data.substring(0, startPortion.indexInNode));
23624					node.parentNode.insertBefore(precedingTextNode, node);
23625				}
23626
23627				// Create the replacement node:
23628				var newNode = this.getPortionReplacementNode(
23629					endPortion,
23630					match
23631				);
23632
23633				node.parentNode.insertBefore(newNode, node);
23634
23635				if (endPortion.endIndexInNode < node.length) { // ?????
23636					// Add `after` text node (after the match)
23637					followingTextNode = doc.createTextNode(node.data.substring(endPortion.endIndexInNode));
23638					node.parentNode.insertBefore(followingTextNode, node);
23639				}
23640
23641				node.parentNode.removeChild(node);
23642
23643				this.reverts.push(function() {
23644					if (precedingTextNode === newNode.previousSibling) {
23645						precedingTextNode.parentNode.removeChild(precedingTextNode);
23646					}
23647					if (followingTextNode === newNode.nextSibling) {
23648						followingTextNode.parentNode.removeChild(followingTextNode);
23649					}
23650					newNode.parentNode.replaceChild(node, newNode);
23651				});
23652
23653				return newNode;
23654
23655			} else {
23656				// Replace matchStartNode -> [innerMatchNodes...] -> matchEndNode (in that order)
23657
23658
23659				precedingTextNode = doc.createTextNode(
23660					matchStartNode.data.substring(0, startPortion.indexInNode)
23661				);
23662
23663				followingTextNode = doc.createTextNode(
23664					matchEndNode.data.substring(endPortion.endIndexInNode)
23665				);
23666
23667				var firstNode = this.getPortionReplacementNode(
23668					startPortion,
23669					match
23670				);
23671
23672				var innerNodes = [];
23673
23674				for (var i = 0, l = innerPortions.length; i < l; ++i) {
23675					var portion = innerPortions[i];
23676					var innerNode = this.getPortionReplacementNode(
23677						portion,
23678						match
23679					);
23680					portion.node.parentNode.replaceChild(innerNode, portion.node);
23681					this.reverts.push((function(portion, innerNode) {
23682						return function() {
23683							innerNode.parentNode.replaceChild(portion.node, innerNode);
23684						};
23685					}(portion, innerNode)));
23686					innerNodes.push(innerNode);
23687				}
23688
23689				var lastNode = this.getPortionReplacementNode(
23690					endPortion,
23691					match
23692				);
23693
23694				matchStartNode.parentNode.insertBefore(precedingTextNode, matchStartNode);
23695				matchStartNode.parentNode.insertBefore(firstNode, matchStartNode);
23696				matchStartNode.parentNode.removeChild(matchStartNode);
23697
23698				matchEndNode.parentNode.insertBefore(lastNode, matchEndNode);
23699				matchEndNode.parentNode.insertBefore(followingTextNode, matchEndNode);
23700				matchEndNode.parentNode.removeChild(matchEndNode);
23701
23702				this.reverts.push(function() {
23703					precedingTextNode.parentNode.removeChild(precedingTextNode);
23704					firstNode.parentNode.replaceChild(matchStartNode, firstNode);
23705					followingTextNode.parentNode.removeChild(followingTextNode);
23706					lastNode.parentNode.replaceChild(matchEndNode, lastNode);
23707				});
23708
23709				return lastNode;
23710			}
23711		}
23712
23713	};
23714
23715	return exposed;
23716
23717}));
23718(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.tippy=t()})(this,function(){'use strict';function t(e){return'[object Object]'==={}.toString.call(e)}function o(e){return[].slice.call(e)}function n(e){if(e instanceof Element||t(e))return[e];if(e instanceof NodeList)return o(e);if(Array.isArray(e))return e;try{return o(document.querySelectorAll(e))}catch(e){return[]}}function r(e){e.refObj=!0,e.attributes=e.attributes||{},e.setAttribute=function(t,o){e.attributes[t]=o},e.getAttribute=function(t){return e.attributes[t]},e.removeAttribute=function(t){delete e.attributes[t]},e.hasAttribute=function(t){return t in e.attributes},e.addEventListener=function(){},e.removeEventListener=function(){},e.classList={classNames:{},add:function(t){return e.classList.classNames[t]=!0},remove:function(t){return delete e.classList.classNames[t],!0},contains:function(t){return t in e.classList.classNames}}}function s(e){for(var t=['','webkit'],o=e.charAt(0).toUpperCase()+e.slice(1),n=0;n<t.length;n++){var i=t[n],r=i?i+o:e;if('undefined'!=typeof document.body.style[r])return r}return null}function a(){return document.createElement('div')}function p(e,t,o){var i=a();i.setAttribute('class','tippy-popper'),i.setAttribute('role','tooltip'),i.setAttribute('id','tippy-'+e),i.style.zIndex=o.zIndex,i.style.maxWidth=o.maxWidth;var n=a();n.setAttribute('class','tippy-tooltip'),n.setAttribute('data-size',o.size),n.setAttribute('data-animation',o.animation),n.setAttribute('data-state','hidden'),o.theme.split(' ').forEach(function(e){n.classList.add(e+'-theme')});var r=a();if(r.setAttribute('class','tippy-content'),o.arrow){var p=a();p.style[s('transform')]=o.arrowTransform,'round'===o.arrowType?(p.classList.add('tippy-roundarrow'),p.innerHTML='<svg viewBox="0 0 24 8" xmlns="http://www.w3.org/2000/svg"><path d="M3 8s2.021-.015 5.253-4.218C9.584 2.051 10.797 1.007 12 1c1.203-.007 2.416 1.035 3.761 2.782C19.012 8.005 21 8 21 8H3z"/></svg>'):p.classList.add('tippy-arrow'),n.appendChild(p)}if(o.animateFill){n.setAttribute('data-animatefill','');var l=a();l.classList.add('tippy-backdrop'),l.setAttribute('data-state','hidden'),n.appendChild(l)}o.inertia&&n.setAttribute('data-inertia',''),o.interactive&&n.setAttribute('data-interactive','');var d=o.html;if(d){var c;d instanceof Element?(r.appendChild(d),c='#'+(d.id||'tippy-html-template')):(r.innerHTML=document.querySelector(d).innerHTML,c=d),i.setAttribute('data-html',''),n.setAttribute('data-template-id',c),o.interactive&&i.setAttribute('tabindex','-1')}else r[o.allowTitleHTML?'innerHTML':'textContent']=t;return n.appendChild(r),i.appendChild(n),i}function l(e,t,o,i){var n=o.onTrigger,r=o.onMouseLeave,s=o.onBlur,a=o.onDelegateShow,p=o.onDelegateHide,l=[];if('manual'===e)return l;var d=function(e,o){t.addEventListener(e,o),l.push({event:e,handler:o})};return i.target?(je.supportsTouch&&i.touchHold&&(d('touchstart',a),d('touchend',p)),'mouseenter'===e&&(d('mouseover',a),d('mouseout',p)),'focus'===e&&(d('focusin',a),d('focusout',p)),'click'===e&&d('click',a)):(d(e,n),je.supportsTouch&&i.touchHold&&(d('touchstart',n),d('touchend',r)),'mouseenter'===e&&d('mouseleave',r),'focus'===e&&d(ze?'focu
23718sout':'blur',s)),l}function d(e,t){var o=Ve.reduce(function(o,i){var n=e.getAttribute('data-tippy-'+i.toLowerCase())||t[i];return'false'===n&&(n=!1),'true'===n&&(n=!0),isFinite(n)&&!isNaN(parseFloat(n))&&(n=parseFloat(n)),'target'!==i&&'string'==typeof n&&'['===n.trim().charAt(0)&&(n=JSON.parse(n)),o[i]=n,o},{});return Ze({},t,o)}function c(e,t){return t.arrow&&(t.animateFill=!1),t.appendTo&&'function'==typeof t.appendTo&&(t.appendTo=t.appendTo()),'function'==typeof t.html&&(t.html=t.html(e)),t}function f(e){var t=function(t){return e.querySelector(t)};return{tooltip:t(Xe.TOOLTIP),backdrop:t(Xe.BACKDROP),content:t(Xe.CONTENT),arrow:t(Xe.ARROW)||t(Xe.ROUND_ARROW)}}function m(e){var t=e.getAttribute('title');t&&e.setAttribute('data-original-title',t),e.removeAttribute('title')}function u(e){return e&&'[object Function]'==={}.toString.call(e)}function h(e,t){if(1!==e.nodeType)return[];var o=getComputedStyle(e,null);return t?o[t]:o}function g(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function b(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var t=h(e),o=t.overflow,i=t.overflowX,n=t.overflowY;return /(auto|scroll|overlay)/.test(o+n+i)?e:b(g(e))}function y(e){return 11===e?it:10===e?nt:it||nt}function v(e){if(!e)return document.documentElement;for(var t=y(10)?document.body:null,o=e.offsetParent;o===t&&e.nextElementSibling;)o=(e=e.nextElementSibling).offsetParent;var i=o&&o.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TD','TABLE'].indexOf(o.nodeName)&&'static'===h(o,'position')?v(o):o:e?e.ownerDocument.documentElement:document.documentElement}function w(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||v(e.firstElementChild)===e)}function E(e){return null===e.parentNode?e:E(e.parentNode)}function T(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,i=o?e:t,n=o?t:e,r=document.createRange();r.setStart(i,0),r.setEnd(n,0);var s=r.commonAncestorContainer;if(e!==s&&t!==s||i.contains(n))return w(s)?s:v(s);var a=E(e);return a.host?T(a.host,t):T(e,E(t).host)}function L(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:'top',o='top'===t?'scrollTop':'scrollLeft',i=e.nodeName;if('BODY'===i||'HTML'===i){var n=e.ownerDocument.documentElement,r=e.ownerDocument.scrollingElement||n;return r[o]}return e[o]}function O(e,t){var o=!!(2<arguments.length&&void 0!==arguments[2])&&arguments[2],i=L(t,'top'),n=L(t,'left'),r=o?-1:1;return e.top+=i*r,e.bottom+=i*r,e.left+=n*r,e.right+=n*r,e}function x(e,t){var o='x'===t?'Left':'Top',i='Left'===o?'Right':'Bottom';return parseFloat(e['border'+o+'Width'],10)+parseFloat(e['border'+i+'Width'],10)}function A(e,t,o,i){return Ye(t['offset'+e],t['scroll'+e],o['client'+e],o['offset'+e],o['scroll'+e],y(10)?o['offset'+e]+i['margin'+('Height'===e?'Top':'Left')]+i['margin'+('Height'===e?'Bottom':'Right')]:0)}function C(){var e=document.body,t=document.documentElement,o=y(10)&&getComputedStyle(t);return{height:A('Height',e,t,o),width:A('Width',e,t,o)}}function k(e){return pt({},e,{right:e.left+e.width,bottom:e.top+e.height})}function S(e){var t={};try{if(y(10)){t=e.getBoundingClientRect();var o=L(e,'top'),i=L(e,'left');t.top+=o,t.left+=i,t.bottom+=o,t.right+=i}else t=e.getBoundingClientRect()}catch(t){}var n={left:t.left,top:t.top,width:t.right-t.left,height:t.bottom-t.top}
vendor: 5,921 bytes, line 23718
23718,r='HTML'===e.nodeName?C():{},s=r.width||e.clientWidth||n.right-n.left,a=r.height||e.clientHeight||n.bottom-n.top,p=e.offsetWidth-s,l=e.offsetHeight-a;if(p||l){var d=h(e);p-=x(d,'x'),l-=x(d,'y'),n.width-=p,n.height-=l}return k(n)}function P(e,t){var o=!!(2<arguments.length&&void 0!==arguments[2])&&arguments[2],i=y(10),n='HTML'===t.nodeName,r=S(e),s=S(t),a=b(e),p=h(t),l=parseFloat(p.borderTopWidth,10),d=parseFloat(p.borderLeftWidth,10);o&&'HTML'===t.nodeName&&(s.top=Ye(s.top,0),s.left=Ye(s.left,0));var c=k({top:r.top-s.top-l,left:r.left-s.left-d,width:r.width,height:r.height});if(c.marginTop=0,c.marginLeft=0,!i&&n){var f=parseFloat(p.marginTop,10),m=parseFloat(p.marginLeft,10);c.top-=l-f,c.bottom-=l-f,c.left-=d-m,c.right-=d-m,c.marginTop=f,c.marginLeft=m}return(i&&!o?t.contains(a):t===a&&'BODY'!==a.nodeName)&&(c=O(c,t)),c}function I(e){var t=!!(1<arguments.length&&void 0!==arguments[1])&&arguments[1],o=e.ownerDocument.documentElement,i=P(e,o),n=Ye(o.clientWidth,window.innerWidth||0),r=Ye(o.clientHeight,window.innerHeight||0),s=t?0:L(o),a=t?0:L(o,'left'),p={top:s-i.top+i.marginTop,left:a-i.left+i.marginLeft,width:n,height:r};return k(p)}function D(e){var t=e.nodeName;return'BODY'!==t&&'HTML'!==t&&('fixed'===h(e,'position')||D(g(e)))}function R(e){if(!e||!e.parentElement||y())return document.documentElement;for(var t=e.parentElement;t&&'none'===h(t,'transform');)t=t.parentElement;return t||document.documentElement}function _(e,t,o,i){var n=!!(4<arguments.length&&void 0!==arguments[4])&&arguments[4],r={top:0,left:0},s=n?R(e):T(e,t);if('viewport'===i)r=I(s,n);else{var a;'scrollParent'===i?(a=b(g(t)),'BODY'===a.nodeName&&(a=e.ownerDocument.documentElement)):'window'===i?a=e.ownerDocument.documentElement:a=i;var p=P(a,s,n);if('HTML'===a.nodeName&&!D(s)){var l=C(),d=l.height,c=l.width;r.top+=p.top-p.marginTop,r.bottom=d+p.top,r.left+=p.left-p.marginLeft,r.right=c+p.left}else r=p}return r.left+=o,r.top+=o,r.right-=o,r.bottom-=o,r}function H(e){var t=e.width,o=e.height;return t*o}function N(e,t,o,i,n){var r=5<arguments.length&&void 0!==arguments[5]?arguments[5]:0;if(-1===e.indexOf('auto'))return e;var s=_(o,i,r,n),a={top:{width:s.width,height:t.top-s.top},right:{width:s.right-t.right,height:s.height},bottom:{width:s.width,height:s.bottom-t.bottom},left:{width:t.left-s.left,height:s.height}},p=Object.keys(a).map(function(e){return pt({key:e},a[e],{area:H(a[e])})}).sort(function(e,t){return t.area-e.area}),l=p.filter(function(e){var t=e.width,i=e.height;return t>=o.clientWidth&&i>=o.clientHeight}),d=0<l.length?l[0].key:p[0].key,c=e.split('-')[1];return d+(c?'-'+c:'')}function M(e,t,o){var i=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null,n=i?R(t):T(t,o);return P(o,n,i)}function W(e){var t=getComputedStyle(e),o=parseFloat(t.marginTop)+parseFloat(t.marginBottom),i=parseFloat(t.marginLeft)+parseFloat(t.marginRight),n={width:e.offsetWidth+i,height:e.offsetHeight+o};return n}function B(e){var t={left:'right',right:'left',bottom:'top',top:'bottom'};return e.replace(/left|right|bottom|top/g,function(e){return t[e]})}function U(e,t,o){o=o.split('-')[0];var i=W(e),n={width:i.width,height:i.height},r=-1!==['right','left'].indexOf(o),s=r?'top':'left',a=r?'left':'top',p=r?'height':'width',l=r?'width':'height';return n[s]=t[s]+t[p]/2-i[p]/2,n[a]=o===a?t[a]-i[l]:t[B(a)],n}function F(e,t){return Array.prototype.find?e.find(t):e.filter(t)[0]}function Y(e,t,o){if(Array.prototype.findIndex)return e.findIndex(function(e){return e[t]===o});var i=F(e,function(e){return e[t]===o});return e.indexOf(i)}function q(e,t,o){var i=void 0===o?e:e.slice(0,Y(e,'name',o));return i.forEach(function(e){e['function']&&console.warn('`modifier.function` is deprecated, use `modifier.fn`!');var o=e['function']||e.fn;e.enabled&&u(o)&&(t.offsets.popper=k(t.offsets.popper),t.offsets.reference=k(t.offsets.reference),t=o(t,e))}),t}function z(){if(!this.state.isDestroyed){var e={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};e.offsets.reference=M(this.state,this.popper,this.reference,this.options.positionFixed),e.placement=N(this.options.placement,e.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),e.originalPlacement=e.placement,e.positionFixed=this.options.positionFixed,e.offsets.popper=U(this.popper,e.offsets.reference,e.placement),e.offsets.popper.position=this.options.positionFixed?'fixed':'absolute',e=q(this.modifiers,e),this.state.isCreated?this.options.onUpdate(e):(this.state.isCreated=!0,this.options.onCreate(e))}}function j(e,t){return e.some(function(e){var o=e.name,i=e.enabled;return i&&o===t})}function X(e){for(var t=[!1,'ms','Webkit','Moz','O'],o=e.charAt(0).toUpperCase()+e.slice(1),n=0;n<t.length;n++){var i=t[n],r=i?''+i+o:e;if('undefined'!=typeof document.body.style[r])return r}return null}function K(){return this.state.isDestroyed=!0,j(this.modifiers,'applyStyle')&&(this.popper.removeAttribute('x-placement'),this.popper.style.position='',this.popper.style.top='',this.popper.style.left='',this.popper.style.right='',this.popper.style.bottom='',this.popper.style.willChange='',this.popper.style[X('transform')]=''),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function V(e){var t=e.ownerDocument;return t?t.defaultView:window}function G(e,t,o,i){var n='BODY'===e.nodeName,r=n?e.ownerDocument.defaultView:e;r.addEventListener(t,o,{passive:!0}),n||G(b(r.parentNode),t,o,i),i.push(r)}function Q(e,t,o,i){o.updateBound=i,V(e).addEventListener('resize',o.updateBound,{passive:!0});var n=b(e);return G(n,'scroll',o.updateBound,o.scrollParents),o.scrollElement=n,o.eventsEnabled=!0,o}function Z(){this.state.eventsEnabled||(this.state=Q(this.reference,this.options,this.state,this.scheduleUpdate))}function $(e,t){return V(e).removeEventListener('resize',t.updateBound),t.scrollParents.forEac
23718h(function(e){e.removeEventListener('scroll',t.updateBound)}),t.updateBound=null,t.scrollParents=[],t.scrollElement=null,t.eventsEnabled=!1,t}function J(){this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=$(this.reference,this.state))}function ee(e){return''!==e&&!isNaN(parseFloat(e))&&isFinite(e)}function te(e,t){Object.keys(t).forEach(function(o){var i='';-1!==['width','height','top','right','bottom','left'].indexOf(o)&&ee(t[o])&&(i='px'),e.style[o]=t[o]+i})}function oe(e,t){Object.keys(t).forEach(function(o){var i=t[o];!1===i?e.removeAttribute(o):e.setAttribute(o,t[o])})}function ie(e,t,o){var i=F(e,function(e){var o=e.name;return o===t}),n=!!i&&e.some(function(e){return e.name===o&&e.enabled&&e.order<i.order});if(!n){var r='`'+t+'`';console.warn('`'+o+'`'+' modifier is required by '+r+' modifier in order to work, be sure to include it before '+r+'!')}return n}function ne(e){return'end'===e?'start':'start'===e?'end':e}function re(e){var t=!!(1<arguments.length&&void 0!==arguments[1])&&arguments[1],o=dt.indexOf(e),i=dt.slice(o+1).concat(dt.slice(0,o));return t?i.reverse():i}function se(e,t,o,i){var n=e.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+n[1],s=n[2];if(!r)return e;if(0===s.indexOf('%')){var a;switch(s){case'%p':a=o;break;case'%':case'%r':default:a=i;}var p=k(a);return p[t]/100*r}if('vh'===s||'vw'===s){var l;return l='vh'===s?Ye(document.documentElement.clientHeight,window.innerHeight||0):Ye(document.documentElement.clientWidth,window.innerWidth||0),l/100*r}return r}function ae(e,t,o,i){var n=[0,0],r=-1!==['right','left'].indexOf(i),s=e.split(/(\+|\-)/).map(function(e){return e.trim()}),a=s.indexOf(F(s,function(e){return-1!==e.search(/,|\s/)}));s[a]&&-1===s[a].indexOf(',')&&console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');var p=/\s*,\s*|\s+/,l=-1===a?[s]:[s.slice(0,a).concat([s[a].split(p)[0]]),[s[a].split(p)[1]].concat(s.slice(a+1))];return l=l.map(function(e,i){var n=(1===i?!r:r)?'height':'width',s=!1;return e.reduce(function(e,t){return''===e[e.length-1]&&-1!==['+','-'].indexOf(t)?(e[e.length-1]=t,s=!0,e):s?(e[e.length-1]+=t,s=!1,e):e.concat(t)},[]).map(function(e){return se(e,n,t,o)})}),l.forEach(function(e,t){e.forEach(function(o,i){ee(o)&&(n[t]+=o*('-'===e[i-1]?-1:1))})}),n}function pe(e,t){var o=t.offset,i=e.placement,n=e.offsets,r=n.popper,s=n.reference,a=i.split('-')[0],p=void 0;return p=ee(+o)?[+o,0]:ae(o,r,s,a),'left'===a?(r.top+=p[0],r.left-=p[1]):'right'===a?(r.top+=p[0],r.left+=p[1]):'top'===a?(r.left+=p[0],r.top-=p[1]):'bottom'===a&&(r.left+=p[0],r.top+=p[1]),e.popper=r,e}function le(e){void e.offsetHeight}function de(e,t,o){var i=e.popper,n=e.options,r=n.onCreate,s=n.onUpdate;n.onCreate=n.onUpdate=function(){le(i),t&&t(),s(),n.onCreate=r,n.onUpdate=s},o||e.scheduleUpdate()}function ce(e){return e.getAttribute('x-placement').replace(/-.+/,'')}function fe(e,t,o){if(!t.getAttribute('x-placement'))return!0;var i=e.clientX,n=e.clientY,r=o.interactiveBorder,s=o.distance,a=t.getBoundingClientRect(),p=ce(t),l=r+s,d={top:a.top-n>r,bottom:n-a.bottom>r,left:a.left-i>r,right:i-a.right>r};return'top'===p?d.top=a.top-n>l:'bottom'===p?d.bottom=n-a.bottom>l:'left'===p?d.left=a.left-i>l:'right'===p?d.right=i-a.right>l:void 0,d.top||d.bottom||d.left||d.right}function me(e,t,o,i){if(!t.length)return'';var n={scale:function(){return 1===t.length?''+t[0]:o?t[0]+', '+t[1]:t[1]+', '+t[0]}(),translate:function(){return 1===t.length?i?-t[0]+'px':t[0]+'px':o?i?t[0]+'px, '+-t[1]+'px':t[0]+'px, '+t[1]+'px':i?-t[1]+'px, '+t[0]+'px':t[1]+'px, '+t[0]+'px'}()};return n[e]}function ue(e,t){if(!e)return'';return t?e:{X:'Y',Y:'X'}[e]}function he(e,t,o){var i=ce(e),n='top'===i||'bottom'===i,r='right'===i||'bottom'===i,a=function(e){var t=o.match(e);return t?t[1]:''},p=function(e){var t=o.match(e);return t?t[1].split(',').map(parseFloat):[]},l={translate:/translateX?Y?\(([^)]+)\)/,scale:/scaleX?Y?\(([^)]+)\)/},d={translate:{axis:a(/translate([XY])/),numbers:p(l.translate)},scale:{axis:a(/scale([XY])/),numbers:p(l.scale)}},c=o.replace(l.translate,'translate'+ue(d.translate.axis,n)+'('+me('translate',d.translate.numbers,n,r)+')').replace(l.scale,'scale'+ue(d.scale.axis,n)+'('+me('scale',d.scale.numbers,n,r)+')');t.style[s('transform')]=c}function ge(e){return-(e-Ke.distance)+'px'}function be(e){requestAnimationFrame(function(){setTimeout(e,1)})}function ye(t,o){var i=Element.prototype.closest||function(t){for(var o=this;o;){if(e.call(o,t))return o;o=o.parentElement}};return i.call(t,o)}function ve(e,t){return Array.isArray(e)?e[t]:e}function we(e,t){e.forEach(function(e){e&&e.setAttribute('data-state',t)})}
23718function Ee(e,t){e.filter(Boolean).forEach(function(e){e.style[s('transitionDuration')]=t+'ms'})}function Te(e){var t=window.scrollX||window.pageXOffset,o=window.scrollY||window.pageYOffset;e.focus(),scroll(t,o)}function Le(){var e=this._(ht).lastTriggerEvent;return this.options.followCursor&&!je.usingTouch&&e&&'focus'!==e.type}function Oe(e){var t=ye(e.target,this.options.target);if(t&&!t._tippy){var o=t.getAttribute('title')||this.title;o&&(t.setAttribute('title',o),We(t,Ze({},this.options,{target:null})),xe.call(t._tippy,e))}}function xe(e){var t=this,o=this.options;if(Pe.call(this),!this.state.visible){if(o.target)return void Oe.call(this,e);if(this._(ht).isPreparingToShow=!0,o.wait)return void o.wait.call(this.popper,this.show.bind(this),e);if(Le.call(this)){this._(ht).followCursorListener||Ie.call(this);var i=f(this.popper),n=i.arrow;n&&(n.style.margin='0'),document.addEventListener('mousemove',this._(ht).followCursorListener)}var r=ve(o.delay,0);r?this._(ht).showTimeout=setTimeout(function(){t.show()},r):this.show()}}function Ae(){var e=this;if(Pe.call(this),!!this.state.visible){this._(ht).isPreparingToShow=!1;var t=ve(this.options.delay,1);t?this._(ht).hideTimeout=setTimeout(function(){e.state.visible&&e.hide()},t):this.hide()}}function Ce(){var e=this;return{onTrigger:function(t){if(e.state.enabled){var o=je.supportsTouch&&je.usingTouch&&-1<['mouseenter','mouseover','focus'].indexOf(t.type);o&&e.options.touchHold||(e._(ht).lastTriggerEvent=t,'click'===t.type&&'persistent'!==e.options.hideOnClick&&e.state.visible?Ae.call(e):xe.call(e,t))}},onMouseLeave:function(t){if(!(-1<['mouseleave','mouseout'].indexOf(t.type)&&je.supportsTouch&&je.usingTouch&&e.options.touchHold)){if(e.options.interactive){var o=Ae.bind(e),i=function t(i){var n=ye(i.target,Xe.REFERENCE),r=ye(i.target,Xe.POPPER)===e.popper,s=n===e.reference;r||s||fe(i,e.popper,e.options)&&(document.body.removeEventListener('mouseleave',o),document.removeEventListener('mousemove',t),Ae.call(e,t))};return document.body.addEventListener('mouseleave',o),void document.addEventListener('mousemove',i)}Ae.call(e)}},onBlur:function(t){if(!(t.target!==e.reference||je.usingTouch)){if(e.options.interactive){if(!t.relatedTarget)return;if(ye(t.relatedTarget,Xe.POPPER))return}Ae.call(e)}},onDelegateShow:function(t){ye(t.target,e.options.target)&&xe.call(e,t)},onDelegateHide:function(t){ye(t.target,e.options.target)&&Ae.call(e)}}}function ke(){var e=this,t=this.popper,o=this.reference,i=this.options,n=f(t),r=n.tooltip,s=i.popperOptions,a='round'===i.arrowType?Xe.ROUND_ARROW:Xe.ARROW,p=r.querySelector(a),l=Ze({placement:i.placement},s||{},{modifiers:Ze({},s?s.modifiers:{},{arrow:Ze({element:a},s&&s.modifiers?s.modifiers.arrow:{}),flip:Ze({enabled:i.flip,padding:i.distance+5,behavior:i.flipBehavior},s&&s.modifiers?s.modifiers.flip:{}),offset:Ze({offset:i.offset},s&&s.modifiers?s.modifiers.offset:{})}),onCreate:function(){r.style[ce(t)]=ge(i.distance),p&&i.arrowTransform&&he(t,p,i.arrowTransform)},onUpdate:function(){var e=r.style;e.top='',e.bottom='',e.left='',e.right='',e[ce(t)]=ge(i.distance),p&&i.arrowTransform&&he(t,p,i.arrowTransform)}});return Re.call(this,{target:t,callback:function(){e.popperInstance.update()},options:{childList:!0,subtree:!0,characterData:!0}}),new ft(o,t,l)}function Se(e){var t=this.options;if(this.popperInstance?(this.popperInstance.scheduleUpdate(),t.livePlacement&&!Le.call(this)&&this.popperInstance.enableEventListeners()):(this.popperInstance=ke.call(this),!t.livePlacement&&this.popperInstance.disableEventListeners()),!Le.call(this)){var o=f(this.popper),i=o.arrow;i&&(i.style.margin=''),this.popperInstance.reference=this.reference}de(this.popperInstance,e,!0),t.appendTo.contains(this.popper)||t.appendTo.appendChild(this.popper)}function Pe(){var e=this._(ht),t=e.showTimeout,o=e.hideTimeout;clearTimeout(t),clearTimeout(o)}function Ie(){var e=this;this._(ht).followCursorListener=function(t){var o=e._(ht).lastMouseMoveEvent=t,i=o.clientX,n=o.clientY;e.popperInstance&&(e.popperInstance.reference={getBoundingClientRect:function(){return{width:0,height:0,top:n,left:i,right:i,bottom:n}},clientWidth:0,clientHeight:0},e.popperInstance.scheduleUpdate())}}function De(){var e=this,t=function(){e.popper.style[s('transitionDuration')]=e.options.updateDuration+'ms'},o=function(){e.popper.style[s('transitionDuration')]=''};
23718(function i(){e.popperInstance&&e.popperInstance.update(),t(),e.state.visible?requestAnimationFrame(i):o()})()}function Re(e){var t=e.target,o=e.callback,i=e.options;if(window.MutationObserver){var n=new MutationObserver(o);n.observe(t,i),this._(ht).mutationObservers.push(n)}}function _e(e,t){if(!e)return t();var o=f(this.popper),i=o.tooltip,n=function(e,t){t&&i[e+'EventListener']('transition'in document.body.style?'transitionend':'webkitTransitionEnd',t)},r=function o(r){r.target===i&&(n('remove',o),t())};n('remove',this._(ht).transitionendListener),n('add',r),this._(ht).transitionendListener=r}function He(e,t){return e.reduce(function(e,o){var i=yt,n=c(o,t.performance?t:d(o,t)),r=o.getAttribute('title');if(!r&&!n.target&&!n.html&&!n.dynamicTitle)return e;o.setAttribute(n.target?'data-tippy-delegate':'data-tippy',''),m(o);var s=p(i,r,n),a=new bt({id:i,reference:o,popper:s,options:n,title:r,popperInstance:null});n.createPopperInstanceOnInit&&(a.popperInstance=ke.call(a),a.popperInstance.disableEventListeners());var u=Ce.call(a);return a.listeners=n.trigger.trim().split(' ').reduce(function(e,t){return e.concat(l(t,o,u,n))},[]),n.dynamicTitle&&Re.call(a,{target:o,callback:function(){var e=f(s),t=e.content,i=o.getAttribute('title');i&&(t[n.allowTitleHTML?'innerHTML':'textContent']=a.title=i,m(o))},options:{attributes:!0}}),o._tippy=a,s._tippy=a,s._reference=o,e.push(a),yt++,e},[])}function Ne(e){var t=o(document.querySelectorAll(Xe.POPPER));t.forEach(function(t){var o=t._tippy;if(o){var i=o.options;(!0===i.hideOnClick||-1<i.trigger.indexOf('focus'))&&(!e||t!==e.popper)&&o.hide()}})}function Me(){var t=function(){je.usingTouch||(je.usingTouch=!0,je.iOS&&document.body.classList.add('tippy-touch'),je.dynamicInputDetection&&window.performance&&document.addEventListener('mousemove',i),je.onUserInputChange('touch'))},i=function(){var e;return function(){var t=performance.now();20>t-e&&(je.usingTouch=!1,document.removeEventListener('mousemove',i),!je.iOS&&document.body.classList.remove('tippy-touch'),je.onUserInputChange('mouse')),e=t}}();document.addEventListener('click',function(e){if(!(e.target instanceof Element))return Ne();var t=ye(e.target,Xe.REFERENCE),o=ye(e.target,Xe.POPPER);if(!(o&&o._tippy&&o._tippy.options.interactive)){if(t&&t._tippy){var i=t._tippy.options,n=-1<i.trigger.indexOf('click'),r=i.multiple;if(!r&&je.usingTouch||!r&&n)return Ne(t._tippy);if(!0!==i.hideOnClick||n)return}Ne()}}),document.addEventListener('touchstart',t),window.addEventListener('blur',function(){var t=document,o=t.activeElement;o&&o.blur&&e.call(o,Xe.REFERENCE)&&o.blur()}),window.addEventListener('resize',function(){o(document.querySelectorAll(Xe.POPPER)).forEach(function(e){var t=e._tippy;t&&!t.options.livePlacement&&t.popperInstance.scheduleUpdate()})}),!je.supportsTouch&&(navigator.maxTouchPoints||navigator.msMaxTouchPoints)&&document.addEventListener('pointerdown',t)}function We(e,o,i){je.supported&&!vt&&(Me(),vt=!0),t(e)&&r(e),o=Ze({},Ke,o);var s=n(e),a=s[0];return{selector:e,options:o,tooltips:je.supported?He(i&&a?[a]:s,o):[],destroyAll:function(){this.tooltips.forEach(function(e){return e.destroy()}),this.tooltips=[]}}}var Be=Math.min,Ue=Math.round,Fe=Math.floor,Ye=Math.max,qe='undefined'!=typeof window,ze=qe&&/MSIE |Trident\//.test(navigator.userAgent),je={};qe&&(je.supported='requestAnimationFrame'in window,je.supportsTouch='ontouchstart'in window,je.usingTouch=!1,je.dynamicInputDetection=!0,je.iOS=/iPhone|iPad|iPod/.test(navigator.platform)&&!window.MSStream,je.onUserInputChange=function(){});for(var Xe={POPPER:'.tippy-popper',TOOLTIP:'.tippy-tooltip',CONTENT:'.tippy-content',BACKDROP:'.tippy-backdrop',ARROW:'.tippy-arrow',ROUND_ARROW:'.tippy-roundarrow',REFERENCE:'[data-tippy]'},Ke={placement:'top',livePlacement:!0,trigger:'mouseenter focus',animation:'shift-away',html:!1,animateFill:!0,arrow:!1,delay:0,duration:[350,300],interactive:!1,interactiveBorder:2,theme:'dark',size:'regular',distance:10,offset:0,hideOnClick:!0,multiple:!1,followCursor:!1,inertia:!1,updateDuration:350,sticky:!1,appendTo:function(){return document.body},zIndex:9999,touchHold:!1,performance:!1,dynamicTitle:!1,flip:!0,flipBehavior:'flip',arrowType:'sharp',arrowTransform:'',maxWidth:'',target:null,allowTitleHTML:!0,popperOptions:{},createPopperInstanceOnInit:!1,onShow:function(){},onShown:function(){},onHide:function(){},onHidden:function(){}},Ve=je.supported&&Object.keys(Ke),Ge=function(e,t){if(!(e instanceof t))throw new TypeError('Cannot call a class as a function')},Qe=function(){function e(e,t){for(var o,n=0;n<t.length;n++)o=t[n],o.enumerable=o.enumerable||!1,o.configurable=!0,('value'in o)&&(o.writable=!0),Object.defineProperty(e,o.key,o)}return function(t,o,i){return o&&e(t.prototype,o),i&&e(t,i),t}}(),Ze=Object.assign||function(e){for(var t,o=1;o<arguments.length;o++)for(var i in t=arguments[o],t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e},$e='undefined'!=typeof window&&'undefined'!=typeof document,Je=['Edge','Trident','Firefox'],et=0,tt=0;tt<Je.length;tt+=1)if($e&&0<=navigator.userAgent.indexOf(Je[tt])){et=1;break}var i=$e&&window.Promise,ot=i?function(e){var t=!1;return function(){t||(t=!0,window.Promise.resolve().then(function(){t=!1,e()}))}}:function(e){var t=!1;return function(){t||(t=!0,setTimeout(function(){t=!1,e()},et))}},it=$e&&!!(window.MSInputMethodContext&&document.documentMode),nt=$e&&/MSIE 10/.test(navigator.userAgent),rt=function(e,t){if(!(e instanceof t))throw new TypeError('Cannot call a class as a function')},st=function(){function e(e,t){for(var o,n=0;n<t.length;n++)o=t[n],o.enumerable=o.enumerable||!1,o.configurable=!0,'value'in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}return function(t,o,i){return o&&e(t.prototype,o),i&&e(t,i),t}}(),at=function(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e},pt=Object.assign||function(e){for(var t,o=1;o<arguments.length;o++)for(var i in t=arguments[o],t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e},lt=['auto-start','auto','auto-end','top-start','top','top-end','right-start','right','right-end','bottom-end','bottom','bottom-start','left-end','left','left-start'],dt=lt.slice(3),ct={FLIP:'flip',CLOCKWISE:'clockwise',COUNTERCLOCKWISE:'counterclockwise'},ft=function(){function e(t,o){var i=this,n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};rt(this,e),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=ot(this.update.bind(this)),this.options=pt({},e.Defaults,n),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=t&&t.jquery?t[0]:t,this.popper=o&&o.jquery?o[0]:o,this.options.modifiers={},Object.keys(pt({}
vendor: 5,690 bytes, line 23718
23718,e.Defaults.modifiers,n.modifiers)).forEach(function(t){i.options.modifiers[t]=pt({},e.Defaults.modifiers[t]||{},n.modifiers?n.modifiers[t]:{})}),this.modifiers=Object.keys(this.options.modifiers).map(function(e){return pt({name:e},i.options.modifiers[e])}).sort(function(e,t){return e.order-t.order}),this.modifiers.forEach(function(e){e.enabled&&u(e.onLoad)&&e.onLoad(i.reference,i.popper,i.options,e,i.state)}),this.update();var r=this.options.eventsEnabled;r&&this.enableEventListeners(),this.state.eventsEnabled=r}return st(e,[{key:'update',value:function(){return z.call(this)}},{key:'destroy',value:function(){return K.call(this)}},{key:'enableEventListeners',value:function(){return Z.call(this)}},{key:'disableEventListeners',value:function(){return J.call(this)}}]),e}();ft.Utils=('undefined'==typeof window?global:window).PopperUtils,ft.placements=lt,ft.Defaults={placement:'bottom',positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(e){var t=e.placement,o=t.split('-')[0],i=t.split('-')[1];if(i){var n=e.offsets,r=n.reference,s=n.popper,a=-1!==['bottom','top'].indexOf(o),p=a?'left':'top',l=a?'width':'height',d={start:at({},p,r[p]),end:at({},p,r[p]+r[l]-s[l])};e.offsets.popper=pt({},s,d[i])}return e}},offset:{order:200,enabled:!0,fn:pe,offset:0},preventOverflow:{order:300,enabled:!0,fn:function(e,t){var o=t.boundariesElement||v(e.instance.popper);e.instance.reference===o&&(o=v(o));var i=X('transform'),n=e.instance.popper.style,r=n.top,s=n.left,a=n[i];n.top='',n.left='',n[i]='';var p=_(e.instance.popper,e.instance.reference,t.padding,o,e.positionFixed);n.top=r,n.left=s,n[i]=a,t.boundaries=p;var l=t.priority,d=e.offsets.popper,c={primary:function(e){var o=d[e];return d[e]<p[e]&&!t.escapeWithReference&&(o=Ye(d[e],p[e])),at({},e,o)},secondary:function(e){var o='right'===e?'left':'top',i=d[o];return d[e]>p[e]&&!t.escapeWithReference&&(i=Be(d[o],p[e]-('right'===e?d.width:d.height))),at({},o,i)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';d=pt({},d,c[t](e))}),e.offsets.popper=d,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,i=t.reference,n=e.placement.split('-')[0],r=Fe,s=-1!==['top','bottom'].indexOf(n),a=s?'right':'bottom',p=s?'left':'top',l=s?'width':'height';return o[a]<r(i[p])&&(e.offsets.popper[p]=r(i[p])-o[l]),o[p]>r(i[a])&&(e.offsets.popper[p]=r(i[a])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){var o;if(!ie(e.instance.modifiers,'arrow','keepTogether'))return e;var i=t.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var n=e.placement.split('-')[0],r=e.offsets,s=r.popper,a=r.reference,p=-1!==['left','right'].indexOf(n),l=p?'height':'width',d=p?'Top':'Left',c=d.toLowerCase(),f=p?'left':'top',m=p?'bottom':'right',u=W(i)[l];a[m]-u<s[c]&&(e.offsets.popper[c]-=s[c]-(a[m]-u)),a[c]+u>s[m]&&(e.offsets.popper[c]+=a[c]+u-s[m]),e.offsets.popper=k(e.offsets.popper);var g=a[c]+a[l]/2-u/2,b=h(e.instance.popper),y=parseFloat(b['margin'+d],10),v=parseFloat(b['border'+d+'Width'],10),w=g-e.offsets.popper[c]-y-v;return w=Ye(Be(s[l]-u,w),0),e.arrowElement=i,e.offsets.arrow=(o={},at(o,c,Ue(w)),at(o,f,''),o),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(j(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=_(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),i=e.placement.split('-')[0],n=B(i),r=e.placement.split('-')[1]||'',s=[];switch(t.behavior){case ct.FLIP:s=[i,n];break;case ct.CLOCKWISE:s=re(i);break;case ct.COUNTERCLOCKWISE:s=re(i,!0);break;default:s=t.behavior;}return s.forEach(function(a,p){if(i!==a||s.length===p+1)return e;i=e.placement.split('-')[0],n=B(i);var l=e.offsets.popper,d=e.offsets.reference,c=Fe,f='left'===i&&c(l.right)>c(d.left)||'right'===i&&c(l.left)<c(d.right)||'top'===i&&c(l.bottom)>c(d.top)||'bottom'===i&&c(l.top)<c(d.bottom),m=c(l.left)<c(o.left),u=c(l.right)>c(o.right),h=c(l.top)<c(o.top),g=c(l.bottom)>c(o.bottom),b='left'===i&&m||'right'===i&&u||'top'===i&&h||'bottom'===i&&g,y=-1!==['top','bottom'].indexOf(i),v=!!t.flipVariations&&(y&&'start'===r&&m||y&&'end'===r&&u||!y&&'start'===r&&h||!y&&'end'===r&&g);(f||b||v)&&(e.flipped=!0,(f||b)&&(i=s[p+1]),v&&(r=ne(r)),e.placement=i+(r?'-'+r:''),e.offsets.popper=pt({},e.offsets.popper,U(e.instance.popper,e.offsets.reference,e.placement)),e=q(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],i=e.offsets,n=i.popper,r=i.reference,s=-1!==['left','right'].indexOf(o),a=-1===['top','left'].indexOf(o);return n[s?'left':'top']=r[o]-(a?n[s?'width':'height']:0),e.placement=B(t),e.offsets.popper=k(n),e}},hide:{order:800,enabled:!0,fn:function(e){if(!ie(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=F(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottom<o.top||t.left>o.right||t.top>o.bottom||t.right<o.left){if(!0===e.hide)return e;e.hide=!0,e.attributes['x-out-of-boundaries']=''}else{if(!1===e.hide)return e;e.hide=!1,e.attributes['x-out-of-boundaries']=!1}return e}},computeStyle:{order:850,enabled:!0,fn:function(e,t){var o=t.x,i=t.y,n=e.offsets.popper,r=F(e.instance.modifiers,function(e){return'applyStyle'===e.name}).gpuAcceleration;
23718void 0!==r&&console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');var s=void 0===r?t.gpuAcceleration:r,a=v(e.instance.popper),p=S(a),l={position:n.position},d={left:Fe(n.left),top:Ue(n.top),bottom:Ue(n.bottom),right:Fe(n.right)},c='bottom'===o?'top':'bottom',f='right'===i?'left':'right',m=X('transform'),u=void 0,h=void 0;if(h='bottom'==c?-p.height+d.bottom:d.top,u='right'==f?-p.width+d.right:d.left,s&&m)l[m]='translate3d('+u+'px, '+h+'px, 0)',l[c]=0,l[f]=0,l.willChange='transform';else{var g='bottom'==c?-1:1,b='right'==f?-1:1;l[c]=h*g,l[f]=u*b,l.willChange=c+', '+f}var y={"x-placement":e.placement};return e.attributes=pt({},y,e.attributes),e.styles=pt({},l,e.styles),e.arrowStyles=pt({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return te(e.instance.popper,e.styles),oe(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&te(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,i,n){var r=M(n,t,e,o.positionFixed),s=N(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',s),te(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}};var mt={};if(qe){var ut=Element.prototype;mt=ut.matches||ut.matchesSelector||ut.webkitMatchesSelector||ut.mozMatchesSelector||ut.msMatchesSelector||function(e){for(var t=(this.document||this.ownerDocument).querySelectorAll(e),o=t.length;0<=--o&&t.item(o)!==this;);return-1<o}}var e=mt,ht={},gt=function(e){return function(t){return t===ht&&e}},bt=function(){function e(t){for(var o in Ge(this,e),t)this[o]=t[o];this.state={destroyed:!1,visible:!1,enabled:!0},this._=gt({mutationObservers:[]})}return Qe(e,[{key:'enable',value:function(){this.state.enabled=!0}},{key:'disable',value:function(){this.state.enabled=!1}},{key:'show',value:function(e){var t=this;if(!this.state.destroyed&&this.state.enabled){var o=this.popper,i=this.reference,n=this.options,r=f(o),a=r.tooltip,p=r.backdrop,l=r.content;return n.dynamicTitle&&!i.getAttribute('data-original-title')||i.hasAttribute('disabled')?void 0:i.refObj||document.documentElement.contains(i)?void(n.onShow.call(o,this),e=ve(void 0===e?n.duration:e,0),Ee([o,a,p],0),o.style.visibility='visible',this.state.visible=!0,Se.call(this,function(){if(t.state.visible){if(Le.call(t)||t.popperInstance.scheduleUpdate(),Le.call(t)){t.popperInstance.disableEventListeners();var r=ve(n.delay,0),d=t._(ht).lastTriggerEvent;d&&t._(ht).followCursorListener(r&&t._(ht).lastMouseMoveEvent?t._(ht).lastMouseMoveEvent:d)}Ee([a,p,p?l:null],e),p&&getComputedStyle(p)[s('transform')],n.interactive&&i.classList.add('tippy-active'),n.sticky&&De.call(t),we([a,p],'visible'),_e.call(t,e,function(){n.updateDuration||a.classList.add('tippy-notransition'),n.interactive&&Te(o),i.setAttribute('aria-describedby','tippy-'+t.id),n.onShown.call(o,t)})}})):void this.destroy()}}},{key:'hide',value:function(e){var t=this;if(!this.state.destroyed&&this.state.enabled){var o=this.popper,i=this.reference,n=this.options,r=f(o),s=r.tooltip,a=r.backdrop,p=r.content;n.onHide.call(o,this),e=ve(void 0===e?n.duration:e,1),n.updateDuration||s.classList.remove('tippy-notransition'),n.interactive&&i.classList.remove('tippy-active'),o.style.visibility='hidden',this.state.visible=!1,Ee([s,a,a?p:null],e),we([s,a],'hidden'),n.interactive&&-1<n.trigger.indexOf('click')&&Te(i),be(function(){_e.call(t,e,function(){t.state.visible||!n.appendTo.contains(o)||(!t._(ht).isPreparingToShow&&(document.removeEventListener('mousemove',t._(ht).followCursorListener),t._(ht).lastMouseMoveEvent=null),t.popperInstance&&t.popperInstance.disableEventListeners(),i.removeAttribute('aria-describedby'),n.appendTo.removeChild(o),n.onHidden.call(o,t))})})}}},{key:'destroy',value:function(){var e=this,t=!(0<arguments.length&&void 0!==arguments[0])||arguments[0];if(!this.state.destroyed){this.state.visible&&this.hide(0),this.listeners.forEach(function(t){e.reference.removeEventListener(t.event,t.handler)}),this.title&&this.reference.setAttribute('title',this.title),delete this.reference._tippy;['data-original-title','data-tippy','data-tippy-delegate'].forEach(function(t){e.reference.removeAttribute(t)}),this.options.target&&t&&o(this.reference.querySelectorAll(this.options.target)).forEac
23718h(function(e){return e._tippy&&e._tippy.destroy()}),this.popperInstance&&this.popperInstance.destroy(),this._(ht).mutationObservers.forEach(function(e){e.disconnect()}),this.state.destroyed=!0}}}]),e}(),yt=1,vt=!1;return We.version='2.5.4',We.browser=je,We.defaults=Ke,We.one=function(e,t){return We(e,t,!0).tooltips[0]},We.disableAnimations=function(){Ke.updateDuration=Ke.duration=0,Ke.animateFill=!1},We});
23719!function() {
23720  var d3 = {
23721    version: "3.5.5"
23722  };
23723  var d3_arraySlice = [].slice, d3_array = function(list) {
23724    return d3_arraySlice.call(list);
23725  };
23726  var d3_document = this.document;
23727  function d3_documentElement(node) {
23728    return node && (node.ownerDocument || node.document || node).documentElement;
23729  }
23730  function d3_window(node) {
23731    return node && (node.ownerDocument && node.ownerDocument.defaultView || node.document && node || node.defaultView);
23732  }
23733  if (d3_document) {
23734    try {
23735      d3_array(d3_document.documentElement.childNodes)[0].nodeType;
23736    } catch (e) {
23737      d3_array = function(list) {
23738        var i = list.length, array = new Array(i);
23739        while (i--) array[i] = list[i];
23740        return array;
23741      };
23742    }
23743  }
23744  if (!Date.now) Date.now = function() {
23745    return +new Date();
23746  };
23747  if (d3_document) {
23748    try {
23749      d3_document.createElement("DIV").style.setProperty("opacity", 0, "");
23750    } catch (error) {
23751      var d3_element_prototype = this.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = this.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty;
23752      d3_element_prototype.setAttribute = function(name, value) {
23753        d3_element_setAttribute.call(this, name, value + "");
23754      };
23755      d3_element_prototype.setAttributeNS = function(space, local, value) {
23756        d3_element_setAttributeNS.call(this, space, local, value + "");
23757      };
23758      d3_style_prototype.setProperty = function(name, value, priority) {
23759        d3_style_setProperty.call(this, name, value + "", priority);
23760      };
23761    }
23762  }
23763  d3.ascending = d3_ascending;
23764  function d3_ascending(a, b) {
23765    return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
23766  }
vendor: 35,440 bytes, lines 23767-24854
23767  d3.descending = function(a, b) {
23768    return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
23769  };
23770  d3.min = function(array, f) {
23771    var i = -1, n = array.length, a, b;
23772    if (arguments.length === 1) {
23773      while (++i < n) if ((b = array[i]) != null && b >= b) {
23774        a = b;
23775        break;
23776      }
23777      while (++i < n) if ((b = array[i]) != null && a > b) a = b;
23778    } else {
23779      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {
23780        a = b;
23781        break;
23782      }
23783      while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b;
23784    }
23785    return a;
23786  };
23787  d3.max = function(array, f) {
23788    var i = -1, n = array.length, a, b;
23789    if (arguments.length === 1) {
23790      while (++i < n) if ((b = array[i]) != null && b >= b) {
23791        a = b;
23792        break;
23793      }
23794      while (++i < n) if ((b = array[i]) != null && b > a) a = b;
23795    } else {
23796      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {
23797        a = b;
23798        break;
23799      }
23800      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b;
23801    }
23802    return a;
23803  };
23804  d3.extent = function(array, f) {
23805    var i = -1, n = array.length, a, b, c;
23806    if (arguments.length === 1) {
23807      while (++i < n) if ((b = array[i]) != null && b >= b) {
23808        a = c = b;
23809        break;
23810      }
23811      while (++i < n) if ((b = array[i]) != null) {
23812        if (a > b) a = b;
23813        if (c < b) c = b;
23814      }
23815    } else {
23816      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {
23817        a = c = b;
23818        break;
23819      }
23820      while (++i < n) if ((b = f.call(array, array[i], i)) != null) {
23821        if (a > b) a = b;
23822        if (c < b) c = b;
23823      }
23824    }
23825    return [ a, c ];
23826  };
23827  function d3_number(x) {
23828    return x === null ? NaN : +x;
23829  }
23830  function d3_numeric(x) {
23831    return !isNaN(x);
23832  }
23833  d3.sum = function(array, f) {
23834    var s = 0, n = array.length, a, i = -1;
23835    if (arguments.length === 1) {
23836      while (++i < n) if (d3_numeric(a = +array[i])) s += a;
23837    } else {
23838      while (++i < n) if (d3_numeric(a = +f.call(array, array[i], i))) s += a;
23839    }
23840    return s;
23841  };
23842  d3.mean = function(array, f) {
23843    var s = 0, n = array.length, a, i = -1, j = n;
23844    if (arguments.length === 1) {
23845      while (++i < n) if (d3_numeric(a = d3_number(array[i]))) s += a; else --j;
23846    } else {
23847      while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) s += a; else --j;
23848    }
23849    if (j) return s / j;
23850  };
23851  d3.quantile = function(values, p) {
23852    var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h;
23853    return e ? v + e * (values[h] - v) : v;
23854  };
23855  d3.median = function(array, f) {
23856    var numbers = [], n = array.length, a, i = -1;
23857    if (arguments.length === 1) {
23858      while (++i < n) if (d3_numeric(a = d3_number(array[i]))) numbers.push(a);
23859    } else {
23860      while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) numbers.push(a);
23861    }
23862    if (numbers.length) return d3.quantile(numbers.sort(d3_ascending), .5);
23863  };
23864  d3.variance = function(array, f) {
23865    var n = array.length, m = 0, a, d, s = 0, i = -1, j = 0;
23866    if (arguments.length === 1) {
23867      while (++i < n) {
23868        if (d3_numeric(a = d3_number(array[i]))) {
23869          d = a - m;
23870          m += d / ++j;
23871          s += d * (a - m);
23872        }
23873      }
23874    } else {
23875      while (++i < n) {
23876        if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) {
23877          d = a - m;
23878          m += d / ++j;
23879          s += d * (a - m);
23880        }
23881      }
23882    }
23883    if (j > 1) return s / (j - 1);
23884  };
23885  d3.deviation = function() {
23886    var v = d3.variance.apply(this, arguments);
23887    return v ? Math.sqrt(v) : v;
23888  };
23889  function d3_bisector(compare) {
23890    return {
23891      left: function(a, x, lo, hi) {
23892        if (arguments.length < 3) lo = 0;
23893        if (arguments.length < 4) hi = a.length;
23894        while (lo < hi) {
23895          var mid = lo + hi >>> 1;
23896          if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid;
23897        }
23898        return lo;
23899      },
23900      right: function(a, x, lo, hi) {
23901        if (arguments.length < 3) lo = 0;
23902        if (arguments.length < 4) hi = a.length;
23903        while (lo < hi) {
23904          var mid = lo + hi >>> 1;
23905          if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1;
23906        }
23907        return lo;
23908      }
23909    };
23910  }
23911  var d3_bisect = d3_bisector(d3_ascending);
23912  d3.bisectLeft = d3_bisect.left;
23913  d3.bisect = d3.bisectRight = d3_bisect.right;
23914  d3.bisector = function(f) {
23915    return d3_bisector(f.length === 1 ? function(d, x) {
23916      return d3_ascending(f(d), x);
23917    } : f);
23918  };
23919  d3.shuffle = function(array, i0, i1) {
23920    if ((m = arguments.length) < 3) {
23921      i1 = array.length;
23922      if (m < 2) i0 = 0;
23923    }
23924    var m = i1 - i0, t, i;
23925    while (m) {
23926      i = Math.random() * m-- | 0;
23927      t = array[m + i0], array[m + i0] = array[i + i0], array[i + i0] = t;
23928    }
23929    return array;
23930  };
23931  d3.permute = function(array, indexes) {
23932    var i = indexes.length, permutes = new Array(i);
23933    while (i--) permutes[i] = array[indexes[i]];
23934    return permutes;
23935  };
23936  d3.pairs = function(array) {
23937    var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n);
23938    while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ];
23939    return pairs;
23940  };
23941  d3.zip = function() {
23942    if (!(n = arguments.length)) return [];
23943    for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) {
23944      for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) {
23945        zip[j] = arguments[j][i];
23946      }
23947    }
23948    return zips;
23949  };
23950  function d3_zipLength(d) {
23951    return d.length;
23952  }
23953  d3.transpose = function(matrix) {
23954    return d3.zip.apply(d3, matrix);
23955  };
23956  d3.keys = function(map) {
23957    var keys = [];
23958    for (var key in map) keys.push(key);
23959    return keys;
23960  };
23961  d3.values = function(map) {
23962    var values = [];
23963    for (var key in map) values.push(map[key]);
23964    return values;
23965  };
23966  d3.entries = function(map) {
23967    var entries = [];
23968    for (var key in map) entries.push({
23969      key: key,
23970      value: map[key]
23971    });
23972    return entries;
23973  };
23974  d3.merge = function(arrays) {
23975    var n = arrays.length, m, i = -1, j = 0, merged, array;
23976    while (++i < n) j += arrays[i].length;
23977    merged = new Array(j);
23978    while (--n >= 0) {
23979      array = arrays[n];
23980      m = array.length;
23981      while (--m >= 0) {
23982        merged[--j] = array[m];
23983      }
23984    }
23985    return merged;
23986  };
23987  var abs = Math.abs;
23988  d3.range = function(start, stop, step) {
23989    if (arguments.length < 3) {
23990      step = 1;
23991      if (arguments.length < 2) {
23992        stop = start;
23993        start = 0;
23994      }
23995    }
23996    if ((stop - start) / step === Infinity) throw new Error("infinite range");
23997    var range = [], k = d3_range_integerScale(abs(step)), i = -1, j;
23998    start *= k, stop *= k, step *= k;
23999    if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k);
24000    return range;
24001  };
24002  function d3_range_integerScale(x) {
24003    var k = 1;
24004    while (x * k % 1) k *= 10;
24005    return k;
24006  }
24007  function d3_class(ctor, properties) {
24008    for (var key in properties) {
24009      Object.defineProperty(ctor.prototype, key, {
24010        value: properties[key],
24011        enumerable: false
24012      });
24013    }
24014  }
24015  d3.map = function(object, f) {
24016    var map = new d3_Map();
24017    if (object instanceof d3_Map) {
24018      object.forEach(function(key, value) {
24019        map.set(key, value);
24020      });
24021    } else if (Array.isArray(object)) {
24022      var i = -1, n = object.length, o;
24023      if (arguments.length === 1) while (++i < n) map.set(i, object[i]); else while (++i < n) map.set(f.call(object, o = object[i], i), o);
24024    } else {
24025      for (var key in object) map.set(key, object[key]);
24026    }
24027    return map;
24028  };
24029  function d3_Map() {
24030    this._ = Object.create(null);
24031  }
24032  var d3_map_proto = "__proto__", d3_map_zero = "\x00";
24033  d3_class(d3_Map, {
24034    has: d3_map_has,
24035    get: function(key) {
24036      return this._[d3_map_escape(key)];
24037    },
24038    set: function(key, value) {
24039      return this._[d3_map_escape(key)] = value;
24040    },
24041    remove: d3_map_remove,
24042    keys: d3_map_keys,
24043    values: function() {
24044      var values = [];
24045      for (var key in this._) values.push(this._[key]);
24046      return values;
24047    },
24048    entries: function() {
24049      var entries = [];
24050      for (var key in this._) entries.push({
24051        key: d3_map_unescape(key),
24052        value: this._[key]
24053      });
24054      return entries;
24055    },
24056    size: d3_map_size,
24057    empty: d3_map_empty,
24058    forEach: function(f) {
24059      for (var key in this._) f.call(this, d3_map_unescape(key), this._[key]);
24060    }
24061  });
24062  function d3_map_escape(key) {
24063    return (key += "") === d3_map_proto || key[0] === d3_map_zero ? d3_map_zero + key : key;
24064  }
24065  function d3_map_unescape(key) {
24066    return (key += "")[0] === d3_map_zero ? key.slice(1) : key;
24067  }
24068  function d3_map_has(key) {
24069    return d3_map_escape(key) in this._;
24070  }
24071  function d3_map_remove(key) {
24072    return (key = d3_map_escape(key)) in this._ && delete this._[key];
24073  }
24074  function d3_map_keys() {
24075    var keys = [];
24076    for (var key in this._) keys.push(d3_map_unescape(key));
24077    return keys;
24078  }
24079  function d3_map_size() {
24080    var size = 0;
24081    for (var key in this._) ++size;
24082    return size;
24083  }
24084  function d3_map_empty() {
24085    for (var key in this._) return false;
24086    return true;
24087  }
24088  d3.nest = function() {
24089    var nest = {}, keys = [], sortKeys = [], sortValues, rollup;
24090    function map(mapType, array, depth) {
24091      if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array;
24092      var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values;
24093      while (++i < n) {
24094        if (values = valuesByKey.get(keyValue = key(object = array[i]))) {
24095          values.push(object);
24096        } else {
24097          valuesByKey.set(keyValue, [ object ]);
24098        }
24099      }
24100      if (mapType) {
24101        object = mapType();
24102        setter = function(keyValue, values) {
24103          object.set(keyValue, map(mapType, values, depth));
24104        };
24105      } else {
24106        object = {};
24107        setter = function(keyValue, values) {
24108          object[keyValue] = map(mapType, values, depth);
24109        };
24110      }
24111      valuesByKey.forEach(setter);
24112      return object;
24113    }
24114    function entries(map, depth) {
24115      if (depth >= keys.length) return map;
24116      var array = [], sortKey = sortKeys[depth++];
24117      map.forEach(function(key, keyMap) {
24118        array.push({
24119          key: key,
24120          values: entries(keyMap, depth)
24121        });
24122      });
24123      return sortKey ? array.sort(function(a, b) {
24124        return sortKey(a.key, b.key);
24125      }) : array;
24126    }
24127    nest.map = function(array, mapType) {
24128      return map(mapType, array, 0);
24129    };
24130    nest.entries = function(array) {
24131      return entries(map(d3.map, array, 0), 0);
24132    };
24133    nest.key = function(d) {
24134      keys.push(d);
24135      return nest;
24136    };
24137    nest.sortKeys = function(order) {
24138      sortKeys[keys.length - 1] = order;
24139      return nest;
24140    };
24141    nest.sortValues = function(order) {
24142      sortValues = order;
24143      return nest;
24144    };
24145    nest.rollup = function(f) {
24146      rollup = f;
24147      return nest;
24148    };
24149    return nest;
24150  };
24151  d3.set = function(array) {
24152    var set = new d3_Set();
24153    if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]);
24154    return set;
24155  };
24156  function d3_Set() {
24157    this._ = Object.create(null);
24158  }
24159  d3_class(d3_Set, {
24160    has: d3_map_has,
24161    add: function(key) {
24162      this._[d3_map_escape(key += "")] = true;
24163      return key;
24164    },
24165    remove: d3_map_remove,
24166    values: d3_map_keys,
24167    size: d3_map_size,
24168    empty: d3_map_empty,
24169    forEach: function(f) {
24170      for (var key in this._) f.call(this, d3_map_unescape(key));
24171    }
24172  });
24173  d3.behavior = {};
24174  function d3_identity(d) {
24175    return d;
24176  }
24177  d3.rebind = function(target, source) {
24178    var i = 1, n = arguments.length, method;
24179    while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]);
24180    return target;
24181  };
24182  function d3_rebind(target, source, method) {
24183    return function() {
24184      var value = method.apply(source, arguments);
24185      return value === source ? target : value;
24186    };
24187  }
24188  function d3_vendorSymbol(object, name) {
24189    if (name in object) return name;
24190    name = name.charAt(0).toUpperCase() + name.slice(1);
24191    for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) {
24192      var prefixName = d3_vendorPrefixes[i] + name;
24193      if (prefixName in object) return prefixName;
24194    }
24195  }
24196  var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ];
24197  function d3_noop() {}
24198  d3.dispatch = function() {
24199    var dispatch = new d3_dispatch(), i = -1, n = arguments.length;
24200    while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
24201    return dispatch;
24202  };
24203  function d3_dispatch() {}
24204  d3_dispatch.prototype.on = function(type, listener) {
24205    var i = type.indexOf("."), name = "";
24206    if (i >= 0) {
24207      name = type.slice(i + 1);
24208      type = type.slice(0, i);
24209    }
24210    if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener);
24211    if (arguments.length === 2) {
24212      if (listener == null) for (type in this) {
24213        if (this.hasOwnProperty(type)) this[type].on(name, null);
24214      }
24215      return this;
24216    }
24217  };
24218  function d3_dispatch_event(dispatch) {
24219    var listeners = [], listenerByName = new d3_Map();
24220    function event() {
24221      var z = listeners, i = -1, n = z.length, l;
24222      while (++i < n) if (l = z[i].on) l.apply(this, arguments);
24223      return dispatch;
24224    }
24225    event.on = function(name, listener) {
24226      var l = listenerByName.get(name), i;
24227      if (arguments.length < 2) return l && l.on;
24228      if (l) {
24229        l.on = null;
24230        listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1));
24231        listenerByName.remove(name);
24232      }
24233      if (listener) listeners.push(listenerByName.set(name, {
24234        on: listener
24235      }));
24236      return dispatch;
24237    };
24238    return event;
24239  }
24240  d3.event = null;
24241  function d3_eventPreventDefault() {
24242    d3.event.preventDefault();
24243  }
24244  function d3_eventSource() {
24245    var e = d3.event, s;
24246    while (s = e.sourceEvent) e = s;
24247    return e;
24248  }
24249  function d3_eventDispatch(target) {
24250    var dispatch = new d3_dispatch(), i = 0, n = arguments.length;
24251    while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
24252    dispatch.of = function(thiz, argumentz) {
24253      return function(e1) {
24254        try {
24255          var e0 = e1.sourceEvent = d3.event;
24256          e1.target = target;
24257          d3.event = e1;
24258          dispatch[e1.type].apply(thiz, argumentz);
24259        } finally {
24260          d3.event = e0;
24261        }
24262      };
24263    };
24264    return dispatch;
24265  }
24266  d3.requote = function(s) {
24267    return s.replace(d3_requote_re, "\\$&");
24268  };
24269  var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
24270  var d3_subclass = {}.__proto__ ? function(object, prototype) {
24271    object.__proto__ = prototype;
24272  } : function(object, prototype) {
24273    for (var property in prototype) object[property] = prototype[property];
24274  };
24275  function d3_selection(groups) {
24276    d3_subclass(groups, d3_selectionPrototype);
24277    return groups;
24278  }
24279  var d3_select = function(s, n) {
24280    return n.querySelector(s);
24281  }, d3_selectAll = function(s, n) {
24282    return n.querySelectorAll(s);
24283  }, d3_selectMatches = function(n, s) {
24284    var d3_selectMatcher = n.matches || n[d3_vendorSymbol(n, "matchesSelector")];
24285    d3_selectMatches = function(n, s) {
24286      return d3_selectMatcher.call(n, s);
24287    };
24288    return d3_selectMatches(n, s);
24289  };
24290  if (typeof Sizzle === "function") {
24291    d3_select = function(s, n) {
24292      return Sizzle(s, n)[0] || null;
24293    };
24294    d3_selectAll = Sizzle;
24295    d3_selectMatches = Sizzle.matchesSelector;
24296  }
24297  d3.selection = function() {
24298    return d3.select(d3_document.documentElement);
24299  };
24300  var d3_selectionPrototype = d3.selection.prototype = [];
24301  d3_selectionPrototype.select = function(selector) {
24302    var subgroups = [], subgroup, subnode, group, node;
24303    selector = d3_selection_selector(selector);
24304    for (var j = -1, m = this.length; ++j < m; ) {
24305      subgroups.push(subgroup = []);
24306      subgroup.parentNode = (group = this[j]).parentNode;
24307      for (var i = -1, n = group.length; ++i < n; ) {
24308        if (node = group[i]) {
24309          subgroup.push(subnode = selector.call(node, node.__data__, i, j));
24310          if (subnode && "__data__" in node) subnode.__data__ = node.__data__;
24311        } else {
24312          subgroup.push(null);
24313        }
24314      }
24315    }
24316    return d3_selection(subgroups);
24317  };
24318  function d3_selection_selector(selector) {
24319    return typeof selector === "function" ? selector : function() {
24320      return d3_select(selector, this);
24321    };
24322  }
24323  d3_selectionPrototype.selectAll = function(selector) {
24324    var subgroups = [], subgroup, node;
24325    selector = d3_selection_selectorAll(selector);
24326    for (var j = -1, m = this.length; ++j < m; ) {
24327      for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
24328        if (node = group[i]) {
24329          subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j)));
24330          subgroup.parentNode = node;
24331        }
24332      }
24333    }
24334    return d3_selection(subgroups);
24335  };
24336  function d3_selection_selectorAll(selector) {
24337    return typeof selector === "function" ? selector : function() {
24338      return d3_selectAll(selector, this);
24339    };
24340  }
24341  var d3_nsPrefix = {
24342    svg: "http://www.w3.org/2000/svg",
24343    xhtml: "http://www.w3.org/1999/xhtml",
24344    xlink: "http://www.w3.org/1999/xlink",
24345    xml: "http://www.w3.org/XML/1998/namespace",
24346    xmlns: "http://www.w3.org/2000/xmlns/"
24347  };
24348  d3.ns = {
24349    prefix: d3_nsPrefix,
24350    qualify: function(name) {
24351      var i = name.indexOf(":"), prefix = name;
24352      if (i >= 0) {
24353        prefix = name.slice(0, i);
24354        name = name.slice(i + 1);
24355      }
24356      return d3_nsPrefix.hasOwnProperty(prefix) ? {
24357        space: d3_nsPrefix[prefix],
24358        local: name
24359      } : name;
24360    }
24361  };
24362  d3_selectionPrototype.attr = function(name, value) {
24363    if (arguments.length < 2) {
24364      if (typeof name === "string") {
24365        var node = this.node();
24366        name = d3.ns.qualify(name);
24367        return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name);
24368      }
24369      for (value in name) this.each(d3_selection_attr(value, name[value]));
24370      return this;
24371    }
24372    return this.each(d3_selection_attr(name, value));
24373  };
24374  function d3_selection_attr(name, value) {
24375    name = d3.ns.qualify(name);
24376    function attrNull() {
24377      this.removeAttribute(name);
24378    }
24379    function attrNullNS() {
24380      this.removeAttributeNS(name.space, name.local);
24381    }
24382    function attrConstant() {
24383      this.setAttribute(name, value);
24384    }
24385    function attrConstantNS() {
24386      this.setAttributeNS(name.space, name.local, value);
24387    }
24388    function attrFunction() {
24389      var x = value.apply(this, arguments);
24390      if (x == null) this.removeAttribute(name); else this.setAttribute(name, x);
24391    }
24392    function attrFunctionNS() {
24393      var x = value.apply(this, arguments);
24394      if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x);
24395    }
24396    return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant;
24397  }
24398  function d3_collapse(s) {
24399    return s.trim().replace(/\s+/g, " ");
24400  }
24401  d3_selectionPrototype.classed = function(name, value) {
24402    if (arguments.length < 2) {
24403      if (typeof name === "string") {
24404        var node = this.node(), n = (name = d3_selection_classes(name)).length, i = -1;
24405        if (value = node.classList) {
24406          while (++i < n) if (!value.contains(name[i])) return false;
24407        } else {
24408          value = node.getAttribute("class");
24409          while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false;
24410        }
24411        return true;
24412      }
24413      for (value in name) this.each(d3_selection_classed(value, name[value]));
24414      return this;
24415    }
24416    return this.each(d3_selection_classed(name, value));
24417  };
24418  function d3_selection_classedRe(name) {
24419    return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g");
24420  }
24421  function d3_selection_classes(name) {
24422    return (name + "").trim().split(/^|\s+/);
24423  }
24424  function d3_selection_classed(name, value) {
24425    name = d3_selection_classes(name).map(d3_selection_classedName);
24426    var n = name.length;
24427    function classedConstant() {
24428      var i = -1;
24429      while (++i < n) name[i](this, value);
24430    }
24431    function classedFunction() {
24432      var i = -1, x = value.apply(this, arguments);
24433      while (++i < n) name[i](this, x);
24434    }
24435    return typeof value === "function" ? classedFunction : classedConstant;
24436  }
24437  function d3_selection_classedName(name) {
24438    var re = d3_selection_classedRe(name);
24439    return function(node, value) {
24440      if (c = node.classList) return value ? c.add(name) : c.remove(name);
24441      var c = node.getAttribute("class") || "";
24442      if (value) {
24443        re.lastIndex = 0;
24444        if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name));
24445      } else {
24446        node.setAttribute("class", d3_collapse(c.replace(re, " ")));
24447      }
24448    };
24449  }
24450  d3_selectionPrototype.style = function(name, value, priority) {
24451    var n = arguments.length;
24452    if (n < 3) {
24453      if (typeof name !== "string") {
24454        if (n < 2) value = "";
24455        for (priority in name) this.each(d3_selection_style(priority, name[priority], value));
24456        return this;
24457      }
24458      if (n < 2) {
24459        var node = this.node();
24460        return d3_window(node).getComputedStyle(node, null).getPropertyValue(name);
24461      }
24462      priority = "";
24463    }
24464    return this.each(d3_selection_style(name, value, priority));
24465  };
24466  function d3_selection_style(name, value, priority) {
24467    function styleNull() {
24468      this.style.removeProperty(name);
24469    }
24470    function styleConstant() {
24471      this.style.setProperty(name, value, priority);
24472    }
24473    function styleFunction() {
24474      var x = value.apply(this, arguments);
24475      if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority);
24476    }
24477    return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant;
24478  }
24479  d3_selectionPrototype.property = function(name, value) {
24480    if (arguments.length < 2) {
24481      if (typeof name === "string") return this.node()[name];
24482      for (value in name) this.each(d3_selection_property(value, name[value]));
24483      return this;
24484    }
24485    return this.each(d3_selection_property(name, value));
24486  };
24487  function d3_selection_property(name, value) {
24488    function propertyNull() {
24489      delete this[name];
24490    }
24491    function propertyConstant() {
24492      this[name] = value;
24493    }
24494    function propertyFunction() {
24495      var x = value.apply(this, arguments);
24496      if (x == null) delete this[name]; else this[name] = x;
24497    }
24498    return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant;
24499  }
24500  d3_selectionPrototype.text = function(value) {
24501    return arguments.length ? this.each(typeof value === "function" ? function() {
24502      var v = value.apply(this, arguments);
24503      this.textContent = v == null ? "" : v;
24504    } : value == null ? function() {
24505      this.textContent = "";
24506    } : function() {
24507      this.textContent = value;
24508    }) : this.node().textContent;
24509  };
24510  d3_selectionPrototype.html = function(value) {
24511    return arguments.length ? this.each(typeof value === "function" ? function() {
24512      var v = value.apply(this, arguments);
24513      this.innerHTML = v == null ? "" : v;
24514    } : value == null ? function() {
24515      this.innerHTML = "";
24516    } : function() {
24517      this.innerHTML = value;
24518    }) : this.node().innerHTML;
24519  };
24520  d3_selectionPrototype.append = function(name) {
24521    name = d3_selection_creator(name);
24522    return this.select(function() {
24523      return this.appendChild(name.apply(this, arguments));
24524    });
24525  };
24526  function d3_selection_creator(name) {
24527    function create() {
24528      var document = this.ownerDocument, namespace = this.namespaceURI;
24529      return namespace ? document.createElementNS(namespace, name) : document.createElement(name);
24530    }
24531    function createNS() {
24532      return this.ownerDocument.createElementNS(name.space, name.local);
24533    }
24534    return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? createNS : create;
24535  }
24536  d3_selectionPrototype.insert = function(name, before) {
24537    name = d3_selection_creator(name);
24538    before = d3_selection_selector(before);
24539    return this.select(function() {
24540      return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null);
24541    });
24542  };
24543  d3_selectionPrototype.remove = function() {
24544    return this.each(d3_selectionRemove);
24545  };
24546  function d3_selectionRemove() {
24547    var parent = this.parentNode;
24548    if (parent) parent.removeChild(this);
24549  }
24550  d3_selectionPrototype.data = function(value, key) {
24551    var i = -1, n = this.length, group, node;
24552    if (!arguments.length) {
24553      value = new Array(n = (group = this[0]).length);
24554      while (++i < n) {
24555        if (node = group[i]) {
24556          value[i] = node.__data__;
24557        }
24558      }
24559      return value;
24560    }
24561    function bind(group, groupData) {
24562      var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData;
24563      if (key) {
24564        var nodeByKeyValue = new d3_Map(), keyValues = new Array(n), keyValue;
24565        for (i = -1; ++i < n; ) {
24566          if (nodeByKeyValue.has(keyValue = key.call(node = group[i], node.__data__, i))) {
24567            exitNodes[i] = node;
24568          } else {
24569            nodeByKeyValue.set(keyValue, node);
24570          }
24571          keyValues[i] = keyValue;
24572        }
24573        for (i = -1; ++i < m; ) {
24574          if (!(node = nodeByKeyValue.get(keyValue = key.call(groupData, nodeData = groupData[i], i)))) {
24575            enterNodes[i] = d3_selection_dataNode(nodeData);
24576          } else if (node !== true) {
24577            updateNodes[i] = node;
24578            node.__data__ = nodeData;
24579          }
24580          nodeByKeyValue.set(keyValue, true);
24581        }
24582        for (i = -1; ++i < n; ) {
24583          if (nodeByKeyValue.get(keyValues[i]) !== true) {
24584            exitNodes[i] = group[i];
24585          }
24586        }
24587      } else {
24588        for (i = -1; ++i < n0; ) {
24589          node = group[i];
24590          nodeData = groupData[i];
24591          if (node) {
24592            node.__data__ = nodeData;
24593            updateNodes[i] = node;
24594          } else {
24595            enterNodes[i] = d3_selection_dataNode(nodeData);
24596          }
24597        }
24598        for (;i < m; ++i) {
24599          enterNodes[i] = d3_selection_dataNode(groupData[i]);
24600        }
24601        for (;i < n; ++i) {
24602          exitNodes[i] = group[i];
24603        }
24604      }
24605      enterNodes.update = updateNodes;
24606      enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode;
24607      enter.push(enterNodes);
24608      update.push(updateNodes);
24609      exit.push(exitNodes);
24610    }
24611    var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]);
24612    if (typeof value === "function") {
24613      while (++i < n) {
24614        bind(group = this[i], value.call(group, group.parentNode.__data__, i));
24615      }
24616    } else {
24617      while (++i < n) {
24618        bind(group = this[i], value);
24619      }
24620    }
24621    update.enter = function() {
24622      return enter;
24623    };
24624    update.exit = function() {
24625      return exit;
24626    };
24627    return update;
24628  };
24629  function d3_selection_dataNode(data) {
24630    return {
24631      __data__: data
24632    };
24633  }
24634  d3_selectionPrototype.datum = function(value) {
24635    return arguments.length ? this.property("__data__", value) : this.property("__data__");
24636  };
24637  d3_selectionPrototype.filter = function(filter) {
24638    var subgroups = [], subgroup, group, node;
24639    if (typeof filter !== "function") filter = d3_selection_filter(filter);
24640    for (var j = 0, m = this.length; j < m; j++) {
24641      subgroups.push(subgroup = []);
24642      subgroup.parentNode = (group = this[j]).parentNode;
24643      for (var i = 0, n = group.length; i < n; i++) {
24644        if ((node = group[i]) && filter.call(node, node.__data__, i, j)) {
24645          subgroup.push(node);
24646        }
24647      }
24648    }
24649    return d3_selection(subgroups);
24650  };
24651  function d3_selection_filter(selector) {
24652    return function() {
24653      return d3_selectMatches(this, selector);
24654    };
24655  }
24656  d3_selectionPrototype.order = function() {
24657    for (var j = -1, m = this.length; ++j < m; ) {
24658      for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) {
24659        if (node = group[i]) {
24660          if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);
24661          next = node;
24662        }
24663      }
24664    }
24665    return this;
24666  };
24667  d3_selectionPrototype.sort = function(comparator) {
24668    comparator = d3_selection_sortComparator.apply(this, arguments);
24669    for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator);
24670    return this.order();
24671  };
24672  function d3_selection_sortComparator(comparator) {
24673    if (!arguments.length) comparator = d3_ascending;
24674    return function(a, b) {
24675      return a && b ? comparator(a.__data__, b.__data__) : !a - !b;
24676    };
24677  }
24678  d3_selectionPrototype.each = function(callback) {
24679    return d3_selection_each(this, function(node, i, j) {
24680      callback.call(node, node.__data__, i, j);
24681    });
24682  };
24683  function d3_selection_each(groups, callback) {
24684    for (var j = 0, m = groups.length; j < m; j++) {
24685      for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) {
24686        if (node = group[i]) callback(node, i, j);
24687      }
24688    }
24689    return groups;
24690  }
24691  d3_selectionPrototype.call = function(callback) {
24692    var args = d3_array(arguments);
24693    callback.apply(args[0] = this, args);
24694    return this;
24695  };
24696  d3_selectionPrototype.empty = function() {
24697    return !this.node();
24698  };
24699  d3_selectionPrototype.node = function() {
24700    for (var j = 0, m = this.length; j < m; j++) {
24701      for (var group = this[j], i = 0, n = group.length; i < n; i++) {
24702        var node = group[i];
24703        if (node) return node;
24704      }
24705    }
24706    return null;
24707  };
24708  d3_selectionPrototype.size = function() {
24709    var n = 0;
24710    d3_selection_each(this, function() {
24711      ++n;
24712    });
24713    return n;
24714  };
24715  function d3_selection_enter(selection) {
24716    d3_subclass(selection, d3_selection_enterPrototype);
24717    return selection;
24718  }
24719  var d3_selection_enterPrototype = [];
24720  d3.selection.enter = d3_selection_enter;
24721  d3.selection.enter.prototype = d3_selection_enterPrototype;
24722  d3_selection_enterPrototype.append = d3_selectionPrototype.append;
24723  d3_selection_enterPrototype.empty = d3_selectionPrototype.empty;
24724  d3_selection_enterPrototype.node = d3_selectionPrototype.node;
24725  d3_selection_enterPrototype.call = d3_selectionPrototype.call;
24726  d3_selection_enterPrototype.size = d3_selectionPrototype.size;
24727  d3_selection_enterPrototype.select = function(selector) {
24728    var subgroups = [], subgroup, subnode, upgroup, group, node;
24729    for (var j = -1, m = this.length; ++j < m; ) {
24730      upgroup = (group = this[j]).update;
24731      subgroups.push(subgroup = []);
24732      subgroup.parentNode = group.parentNode;
24733      for (var i = -1, n = group.length; ++i < n; ) {
24734        if (node = group[i]) {
24735          subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j));
24736          subnode.__data__ = node.__data__;
24737        } else {
24738          subgroup.push(null);
24739        }
24740      }
24741    }
24742    return d3_selection(subgroups);
24743  };
24744  d3_selection_enterPrototype.insert = function(name, before) {
24745    if (arguments.length < 2) before = d3_selection_enterInsertBefore(this);
24746    return d3_selectionPrototype.insert.call(this, name, before);
24747  };
24748  function d3_selection_enterInsertBefore(enter) {
24749    var i0, j0;
24750    return function(d, i, j) {
24751      var group = enter[j].update, n = group.length, node;
24752      if (j != j0) j0 = j, i0 = 0;
24753      if (i >= i0) i0 = i + 1;
24754      while (!(node = group[i0]) && ++i0 < n) ;
24755      return node;
24756    };
24757  }
24758  d3.select = function(node) {
24759    var group;
24760    if (typeof node === "string") {
24761      group = [ d3_select(node, d3_document) ];
24762      group.parentNode = d3_document.documentElement;
24763    } else {
24764      group = [ node ];
24765      group.parentNode = d3_documentElement(node);
24766    }
24767    return d3_selection([ group ]);
24768  };
24769  d3.selectAll = function(nodes) {
24770    var group;
24771    if (typeof nodes === "string") {
24772      group = d3_array(d3_selectAll(nodes, d3_document));
24773      group.parentNode = d3_document.documentElement;
24774    } else {
24775      group = nodes;
24776      group.parentNode = null;
24777    }
24778    return d3_selection([ group ]);
24779  };
24780  d3_selectionPrototype.on = function(type, listener, capture) {
24781    var n = arguments.length;
24782    if (n < 3) {
24783      if (typeof type !== "string") {
24784        if (n < 2) listener = false;
24785        for (capture in type) this.each(d3_selection_on(capture, type[capture], listener));
24786        return this;
24787      }
24788      if (n < 2) return (n = this.node()["__on" + type]) && n._;
24789      capture = false;
24790    }
24791    return this.each(d3_selection_on(type, listener, capture));
24792  };
24793  function d3_selection_on(type, listener, capture) {
24794    var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener;
24795    if (i > 0) type = type.slice(0, i);
24796    var filter = d3_selection_onFilters.get(type);
24797    if (filter) type = filter, wrap = d3_selection_onFilter;
24798    function onRemove() {
24799      var l = this[name];
24800      if (l) {
24801        this.removeEventListener(type, l, l.$);
24802        delete this[name];
24803      }
24804    }
24805    function onAdd() {
24806      var l = wrap(listener, d3_array(arguments));
24807      onRemove.call(this);
24808      this.addEventListener(type, this[name] = l, l.$ = capture);
24809      l._ = listener;
24810    }
24811    function removeAll() {
24812      var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match;
24813      for (var name in this) {
24814        if (match = name.match(re)) {
24815          var l = this[name];
24816          this.removeEventListener(match[1], l, l.$);
24817          delete this[name];
24818        }
24819      }
24820    }
24821    return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll;
24822  }
24823  var d3_selection_onFilters = d3.map({
24824    mouseenter: "mouseover",
24825    mouseleave: "mouseout"
24826  });
24827  if (d3_document) {
24828    d3_selection_onFilters.forEach(function(k) {
24829      if ("on" + k in d3_document) d3_selection_onFilters.remove(k);
24830    });
24831  }
24832  function d3_selection_onListener(listener, argumentz) {
24833    return function(e) {
24834      var o = d3.event;
24835      d3.event = e;
24836      argumentz[0] = this.__data__;
24837      try {
24838        listener.apply(this, argumentz);
24839      } finally {
24840        d3.event = o;
24841      }
24842    };
24843  }
24844  function d3_selection_onFilter(listener, argumentz) {
24845    var l = d3_selection_onListener(listener, argumentz);
24846    return function(e) {
24847      var target = this, related = e.relatedTarget;
24848      if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) {
24849        l.call(target, e);
24850      }
24851    };
24852  }
24853  var d3_event_dragSelect, d3_event_dragId = 0;
24854  function d3_event_dragSuppress(node) {
vendor: 13,157 bytes, lines 24855-25209
24855    var name = ".dragsuppress-" + ++d3_event_dragId, click = "click" + name, w = d3.select(d3_window(node)).on("touchmove" + name, d3_eventPreventDefault).on("dragstart" + name, d3_eventPreventDefault).on("selectstart" + name, d3_eventPreventDefault);
24856    if (d3_event_dragSelect == null) {
24857      d3_event_dragSelect = "onselectstart" in node ? false : d3_vendorSymbol(node.style, "userSelect");
24858    }
24859    if (d3_event_dragSelect) {
24860      var style = d3_documentElement(node).style, select = style[d3_event_dragSelect];
24861      style[d3_event_dragSelect] = "none";
24862    }
24863    return function(suppressClick) {
24864      w.on(name, null);
24865      if (d3_event_dragSelect) style[d3_event_dragSelect] = select;
24866      if (suppressClick) {
24867        var off = function() {
24868          w.on(click, null);
24869        };
24870        w.on(click, function() {
24871          d3_eventPreventDefault();
24872          off();
24873        }, true);
24874        setTimeout(off, 0);
24875      }
24876    };
24877  }
24878  d3.mouse = function(container) {
24879    return d3_mousePoint(container, d3_eventSource());
24880  };
24881  var d3_mouse_bug44083 = this.navigator && /WebKit/.test(this.navigator.userAgent) ? -1 : 0;
24882  function d3_mousePoint(container, e) {
24883    if (e.changedTouches) e = e.changedTouches[0];
24884    var svg = container.ownerSVGElement || container;
24885    if (svg.createSVGPoint) {
24886      var point = svg.createSVGPoint();
24887      if (d3_mouse_bug44083 < 0) {
24888        var window = d3_window(container);
24889        if (window.scrollX || window.scrollY) {
24890          svg = d3.select("body").append("svg").style({
24891            position: "absolute",
24892            top: 0,
24893            left: 0,
24894            margin: 0,
24895            padding: 0,
24896            border: "none"
24897          }, "important");
24898          var ctm = svg[0][0].getScreenCTM();
24899          d3_mouse_bug44083 = !(ctm.f || ctm.e);
24900          svg.remove();
24901        }
24902      }
24903      if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; else point.x = e.clientX, 
24904      point.y = e.clientY;
24905      point = point.matrixTransform(container.getScreenCTM().inverse());
24906      return [ point.x, point.y ];
24907    }
24908    var rect = container.getBoundingClientRect();
24909    return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ];
24910  }
24911  d3.touch = function(container, touches, identifier) {
24912    if (arguments.length < 3) identifier = touches, touches = d3_eventSource().changedTouches;
24913    if (touches) for (var i = 0, n = touches.length, touch; i < n; ++i) {
24914      if ((touch = touches[i]).identifier === identifier) {
24915        return d3_mousePoint(container, touch);
24916      }
24917    }
24918  };
24919  d3.behavior.drag = function() {
24920    var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, d3_window, "mousemove", "mouseup"), touchstart = dragstart(d3_behavior_dragTouchId, d3.touch, d3_identity, "touchmove", "touchend");
24921    function drag() {
24922      this.on("mousedown.drag", mousedown).on("touchstart.drag", touchstart);
24923    }
24924    function dragstart(id, position, subject, move, end) {
24925      return function() {
24926        var that = this, target = d3.event.target, parent = that.parentNode, dispatch = event.of(that, arguments), dragged = 0, dragId = id(), dragName = ".drag" + (dragId == null ? "" : "-" + dragId), dragOffset, dragSubject = d3.select(subject(target)).on(move + dragName, moved).on(end + dragName, ended), dragRestore = d3_event_dragSuppress(target), position0 = position(parent, dragId);
24927        if (origin) {
24928          dragOffset = origin.apply(that, arguments);
24929          dragOffset = [ dragOffset.x - position0[0], dragOffset.y - position0[1] ];
24930        } else {
24931          dragOffset = [ 0, 0 ];
24932        }
24933        dispatch({
24934          type: "dragstart"
24935        });
24936        function moved() {
24937          var position1 = position(parent, dragId), dx, dy;
24938          if (!position1) return;
24939          dx = position1[0] - position0[0];
24940          dy = position1[1] - position0[1];
24941          dragged |= dx | dy;
24942          position0 = position1;
24943          dispatch({
24944            type: "drag",
24945            x: position1[0] + dragOffset[0],
24946            y: position1[1] + dragOffset[1],
24947            dx: dx,
24948            dy: dy
24949          });
24950        }
24951        function ended() {
24952          if (!position(parent, dragId)) return;
24953          dragSubject.on(move + dragName, null).on(end + dragName, null);
24954          dragRestore(dragged && d3.event.target === target);
24955          dispatch({
24956            type: "dragend"
24957          });
24958        }
24959      };
24960    }
24961    drag.origin = function(x) {
24962      if (!arguments.length) return origin;
24963      origin = x;
24964      return drag;
24965    };
24966    return d3.rebind(drag, event, "on");
24967  };
24968  function d3_behavior_dragTouchId() {
24969    return d3.event.changedTouches[0].identifier;
24970  }
24971  d3.touches = function(container, touches) {
24972    if (arguments.length < 2) touches = d3_eventSource().touches;
24973    return touches ? d3_array(touches).map(function(touch) {
24974      var point = d3_mousePoint(container, touch);
24975      point.identifier = touch.identifier;
24976      return point;
24977    }) : [];
24978  };
24979  var ε = 1e-6, ε2 = ε * ε, π = Math.PI, τ = 2 * π, τε = τ - ε, halfπ = π / 2, d3_radians = π / 180, d3_degrees = 180 / π;
24980  function d3_sgn(x) {
24981    return x > 0 ? 1 : x < 0 ? -1 : 0;
24982  }
24983  function d3_cross2d(a, b, c) {
24984    return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
24985  }
24986  function d3_acos(x) {
24987    return x > 1 ? 0 : x < -1 ? π : Math.acos(x);
24988  }
24989  function d3_asin(x) {
24990    return x > 1 ? halfπ : x < -1 ? -halfπ : Math.asin(x);
24991  }
24992  function d3_sinh(x) {
24993    return ((x = Math.exp(x)) - 1 / x) / 2;
24994  }
24995  function d3_cosh(x) {
24996    return ((x = Math.exp(x)) + 1 / x) / 2;
24997  }
24998  function d3_tanh(x) {
24999    return ((x = Math.exp(2 * x)) - 1) / (x + 1);
25000  }
25001  function d3_haversin(x) {
25002    return (x = Math.sin(x / 2)) * x;
25003  }
25004  var ρ = Math.SQRT2, ρ2 = 2, ρ4 = 4;
25005  d3.interpolateZoom = function(p0, p1) {
25006    var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2];
25007    var dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1), dr = r1 - r0, S = (dr || Math.log(w1 / w0)) / ρ;
25008    function interpolate(t) {
25009      var s = t * S;
25010      if (dr) {
25011        var coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0));
25012        return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(ρ * s + r0) ];
25013      }
25014      return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * s) ];
25015    }
25016    interpolate.duration = S * 1e3;
25017    return interpolate;
25018  };
25019  d3.behavior.zoom = function() {
25020    var view = {
25021      x: 0,
25022      y: 0,
25023      k: 1
25024    }, translate0, center0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, duration = 250, zooming = 0, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1;
25025    if (!d3_behavior_zoomWheel) {
25026      d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() {
25027        return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1);
25028      }, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() {
25029        return d3.event.wheelDelta;
25030      }, "mousewheel") : (d3_behavior_zoomDelta = function() {
25031        return -d3.event.detail;
25032      }, "MozMousePixelScroll");
25033    }
25034    function zoom(g) {
25035      g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted);
25036    }
25037    zoom.event = function(g) {
25038      g.each(function() {
25039        var dispatch = event.of(this, arguments), view1 = view;
25040        if (d3_transitionInheritId) {
25041          d3.select(this).transition().each("start.zoom", function() {
25042            view = this.__chart__ || {
25043              x: 0,
25044              y: 0,
25045              k: 1
25046            };
25047            zoomstarted(dispatch);
25048          }).tween("zoom:zoom", function() {
25049            var dx = size[0], dy = size[1], cx = center0 ? center0[0] : dx / 2, cy = center0 ? center0[1] : dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]);
25050            return function(t) {
25051              var l = i(t), k = dx / l[2];
25052              this.__chart__ = view = {
25053                x: cx - l[0] * k,
25054                y: cy - l[1] * k,
25055                k: k
25056              };
25057              zoomed(dispatch);
25058            };
25059          }).each("interrupt.zoom", function() {
25060            zoomended(dispatch);
25061          }).each("end.zoom", function() {
25062            zoomended(dispatch);
25063          });
25064        } else {
25065          this.__chart__ = view;
25066          zoomstarted(dispatch);
25067          zoomed(dispatch);
25068          zoomended(dispatch);
25069        }
25070      });
25071    };
25072    zoom.translate = function(_) {
25073      if (!arguments.length) return [ view.x, view.y ];
25074      view = {
25075        x: +_[0],
25076        y: +_[1],
25077        k: view.k
25078      };
25079      rescale();
25080      return zoom;
25081    };
25082    zoom.scale = function(_) {
25083      if (!arguments.length) return view.k;
25084      view = {
25085        x: view.x,
25086        y: view.y,
25087        k: +_
25088      };
25089      rescale();
25090      return zoom;
25091    };
25092    zoom.scaleExtent = function(_) {
25093      if (!arguments.length) return scaleExtent;
25094      scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ];
25095      return zoom;
25096    };
25097    zoom.center = function(_) {
25098      if (!arguments.length) return center;
25099      center = _ && [ +_[0], +_[1] ];
25100      return zoom;
25101    };
25102    zoom.size = function(_) {
25103      if (!arguments.length) return size;
25104      size = _ && [ +_[0], +_[1] ];
25105      return zoom;
25106    };
25107    zoom.duration = function(_) {
25108      if (!arguments.length) return duration;
25109      duration = +_;
25110      return zoom;
25111    };
25112    zoom.x = function(z) {
25113      if (!arguments.length) return x1;
25114      x1 = z;
25115      x0 = z.copy();
25116      view = {
25117        x: 0,
25118        y: 0,
25119        k: 1
25120      };
25121      return zoom;
25122    };
25123    zoom.y = function(z) {
25124      if (!arguments.length) return y1;
25125      y1 = z;
25126      y0 = z.copy();
25127      view = {
25128        x: 0,
25129        y: 0,
25130        k: 1
25131      };
25132      return zoom;
25133    };
25134    function location(p) {
25135      return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ];
25136    }
25137    function point(l) {
25138      return [ l[0] * view.k + view.x, l[1] * view.k + view.y ];
25139    }
25140    function scaleTo(s) {
25141      view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s));
25142    }
25143    function translateTo(p, l) {
25144      l = point(l);
25145      view.x += p[0] - l[0];
25146      view.y += p[1] - l[1];
25147    }
25148    function zoomTo(that, p, l, k) {
25149      that.__chart__ = {
25150        x: view.x,
25151        y: view.y,
25152        k: view.k
25153      };
25154      scaleTo(Math.pow(2, k));
25155      translateTo(center0 = p, l);
25156      that = d3.select(that);
25157      if (duration > 0) that = that.transition().duration(duration);
25158      that.call(zoom.event);
25159    }
25160    function rescale() {
25161      if (x1) x1.domain(x0.range().map(function(x) {
25162        return (x - view.x) / view.k;
25163      }).map(x0.invert));
25164      if (y1) y1.domain(y0.range().map(function(y) {
25165        return (y - view.y) / view.k;
25166      }).map(y0.invert));
25167    }
25168    function zoomstarted(dispatch) {
25169      if (!zooming++) dispatch({
25170        type: "zoomstart"
25171      });
25172    }
25173    function zoomed(dispatch) {
25174      rescale();
25175      dispatch({
25176        type: "zoom",
25177        scale: view.k,
25178        translate: [ view.x, view.y ]
25179      });
25180    }
25181    function zoomended(dispatch) {
25182      if (!--zooming) dispatch({
25183        type: "zoomend"
25184      });
25185      center0 = null;
25186    }
25187    function mousedowned() {
25188      var that = this, target = d3.event.target, dispatch = event.of(that, arguments), dragged = 0, subject = d3.select(d3_window(that)).on(mousemove, moved).on(mouseup, ended), location0 = location(d3.mouse(that)), dragRestore = d3_event_dragSuppress(that);
25189      d3_selection_interrupt.call(that);
25190      zoomstarted(dispatch);
25191      function moved() {
25192        dragged = 1;
25193        translateTo(d3.mouse(that), location0);
25194        zoomed(dispatch);
25195      }
25196      function ended() {
25197        subject.on(mousemove, null).on(mouseup, null);
25198        dragRestore(dragged && d3.event.target === target);
25199        zoomended(dispatch);
25200      }
25201    }
25202    function touchstarted() {
25203      var that = this, dispatch = event.of(that, arguments), locations0 = {}, distance0 = 0, scale0, zoomName = ".zoom-" + d3.event.changedTouches[0].identifier, touchmove = "touchmove" + zoomName, touchend = "touchend" + zoomName, targets = [], subject = d3.select(that), dragRestore = d3_event_dragSuppress(that);
25204      started();
25205      zoomstarted(dispatch);
25206      subject.on(mousedown, null).on(touchstart, started);
25207      function relocate() {
25208        var touches = d3.touches(that);
25209        scale0 = view.k;
vendor: 16,068 bytes, lines 25210-25670
25210        touches.forEach(function(t) {
25211          if (t.identifier in locations0) locations0[t.identifier] = location(t);
25212        });
25213        return touches;
25214      }
25215      function started() {
25216        var target = d3.event.target;
25217        d3.select(target).on(touchmove, moved).on(touchend, ended);
25218        targets.push(target);
25219        var changed = d3.event.changedTouches;
25220        for (var i = 0, n = changed.length; i < n; ++i) {
25221          locations0[changed[i].identifier] = null;
25222        }
25223        var touches = relocate(), now = Date.now();
25224        if (touches.length === 1) {
25225          if (now - touchtime < 500) {
25226            var p = touches[0];
25227            zoomTo(that, p, locations0[p.identifier], Math.floor(Math.log(view.k) / Math.LN2) + 1);
25228            d3_eventPreventDefault();
25229          }
25230          touchtime = now;
25231        } else if (touches.length > 1) {
25232          var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1];
25233          distance0 = dx * dx + dy * dy;
25234        }
25235      }
25236      function moved() {
25237        var touches = d3.touches(that), p0, l0, p1, l1;
25238        d3_selection_interrupt.call(that);
25239        for (var i = 0, n = touches.length; i < n; ++i, l1 = null) {
25240          p1 = touches[i];
25241          if (l1 = locations0[p1.identifier]) {
25242            if (l0) break;
25243            p0 = p1, l0 = l1;
25244          }
25245        }
25246        if (l1) {
25247          var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0);
25248          p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ];
25249          l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ];
25250          scaleTo(scale1 * scale0);
25251        }
25252        touchtime = null;
25253        translateTo(p0, l0);
25254        zoomed(dispatch);
25255      }
25256      function ended() {
25257        if (d3.event.touches.length) {
25258          var changed = d3.event.changedTouches;
25259          for (var i = 0, n = changed.length; i < n; ++i) {
25260            delete locations0[changed[i].identifier];
25261          }
25262          for (var identifier in locations0) {
25263            return void relocate();
25264          }
25265        }
25266        d3.selectAll(targets).on(zoomName, null);
25267        subject.on(mousedown, mousedowned).on(touchstart, touchstarted);
25268        dragRestore();
25269        zoomended(dispatch);
25270      }
25271    }
25272    function mousewheeled() {
25273      var dispatch = event.of(this, arguments);
25274      if (mousewheelTimer) clearTimeout(mousewheelTimer); else translate0 = location(center0 = center || d3.mouse(this)), 
25275      d3_selection_interrupt.call(this), zoomstarted(dispatch);
25276      mousewheelTimer = setTimeout(function() {
25277        mousewheelTimer = null;
25278        zoomended(dispatch);
25279      }, 50);
25280      d3_eventPreventDefault();
25281      scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k);
25282      translateTo(center0, translate0);
25283      zoomed(dispatch);
25284    }
25285    function dblclicked() {
25286      var p = d3.mouse(this), k = Math.log(view.k) / Math.LN2;
25287      zoomTo(this, p, location(p), d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1);
25288    }
25289    return d3.rebind(zoom, event, "on");
25290  };
25291  var d3_behavior_zoomInfinity = [ 0, Infinity ], d3_behavior_zoomDelta, d3_behavior_zoomWheel;
25292  d3.color = d3_color;
25293  function d3_color() {}
25294  d3_color.prototype.toString = function() {
25295    return this.rgb() + "";
25296  };
25297  d3.hsl = d3_hsl;
25298  function d3_hsl(h, s, l) {
25299    return this instanceof d3_hsl ? void (this.h = +h, this.s = +s, this.l = +l) : arguments.length < 2 ? h instanceof d3_hsl ? new d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : new d3_hsl(h, s, l);
25300  }
25301  var d3_hslPrototype = d3_hsl.prototype = new d3_color();
25302  d3_hslPrototype.brighter = function(k) {
25303    k = Math.pow(.7, arguments.length ? k : 1);
25304    return new d3_hsl(this.h, this.s, this.l / k);
25305  };
25306  d3_hslPrototype.darker = function(k) {
25307    k = Math.pow(.7, arguments.length ? k : 1);
25308    return new d3_hsl(this.h, this.s, k * this.l);
25309  };
25310  d3_hslPrototype.rgb = function() {
25311    return d3_hsl_rgb(this.h, this.s, this.l);
25312  };
25313  function d3_hsl_rgb(h, s, l) {
25314    var m1, m2;
25315    h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h;
25316    s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s;
25317    l = l < 0 ? 0 : l > 1 ? 1 : l;
25318    m2 = l <= .5 ? l * (1 + s) : l + s - l * s;
25319    m1 = 2 * l - m2;
25320    function v(h) {
25321      if (h > 360) h -= 360; else if (h < 0) h += 360;
25322      if (h < 60) return m1 + (m2 - m1) * h / 60;
25323      if (h < 180) return m2;
25324      if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;
25325      return m1;
25326    }
25327    function vv(h) {
25328      return Math.round(v(h) * 255);
25329    }
25330    return new d3_rgb(vv(h + 120), vv(h), vv(h - 120));
25331  }
25332  d3.hcl = d3_hcl;
25333  function d3_hcl(h, c, l) {
25334    return this instanceof d3_hcl ? void (this.h = +h, this.c = +c, this.l = +l) : arguments.length < 2 ? h instanceof d3_hcl ? new d3_hcl(h.h, h.c, h.l) : h instanceof d3_lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : new d3_hcl(h, c, l);
25335  }
25336  var d3_hclPrototype = d3_hcl.prototype = new d3_color();
25337  d3_hclPrototype.brighter = function(k) {
25338    return new d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)));
25339  };
25340  d3_hclPrototype.darker = function(k) {
25341    return new d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)));
25342  };
25343  d3_hclPrototype.rgb = function() {
25344    return d3_hcl_lab(this.h, this.c, this.l).rgb();
25345  };
25346  function d3_hcl_lab(h, c, l) {
25347    if (isNaN(h)) h = 0;
25348    if (isNaN(c)) c = 0;
25349    return new d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c);
25350  }
25351  d3.lab = d3_lab;
25352  function d3_lab(l, a, b) {
25353    return this instanceof d3_lab ? void (this.l = +l, this.a = +a, this.b = +b) : arguments.length < 2 ? l instanceof d3_lab ? new d3_lab(l.l, l.a, l.b) : l instanceof d3_hcl ? d3_hcl_lab(l.h, l.c, l.l) : d3_rgb_lab((l = d3_rgb(l)).r, l.g, l.b) : new d3_lab(l, a, b);
25354  }
25355  var d3_lab_K = 18;
25356  var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883;
25357  var d3_labPrototype = d3_lab.prototype = new d3_color();
25358  d3_labPrototype.brighter = function(k) {
25359    return new d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b);
25360  };
25361  d3_labPrototype.darker = function(k) {
25362    return new d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b);
25363  };
25364  d3_labPrototype.rgb = function() {
25365    return d3_lab_rgb(this.l, this.a, this.b);
25366  };
25367  function d3_lab_rgb(l, a, b) {
25368    var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200;
25369    x = d3_lab_xyz(x) * d3_lab_X;
25370    y = d3_lab_xyz(y) * d3_lab_Y;
25371    z = d3_lab_xyz(z) * d3_lab_Z;
25372    return new d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z));
25373  }
25374  function d3_lab_hcl(l, a, b) {
25375    return l > 0 ? new d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : new d3_hcl(NaN, NaN, l);
25376  }
25377  function d3_lab_xyz(x) {
25378    return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037;
25379  }
25380  function d3_xyz_lab(x) {
25381    return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29;
25382  }
25383  function d3_xyz_rgb(r) {
25384    return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055));
25385  }
25386  d3.rgb = d3_rgb;
25387  function d3_rgb(r, g, b) {
25388    return this instanceof d3_rgb ? void (this.r = ~~r, this.g = ~~g, this.b = ~~b) : arguments.length < 2 ? r instanceof d3_rgb ? new d3_rgb(r.r, r.g, r.b) : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb) : new d3_rgb(r, g, b);
25389  }
25390  function d3_rgbNumber(value) {
25391    return new d3_rgb(value >> 16, value >> 8 & 255, value & 255);
25392  }
25393  function d3_rgbString(value) {
25394    return d3_rgbNumber(value) + "";
25395  }
25396  var d3_rgbPrototype = d3_rgb.prototype = new d3_color();
25397  d3_rgbPrototype.brighter = function(k) {
25398    k = Math.pow(.7, arguments.length ? k : 1);
25399    var r = this.r, g = this.g, b = this.b, i = 30;
25400    if (!r && !g && !b) return new d3_rgb(i, i, i);
25401    if (r && r < i) r = i;
25402    if (g && g < i) g = i;
25403    if (b && b < i) b = i;
25404    return new d3_rgb(Math.min(255, r / k), Math.min(255, g / k), Math.min(255, b / k));
25405  };
25406  d3_rgbPrototype.darker = function(k) {
25407    k = Math.pow(.7, arguments.length ? k : 1);
25408    return new d3_rgb(k * this.r, k * this.g, k * this.b);
25409  };
25410  d3_rgbPrototype.hsl = function() {
25411    return d3_rgb_hsl(this.r, this.g, this.b);
25412  };
25413  d3_rgbPrototype.toString = function() {
25414    return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b);
25415  };
25416  function d3_rgb_hex(v) {
25417    return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16);
25418  }
25419  function d3_rgb_parse(format, rgb, hsl) {
25420    var r = 0, g = 0, b = 0, m1, m2, color;
25421    m1 = /([a-z]+)\((.*)\)/i.exec(format);
25422    if (m1) {
25423      m2 = m1[2].split(",");
25424      switch (m1[1]) {
25425       case "hsl":
25426        {
25427          return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100);
25428        }
25429
25430       case "rgb":
25431        {
25432          return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2]));
25433        }
25434      }
25435    }
25436    if (color = d3_rgb_names.get(format.toLowerCase())) {
25437      return rgb(color.r, color.g, color.b);
25438    }
25439    if (format != null && format.charAt(0) === "#" && !isNaN(color = parseInt(format.slice(1), 16))) {
25440      if (format.length === 4) {
25441        r = (color & 3840) >> 4;
25442        r = r >> 4 | r;
25443        g = color & 240;
25444        g = g >> 4 | g;
25445        b = color & 15;
25446        b = b << 4 | b;
25447      } else if (format.length === 7) {
25448        r = (color & 16711680) >> 16;
25449        g = (color & 65280) >> 8;
25450        b = color & 255;
25451      }
25452    }
25453    return rgb(r, g, b);
25454  }
25455  function d3_rgb_hsl(r, g, b) {
25456    var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2;
25457    if (d) {
25458      s = l < .5 ? d / (max + min) : d / (2 - max - min);
25459      if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4;
25460      h *= 60;
25461    } else {
25462      h = NaN;
25463      s = l > 0 && l < 1 ? 0 : h;
25464    }
25465    return new d3_hsl(h, s, l);
25466  }
25467  function d3_rgb_lab(r, g, b) {
25468    r = d3_rgb_xyz(r);
25469    g = d3_rgb_xyz(g);
25470    b = d3_rgb_xyz(b);
25471    var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z);
25472    return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z));
25473  }
25474  function d3_rgb_xyz(r) {
25475    return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4);
25476  }
25477  function d3_rgb_parseNumber(c) {
25478    var f = parseFloat(c);
25479    return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f;
25480  }
25481  var d3_rgb_names = d3.map({
25482    aliceblue: 15792383,
25483    antiquewhite: 16444375,
25484    aqua: 65535,
25485    aquamarine: 8388564,
25486    azure: 15794175,
25487    beige: 16119260,
25488    bisque: 16770244,
25489    black: 0,
25490    blanchedalmond: 16772045,
25491    blue: 255,
25492    blueviolet: 9055202,
25493    brown: 10824234,
25494    burlywood: 14596231,
25495    cadetblue: 6266528,
25496    chartreuse: 8388352,
25497    chocolate: 13789470,
25498    coral: 16744272,
25499    cornflowerblue: 6591981,
25500    cornsilk: 16775388,
25501    crimson: 14423100,
25502    cyan: 65535,
25503    darkblue: 139,
25504    darkcyan: 35723,
25505    darkgoldenrod: 12092939,
25506    darkgray: 11119017,
25507    darkgreen: 25600,
25508    darkgrey: 11119017,
25509    darkkhaki: 12433259,
25510    darkmagenta: 9109643,
25511    darkolivegreen: 5597999,
25512    darkorange: 16747520,
25513    darkorchid: 10040012,
25514    darkred: 9109504,
25515    darksalmon: 15308410,
25516    darkseagreen: 9419919,
25517    darkslateblue: 4734347,
25518    darkslategray: 3100495,
25519    darkslategrey: 3100495,
25520    darkturquoise: 52945,
25521    darkviolet: 9699539,
25522    deeppink: 16716947,
25523    deepskyblue: 49151,
25524    dimgray: 6908265,
25525    dimgrey: 6908265,
25526    dodgerblue: 2003199,
25527    firebrick: 11674146,
25528    floralwhite: 16775920,
25529    forestgreen: 2263842,
25530    fuchsia: 16711935,
25531    gainsboro: 14474460,
25532    ghostwhite: 16316671,
25533    gold: 16766720,
25534    goldenrod: 14329120,
25535    gray: 8421504,
25536    green: 32768,
25537    greenyellow: 11403055,
25538    grey: 8421504,
25539    honeydew: 15794160,
25540    hotpink: 16738740,
25541    indianred: 13458524,
25542    indigo: 4915330,
25543    ivory: 16777200,
25544    khaki: 15787660,
25545    lavender: 15132410,
25546    lavenderblush: 16773365,
25547    lawngreen: 8190976,
25548    lemonchiffon: 16775885,
25549    lightblue: 11393254,
25550    lightcoral: 15761536,
25551    lightcyan: 14745599,
25552    lightgoldenrodyellow: 16448210,
25553    lightgray: 13882323,
25554    lightgreen: 9498256,
25555    lightgrey: 13882323,
25556    lightpink: 16758465,
25557    lightsalmon: 16752762,
25558    lightseagreen: 2142890,
25559    lightskyblue: 8900346,
25560    lightslategray: 7833753,
25561    lightslategrey: 7833753,
25562    lightsteelblue: 11584734,
25563    lightyellow: 16777184,
25564    lime: 65280,
25565    limegreen: 3329330,
25566    linen: 16445670,
25567    magenta: 16711935,
25568    maroon: 8388608,
25569    mediumaquamarine: 6737322,
25570    mediumblue: 205,
25571    mediumorchid: 12211667,
25572    mediumpurple: 9662683,
25573    mediumseagreen: 3978097,
25574    mediumslateblue: 8087790,
25575    mediumspringgreen: 64154,
25576    mediumturquoise: 4772300,
25577    mediumvioletred: 13047173,
25578    midnightblue: 1644912,
25579    mintcream: 16121850,
25580    mistyrose: 16770273,
25581    moccasin: 16770229,
25582    navajowhite: 16768685,
25583    navy: 128,
25584    oldlace: 16643558,
25585    olive: 8421376,
25586    olivedrab: 7048739,
25587    orange: 16753920,
25588    orangered: 16729344,
25589    orchid: 14315734,
25590    palegoldenrod: 15657130,
25591    palegreen: 10025880,
25592    paleturquoise: 11529966,
25593    palevioletred: 14381203,
25594    papayawhip: 16773077,
25595    peachpuff: 16767673,
25596    peru: 13468991,
25597    pink: 16761035,
25598    plum: 14524637,
25599    powderblue: 11591910,
25600    purple: 8388736,
25601    rebeccapurple: 6697881,
25602    red: 16711680,
25603    rosybrown: 12357519,
25604    royalblue: 4286945,
25605    saddlebrown: 9127187,
25606    salmon: 16416882,
25607    sandybrown: 16032864,
25608    seagreen: 3050327,
25609    seashell: 16774638,
25610    sienna: 10506797,
25611    silver: 12632256,
25612    skyblue: 8900331,
25613    slateblue: 6970061,
25614    slategray: 7372944,
25615    slategrey: 7372944,
25616    snow: 16775930,
25617    springgreen: 65407,
25618    steelblue: 4620980,
25619    tan: 13808780,
25620    teal: 32896,
25621    thistle: 14204888,
25622    tomato: 16737095,
25623    turquoise: 4251856,
25624    violet: 15631086,
25625    wheat: 16113331,
25626    white: 16777215,
25627    whitesmoke: 16119285,
25628    yellow: 16776960,
25629    yellowgreen: 10145074
25630  });
25631  d3_rgb_names.forEach(function(key, value) {
25632    d3_rgb_names.set(key, d3_rgbNumber(value));
25633  });
25634  function d3_functor(v) {
25635    return typeof v === "function" ? v : function() {
25636      return v;
25637    };
25638  }
25639  d3.functor = d3_functor;
25640  d3.xhr = d3_xhrType(d3_identity);
25641  function d3_xhrType(response) {
25642    return function(url, mimeType, callback) {
25643      if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, 
25644      mimeType = null;
25645      return d3_xhr(url, mimeType, response, callback);
25646    };
25647  }
25648  function d3_xhr(url, mimeType, response, callback) {
25649    var xhr = {}, dispatch = d3.dispatch("beforesend", "progress", "load", "error"), headers = {}, request = new XMLHttpRequest(), responseType = null;
25650    if (this.XDomainRequest && !("withCredentials" in request) && /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest();
25651    "onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() {
25652      request.readyState > 3 && respond();
25653    };
25654    function respond() {
25655      var status = request.status, result;
25656      if (!status && d3_xhrHasResponse(request) || status >= 200 && status < 300 || status === 304) {
25657        try {
25658          result = response.call(xhr, request);
25659        } catch (e) {
25660          dispatch.error.call(xhr, e);
25661          return;
25662        }
25663        dispatch.load.call(xhr, result);
25664      } else {
25665        dispatch.error.call(xhr, request);
25666      }
25667    }
25668    request.onprogress = function(event) {
25669      var o = d3.event;
25670      d3.event = event;
vendor: 6,492 bytes, lines 25671-25857
25671      try {
25672        dispatch.progress.call(xhr, request);
25673      } finally {
25674        d3.event = o;
25675      }
25676    };
25677    xhr.header = function(name, value) {
25678      name = (name + "").toLowerCase();
25679      if (arguments.length < 2) return headers[name];
25680      if (value == null) delete headers[name]; else headers[name] = value + "";
25681      return xhr;
25682    };
25683    xhr.mimeType = function(value) {
25684      if (!arguments.length) return mimeType;
25685      mimeType = value == null ? null : value + "";
25686      return xhr;
25687    };
25688    xhr.responseType = function(value) {
25689      if (!arguments.length) return responseType;
25690      responseType = value;
25691      return xhr;
25692    };
25693    xhr.response = function(value) {
25694      response = value;
25695      return xhr;
25696    };
25697    [ "get", "post" ].forEach(function(method) {
25698      xhr[method] = function() {
25699        return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments)));
25700      };
25701    });
25702    xhr.send = function(method, data, callback) {
25703      if (arguments.length === 2 && typeof data === "function") callback = data, data = null;
25704      request.open(method, url, true);
25705      if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*";
25706      if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]);
25707      if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType);
25708      if (responseType != null) request.responseType = responseType;
25709      if (callback != null) xhr.on("error", callback).on("load", function(request) {
25710        callback(null, request);
25711      });
25712      dispatch.beforesend.call(xhr, request);
25713      request.send(data == null ? null : data);
25714      return xhr;
25715    };
25716    xhr.abort = function() {
25717      request.abort();
25718      return xhr;
25719    };
25720    d3.rebind(xhr, dispatch, "on");
25721    return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback));
25722  }
25723  function d3_xhr_fixCallback(callback) {
25724    return callback.length === 1 ? function(error, request) {
25725      callback(error == null ? request : null);
25726    } : callback;
25727  }
25728  function d3_xhrHasResponse(request) {
25729    var type = request.responseType;
25730    return type && type !== "text" ? request.response : request.responseText;
25731  }
25732  d3.dsv = function(delimiter, mimeType) {
25733    var reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0);
25734    function dsv(url, row, callback) {
25735      if (arguments.length < 3) callback = row, row = null;
25736      var xhr = d3_xhr(url, mimeType, row == null ? response : typedResponse(row), callback);
25737      xhr.row = function(_) {
25738        return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row;
25739      };
25740      return xhr;
25741    }
25742    function response(request) {
25743      return dsv.parse(request.responseText);
25744    }
25745    function typedResponse(f) {
25746      return function(request) {
25747        return dsv.parse(request.responseText, f);
25748      };
25749    }
25750    dsv.parse = function(text, f) {
25751      var o;
25752      return dsv.parseRows(text, function(row, i) {
25753        if (o) return o(row, i - 1);
25754        var a = new Function("d", "return {" + row.map(function(name, i) {
25755          return JSON.stringify(name) + ": d[" + i + "]";
25756        }).join(",") + "}");
25757        o = f ? function(row, i) {
25758          return f(a(row), i);
25759        } : a;
25760      });
25761    };
25762    dsv.parseRows = function(text, f) {
25763      var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol;
25764      function token() {
25765        if (I >= N) return EOF;
25766        if (eol) return eol = false, EOL;
25767        var j = I;
25768        if (text.charCodeAt(j) === 34) {
25769          var i = j;
25770          while (i++ < N) {
25771            if (text.charCodeAt(i) === 34) {
25772              if (text.charCodeAt(i + 1) !== 34) break;
25773              ++i;
25774            }
25775          }
25776          I = i + 2;
25777          var c = text.charCodeAt(i + 1);
25778          if (c === 13) {
25779            eol = true;
25780            if (text.charCodeAt(i + 2) === 10) ++I;
25781          } else if (c === 10) {
25782            eol = true;
25783          }
25784          return text.slice(j + 1, i).replace(/""/g, '"');
25785        }
25786        while (I < N) {
25787          var c = text.charCodeAt(I++), k = 1;
25788          if (c === 10) eol = true; else if (c === 13) {
25789            eol = true;
25790            if (text.charCodeAt(I) === 10) ++I, ++k;
25791          } else if (c !== delimiterCode) continue;
25792          return text.slice(j, I - k);
25793        }
25794        return text.slice(j);
25795      }
25796      while ((t = token()) !== EOF) {
25797        var a = [];
25798        while (t !== EOL && t !== EOF) {
25799          a.push(t);
25800          t = token();
25801        }
25802        if (f && (a = f(a, n++)) == null) continue;
25803        rows.push(a);
25804      }
25805      return rows;
25806    };
25807    dsv.format = function(rows) {
25808      if (Array.isArray(rows[0])) return dsv.formatRows(rows);
25809      var fieldSet = new d3_Set(), fields = [];
25810      rows.forEach(function(row) {
25811        for (var field in row) {
25812          if (!fieldSet.has(field)) {
25813            fields.push(fieldSet.add(field));
25814          }
25815        }
25816      });
25817      return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) {
25818        return fields.map(function(field) {
25819          return formatValue(row[field]);
25820        }).join(delimiter);
25821      })).join("\n");
25822    };
25823    dsv.formatRows = function(rows) {
25824      return rows.map(formatRow).join("\n");
25825    };
25826    function formatRow(row) {
25827      return row.map(formatValue).join(delimiter);
25828    }
25829    function formatValue(text) {
25830      return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text;
25831    }
25832    return dsv;
25833  };
25834  d3.csv = d3.dsv(",", "text/csv");
25835  d3.tsv = d3.dsv("	", "text/tab-separated-values");
25836  var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_active, d3_timer_frame = this[d3_vendorSymbol(this, "requestAnimationFrame")] || function(callback) {
25837    setTimeout(callback, 17);
25838  };
25839  d3.timer = function(callback, delay, then) {
25840    var n = arguments.length;
25841    if (n < 2) delay = 0;
25842    if (n < 3) then = Date.now();
25843    var time = then + delay, timer = {
25844      c: callback,
25845      t: time,
25846      f: false,
25847      n: null
25848    };
25849    if (d3_timer_queueTail) d3_timer_queueTail.n = timer; else d3_timer_queueHead = timer;
25850    d3_timer_queueTail = timer;
25851    if (!d3_timer_interval) {
25852      d3_timer_timeout = clearTimeout(d3_timer_timeout);
25853      d3_timer_interval = 1;
25854      d3_timer_frame(d3_timer_step);
25855    }
25856  };
25857  function d3_timer_step() {
25858    var now = d3_timer_mark(), delay = d3_timer_sweep() - now;
25859    if (delay > 24) {
25860      if (isFinite(delay)) {
25861        clearTimeout(d3_timer_timeout);
25862        d3_timer_timeout = setTimeout(d3_timer_step, delay);
25863      }
25864      d3_timer_interval = 0;
25865    } else {
25866      d3_timer_interval = 1;
25867      d3_timer_frame(d3_timer_step);
25868    }
25869  }
25870  d3.timer.flush = function() {
25871    d3_timer_mark();
25872    d3_timer_sweep();
25873  };
25874  function d3_timer_mark() {
25875    var now = Date.now();
25876    d3_timer_active = d3_timer_queueHead;
25877    while (d3_timer_active) {
25878      if (now >= d3_timer_active.t) d3_timer_active.f = d3_timer_active.c(now - d3_timer_active.t);
25879      d3_timer_active = d3_timer_active.n;
25880    }
25881    return now;
25882  }
25883  function d3_timer_sweep() {
25884    var t0, t1 = d3_timer_queueHead, time = Infinity;
25885    while (t1) {
25886      if (t1.f) {
25887        t1 = t0 ? t0.n = t1.n : d3_timer_queueHead = t1.n;
25888      } else {
25889        if (t1.t < time) time = t1.t;
25890        t1 = (t0 = t1).n;
25891      }
25892    }
25893    d3_timer_queueTail = t0;
25894    return time;
25895  }
25896  function d3_format_precision(x, p) {
25897    return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1);
25898  }
25899  d3.round = function(x, n) {
25900    return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x);
25901  };
25902  var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix);
25903  d3.formatPrefix = function(value, precision) {
25904    var i = 0;
25905    if (value) {
25906      if (value < 0) value *= -1;
25907      if (precision) value = d3.round(value, d3_format_precision(value, precision));
25908      i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10);
25909      i = Math.max(-24, Math.min(24, Math.floor((i - 1) / 3) * 3));
25910    }
25911    return d3_formatPrefixes[8 + i / 3];
25912  };
25913  function d3_formatPrefix(d, i) {
25914    var k = Math.pow(10, abs(8 - i) * 3);
25915    return {
25916      scale: i > 8 ? function(d) {
25917        return d / k;
25918      } : function(d) {
25919        return d * k;
25920      },
25921      symbol: d
25922    };
25923  }
25924  function d3_locale_numberFormat(locale) {
25925    var locale_decimal = locale.decimal, locale_thousands = locale.thousands, locale_grouping = locale.grouping, locale_currency = locale.currency, formatGroup = locale_grouping && locale_thousands ? function(value, width) {
25926      var i = value.length, t = [], j = 0, g = locale_grouping[0], length = 0;
25927      while (i > 0 && g > 0) {
25928        if (length + g + 1 > width) g = Math.max(1, width - length);
25929        t.push(value.substring(i -= g, i + g));
25930        if ((length += g + 1) > width) break;
25931        g = locale_grouping[j = (j + 1) % locale_grouping.length];
25932      }
25933      return t.reverse().join(locale_thousands);
25934    } : d3_identity;
25935    return function(specifier) {
25936      var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "-", symbol = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, prefix = "", suffix = "", integer = false, exponent = true;
25937      if (precision) precision = +precision.substring(1);
25938      if (zfill || fill === "0" && align === "=") {
25939        zfill = fill = "0";
25940        align = "=";
25941      }
25942      switch (type) {
25943       case "n":
25944        comma = true;
25945        type = "g";
25946        break;
25947
25948       case "%":
25949        scale = 100;
25950        suffix = "%";
25951        type = "f";
25952        break;
25953
25954       case "p":
25955        scale = 100;
25956        suffix = "%";
25957        type = "r";
25958        break;
25959
25960       case "b":
25961       case "o":
25962       case "x":
25963       case "X":
25964        if (symbol === "#") prefix = "0" + type.toLowerCase();
25965
25966       case "c":
25967        exponent = false;
25968
25969       case "d":
25970        integer = true;
25971        precision = 0;
25972        break;
25973
25974       case "s":
25975        scale = -1;
25976        type = "r";
25977        break;
25978      }
25979      if (symbol === "$") prefix = locale_currency[0], suffix = locale_currency[1];
25980      if (type == "r" && !precision) type = "g";
25981      if (precision != null) {
25982        if (type == "g") precision = Math.max(1, Math.min(21, precision)); else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision));
25983      }
25984      type = d3_format_types.get(type) || d3_format_typeDefault;
25985      var zcomma = zfill && comma;
25986      return function(value) {
25987        var fullSuffix = suffix;
25988        if (integer && value % 1) return "";
25989        var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign === "-" ? "" : sign;
25990        if (scale < 0) {
25991          var unit = d3.formatPrefix(value, precision);
25992          value = unit.scale(value);
25993          fullSuffix = unit.symbol + suffix;
25994        } else {
25995          value *= scale;
25996        }
25997        value = type(value, precision);
25998        var i = value.lastIndexOf("."), before, after;
25999        if (i < 0) {
26000          var j = exponent ? value.lastIndexOf("e") : -1;
26001          if (j < 0) before = value, after = ""; else before = value.substring(0, j), after = value.substring(j);
26002        } else {
26003          before = value.substring(0, i);
26004          after = locale_decimal + value.substring(i + 1);
26005        }
26006        if (!zfill && comma) before = formatGroup(before, Infinity);
26007        var length = prefix.length + before.length + after.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : "";
26008        if (zcomma) before = formatGroup(padding + before, padding.length ? width - after.length : Infinity);
26009        negative += prefix;
26010        value = before + after;
26011        return (align === "<" ? negative + value + padding : align === ">" ? padding + negative + value : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + fullSuffix;
26012      };
26013    };
26014  }
26015  var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i;
26016  var d3_format_types = d3.map({
26017    b: function(x) {
26018      return x.toString(2);
26019    },
26020    c: function(x) {
26021      return String.fromCharCode(x);
26022    },
26023    o: function(x) {
26024      return x.toString(8);
26025    },
26026    x: function(x) {
26027      return x.toString(16);
26028    },
26029    X: function(x) {
26030      return x.toString(16).toUpperCase();
26031    },
26032    g: function(x, p) {
26033      return x.toPrecision(p);
26034    },
26035    e: function(x, p) {
26036      return x.toExponential(p);
26037    },
26038    f: function(x, p) {
26039      return x.toFixed(p);
26040    },
26041    r: function(x, p) {
26042      return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p))));
26043    }
26044  });
26045  function d3_format_typeDefault(x) {
26046    return x + "";
26047  }
26048  var d3_time = d3.time = {}, d3_date = Date;
26049  function d3_date_utc() {
26050    this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]);
26051  }
26052  d3_date_utc.prototype = {
26053    getDate: function() {
26054      return this._.getUTCDate();
26055    },
26056    getDay: function() {
26057      return this._.getUTCDay();
26058    },
26059    getFullYear: function() {
26060      return this._.getUTCFullYear();
26061    },
26062    getHours: function() {
26063      return this._.getUTCHours();
26064    },
26065    getMilliseconds: function() {
26066      return this._.getUTCMilliseconds();
26067    },
26068    getMinutes: function() {
26069      return this._.getUTCMinutes();
26070    },
26071    getMonth: function() {
26072      return this._.getUTCMonth();
26073    },
26074    getSeconds: function() {
26075      return this._.getUTCSeconds();
26076    },
26077    getTime: function() {
26078      return this._.getTime();
26079    },
26080    getTimezoneOffset: function() {
26081      return 0;
26082    },
26083    valueOf: function() {
26084      return this._.valueOf();
26085    },
26086    setDate: function() {
26087      d3_time_prototype.setUTCDate.apply(this._, arguments);
26088    },
26089    setDay: function() {
26090      d3_time_prototype.setUTCDay.apply(this._, arguments);
26091    },
26092    setFullYear: function() {
26093      d3_time_prototype.setUTCFullYear.apply(this._, arguments);
26094    },
26095    setHours: function() {
26096      d3_time_prototype.setUTCHours.apply(this._, arguments);
26097    },
26098    setMilliseconds: function() {
26099      d3_time_prototype.setUTCMilliseconds.apply(this._, arguments);
26100    },
26101    setMinutes: function() {
26102      d3_time_prototype.setUTCMinutes.apply(this._, arguments);
26103    },
26104    setMonth: function() {
26105      d3_time_prototype.setUTCMonth.apply(this._, arguments);
26106    },
26107    setSeconds: function() {
26108      d3_time_prototype.setUTCSeconds.apply(this._, arguments);
26109    },
26110    setTime: function() {
26111      d3_time_prototype.setTime.apply(this._, arguments);
26112    }
26113  };
26114  var d3_time_prototype = Date.prototype;
26115  function d3_time_interval(local, step, number) {
26116    function round(date) {
26117      var d0 = local(date), d1 = offset(d0, 1);
26118      return date - d0 < d1 - date ? d0 : d1;
26119    }
26120    function ceil(date) {
26121      step(date = local(new d3_date(date - 1)), 1);
26122      return date;
26123    }
26124    function offset(date, k) {
26125      step(date = new d3_date(+date), k);
26126      return date;
26127    }
26128    function range(t0, t1, dt) {
26129      var time = ceil(t0), times = [];
26130      if (dt > 1) {
26131        while (time < t1) {
26132          if (!(number(time) % dt)) times.push(new Date(+time));
26133          step(time, 1);
26134        }
26135      } else {
26136        while (time < t1) times.push(new Date(+time)), step(time, 1);
26137      }
26138      return times;
26139    }
26140    function range_utc(t0, t1, dt) {
26141      try {
26142        d3_date = d3_date_utc;
26143        var utc = new d3_date_utc();
26144        utc._ = t0;
26145        return range(utc, t1, dt);
26146      } finally {
26147        d3_date = Date;
26148      }
26149    }
26150    local.floor = local;
26151    local.round = round;
26152    local.ceil = ceil;
26153    local.offset = offset;
26154    local.range = range;
26155    var utc = local.utc = d3_time_interval_utc(local);
26156    utc.floor = utc;
26157    utc.round = d3_time_interval_utc(round);
26158    utc.ceil = d3_time_interval_utc(ceil);
26159    utc.offset = d3_time_interval_utc(offset);
26160    utc.range = range_utc;
26161    return local;
26162  }
26163  function d3_time_interval_utc(method) {
26164    return function(date, k) {
26165      try {
26166        d3_date = d3_date_utc;
26167        var utc = new d3_date_utc();
26168        utc._ = date;
26169        return method(utc, k)._;
26170      } finally {
26171        d3_date = Date;
26172      }
26173    };
26174  }
26175  d3_time.year = d3_time_interval(function(date) {
26176    date = d3_time.day(date);
26177    date.setMonth(0, 1);
26178    return date;
26179  }, function(date, offset) {
26180    date.setFullYear(date.getFullYear() + offset);
26181  }, function(date) {
26182    return date.getFullYear();
26183  });
26184  d3_time.years = d3_time.year.range;
26185  d3_time.years.utc = d3_time.year.utc.range;
26186  d3_time.day = d3_time_interval(function(date) {
26187    var day = new d3_date(2e3, 0);
26188    day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());
26189    return day;
26190  }, function(date, offset) {
26191    date.setDate(date.getDate() + offset);
26192  }, function(date) {
26193    return date.getDate() - 1;
26194  });
26195  d3_time.days = d3_time.day.range;
26196  d3_time.days.utc = d3_time.day.utc.range;
26197  d3_time.dayOfYear = function(date) {
26198    var year = d3_time.year(date);
26199    return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5);
26200  };
26201  [ "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" ].forEach(function(day, i) {
26202    i = 7 - i;
26203    var interval = d3_time[day] = d3_time_interval(function(date) {
26204      (date = d3_time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7);
26205      return date;
26206    }, function(date, offset) {
26207      date.setDate(date.getDate() + Math.floor(offset) * 7);
26208    }, function(date) {
26209      var day = d3_time.year(date).getDay();
26210      return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i);
26211    });
26212    d3_time[day + "s"] = interval.range;
26213    d3_time[day + "s"].utc = interval.utc.range;
26214    d3_time[day + "OfYear"] = function(date) {
26215      var day = d3_time.year(date).getDay();
26216      return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7);
26217    };
26218  });
26219  d3_time.week = d3_time.sunday;
26220  d3_time.weeks = d3_time.sunday.range;
26221  d3_time.weeks.utc = d3_time.sunday.utc.range;
26222  d3_time.weekOfYear = d3_time.sundayOfYear;
26223  function d3_locale_timeFormat(locale) {
26224    var locale_dateTime = locale.dateTime, locale_date = locale.date, locale_time = locale.time, locale_periods = locale.periods, locale_days = locale.days, locale_shortDays = locale.shortDays, locale_months = locale.months, locale_shortMonths = locale.shortMonths;
26225    function d3_time_format(template) {
26226      var n = template.length;
26227      function format(date) {
26228        var string = [], i = -1, j = 0, c, p, f;
26229        while (++i < n) {
26230          if (template.charCodeAt(i) === 37) {
26231            string.push(template.slice(j, i));
26232            if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i);
26233            if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p);
26234            string.push(c);
26235            j = i + 1;
26236          }
26237        }
26238        string.push(template.slice(j, i));
26239        return string.join("");
26240      }
26241      format.parse = function(string) {
26242        var d = {
26243          y: 1900,
26244          m: 0,
26245          d: 1,
26246          H: 0,
26247          M: 0,
26248          S: 0,
26249          L: 0,
26250          Z: null
26251        }, i = d3_time_parse(d, template, string, 0);
26252        if (i != string.length) return null;
26253        if ("p" in d) d.H = d.H % 12 + d.p * 12;
26254        var localZ = d.Z != null && d3_date !== d3_date_utc, date = new (localZ ? d3_date_utc : d3_date)();
26255        if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("w" in d && ("W" in d || "U" in d)) {
26256          date.setFullYear(d.y, 0, 1);
26257          date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7);
26258        } else date.setFullYear(d.y, d.m, d.d);
26259        date.setHours(d.H + (d.Z / 100 | 0), d.M + d.Z % 100, d.S, d.L);
26260        return localZ ? date._ : date;
26261      };
26262      format.toString = function() {
26263        return template;
26264      };
26265      return format;
26266    }
26267    function d3_time_parse(date, template, string, j) {
26268      var c, p, t, i = 0, n = template.length, m = string.length;
26269      while (i < n) {
26270        if (j >= m) return -1;
26271        c = template.charCodeAt(i++);
26272        if (c === 37) {
26273          t = template.charAt(i++);
26274          p = d3_time_parsers[t in d3_time_formatPads ? template.charAt(i++) : t];
26275          if (!p || (j = p(date, string, j)) < 0) return -1;
26276        } else if (c != string.charCodeAt(j++)) {
26277          return -1;
26278        }
26279      }
26280      return j;
26281    }
26282    d3_time_format.utc = function(template) {
26283      var local = d3_time_format(template);
26284      function format(date) {
26285        try {
26286          d3_date = d3_date_utc;
26287          var utc = new d3_date();
26288          utc._ = date;
26289          return local(utc);
26290        } finally {
26291          d3_date = Date;
26292        }
26293      }
26294      format.parse = function(string) {
26295        try {
26296          d3_date = d3_date_utc;
26297          var date = local.parse(string);
26298          return date && date._;
26299        } finally {
26300          d3_date = Date;
26301        }
26302      };
26303      format.toString = local.toString;
26304      return format;
26305    };
26306    d3_time_format.multi = d3_time_format.utc.multi = d3_time_formatMulti;
26307    var d3_time_periodLookup = d3.map(), d3_time_dayRe = d3_time_formatRe(locale_days), d3_time_dayLookup = d3_time_formatLookup(locale_days), d3_time_dayAbbrevRe = d3_time_formatRe(locale_shortDays), d3_time_dayAbbrevLookup = d3_time_formatLookup(locale_shortDays), d3_time_monthRe = d3_time_formatRe(locale_months), d3_time_monthLookup = d3_time_formatLookup(locale_months), d3_time_monthAbbrevRe = d3_time_formatRe(locale_shortMonths), d3_time_monthAbbrevLookup = d3_time_formatLookup(locale_shortMonths);
26308    locale_periods.forEach(function(p, i) {
26309      d3_time_periodLookup.set(p.toLowerCase(), i);
26310    });
26311    var d3_time_formats = {
26312      a: function(d) {
26313        return locale_shortDays[d.getDay()];
26314      },
26315      A: function(d) {
26316        return locale_days[d.getDay()];
26317      },
26318      b: function(d) {
26319        return locale_shortMonths[d.getMonth()];
26320      },
26321      B: function(d) {
26322        return locale_months[d.getMonth()];
26323      },
26324      c: d3_time_format(locale_dateTime),
26325      d: function(d, p) {
26326        return d3_time_formatPad(d.getDate(), p, 2);
26327      },
26328      e: function(d, p) {
26329        return d3_time_formatPad(d.getDate(), p, 2);
26330      },
26331      H: function(d, p) {
26332        return d3_time_formatPad(d.getHours(), p, 2);
26333      },
26334      I: function(d, p) {
26335        return d3_time_formatPad(d.getHours() % 12 || 12, p, 2);
26336      },
26337      j: function(d, p) {
26338        return d3_time_formatPad(1 + d3_time.dayOfYear(d), p, 3);
26339      },
26340      L: function(d, p) {
26341        return d3_time_formatPad(d.getMilliseconds(), p, 3);
26342      },
26343      m: function(d, p) {
26344        return d3_time_formatPad(d.getMonth() + 1, p, 2);
26345      },
26346      M: function(d, p) {
26347        return d3_time_formatPad(d.getMinutes(), p, 2);
26348      },
26349      p: function(d) {
26350        return locale_periods[+(d.getHours() >= 12)];
26351      },
26352      S: function(d, p) {
26353        return d3_time_formatPad(d.getSeconds(), p, 2);
26354      },
26355      U: function(d, p) {
26356        return d3_time_formatPad(d3_time.sundayOfYear(d), p, 2);
26357      },
26358      w: function(d) {
26359        return d.getDay();
26360      },
26361      W: function(d, p) {
26362        return d3_time_formatPad(d3_time.mondayOfYear(d), p, 2);
26363      },
26364      x: d3_time_format(locale_date),
26365      X: d3_time_format(locale_time),
26366      y: function(d, p) {
26367        return d3_time_formatPad(d.getFullYear() % 100, p, 2);
26368      },
26369      Y: function(d, p) {
26370        return d3_time_formatPad(d.getFullYear() % 1e4, p, 4);
26371      },
26372      Z: d3_time_zone,
26373      "%": function() {
26374        return "%";
26375      }
26376    };
26377    var d3_time_parsers = {
26378      a: d3_time_parseWeekdayAbbrev,
26379      A: d3_time_parseWeekday,
26380      b: d3_time_parseMonthAbbrev,
26381      B: d3_time_parseMonth,
26382      c: d3_time_parseLocaleFull,
26383      d: d3_time_parseDay,
26384      e: d3_time_parseDay,
26385      H: d3_time_parseHour24,
26386      I: d3_time_parseHour24,
26387      j: d3_time_parseDayOfYear,
26388      L: d3_time_parseMilliseconds,
26389      m: d3_time_parseMonthNumber,
26390      M: d3_time_parseMinutes,
26391      p: d3_time_parseAmPm,
26392      S: d3_time_parseSeconds,
26393      U: d3_time_parseWeekNumberSunday,
26394      w: d3_time_parseWeekdayNumber,
26395      W: d3_time_parseWeekNumberMonday,
26396      x: d3_time_parseLocaleDate,
26397      X: d3_time_parseLocaleTime,
26398      y: d3_time_parseYear,
26399      Y: d3_time_parseFullYear,
26400      Z: d3_time_parseZone,
26401      "%": d3_time_parseLiteralPercent
26402    };
26403    function d3_time_parseWeekdayAbbrev(date, string, i) {
26404      d3_time_dayAbbrevRe.lastIndex = 0;
26405      var n = d3_time_dayAbbrevRe.exec(string.slice(i));
26406      return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
26407    }
26408    function d3_time_parseWeekday(date, string, i) {
26409      d3_time_dayRe.lastIndex = 0;
26410      var n = d3_time_dayRe.exec(string.slice(i));
26411      return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
26412    }
26413    function d3_time_parseMonthAbbrev(date, string, i) {
26414      d3_time_monthAbbrevRe.lastIndex = 0;
26415      var n = d3_time_monthAbbrevRe.exec(string.slice(i));
26416      return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
26417    }
26418    function d3_time_parseMonth(date, string, i) {
26419      d3_time_monthRe.lastIndex = 0;
26420      var n = d3_time_monthRe.exec(string.slice(i));
26421      return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
26422    }
26423    function d3_time_parseLocaleFull(date, string, i) {
26424      return d3_time_parse(date, d3_time_formats.c.toString(), string, i);
26425    }
26426    function d3_time_parseLocaleDate(date, string, i) {
26427      return d3_time_parse(date, d3_time_formats.x.toString(), string, i);
26428    }
26429    function d3_time_parseLocaleTime(date, string, i) {
26430      return d3_time_parse(date, d3_time_formats.X.toString(), string, i);
26431    }
26432    function d3_time_parseAmPm(date, string, i) {
26433      var n = d3_time_periodLookup.get(string.slice(i, i += 2).toLowerCase());
26434      return n == null ? -1 : (date.p = n, i);
26435    }
26436    return d3_time_format;
26437  }
26438  var d3_time_formatPads = {
26439    "-": "",
26440    _: " ",
26441    "0": "0"
26442  }, d3_time_numberRe = /^\s*\d+/, d3_time_percentRe = /^%/;
26443  function d3_time_formatPad(value, fill, width) {
26444    var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length;
26445    return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
26446  }
26447  function d3_time_formatRe(names) {
26448    return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i");
26449  }
26450  function d3_time_formatLookup(names) {
26451    var map = new d3_Map(), i = -1, n = names.length;
26452    while (++i < n) map.set(names[i].toLowerCase(), i);
26453    return map;
26454  }
26455  function d3_time_parseWeekdayNumber(date, string, i) {
26456    d3_time_numberRe.lastIndex = 0;
26457    var n = d3_time_numberRe.exec(string.slice(i, i + 1));
26458    return n ? (date.w = +n[0], i + n[0].length) : -1;
26459  }
26460  function d3_time_parseWeekNumberSunday(date, string, i) {
26461    d3_time_numberRe.lastIndex = 0;
26462    var n = d3_time_numberRe.exec(string.slice(i));
26463    return n ? (date.U = +n[0], i + n[0].length) : -1;
26464  }
26465  function d3_time_parseWeekNumberMonday(date, string, i) {
26466    d3_time_numberRe.lastIndex = 0;
26467    var n = d3_time_numberRe.exec(string.slice(i));
26468    return n ? (date.W = +n[0], i + n[0].length) : -1;
26469  }
26470  function d3_time_parseFullYear(date, string, i) {
26471    d3_time_numberRe.lastIndex = 0;
26472    var n = d3_time_numberRe.exec(string.slice(i, i + 4));
26473    return n ? (date.y = +n[0], i + n[0].length) : -1;
26474  }
26475  function d3_time_parseYear(date, string, i) {
26476    d3_time_numberRe.lastIndex = 0;
26477    var n = d3_time_numberRe.exec(string.slice(i, i + 2));
26478    return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1;
26479  }
26480  function d3_time_parseZone(date, string, i) {
26481    return /^[+-]\d{4}$/.test(string = string.slice(i, i + 5)) ? (date.Z = -string, 
26482    i + 5) : -1;
26483  }
26484  function d3_time_expandYear(d) {
26485    return d + (d > 68 ? 1900 : 2e3);
26486  }
26487  function d3_time_parseMonthNumber(date, string, i) {
26488    d3_time_numberRe.lastIndex = 0;
26489    var n = d3_time_numberRe.exec(string.slice(i, i + 2));
26490    return n ? (date.m = n[0] - 1, i + n[0].length) : -1;
26491  }
26492  function d3_time_parseDay(date, string, i) {
26493    d3_time_numberRe.lastIndex = 0;
26494    var n = d3_time_numberRe.exec(string.slice(i, i + 2));
26495    return n ? (date.d = +n[0], i + n[0].length) : -1;
26496  }
26497  function d3_time_parseDayOfYear(date, string, i) {
26498    d3_time_numberRe.lastIndex = 0;
26499    var n = d3_time_numberRe.exec(string.slice(i, i + 3));
26500    return n ? (date.j = +n[0], i + n[0].length) : -1;
26501  }
26502  function d3_time_parseHour24(date, string, i) {
26503    d3_time_numberRe.lastIndex = 0;
26504    var n = d3_time_numberRe.exec(string.slice(i, i + 2));
26505    return n ? (date.H = +n[0], i + n[0].length) : -1;
26506  }
26507  function d3_time_parseMinutes(date, string, i) {
26508    d3_time_numberRe.lastIndex = 0;
26509    var n = d3_time_numberRe.exec(string.slice(i, i + 2));
26510    return n ? (date.M = +n[0], i + n[0].length) : -1;
26511  }
26512  function d3_time_parseSeconds(date, string, i) {
26513    d3_time_numberRe.lastIndex = 0;
26514    var n = d3_time_numberRe.exec(string.slice(i, i + 2));
26515    return n ? (date.S = +n[0], i + n[0].length) : -1;
26516  }
26517  function d3_time_parseMilliseconds(date, string, i) {
26518    d3_time_numberRe.lastIndex = 0;
26519    var n = d3_time_numberRe.exec(string.slice(i, i + 3));
26520    return n ? (date.L = +n[0], i + n[0].length) : -1;
26521  }
26522  function d3_time_zone(d) {
26523    var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = abs(z) / 60 | 0, zm = abs(z) % 60;
26524    return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2);
26525  }
26526  function d3_time_parseLiteralPercent(date, string, i) {
26527    d3_time_percentRe.lastIndex = 0;
26528    var n = d3_time_percentRe.exec(string.slice(i, i + 1));
26529    return n ? i + n[0].length : -1;
26530  }
26531  function d3_time_formatMulti(formats) {
26532    var n = formats.length, i = -1;
26533    while (++i < n) formats[i][0] = this(formats[i][0]);
26534    return function(date) {
26535      var i = 0, f = formats[i];
26536      while (!f[1](date)) f = formats[++i];
26537      return f[0](date);
26538    };
26539  }
26540  d3.locale = function(locale) {
26541    return {
26542      numberFormat: d3_locale_numberFormat(locale),
26543      timeFormat: d3_locale_timeFormat(locale)
26544    };
26545  };
26546  var d3_locale_enUS = d3.locale({
26547    decimal: ".",
26548    thousands: ",",
26549    grouping: [ 3 ],
26550    currency: [ "$", "" ],
26551    dateTime: "%a %b %e %X %Y",
26552    date: "%m/%d/%Y",
26553    time: "%H:%M:%S",
26554    periods: [ "AM", "PM" ],
26555    days: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
26556    shortDays: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ],
26557    months: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ],
26558    shortMonths: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]
26559  });
26560  d3.format = d3_locale_enUS.numberFormat;
26561  d3.geo = {};
26562  function d3_adder() {}
26563  d3_adder.prototype = {
26564    s: 0,
26565    t: 0,
26566    add: function(y) {
26567      d3_adderSum(y, this.t, d3_adderTemp);
26568      d3_adderSum(d3_adderTemp.s, this.s, this);
26569      if (this.s) this.t += d3_adderTemp.t; else this.s = d3_adderTemp.t;
26570    },
26571    reset: function() {
26572      this.s = this.t = 0;
26573    },
26574    valueOf: function() {
26575      return this.s;
26576    }
26577  };
26578  var d3_adderTemp = new d3_adder();
26579  function d3_adderSum(a, b, o) {
26580    var x = o.s = a + b, bv = x - a, av = x - bv;
26581    o.t = a - av + (b - bv);
26582  }
26583  d3.geo.stream = function(object, listener) {
26584    if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) {
26585      d3_geo_streamObjectType[object.type](object, listener);
26586    } else {
26587      d3_geo_streamGeometry(object, listener);
26588    }
26589  };
26590  function d3_geo_streamGeometry(geometry, listener) {
26591    if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) {
26592      d3_geo_streamGeometryType[geometry.type](geometry, listener);
26593    }
26594  }
26595  var d3_geo_streamObjectType = {
26596    Feature: function(feature, listener) {
26597      d3_geo_streamGeometry(feature.geometry, listener);
26598    },
26599    FeatureCollection: function(object, listener) {
26600      var features = object.features, i = -1, n = features.length;
26601      while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener);
26602    }
26603  };
26604  var d3_geo_streamGeometryType = {
26605    Sphere: function(object, listener) {
26606      listener.sphere();
26607    },
26608    Point: function(object, listener) {
26609      object = object.coordinates;
26610      listener.point(object[0], object[1], object[2]);
26611    },
26612    MultiPoint: function(object, listener) {
26613      var coordinates = object.coordinates, i = -1, n = coordinates.length;
26614      while (++i < n) object = coordinates[i], listener.point(object[0], object[1], object[2]);
26615    },
26616    LineString: function(object, listener) {
26617      d3_geo_streamLine(object.coordinates, listener, 0);
26618    },
26619    MultiLineString: function(object, listener) {
26620      var coordinates = object.coordinates, i = -1, n = coordinates.length;
26621      while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0);
26622    },
26623    Polygon: function(object, listener) {
26624      d3_geo_streamPolygon(object.coordinates, listener);
26625    },
26626    MultiPolygon: function(object, listener) {
26627      var coordinates = object.coordinates, i = -1, n = coordinates.length;
26628      while (++i < n) d3_geo_streamPolygon(coordinates[i], listener);
26629    },
26630    GeometryCollection: function(object, listener) {
26631      var geometries = object.geometries, i = -1, n = geometries.length;
26632      while (++i < n) d3_geo_streamGeometry(geometries[i], listener);
26633    }
26634  };
26635  function d3_geo_streamLine(coordinates, listener, closed) {
26636    var i = -1, n = coordinates.length - closed, coordinate;
26637    listener.lineStart();
26638    while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1], coordinate[2]);
26639    listener.lineEnd();
26640  }
26641  function d3_geo_streamPolygon(coordinates, listener) {
26642    var i = -1, n = coordinates.length;
26643    listener.polygonStart();
26644    while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1);
26645    listener.polygonEnd();
26646  }
26647  d3.geo.area = function(object) {
26648    d3_geo_areaSum = 0;
26649    d3.geo.stream(object, d3_geo_area);
26650    return d3_geo_areaSum;
26651  };
26652  var d3_geo_areaSum, d3_geo_areaRingSum = new d3_adder();
26653  var d3_geo_area = {
26654    sphere: function() {
26655      d3_geo_areaSum += 4 * π;
26656    },
26657    point: d3_noop,
26658    lineStart: d3_noop,
26659    lineEnd: d3_noop,
26660    polygonStart: function() {
26661      d3_geo_areaRingSum.reset();
26662      d3_geo_area.lineStart = d3_geo_areaRingStart;
26663    },
26664    polygonEnd: function() {
26665      var area = 2 * d3_geo_areaRingSum;
26666      d3_geo_areaSum += area < 0 ? 4 * π + area : area;
26667      d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop;
26668    }
26669  };
26670  function d3_geo_areaRingStart() {
26671    var λ00, φ00, λ0, cosφ0, sinφ0;
26672    d3_geo_area.point = function(λ, φ) {
26673      d3_geo_area.point = nextPoint;
26674      λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + π / 4), 
26675      sinφ0 = Math.sin(φ);
26676    };
26677    function nextPoint(λ, φ) {
26678      λ *= d3_radians;
26679      φ = φ * d3_radians / 2 + π / 4;
26680      var dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, cosφ = Math.cos(φ), sinφ = Math.sin(φ), k = sinφ0 * sinφ, u = cosφ0 * cosφ + k * Math.cos(adλ), v = k * sdλ * Math.sin(adλ);
26681      d3_geo_areaRingSum.add(Math.atan2(v, u));
26682      λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ;
26683    }
26684    d3_geo_area.lineEnd = function() {
26685      nextPoint(λ00, φ00);
26686    };
26687  }
26688  function d3_geo_cartesian(spherical) {
26689    var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ);
26690    return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ];
26691  }
26692  function d3_geo_cartesianDot(a, b) {
26693    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
26694  }
26695  function d3_geo_cartesianCross(a, b) {
26696    return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ];
26697  }
26698  function d3_geo_cartesianAdd(a, b) {
26699    a[0] += b[0];
26700    a[1] += b[1];
26701    a[2] += b[2];
26702  }
26703  function d3_geo_cartesianScale(vector, k) {
26704    return [ vector[0] * k, vector[1] * k, vector[2] * k ];
26705  }
26706  function d3_geo_cartesianNormalize(d) {
26707    var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
26708    d[0] /= l;
26709    d[1] /= l;
26710    d[2] /= l;
26711  }
26712  function d3_geo_spherical(cartesian) {
26713    return [ Math.atan2(cartesian[1], cartesian[0]), d3_asin(cartesian[2]) ];
26714  }
26715  function d3_geo_sphericalEqual(a, b) {
26716    return abs(a[0] - b[0]) < ε && abs(a[1] - b[1]) < ε;
26717  }
26718  d3.geo.bounds = function() {
26719    var λ0, φ0, λ1, φ1, λ_, λ__, φ__, p0, dλSum, ranges, range;
26720    var bound = {
26721      point: point,
26722      lineStart: lineStart,
26723      lineEnd: lineEnd,
26724      polygonStart: function() {
26725        bound.point = ringPoint;
26726        bound.lineStart = ringStart;
26727        bound.lineEnd = ringEnd;
26728        dλSum = 0;
26729        d3_geo_area.polygonStart();
26730      },
26731      polygonEnd: function() {
26732        d3_geo_area.polygonEnd();
26733        bound.point = point;
26734        bound.lineStart = lineStart;
26735        bound.lineEnd = lineEnd;
26736        if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); else if (dλSum > ε) φ1 = 90; else if (dλSum < -ε) φ0 = -90;
26737        range[0] = λ0, range[1] = λ1;
26738      }
26739    };
26740    function point(λ, φ) {
26741      ranges.push(range = [ λ0 = λ, λ1 = λ ]);
26742      if (φ < φ0) φ0 = φ;
26743      if (φ > φ1) φ1 = φ;
26744    }
26745    function linePoint(λ, φ) {
26746      var p = d3_geo_cartesian([ λ * d3_radians, φ * d3_radians ]);
26747      if (p0) {
26748        var normal = d3_geo_cartesianCross(p0, p), equatorial = [ normal[1], -normal[0], 0 ], inflection = d3_geo_cartesianCross(equatorial, normal);
26749        d3_geo_cartesianNormalize(inflection);
26750        inflection = d3_geo_spherical(inflection);
26751        var dλ = λ - λ_, s = dλ > 0 ? 1 : -1, λi = inflection[0] * d3_degrees * s, antimeridian = abs(dλ) > 180;
26752        if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) {
26753          var φi = inflection[1] * d3_degrees;
26754          if (φi > φ1) φ1 = φi;
26755        } else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) {
26756          var φi = -inflection[1] * d3_degrees;
26757          if (φi < φ0) φ0 = φi;
26758        } else {
26759          if (φ < φ0) φ0 = φ;
26760          if (φ > φ1) φ1 = φ;
26761        }
26762        if (antimeridian) {
26763          if (λ < λ_) {
26764            if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ;
26765          } else {
26766            if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ;
26767          }
26768        } else {
26769          if (λ1 >= λ0) {
26770            if (λ < λ0) λ0 = λ;
26771            if (λ > λ1) λ1 = λ;
26772          } else {
26773            if (λ > λ_) {
26774              if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ;
26775            } else {
26776              if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ;
26777            }
26778          }
26779        }
26780      } else {
26781        point(λ, φ);
26782      }
26783      p0 = p, λ_ = λ;
26784    }
26785    function lineStart() {
26786      bound.point = linePoint;
26787    }
26788    function lineEnd() {
26789      range[0] = λ0, range[1] = λ1;
26790      bound.point = point;
26791      p0 = null;
26792    }
26793    function ringPoint(λ, φ) {
26794      if (p0) {
26795        var dλ = λ - λ_;
26796        dλSum += abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ;
26797      } else λ__ = λ, φ__ = φ;
26798      d3_geo_area.point(λ, φ);
26799      linePoint(λ, φ);
26800    }
26801    function ringStart() {
26802      d3_geo_area.lineStart();
26803    }
26804    function ringEnd() {
26805      ringPoint(λ__, φ__);
26806      d3_geo_area.lineEnd();
26807      if (abs(dλSum) > ε) λ0 = -(λ1 = 180);
26808      range[0] = λ0, range[1] = λ1;
26809      p0 = null;
26810    }
26811    function angle(λ0, λ1) {
26812      return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1;
26813    }
26814    function compareRanges(a, b) {
26815      return a[0] - b[0];
26816    }
26817    function withinRange(x, range) {
26818      return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;
26819    }
26820    return function(feature) {
26821      φ1 = λ1 = -(λ0 = φ0 = Infinity);
26822      ranges = [];
26823      d3.geo.stream(feature, bound);
26824      var n = ranges.length;
26825      if (n) {
26826        ranges.sort(compareRanges);
26827        for (var i = 1, a = ranges[0], b, merged = [ a ]; i < n; ++i) {
26828          b = ranges[i];
26829          if (withinRange(b[0], a) || withinRange(b[1], a)) {
26830            if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];
26831            if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];
26832          } else {
26833            merged.push(a = b);
26834          }
26835        }
26836        var best = -Infinity, dλ;
26837        for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) {
26838          b = merged[i];
26839          if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1];
26840        }
26841      }
26842      ranges = range = null;
26843      return λ0 === Infinity || φ0 === Infinity ? [ [ NaN, NaN ], [ NaN, NaN ] ] : [ [ λ0, φ0 ], [ λ1, φ1 ] ];
26844    };
26845  }();
26846  d3.geo.centroid = function(object) {
26847    d3_geo_centroidW0 = d3_geo_centroidW1 = d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0;
26848    d3.geo.stream(object, d3_geo_centroid);
26849    var x = d3_geo_centroidX2, y = d3_geo_centroidY2, z = d3_geo_centroidZ2, m = x * x + y * y + z * z;
26850    if (m < ε2) {
26851      x = d3_geo_centroidX1, y = d3_geo_centroidY1, z = d3_geo_centroidZ1;
26852      if (d3_geo_centroidW1 < ε) x = d3_geo_centroidX0, y = d3_geo_centroidY0, z = d3_geo_centroidZ0;
26853      m = x * x + y * y + z * z;
26854      if (m < ε2) return [ NaN, NaN ];
26855    }
26856    return [ Math.atan2(y, x) * d3_degrees, d3_asin(z / Math.sqrt(m)) * d3_degrees ];
26857  };
26858  var d3_geo_centroidW0, d3_geo_centroidW1, d3_geo_centroidX0, d3_geo_centroidY0, d3_geo_centroidZ0, d3_geo_centroidX1, d3_geo_centroidY1, d3_geo_centroidZ1, d3_geo_centroidX2, d3_geo_centroidY2, d3_geo_centroidZ2;
26859  var d3_geo_centroid = {
26860    sphere: d3_noop,
26861    point: d3_geo_centroidPoint,
26862    lineStart: d3_geo_centroidLineStart,
26863    lineEnd: d3_geo_centroidLineEnd,
26864    polygonStart: function() {
26865      d3_geo_centroid.lineStart = d3_geo_centroidRingStart;
26866    },
26867    polygonEnd: function() {
26868      d3_geo_centroid.lineStart = d3_geo_centroidLineStart;
26869    }
26870  };
26871  function d3_geo_centroidPoint(λ, φ) {
26872    λ *= d3_radians;
26873    var cosφ = Math.cos(φ *= d3_radians);
26874    d3_geo_centroidPointXYZ(cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ));
26875  }
26876  function d3_geo_centroidPointXYZ(x, y, z) {
26877    ++d3_geo_centroidW0;
26878    d3_geo_centroidX0 += (x - d3_geo_centroidX0) / d3_geo_centroidW0;
26879    d3_geo_centroidY0 += (y - d3_geo_centroidY0) / d3_geo_centroidW0;
26880    d3_geo_centroidZ0 += (z - d3_geo_centroidZ0) / d3_geo_centroidW0;
26881  }
26882  function d3_geo_centroidLineStart() {
26883    var x0, y0, z0;
26884    d3_geo_centroid.point = function(λ, φ) {
26885      λ *= d3_radians;
26886      var cosφ = Math.cos(φ *= d3_radians);
26887      x0 = cosφ * Math.cos(λ);
26888      y0 = cosφ * Math.sin(λ);
26889      z0 = Math.sin(φ);
26890      d3_geo_centroid.point = nextPoint;
26891      d3_geo_centroidPointXYZ(x0, y0, z0);
26892    };
26893    function nextPoint(λ, φ) {
26894      λ *= d3_radians;
26895      var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z);
26896      d3_geo_centroidW1 += w;
26897      d3_geo_centroidX1 += w * (x0 + (x0 = x));
26898      d3_geo_centroidY1 += w * (y0 + (y0 = y));
26899      d3_geo_centroidZ1 += w * (z0 + (z0 = z));
26900      d3_geo_centroidPointXYZ(x0, y0, z0);
26901    }
26902  }
26903  function d3_geo_centroidLineEnd() {
26904    d3_geo_centroid.point = d3_geo_centroidPoint;
26905  }
26906  function d3_geo_centroidRingStart() {
26907    var λ00, φ00, x0, y0, z0;
26908    d3_geo_centroid.point = function(λ, φ) {
26909      λ00 = λ, φ00 = φ;
26910      d3_geo_centroid.point = nextPoint;
26911      λ *= d3_radians;
26912      var cosφ = Math.cos(φ *= d3_radians);
26913      x0 = cosφ * Math.cos(λ);
26914      y0 = cosφ * Math.sin(λ);
26915      z0 = Math.sin(φ);
26916      d3_geo_centroidPointXYZ(x0, y0, z0);
26917    };
26918    d3_geo_centroid.lineEnd = function() {
26919      nextPoint(λ00, φ00);
26920      d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd;
26921      d3_geo_centroid.point = d3_geo_centroidPoint;
26922    };
26923    function nextPoint(λ, φ) {
26924      λ *= d3_radians;
26925      var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), cx = y0 * z - z0 * y, cy = z0 * x - x0 * z, cz = x0 * y - y0 * x, m = Math.sqrt(cx * cx + cy * cy + cz * cz), u = x0 * x + y0 * y + z0 * z, v = m && -d3_acos(u) / m, w = Math.atan2(m, u);
vendor: 4,482 bytes, lines 26926-27054
26926      d3_geo_centroidX2 += v * cx;
26927      d3_geo_centroidY2 += v * cy;
26928      d3_geo_centroidZ2 += v * cz;
26929      d3_geo_centroidW1 += w;
26930      d3_geo_centroidX1 += w * (x0 + (x0 = x));
26931      d3_geo_centroidY1 += w * (y0 + (y0 = y));
26932      d3_geo_centroidZ1 += w * (z0 + (z0 = z));
26933      d3_geo_centroidPointXYZ(x0, y0, z0);
26934    }
26935  }
26936  function d3_geo_compose(a, b) {
26937    function compose(x, y) {
26938      return x = a(x, y), b(x[0], x[1]);
26939    }
26940    if (a.invert && b.invert) compose.invert = function(x, y) {
26941      return x = b.invert(x, y), x && a.invert(x[0], x[1]);
26942    };
26943    return compose;
26944  }
26945  function d3_true() {
26946    return true;
26947  }
26948  function d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener) {
26949    var subject = [], clip = [];
26950    segments.forEach(function(segment) {
26951      if ((n = segment.length - 1) <= 0) return;
26952      var n, p0 = segment[0], p1 = segment[n];
26953      if (d3_geo_sphericalEqual(p0, p1)) {
26954        listener.lineStart();
26955        for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]);
26956        listener.lineEnd();
26957        return;
26958      }
26959      var a = new d3_geo_clipPolygonIntersection(p0, segment, null, true), b = new d3_geo_clipPolygonIntersection(p0, null, a, false);
26960      a.o = b;
26961      subject.push(a);
26962      clip.push(b);
26963      a = new d3_geo_clipPolygonIntersection(p1, segment, null, false);
26964      b = new d3_geo_clipPolygonIntersection(p1, null, a, true);
26965      a.o = b;
26966      subject.push(a);
26967      clip.push(b);
26968    });
26969    clip.sort(compare);
26970    d3_geo_clipPolygonLinkCircular(subject);
26971    d3_geo_clipPolygonLinkCircular(clip);
26972    if (!subject.length) return;
26973    for (var i = 0, entry = clipStartInside, n = clip.length; i < n; ++i) {
26974      clip[i].e = entry = !entry;
26975    }
26976    var start = subject[0], points, point;
26977    while (1) {
26978      var current = start, isSubject = true;
26979      while (current.v) if ((current = current.n) === start) return;
26980      points = current.z;
26981      listener.lineStart();
26982      do {
26983        current.v = current.o.v = true;
26984        if (current.e) {
26985          if (isSubject) {
26986            for (var i = 0, n = points.length; i < n; ++i) listener.point((point = points[i])[0], point[1]);
26987          } else {
26988            interpolate(current.x, current.n.x, 1, listener);
26989          }
26990          current = current.n;
26991        } else {
26992          if (isSubject) {
26993            points = current.p.z;
26994            for (var i = points.length - 1; i >= 0; --i) listener.point((point = points[i])[0], point[1]);
26995          } else {
26996            interpolate(current.x, current.p.x, -1, listener);
26997          }
26998          current = current.p;
26999        }
27000        current = current.o;
27001        points = current.z;
27002        isSubject = !isSubject;
27003      } while (!current.v);
27004      listener.lineEnd();
27005    }
27006  }
27007  function d3_geo_clipPolygonLinkCircular(array) {
27008    if (!(n = array.length)) return;
27009    var n, i = 0, a = array[0], b;
27010    while (++i < n) {
27011      a.n = b = array[i];
27012      b.p = a;
27013      a = b;
27014    }
27015    a.n = b = array[0];
27016    b.p = a;
27017  }
27018  function d3_geo_clipPolygonIntersection(point, points, other, entry) {
27019    this.x = point;
27020    this.z = points;
27021    this.o = other;
27022    this.e = entry;
27023    this.v = false;
27024    this.n = this.p = null;
27025  }
27026  function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) {
27027    return function(rotate, listener) {
27028      var line = clipLine(listener), rotatedClipStart = rotate.invert(clipStart[0], clipStart[1]);
27029      var clip = {
27030        point: point,
27031        lineStart: lineStart,
27032        lineEnd: lineEnd,
27033        polygonStart: function() {
27034          clip.point = pointRing;
27035          clip.lineStart = ringStart;
27036          clip.lineEnd = ringEnd;
27037          segments = [];
27038          polygon = [];
27039        },
27040        polygonEnd: function() {
27041          clip.point = point;
27042          clip.lineStart = lineStart;
27043          clip.lineEnd = lineEnd;
27044          segments = d3.merge(segments);
27045          var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon);
27046          if (segments.length) {
27047            if (!polygonStarted) listener.polygonStart(), polygonStarted = true;
27048            d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener);
27049          } else if (clipStartInside) {
27050            if (!polygonStarted) listener.polygonStart(), polygonStarted = true;
27051            listener.lineStart();
27052            interpolate(null, null, 1, listener);
27053            listener.lineEnd();
27054          }
vendor: 5,682 bytes, lines 27055-27218
27055          if (polygonStarted) listener.polygonEnd(), polygonStarted = false;
27056          segments = polygon = null;
27057        },
27058        sphere: function() {
27059          listener.polygonStart();
27060          listener.lineStart();
27061          interpolate(null, null, 1, listener);
27062          listener.lineEnd();
27063          listener.polygonEnd();
27064        }
27065      };
27066      function point(λ, φ) {
27067        var point = rotate(λ, φ);
27068        if (pointVisible(λ = point[0], φ = point[1])) listener.point(λ, φ);
27069      }
27070      function pointLine(λ, φ) {
27071        var point = rotate(λ, φ);
27072        line.point(point[0], point[1]);
27073      }
27074      function lineStart() {
27075        clip.point = pointLine;
27076        line.lineStart();
27077      }
27078      function lineEnd() {
27079        clip.point = point;
27080        line.lineEnd();
27081      }
27082      var segments;
27083      var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygonStarted = false, polygon, ring;
27084      function pointRing(λ, φ) {
27085        ring.push([ λ, φ ]);
27086        var point = rotate(λ, φ);
27087        ringListener.point(point[0], point[1]);
27088      }
27089      function ringStart() {
27090        ringListener.lineStart();
27091        ring = [];
27092      }
27093      function ringEnd() {
27094        pointRing(ring[0][0], ring[0][1]);
27095        ringListener.lineEnd();
27096        var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length;
27097        ring.pop();
27098        polygon.push(ring);
27099        ring = null;
27100        if (!n) return;
27101        if (clean & 1) {
27102          segment = ringSegments[0];
27103          var n = segment.length - 1, i = -1, point;
27104          if (n > 0) {
27105            if (!polygonStarted) listener.polygonStart(), polygonStarted = true;
27106            listener.lineStart();
27107            while (++i < n) listener.point((point = segment[i])[0], point[1]);
27108            listener.lineEnd();
27109          }
27110          return;
27111        }
27112        if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
27113        segments.push(ringSegments.filter(d3_geo_clipSegmentLength1));
27114      }
27115      return clip;
27116    };
27117  }
27118  function d3_geo_clipSegmentLength1(segment) {
27119    return segment.length > 1;
27120  }
27121  function d3_geo_clipBufferListener() {
27122    var lines = [], line;
27123    return {
27124      lineStart: function() {
27125        lines.push(line = []);
27126      },
27127      point: function(λ, φ) {
27128        line.push([ λ, φ ]);
27129      },
27130      lineEnd: d3_noop,
27131      buffer: function() {
27132        var buffer = lines;
27133        lines = [];
27134        line = null;
27135        return buffer;
27136      },
27137      rejoin: function() {
27138        if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));
27139      }
27140    };
27141  }
27142  function d3_geo_clipSort(a, b) {
27143    return ((a = a.x)[0] < 0 ? a[1] - halfπ - ε : halfπ - a[1]) - ((b = b.x)[0] < 0 ? b[1] - halfπ - ε : halfπ - b[1]);
27144  }
27145  var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate, [ -π, -π / 2 ]);
27146  function d3_geo_clipAntimeridianLine(listener) {
27147    var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean;
27148    return {
27149      lineStart: function() {
27150        listener.lineStart();
27151        clean = 1;
27152      },
27153      point: function(λ1, φ1) {
27154        var sλ1 = λ1 > 0 ? π : -π, dλ = abs(λ1 - λ0);
27155        if (abs(dλ - π) < ε) {
27156          listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? halfπ : -halfπ);
27157          listener.point(sλ0, φ0);
27158          listener.lineEnd();
27159          listener.lineStart();
27160          listener.point(sλ1, φ0);
27161          listener.point(λ1, φ0);
27162          clean = 0;
27163        } else if (sλ0 !== sλ1 && dλ >= π) {
27164          if (abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε;
27165          if (abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε;
27166          φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1);
27167          listener.point(sλ0, φ0);
27168          listener.lineEnd();
27169          listener.lineStart();
27170          listener.point(sλ1, φ0);
27171          clean = 0;
27172        }
27173        listener.point(λ0 = λ1, φ0 = φ1);
27174        sλ0 = sλ1;
27175      },
27176      lineEnd: function() {
27177        listener.lineEnd();
27178        λ0 = φ0 = NaN;
27179      },
27180      clean: function() {
27181        return 2 - clean;
27182      }
27183    };
27184  }
27185  function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) {
27186    var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1);
27187    return abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2;
27188  }
27189  function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) {
27190    var φ;
27191    if (from == null) {
27192      φ = direction * halfπ;
27193      listener.point(-π, φ);
27194      listener.point(0, φ);
27195      listener.point(π, φ);
27196      listener.point(π, 0);
27197      listener.point(π, -φ);
27198      listener.point(0, -φ);
27199      listener.point(-π, -φ);
27200      listener.point(-π, 0);
27201      listener.point(-π, φ);
27202    } else if (abs(from[0] - to[0]) > ε) {
27203      var s = from[0] < to[0] ? π : -π;
27204      φ = direction * s / 2;
27205      listener.point(-s, φ);
27206      listener.point(0, φ);
27207      listener.point(s, φ);
27208    } else {
27209      listener.point(to[0], to[1]);
27210    }
27211  }
27212  function d3_geo_pointInPolygon(point, polygon) {
27213    var meridian = point[0], parallel = point[1], meridianNormal = [ Math.sin(meridian), -Math.cos(meridian), 0 ], polarAngle = 0, winding = 0;
27214    d3_geo_areaRingSum.reset();
27215    for (var i = 0, n = polygon.length; i < n; ++i) {
27216      var ring = polygon[i], m = ring.length;
27217      if (!m) continue;
27218      var point0 = ring[0], λ0 = point0[0], φ0 = point0[1] / 2 + π / 4, sinφ0 
vendor: 6,958 bytes, lines 27218-27395
27218= Math.sin(φ0), cosφ0 = Math.cos(φ0), j = 1;
27219      while (true) {
27220        if (j === m) j = 0;
27221        point = ring[j];
27222        var λ = point[0], φ = point[1] / 2 + π / 4, sinφ = Math.sin(φ), cosφ = Math.cos(φ), dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, antimeridian = adλ > π, k = sinφ0 * sinφ;
27223        d3_geo_areaRingSum.add(Math.atan2(k * sdλ * Math.sin(adλ), cosφ0 * cosφ + k * Math.cos(adλ)));
27224        polarAngle += antimeridian ? dλ + sdλ * τ : dλ;
27225        if (antimeridian ^ λ0 >= meridian ^ λ >= meridian) {
27226          var arc = d3_geo_cartesianCross(d3_geo_cartesian(point0), d3_geo_cartesian(point));
27227          d3_geo_cartesianNormalize(arc);
27228          var intersection = d3_geo_cartesianCross(meridianNormal, arc);
27229          d3_geo_cartesianNormalize(intersection);
27230          var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]);
27231          if (parallel > φarc || parallel === φarc && (arc[0] || arc[1])) {
27232            winding += antimeridian ^ dλ >= 0 ? 1 : -1;
27233          }
27234        }
27235        if (!j++) break;
27236        λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point;
27237      }
27238    }
27239    return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < 0) ^ winding & 1;
27240  }
27241  function d3_geo_clipCircle(radius) {
27242    var cr = Math.cos(radius), smallRadius = cr > 0, notHemisphere = abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians);
27243    return d3_geo_clip(visible, clipLine, interpolate, smallRadius ? [ 0, -radius ] : [ -π, radius - π ]);
27244    function visible(λ, φ) {
27245      return Math.cos(λ) * Math.cos(φ) > cr;
27246    }
27247    function clipLine(listener) {
27248      var point0, c0, v0, v00, clean;
27249      return {
27250        lineStart: function() {
27251          v00 = v0 = false;
27252          clean = 1;
27253        },
27254        point: function(λ, φ) {
27255          var point1 = [ λ, φ ], point2, v = visible(λ, φ), c = smallRadius ? v ? 0 : code(λ, φ) : v ? code(λ + (λ < 0 ? π : -π), φ) : 0;
27256          if (!point0 && (v00 = v0 = v)) listener.lineStart();
27257          if (v !== v0) {
27258            point2 = intersect(point0, point1);
27259            if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) {
27260              point1[0] += ε;
27261              point1[1] += ε;
27262              v = visible(point1[0], point1[1]);
27263            }
27264          }
27265          if (v !== v0) {
27266            clean = 0;
27267            if (v) {
27268              listener.lineStart();
27269              point2 = intersect(point1, point0);
27270              listener.point(point2[0], point2[1]);
27271            } else {
27272              point2 = intersect(point0, point1);
27273              listener.point(point2[0], point2[1]);
27274              listener.lineEnd();
27275            }
27276            point0 = point2;
27277          } else if (notHemisphere && point0 && smallRadius ^ v) {
27278            var t;
27279            if (!(c & c0) && (t = intersect(point1, point0, true))) {
27280              clean = 0;
27281              if (smallRadius) {
27282                listener.lineStart();
27283                listener.point(t[0][0], t[0][1]);
27284                listener.point(t[1][0], t[1][1]);
27285                listener.lineEnd();
27286              } else {
27287                listener.point(t[1][0], t[1][1]);
27288                listener.lineEnd();
27289                listener.lineStart();
27290                listener.point(t[0][0], t[0][1]);
27291              }
27292            }
27293          }
27294          if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) {
27295            listener.point(point1[0], point1[1]);
27296          }
27297          point0 = point1, v0 = v, c0 = c;
27298        },
27299        lineEnd: function() {
27300          if (v0) listener.lineEnd();
27301          point0 = null;
27302        },
27303        clean: function() {
27304          return clean | (v00 && v0) << 1;
27305        }
27306      };
27307    }
27308    function intersect(a, b, two) {
27309      var pa = d3_geo_cartesian(a), pb = d3_geo_cartesian(b);
27310      var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2;
27311      if (!determinant) return !two && a;
27312      var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2);
27313      d3_geo_cartesianAdd(A, B);
27314      var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1);
27315      if (t2 < 0) return;
27316      var t = Math.sqrt(t2), q = d3_geo_cartesianScale(u, (-w - t) / uu);
27317      d3_geo_cartesianAdd(q, A);
27318      q = d3_geo_spherical(q);
27319      if (!two) return q;
27320      var λ0 = a[0], λ1 = b[0], φ0 = a[1], φ1 = b[1], z;
27321      if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z;
27322      var δλ = λ1 - λ0, polar = abs(δλ - π) < ε, meridian = polar || δλ < ε;
27323      if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z;
27324      if (meridian ? polar ? φ0 + φ1 > 0 ^ q[1] < (abs(q[0] - λ0) < ε ? φ0 : φ1) : φ0 <= q[1] && q[1] <= φ1 : δλ > π ^ (λ0 <= q[0] && q[0] <= λ1)) {
27325        var q1 = d3_geo_cartesianScale(u, (-w + t) / uu);
27326        d3_geo_cartesianAdd(q1, A);
27327        return [ q, d3_geo_spherical(q1) ];
27328      }
27329    }
27330    function code(λ, φ) {
27331      var r = smallRadius ? radius : π - radius, code = 0;
27332      if (λ < -r) code |= 1; else if (λ > r) code |= 2;
27333      if (φ < -r) code |= 4; else if (φ > r) code |= 8;
27334      return code;
27335    }
27336  }
27337  function d3_geom_clipLine(x0, y0, x1, y1) {
27338    return function(line) {
27339      var a = line.a, b = line.b, ax = a.x, ay = a.y, bx = b.x, by = b.y, t0 = 0, t1 = 1, dx = bx - ax, dy = by - ay, r;
27340      r = x0 - ax;
27341      if (!dx && r > 0) return;
27342      r /= dx;
27343      if (dx < 0) {
27344        if (r < t0) return;
27345        if (r < t1) t1 = r;
27346      } else if (dx > 0) {
27347        if (r > t1) return;
27348        if (r > t0) t0 = r;
27349      }
27350      r = x1 - ax;
27351      if (!dx && r < 0) return;
27352      r /= dx;
27353      if (dx < 0) {
27354        if (r > t1) return;
27355        if (r > t0) t0 = r;
27356      } else if (dx > 0) {
27357        if (r < t0) return;
27358        if (r < t1) t1 = r;
27359      }
27360      r = y0 - ay;
27361      if (!dy && r > 0) return;
27362      r /= dy;
27363      if (dy < 0) {
27364        if (r < t0) return;
27365        if (r < t1) t1 = r;
27366      } else if (dy > 0) {
27367        if (r > t1) return;
27368        if (r > t0) t0 = r;
27369      }
27370      r = y1 - ay;
27371      if (!dy && r < 0) return;
27372      r /= dy;
27373      if (dy < 0) {
27374        if (r > t1) return;
27375        if (r > t0) t0 = r;
27376      } else if (dy > 0) {
27377        if (r < t0) return;
27378        if (r < t1) t1 = r;
27379      }
27380      if (t0 > 0) line.a = {
27381        x: ax + t0 * dx,
27382        y: ay + t0 * dy
27383      };
27384      if (t1 < 1) line.b = {
27385        x: ax + t1 * dx,
27386        y: ay + t1 * dy
27387      };
27388      return line;
27389    };
27390  }
27391  var d3_geo_clipExtentMAX = 1e9;
27392  d3.geo.clipExtent = function() {
27393    var x0, y0, x1, y1, stream, clip, clipExtent = {
27394      stream: function(output) {
27395        if (stream) stream.valid = false;
27396        stream = clip(output);
27397        stream.valid = true;
27398        return stream;
27399      },
27400      extent: function(_) {
27401        if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ];
27402        clip = d3_geo_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]);
27403        if (stream) stream.valid = false, stream = null;
27404        return clipExtent;
27405      }
27406    };
27407    return clipExtent.extent([ [ 0, 0 ], [ 960, 500 ] ]);
27408  };
27409  function d3_geo_clipExtent(x0, y0, x1, y1) {
27410    return function(listener) {
27411      var listener_ = listener, bufferListener = d3_geo_clipBufferListener(), clipLine = d3_geom_clipLine(x0, y0, x1, y1), segments, polygon, ring;
27412      var clip = {
27413        point: point,
27414        lineStart: lineStart,
27415        lineEnd: lineEnd,
27416        polygonStart: function() {
27417          listener = bufferListener;
27418          segments = [];
27419          polygon = [];
27420          clean = true;
27421        },
27422        polygonEnd: function() {
27423          listener = listener_;
27424          segments = d3.merge(segments);
27425          var clipStartInside = insidePolygon([ x0, y1 ]), inside = clean && clipStartInside, visible = segments.length;
27426          if (inside || visible) {
27427            listener.polygonStart();
27428            if (inside) {
27429              listener.lineStart();
27430              interpolate(null, null, 1, listener);
27431              listener.lineEnd();
27432            }
27433            if (visible) {
27434              d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener);
27435            }
27436            listener.polygonEnd();
27437          }
27438          segments = polygon = ring = null;
27439        }
27440      };
27441      function insidePolygon(p) {
27442        var wn = 0, n = polygon.length, y = p[1];
27443        for (var i = 0; i < n; ++i) {
27444          for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) {
27445            b = v[j];
27446            if (a[1] <= y) {
27447              if (b[1] > y && d3_cross2d(a, b, p) > 0) ++wn;
27448            } else {
27449              if (b[1] <= y && d3_cross2d(a, b, p) < 0) --wn;
27450            }
27451            a = b;
27452          }
27453        }
27454        return wn !== 0;
27455      }
27456      function interpolate(from, to, direction, listener) {
27457        var a = 0, a1 = 0;
27458        if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) {
27459          do {
27460            listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);
27461          } while ((a = (a + direction + 4) % 4) !== a1);
27462        } else {
27463          listener.point(to[0], to[1]);
27464        }
27465      }
27466      function pointVisible(x, y) {
27467        return x0 <= x && x <= x1 && y0 <= y && y <= y1;
27468      }
27469      function point(x, y) {
27470        if (pointVisible(x, y)) listener.point(x, y);
27471      }
27472      var x__, y__, v__, x_, y_, v_, first, clean;
27473      function lineStart() {
27474        clip.point = linePoint;
27475        if (polygon) polygon.push(ring = []);
27476        first = true;
27477        v_ = false;
27478        x_ = y_ = NaN;
27479      }
27480      function lineEnd() {
27481        if (segments) {
27482          linePoint(x__, y__);
27483          if (v__ && v_) bufferListener.rejoin();
27484          segments.push(bufferListener.buffer());
27485        }
27486        clip.point = point;
27487        if (v_) listener.lineEnd();
27488      }
27489      function linePoint(x, y) {
27490        x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x));
27491        y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y));
27492        var v = pointVisible(x, y);
27493        if (polygon) ring.push([ x, y ]);
27494        if (first) {
27495          x__ = x, y__ = y, v__ = v;
27496          first = false;
27497          if (v) {
27498            listener.lineStart();
27499            listener.point(x, y);
27500          }
27501        } else {
27502          if (v && v_) listener.point(x, y); else {
27503            var l = {
27504              a: {
27505                x: x_,
27506                y: y_
27507              },
27508              b: {
27509                x: x,
27510                y: y
27511              }
27512            };
27513            if (clipLine(l)) {
27514              if (!v_) {
27515                listener.lineStart();
27516                listener.point(l.a.x, l.a.y);
27517              }
27518              listener.point(l.b.x, l.b.y);
27519              if (!v) listener.lineEnd();
27520              clean = false;
27521            } else if (v) {
27522              listener.lineStart();
27523              listener.point(x, y);
27524              clean = false;
27525            }
27526          }
27527        }
27528        x_ = x, y_ = y, v_ = v;
27529      }
27530      return clip;
27531    };
27532    function corner(p, direction) {
27533      return abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2;
27534    }
27535    function compare(a, b) {
27536      return comparePoints(a.x, b.x);
27537    }
27538    function comparePoints(a, b) {
27539      var ca = corner(a, 1), cb = corner(b, 1);
27540      return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0];
27541    }
27542  }
27543  function d3_geo_conic(projectAt) {
27544    var φ0 = 0, φ1 = π / 3, m = d3_geo_projectionMutator(projectAt), p = m(φ0, φ1);
27545    p.parallels = function(_) {
27546      if (!arguments.length) return [ φ0 / π * 180, φ1 / π * 180 ];
27547      return m(φ0 = _[0] * π / 180, φ1 = _[1] * π / 180);
27548    };
27549    return p;
27550  }
27551  function d3_geo_conicEqualArea(φ0, φ1) {
27552    var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), ρ0 = Math.sqrt(C) / n;
27553    function forward(λ, φ) {
27554      var ρ = Math.sqrt(C - 2 * n * Math.sin(φ)) / n;
27555      return [ ρ * Math.sin(λ *= n), ρ0 - ρ * Math.cos(λ) ];
27556    }
27557    forward.invert = function(x, y) {
27558      var ρ0_y = ρ0 - y;
27559      return [ Math.atan2(x, ρ0_y) / n, d3_asin((C - (x * x + ρ0_y * ρ0_y) * n * n) / (2 * n)) ];
27560    };
27561    return forward;
27562  }
27563  (d3.geo.conicEqualArea = function() {
27564    return d3_geo_conic(d3_geo_conicEqualArea);
27565  }).raw = d3_geo_conicEqualArea;
27566  d3.geo.albers = function() {
27567    return d3.geo.conicEqualArea().rotate([ 96, 0 ]).center([ -.6, 38.7 ]).parallels([ 29.5, 45.5 ]).scale(1070);
27568  };
27569  d3.geo.albersUsa = function() {
27570    var lower48 = d3.geo.albers();
27571    var alaska = d3.geo.conicEqualArea().rotate([ 154, 0 ]).center([ -2, 58.5 ]).parallels([ 55, 65 ]);
27572    var hawaii = d3.geo.conicEqualArea().rotate([ 157, 0 ]).center([ -3, 19.9 ]).parallels([ 8, 18 ]);
27573    var point, pointStream = {
27574      point: function(x, y) {
27575        point = [ x, y ];
27576      }
27577    }, lower48Point, alaskaPoint, hawaiiPoint;
27578    function albersUsa(coordinates) {
27579      var x = coordinates[0], y = coordinates[1];
27580      point = null;
27581      (lower48Point(x, y), point) || (alaskaPoint(x, y), point) || hawaiiPoint(x, y);
27582      return point;
27583    }
27584    albersUsa.invert = function(coordinates) {
27585      var k = lower48.scale(), t = lower48.translate(), x = (coordinates[0] - t[0]) / k, y = (coordinates[1] - t[1]) / k;
27586      return (y >= .12 && y < .234 && x >= -.425 && x < -.214 ? alaska : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii : lower48).invert(coordinates);
27587    };
27588    albersUsa.stream = function(stream) {
27589      var lower48Stream = lower48.stream(stream), alaskaStream = alaska.stream(stream), hawaiiStream = hawaii.stream(stream);
27590      return {
27591        point: function(x, y) {
27592          lower48Stream.point(x, y);
27593          alaskaStream.point(x, y);
27594          hawaiiStream.point(x, y);
27595        },
27596        sphere: function() {
27597          lower48Stream.sphere();
27598          alaskaStream.sphere();
27599          hawaiiStream.sphere();
27600        },
27601        lineStart: function() {
27602          lower48Stream.lineStart();
27603          alaskaStream.lineStart();
27604          hawaiiStream.lineStart();
27605        },
27606        lineEnd: function() {
27607          lower48Stream.lineEnd();
27608          alaskaStream.lineEnd();
27609          hawaiiStream.lineEnd();
27610        },
27611        polygonStart: function() {
27612          lower48Stream.polygonStart();
27613          alaskaStream.polygonStart();
27614          hawaiiStream.polygonStart();
27615        },
27616        polygonEnd: function() {
27617          lower48Stream.polygonEnd();
27618          alaskaStream.polygonEnd();
27619          hawaiiStream.polygonEnd();
27620        }
27621      };
27622    };
27623    albersUsa.precision = function(_) {
27624      if (!arguments.length) return lower48.precision();
27625      lower48.precision(_);
27626      alaska.precision(_);
27627      hawaii.precision(_);
27628      return albersUsa;
27629    };
27630    albersUsa.scale = function(_) {
27631      if (!arguments.length) return lower48.scale();
27632      lower48.scale(_);
27633      alaska.scale(_ * .35);
27634      hawaii.scale(_);
27635      return albersUsa.translate(lower48.translate());
27636    };
27637    albersUsa.translate = function(_) {
27638      if (!arguments.length) return lower48.translate();
27639      var k = lower48.scale(), x = +_[0], y = +_[1];
27640      lower48Point = lower48.translate(_).clipExtent([ [ x - .455 * k, y - .238 * k ], [ x + .455 * k, y + .238 * k ] ]).stream(pointStream).point;
27641      alaskaPoint = alaska.translate([ x - .307 * k, y + .201 * k ]).clipExtent([ [ x - .425 * k + ε, y + .12 * k + ε ], [ x - .214 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point;
27642      hawaiiPoint = hawaii.translate([ x - .205 * k, y + .212 * k ]).clipExtent([ [ x - .214 * k + ε, y + .166 * k + ε ], [ x - .115 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point;
27643      return albersUsa;
27644    };
27645    return albersUsa.scale(1070);
27646  };
27647  var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = {
27648    point: d3_noop,
27649    lineStart: d3_noop,
27650    lineEnd: d3_noop,
27651    polygonStart: function() {
27652      d3_geo_pathAreaPolygon = 0;
27653      d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart;
27654    },
27655    polygonEnd: function() {
27656      d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop;
27657      d3_geo_pathAreaSum += abs(d3_geo_pathAreaPolygon / 2);
27658    }
27659  };
27660  function d3_geo_pathAreaRingStart() {
27661    var x00, y00, x0, y0;
27662    d3_geo_pathArea.point = function(x, y) {
27663      d3_geo_pathArea.point = nextPoint;
27664      x00 = x0 = x, y00 = y0 = y;
27665    };
27666    function nextPoint(x, y) {
27667      d3_geo_pathAreaPolygon += y0 * x - x0 * y;
27668      x0 = x, y0 = y;
27669    }
27670    d3_geo_pathArea.lineEnd = function() {
27671      nextPoint(x00, y00);
27672    };
27673  }
27674  var d3_geo_pathBoundsX0, d3_geo_pathBoundsY0, d3_geo_pathBoundsX1, d3_geo_pathBoundsY1;
27675  var d3_geo_pathBounds = {
27676    point: d3_geo_pathBoundsPoint,
27677    lineStart: d3_noop,
27678    lineEnd: d3_noop,
27679    polygonStart: d3_noop,
27680    polygonEnd: d3_noop
27681  };
27682  function d3_geo_pathBoundsPoint(x, y) {
27683    if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x;
27684    if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x;
27685    if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y;
27686    if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y;
27687  }
27688  function d3_geo_pathBuffer() {
27689    var pointCircle = d3_geo_pathBufferCircle(4.5), buffer = [];
27690    var stream = {
27691      point: point,
27692      lineStart: function() {
27693        stream.point = pointLineStart;
27694      },
27695      lineEnd: lineEnd,
27696      polygonStart: function() {
27697        stream.lineEnd = lineEndPolygon;
27698      },
27699      polygonEnd: function() {
27700        stream.lineEnd = lineEnd;
27701        stream.point = point;
27702      },
27703      pointRadius: function(_) {
27704        pointCircle = d3_geo_pathBufferCircle(_);
27705        return stream;
27706      },
27707      result: function() {
27708        if (buffer.length) {
27709          var result = buffer.join("");
27710          buffer = [];
27711          return result;
27712        }
27713      }
27714    };
27715    function point(x, y) {
27716      buffer.push("M", x, ",", y, pointCircle);
27717    }
27718    function pointLineStart(x, y) {
27719      buffer.push("M", x, ",", y);
27720      stream.point = pointLine;
27721    }
27722    function pointLine(x, y) {
27723      buffer.push("L", x, ",", y);
27724    }
27725    function lineEnd() {
27726      stream.point = point;
27727    }
27728    function lineEndPolygon() {
27729      buffer.push("Z");
27730    }
27731    return stream;
27732  }
27733  function d3_geo_pathBufferCircle(radius) {
27734    return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z";
27735  }
27736  var d3_geo_pathCentroid = {
27737    point: d3_geo_pathCentroidPoint,
27738    lineStart: d3_geo_pathCentroidLineStart,
27739    lineEnd: d3_geo_pathCentroidLineEnd,
27740    polygonStart: function() {
27741      d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart;
27742    },
27743    polygonEnd: function() {
27744      d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint;
27745      d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart;
27746      d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd;
27747    }
27748  };
27749  function d3_geo_pathCentroidPoint(x, y) {
27750    d3_geo_centroidX0 += x;
27751    d3_geo_centroidY0 += y;
27752    ++d3_geo_centroidZ0;
27753  }
27754  function d3_geo_pathCentroidLineStart() {
27755    var x0, y0;
27756    d3_geo_pathCentroid.point = function(x, y) {
27757      d3_geo_pathCentroid.point = nextPoint;
27758      d3_geo_pathCentroidPoint(x0 = x, y0 = y);
27759    };
27760    function nextPoint(x, y) {
27761      var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy);
27762      d3_geo_centroidX1 += z * (x0 + x) / 2;
27763      d3_geo_centroidY1 += z * (y0 + y) / 2;
27764      d3_geo_centroidZ1 += z;
27765      d3_geo_pathCentroidPoint(x0 = x, y0 = y);
27766    }
27767  }
27768  function d3_geo_pathCentroidLineEnd() {
27769    d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint;
27770  }
27771  function d3_geo_pathCentroidRingStart() {
27772    var x00, y00, x0, y0;
27773    d3_geo_pathCentroid.point = function(x, y) {
27774      d3_geo_pathCentroid.point = nextPoint;
27775      d3_geo_pathCentroidPoint(x00 = x0 = x, y00 = y0 = y);
27776    };
27777    function nextPoint(x, y) {
27778      var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy);
27779      d3_geo_centroidX1 += z * (x0 + x) / 2;
27780      d3_geo_centroidY1 += z * (y0 + y) / 2;
27781      d3_geo_centroidZ1 += z;
27782      z = y0 * x - x0 * y;
27783      d3_geo_centroidX2 += z * (x0 + x);
27784      d3_geo_centroidY2 += z * (y0 + y);
27785      d3_geo_centroidZ2 += z * 3;
27786      d3_geo_pathCentroidPoint(x0 = x, y0 = y);
27787    }
27788    d3_geo_pathCentroid.lineEnd = function() {
27789      nextPoint(x00, y00);
27790    };
27791  }
27792  function d3_geo_pathContext(context) {
27793    var pointRadius = 4.5;
27794    var stream = {
27795      point: point,
27796      lineStart: function() {
27797        stream.point = pointLineStart;
27798      },
27799      lineEnd: lineEnd,
27800      polygonStart: function() {
27801        stream.lineEnd = lineEndPolygon;
27802      },
27803      polygonEnd: function() {
27804        stream.lineEnd = lineEnd;
27805        stream.point = point;
27806      },
27807      pointRadius: function(_) {
27808        pointRadius = _;
27809        return stream;
27810      },
27811      result: d3_noop
27812    };
27813    function point(x, y) {
27814      context.moveTo(x + pointRadius, y);
27815      context.arc(x, y, pointRadius, 0, τ);
27816    }
27817    function pointLineStart(x, y) {
27818      context.moveTo(x, y);
27819      stream.point = pointLine;
27820    }
27821    function pointLine(x, y) {
27822      context.lineTo(x, y);
27823    }
27824    function lineEnd() {
27825      stream.point = point;
27826    }
27827    function lineEndPolygon() {
27828      context.closePath();
27829    }
27830    return stream;
27831  }
27832  function d3_geo_resample(project) {
27833    var δ2 = .5, cosMinDistance = Math.cos(30 * d3_radians), maxDepth = 16;
27834    function resample(stream) {
27835      return (maxDepth ? resampleRecursive : resampleNone)(stream);
27836    }
27837    function resampleNone(stream) {
27838      return d3_geo_transformPoint(stream, function(x, y) {
27839        x = project(x, y);
27840        stream.point(x[0], x[1]);
27841      });
27842    }
27843    function resampleRecursive(stream) {
27844      var λ00, φ00, x00, y00, a00, b00, c00, λ0, x0, y0, a0, b0, c0;
27845      var resample = {
27846        point: point,
27847        lineStart: lineStart,
27848        lineEnd: lineEnd,
27849        polygonStart: function() {
27850          stream.polygonStart();
27851          resample.lineStart = ringStart;
27852        },
27853        polygonEnd: function() {
27854          stream.polygonEnd();
27855          resample.lineStart = lineStart;
27856        }
27857      };
27858      function point(x, y) {
27859        x = project(x, y);
27860        stream.point(x[0], x[1]);
27861      }
27862      function lineStart() {
27863        x0 = NaN;
27864        resample.point = linePoint;
27865        stream.lineStart();
27866      }
27867      function linePoint(λ, φ) {
27868        var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ);
27869        resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);
27870        stream.point(x0, y0);
27871      }
27872      function lineEnd() {
27873        resample.point = point;
27874        stream.lineEnd();
27875      }
27876      function ringStart() {
27877        lineStart();
27878        resample.point = ringPoint;
27879        resample.lineEnd = ringEnd;
27880      }
27881      function ringPoint(λ, φ) {
27882        linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
27883        resample.point = linePoint;
27884      }
27885      function ringEnd() {
27886        resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream);
27887        resample.lineEnd = lineEnd;
27888        lineEnd();
27889      }
27890      return resample;
27891    }
27892    function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) {
27893      var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy;
27894      if (d2 > 4 * δ2 && depth--) {
27895        var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = abs(abs(c) - 1) < ε || abs(λ0 - λ1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2;
27896        if (dz * dz / d2 > δ2 || abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) {
27897          resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream);
27898          stream.point(x2, y2);
27899          resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream);
27900        }
27901      }
27902    }
27903    resample.precision = function(_) {
27904      if (!arguments.length) return Math.sqrt(δ2);
27905      maxDepth = (δ2 = _ * _) > 0 && 16;
27906      return resample;
27907    };
27908    return resample;
27909  }
27910  d3.geo.path = function() {
27911    var pointRadius = 4.5, projection, context, projectStream, contextStream, cacheStream;
27912    function path(object) {
27913      if (object) {
27914        if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments));
27915        if (!cacheStream || !cacheStream.valid) cacheStream = projectStream(contextStream);
27916        d3.geo.stream(object, cacheStream);
27917      }
27918      return contextStream.result();
27919    }
27920    path.area = function(object) {
27921      d3_geo_pathAreaSum = 0;
27922      d3.geo.stream(object, projectStream(d3_geo_pathArea));
27923      return d3_geo_pathAreaSum;
27924    };
27925    path.centroid = function(object) {
27926      d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0;
27927      d3.geo.stream(object, projectStream(d3_geo_pathCentroid));
27928      return d3_geo_centroidZ2 ? [ d3_geo_centroidX2 / d3_geo_centroidZ2, d3_geo_centroidY2 / d3_geo_centroidZ2 ] : d3_geo_centroidZ1 ? [ d3_geo_centroidX1 / d3_geo_centroidZ1, d3_geo_centroidY1 / d3_geo_centroidZ1 ] : d3_geo_centroidZ0 ? [ d3_geo_centroidX0 / d3_geo_centroidZ0, d3_geo_centroidY0 / d3_geo_centroidZ0 ] : [ NaN, NaN ];
27929    };
27930    path.bounds = function(object) {
27931      d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity);
27932      d3.geo.stream(object, projectStream(d3_geo_pathBounds));
27933      return [ [ d3_geo_pathBoundsX0, d3_geo_pathBoundsY0 ], [ d3_geo_pathBoundsX1, d3_geo_pathBoundsY1 ] ];
27934    };
27935    path.projection = function(_) {
27936      if (!arguments.length) return projection;
27937      projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity;
27938      return reset();
27939    };
27940    path.context = function(_) {
27941      if (!arguments.length) return context;
27942      contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_);
27943      if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius);
27944      return reset();
27945    };
27946    path.pointRadius = function(_) {
27947      if (!arguments.length) return pointRadius;
27948      pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_);
27949      return path;
27950    };
27951    function reset() {
27952      cacheStream = null;
27953      return path;
27954    }
27955    return path.projection(d3.geo.albersUsa()).context(null);
27956  };
27957  function d3_geo_pathProjectStream(project) {
27958    var resample = d3_geo_resample(function(x, y) {
27959      return project([ x * d3_degrees, y * d3_degrees ]);
27960    });
27961    return function(stream) {
27962      return d3_geo_projectionRadians(resample(stream));
27963    };
27964  }
27965  d3.geo.transform = function(methods) {
27966    return {
27967      stream: function(stream) {
27968        var transform = new d3_geo_transform(stream);
27969        for (var k in methods) transform[k] = methods[k];
27970        return transform;
27971      }
27972    };
27973  };
27974  function d3_geo_transform(stream) {
27975    this.stream = stream;
27976  }
27977  d3_geo_transform.prototype = {
27978    point: function(x, y) {
27979      this.stream.point(x, y);
27980    },
27981    sphere: function() {
27982      this.stream.sphere();
27983    },
27984    lineStart: function() {
27985      this.stream.lineStart();
27986    },
27987    lineEnd: function() {
27988      this.stream.lineEnd();
27989    },
27990    polygonStart: function() {
27991      this.stream.polygonStart();
27992    },
27993    polygonEnd: function() {
27994      this.stream.polygonEnd();
27995    }
27996  };
27997  function d3_geo_transformPoint(stream, point) {
27998    return {
27999      point: point,
28000      sphere: function() {
28001        stream.sphere();
28002      },
28003      lineStart: function() {
28004        stream.lineStart();
28005      },
28006      lineEnd: function() {
28007        stream.lineEnd();
28008      },
28009      polygonStart: function() {
28010        stream.polygonStart();
28011      },
28012      polygonEnd: function() {
28013        stream.polygonEnd();
28014      }
28015    };
28016  }
28017  d3.geo.projection = d3_geo_projection;
28018  d3.geo.projectionMutator = d3_geo_projectionMutator;
28019  function d3_geo_projection(project) {
28020    return d3_geo_projectionMutator(function() {
28021      return project;
28022    })();
28023  }
28024  function d3_geo_projectionMutator(projectAt) {
28025    var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) {
28026      x = project(x, y);
28027      return [ x[0] * k + δx, δy - x[1] * k ];
28028    }), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, preclip = d3_geo_clipAntimeridian, postclip = d3_identity, clipAngle = null, clipExtent = null, stream;
28029    function projection(point) {
28030      point = projectRotate(point[0] * d3_radians, point[1] * d3_radians);
28031      return [ point[0] * k + δx, δy - point[1] * k ];
28032    }
28033    function invert(point) {
28034      point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k);
28035      return point && [ point[0] * d3_degrees, point[1] * d3_degrees ];
28036    }
28037    projection.stream = function(output) {
28038      if (stream) stream.valid = false;
28039      stream = d3_geo_projectionRadians(preclip(rotate, projectResample(postclip(output))));
28040      stream.valid = true;
28041      return stream;
28042    };
28043    projection.clipAngle = function(_) {
28044      if (!arguments.length) return clipAngle;
28045      preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians);
28046      return invalidate();
28047    };
28048    projection.clipExtent = function(_) {
28049      if (!arguments.length) return clipExtent;
28050      clipExtent = _;
28051      postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity;
28052      return invalidate();
28053    };
28054    projection.scale = function(_) {
28055      if (!arguments.length) return k;
28056      k = +_;
28057      return reset();
28058    };
28059    projection.translate = function(_) {
28060      if (!arguments.length) return [ x, y ];
28061      x = +_[0];
28062      y = +_[1];
28063      return reset();
28064    };
28065    projection.center = function(_) {
28066      if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ];
28067      λ = _[0] % 360 * d3_radians;
28068      φ = _[1] % 360 * d3_radians;
28069      return reset();
28070    };
28071    projection.rotate = function(_) {
28072      if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ];
28073      δλ = _[0] % 360 * d3_radians;
28074      δφ = _[1] % 360 * d3_radians;
28075      δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0;
28076      return reset();
28077    };
28078    d3.rebind(projection, projectResample, "precision");
28079    function reset() {
28080      projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project);
28081      var center = project(λ, φ);
28082      δx = x - center[0] * k;
28083      δy = y + center[1] * k;
28084      return invalidate();
28085    }
28086    function invalidate() {
28087      if (stream) stream.valid = false, stream = null;
28088      return projection;
28089    }
28090    return function() {
28091      project = projectAt.apply(this, arguments);
28092      projection.invert = project.invert && invert;
28093      return reset();
28094    };
28095  }
28096  function d3_geo_projectionRadians(stream) {
28097    return d3_geo_transformPoint(stream, function(x, y) {
28098      stream.point(x * d3_radians, y * d3_radians);
28099    });
28100  }
28101  function d3_geo_equirectangular(λ, φ) {
28102    return [ λ, φ ];
28103  }
28104  (d3.geo.equirectangular = function() {
28105    return d3_geo_projection(d3_geo_equirectangular);
28106  }).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular;
28107  d3.geo.rotation = function(rotate) {
28108    rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0);
28109    function forward(coordinates) {
28110      coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians);
28111      return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates;
28112    }
28113    forward.invert = function(coordinates) {
28114      coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians);
28115      return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates;
28116    };
28117    return forward;
28118  };
28119  function d3_geo_identityRotation(λ, φ) {
28120    return [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ];
28121  }
28122  d3_geo_identityRotation.invert = d3_geo_equirectangular;
28123  function d3_geo_rotation(δλ, δφ, δγ) {
28124    return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ
28124), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_identityRotation;
28125  }
28126  function d3_geo_forwardRotationλ(δλ) {
28127    return function(λ, φ) {
28128      return λ += δλ, [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ];
28129    };
28130  }
28131  function d3_geo_rotationλ(δλ) {
28132    var rotation = d3_geo_forwardRotationλ(δλ);
28133    rotation.invert = d3_geo_forwardRotationλ(-δλ);
28134    return rotation;
28135  }
28136  function d3_geo_rotationφγ(δφ, δγ) {
28137    var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ);
28138    function rotation(λ, φ) {
28139      var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ;
28140      return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), d3_asin(k * cosδγ + y * sinδγ) ];
28141    }
28142    rotation.invert = function(λ, φ) {
28143      var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ;
28144      return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), d3_asin(k * cosδφ - x * sinδφ) ];
28145    };
28146    return rotation;
28147  }
28148  d3.geo.circle = function() {
28149    var origin = [ 0, 0 ], angle, precision = 6, interpolate;
28150    function circle() {
28151      var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, ring = [];
28152      interpolate(null, null, 1, {
28153        point: function(x, y) {
28154          ring.push(x = rotate(x, y));
28155          x[0] *= d3_degrees, x[1] *= d3_degrees;
28156        }
28157      });
28158      return {
28159        type: "Polygon",
28160        coordinates: [ ring ]
28161      };
28162    }
28163    circle.origin = function(x) {
28164      if (!arguments.length) return origin;
28165      origin = x;
28166      return circle;
28167    };
28168    circle.angle = function(x) {
28169      if (!arguments.length) return angle;
28170      interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians);
28171      return circle;
28172    };
28173    circle.precision = function(_) {
28174      if (!arguments.length) return precision;
28175      interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians);
28176      return circle;
28177    };
28178    return circle.angle(90);
28179  };
28180  function d3_geo_circleInterpolate(radius, precision) {
28181    var cr = Math.cos(radius), sr = Math.sin(radius);
28182    return function(from, to, direction, listener) {
28183      var step = direction * precision;
28184      if (from != null) {
28185        from = d3_geo_circleAngle(cr, from);
28186        to = d3_geo_circleAngle(cr, to);
28187        if (direction > 0 ? from < to : from > to) from += direction * τ;
28188      } else {
28189        from = radius + direction * τ;
28190        to = radius - .5 * step;
28191      }
28192      for (var point, t = from; direction > 0 ? t > to : t < to; t -= step) {
28193        listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]);
28194      }
28195    };
28196  }
28197  function d3_geo_circleAngle(cr, point) {
28198    var a = d3_geo_cartesian(point);
28199    a[0] -= cr;
28200    d3_geo_cartesianNormalize(a);
28201    var angle = d3_acos(-a[1]);
28202    return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI);
28203  }
28204  d3.geo.distance = function(a, b) {
28205    var Δλ = (b[0] - a[0]) * d3_radians, φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), t;
28206    return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ);
28207  };
28208  d3.geo.graticule = function() {
28209    var x1, x0, X1, X0, y1, y0, Y1, Y0, dx = 10, dy = dx, DX = 90, DY = 360, x, y, X, Y, precision = 2.5;
28210    function graticule() {
28211      return {
28212        type: "MultiLineString",
28213        coordinates: lines()
28214      };
28215    }
28216    function lines() {
28217      return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X).concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) {
28218        return abs(x % DX) > ε;
28219      }).map(x)).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) {
28220        return abs(y % DY) > ε;
28221      }).map(y));
28222    }
28223    graticule.lines = function() {
28224      return lines().map(function(coordinates) {
28225        return {
28226          type: "LineString",
28227          coordinates: coordinates
28228        };
28229      });
28230    };
28231    graticule.outline = function() {
28232      return {
28233        type: "Polygon",
28234        coordinates: [ X(X0).concat(Y(Y1).slice(1), X(X1).reverse().slice(1), Y(Y0).reverse().slice(1)) ]
28235      };
28236    };
28237    graticule.extent = function(_) {
28238      if (!arguments.length) return graticule.minorExtent();
28239      return graticule.majorExtent(_).minorExtent(_);
28240    };
28241    graticule.majorExtent = function(_) {
28242      if (!arguments.length) return [ [ X0, Y0 ], [ X1, Y1 ] ];
28243      X0 = +_[0][0], X1 = +_[1][0];
28244      Y0 = +_[0][1], Y1 = +_[1][1];
28245      if (X0 > X1) _ = X0, X0 = X1, X1 = _;
28246      if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;
28247      return graticule.precision(precision);
28248    };
28249    graticule.minorExtent = function(_) {
28250      if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ];
28251      x0 = +_[0][0], x1 = +_[1][0];
28252      y0 = +_[0][1], y1 = +_[1][1];
28253      if (x0 > x1) _ = x0, x0 = x1, x1 = _;
28254      if (y0 > y1) _ = y0, y0 = y1, y1 = _;
28255      return graticule.precision(precision);
28256    };
28257    graticule.step = function(_) {
28258      if (!arguments.length) return graticule.minorStep();
28259      return graticule.majorStep(_).minorStep(_);
28260    };
28261    graticule.majorStep = function(_) {
28262      if (!arguments.length) return [ DX, DY ];
28263      DX = +_[0], DY = +_[1];
28264      return graticule;
28265    };
28266    graticule.minorStep = function(_) {
28267      if (!arguments.length) return [ dx, dy ];
28268      dx = +_[0], dy = +_[1];
28269      return graticule;
28270    };
28271    graticule.precision = function(_) {
28272      if (!arguments.length) return precision;
28273      precision = +_;
28274      x = d3_geo_graticuleX(y0, y1, 90);
28275      y = d3_geo_graticuleY(x0, x1, precision);
28276      X = d3_geo_graticuleX(Y0, Y1, 90);
28277      Y = d3_geo_graticuleY(X0, X1, precision);
28278      return graticule;
28279    };
28280    return graticule.majorExtent([ [ -180, -90 + ε ], [ 180, 90 - ε ] ]).minorExtent([ [ -180, -80 - ε ], [ 180, 80 + ε ] ]);
28281  };
28282  function d3_geo_graticuleX(y0, y1, dy) {
28283    var y = d3.range(y0, y1 - ε, dy).concat(y1);
28284    return function(x) {
28285      return y.map(function(y) {
28286        return [ x, y ];
28287      });
28288    };
28289  }
28290  function d3_geo_graticuleY(x0, x1, dx) {
28291    var x = d3.range(x0, x1 - ε, dx).concat(x1);
28292    return function(y) {
28293      return x.map(function(x) {
28294        return [ x, y ];
28295      });
28296    };
28297  }
28298  function d3_source(d) {
28299    return d.source;
28300  }
28301  function d3_target(d) {
28302    return d.target;
28303  }
28304  d3.geo.greatArc = function() {
28305    var source = d3_source, source_, target = d3_target, target_;
28306    function greatArc() {
28307      return {
28308        type: "LineString",
28309        coordinates: [ source_ || source.apply(this, arguments), target_ || target.apply(this, arguments) ]
28310      };
28311    }
28312    greatArc.distance = function() {
28313      return d3.geo.distance(source_ || source.apply(this, arguments), target_ || target.apply(this, arguments));
28314    };
28315    greatArc.source = function(_) {
28316      if (!arguments.length) return source;
28317      source = _, source_ = typeof _ === "function" ? null : _;
28318      return greatArc;
28319    };
28320    greatArc.target = function(_) {
28321      if (!arguments.length) return target;
28322      target = _, target_ = typeof _ === "function" ? null : _;
28323      return greatArc;
28324    };
28325    greatArc.precision = function() {
28326      return arguments.length ? greatArc : 0;
28327    };
28328    return greatArc;
28329  };
28330  d3.geo.interpolate = function(source, target) {
28331    return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians);
28332  };
28333  function d3_geo_interpolate(x0, y0, x1, y1) {
28334    var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), k = 1 / Math.sin(d);
28335    var interpolate = d ? function(t) {
28336      var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1;
28337      return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ];
28338    } : function() {
28339      return [ x0 * d3_degrees, y0 * d3_degrees ];
28340    };
28341    interpolate.distance = d;
28342    return interpolate;
28343  }
28344  d3.geo.length = function(object) {
28345    d3_geo_lengthSum = 0;
28346    d3.geo.stream(object, d3_geo_length);
28347    return d3_geo_lengthSum;
28348  };
28349  var d3_geo_lengthSum;
28350  var d3_geo_length = {
28351    sphere: d3_noop,
28352    point: d3_noop,
28353    lineStart: d3_geo_lengthLineStart,
28354    lineEnd: d3_noop,
28355    polygonStart: d3_noop,
28356    polygonEnd: d3_noop
28357  };
28358  function d3_geo_lengthLineStart() {
28359    var λ0, sinφ0, cosφ0;
28360    d3_geo_length.point = function(λ, φ) {
28361      λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ);
28362      d3_geo_length.point = nextPoint;
28363    };
28364    d3_geo_length.lineEnd = function() {
28365      d3_geo_length.point = d3_geo_length.lineEnd = d3_noop;
28366    };
28367    function nextPoint(λ, φ) {
28368      var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t);
28369      d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ);
28370      λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ;
28371    }
28372  }
28373  function d3_geo_azimuthal(scale, angle) {
28374    function azimuthal(λ, φ) {
28375      var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ);
28376      return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ];
28377    }
28378    azimuthal.invert = function(x, y) {
28379      var ρ = Math.sqrt(x * x + y * y), c = angle(ρ), sinc = Math.sin(c), cosc = Math.cos(c);
28380      return [ Math.atan2(x * sinc, ρ * cosc), Math.asin(ρ && y * sinc / ρ) ];
28381    };
28382    return azimuthal;
28383  }
28384  var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) {
28385    return Math.sqrt(2 / (1 + cosλcosφ));
28386  }, function(ρ) {
28387    return 2 * Math.asin(ρ / 2);
28388  });
28389  (d3.geo.azimuthalEqualArea = function() {
28390    return d3_geo_projection(d3_geo_azimuthalEqualArea);
28391  }).raw = d3_geo_azimuthalEqualArea;
28392  var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) {
28393    var c = Math.acos(cosλcosφ);
28394    return c && c / Math.sin(c);
28395  }, d3_identity);
28396  (d3.geo.azimuthalEquidistant = function() {
28397    return d3_geo_projection(d3_geo_azimuthalEquidistant);
28398  }).raw = d3_geo_azimuthalEquidistant;
28399  function d3_geo_conicConformal(φ0, φ1) {
28400    var cosφ0 = Math.cos(φ0), t = function(φ) {
28401      return Math.tan(π / 4 + φ / 2);
28402    }, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n;
28403    if (!n) return d3_geo_mercator;
28404    function forward(λ, φ) {
28405      if (F > 0) {
28406        if (φ < -halfπ + ε) φ = -halfπ + ε;
28407      } else {
28408        if (φ > halfπ - ε) φ = halfπ - ε;
28409      }
28410      var ρ = F / Math.pow(t(φ), n);
28411      return [ ρ * Math.sin(n * λ), F - ρ * Math.cos(n * λ) ];
28412    }
28413    forward.invert = function(x, y) {
28414      var ρ0_y = F - y, ρ = d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y);
28415      return [ Math.atan2(x, ρ0_y) / n, 2 * Math.atan(Math.pow(F / ρ, 1 / n)) - halfπ ];
28416    };
28417    return forward;
28418  }
28419  (d3.geo.conicConformal = function() {
28420    return d3_geo_conic(d3_geo_conicConformal);
28421  }).raw = d3_geo_conicConformal;
28422  function d3_geo_conicEquidistant(φ0, φ1) {
28423    var cosφ0 = Math.cos(φ0), n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), G = cosφ0 / n + φ0;
28424    if (abs(n) < ε) return d3_geo_equirectangular;
28425    function forward(λ, φ) {
28426      var ρ = G - φ;
28427      return [ ρ * Math.sin(n * λ), G - ρ * Math.cos(n * λ) ];
28428    }
28429    forward.invert = function(x, y) {
28430      var ρ0_y = G - y;
28431      return [ Math.atan2(x, ρ0_y) / n, G - d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y) ];
28432    };
28433    return forward;
28434  }
28435  (d3.geo.conicEquidistant = function() {
28436    return d3_geo_conic(d3_geo_conicEquidistant);
28437  }).raw = d3_geo_conicEquidistant;
28438  var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) {
28439    return 1 / cosλcosφ;
28440  }, Math.atan);
28441  (d3.geo.gnomonic = function() {
28442    return d3_geo_projection(d3_geo_gnomonic);
28443  }).raw = d3_geo_gnomonic;
28444  function d3_geo_mercator(λ, φ) {
28445    return [ λ, Math.log(Math.tan(π / 4 + φ / 2)) ];
28446  }
28447  d3_geo_mercator.invert = function(x, y) {
28448    return [ x, 2 * Math.atan(Math.exp(y)) - halfπ ];
28449  };
28450  function d3_geo_mercatorProjection(project) {
28451    var m = d3_geo_projection(project), scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, clipAuto;
28452    m.scale = function() {
28453      var v = scale.apply(m, arguments);
28454      return v === m ? clipAuto ? m.clipExtent(null) : m : v;
28455    };
28456    m.translate = function() {
28457      var v = translate.apply(m, arguments);
28458      return v === m ? clipAuto ? m.clipExtent(null) : m : v;
28459    };
28460    m.clipExtent = function(_) {
28461      var v = clipExtent.apply(m, arguments);
28462      if (v === m) {
28463        if (clipAuto = _ == null) {
28464          var k = π * scale(), t = translate();
28465          clipExtent([ [ t[0] - k, t[1] - k ], [ t[0] + k, t[1] + k ] ]);
28466        }
28467      } else if (clipAuto) {
28468        v = null;
28469      }
28470      return v;
28471    };
28472    return m.clipExtent(null);
28473  }
28474  (d3.geo.mercator = function() {
28475    return d3_geo_mercatorProjection(d3_geo_mercator);
28476  }).raw = d3_geo_mercator;
28477  var d3_geo_orthographic = d3_geo_azimuthal(function() {
28478    return 1;
28479  }, Math.asin);
28480  (d3.geo.orthographic = function() {
28481    return d3_geo_projection(d3_geo_orthographic);
28482  }).raw = d3_geo_orthographic;
28483  var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) {
28484    return 1 / (1 + cosλcosφ);
28485  }, function(ρ) {
28486    return 2 * Math.atan(ρ);
28487  });
28488  (d3.geo.stereographic = function() {
28489    return d3_geo_projection(d3_geo_stereographic);
28490  }).raw = d3_geo_stereographic;
28491  function d3_geo_transverseMercator(λ, φ) {
28492    return [ Math.log(Math.tan(π / 4 + φ / 2)), -λ ];
28493  }
28494  d3_geo_transverseMercator.invert = function(x, y) {
28495    return [ -y, 2 * Math.atan(Math.exp(x)) - halfπ ];
28496  };
28497  (d3.geo.transverseMercator = function() {
28498    var projection = d3_geo_mercatorProjection(d3_geo_transverseMercator), center = projection.center, rotate = projection.rotate;
28499    projection.center = function(_) {
28500      return _ ? center([ -_[1], _[0] ]) : (_ = center(), [ _[1], -_[0] ]);
28501    };
28502    projection.rotate = function(_) {
28503      return _ ? rotate([ _[0], _[1], _.length > 2 ? _[2] + 90 : 90 ]) : (_ = rotate(), 
28504      [ _[0], _[1], _[2] - 90 ]);
28505    };
28506    return rotate([ 0, 0, 90 ]);
28507  }).raw = d3_geo_transverseMercator;
28508  d3.geom = {};
28509  function d3_geom_pointX(d) {
28510    return d[0];
28511  }
28512  function d3_geom_pointY(d) {
28513    return d[1];
28514  }
28515  d3.geom.hull = function(vertices) {
28516    var x = d3_geom_pointX, y = d3_geom_pointY;
28517    if (arguments.length) return hull(vertices);
28518    function hull(data) {
28519      if (data.length < 3) return [];
28520      var fx = d3_functor(x), fy = d3_functor(y), i, n = data.length, points = [], flippedPoints = [];
28521      for (i = 0; i < n; i++) {
28522        points.push([ +fx.call(this, data[i], i), +fy.call(this, data[i], i), i ]);
28523      }
28524      points.sort(d3_geom_hullOrder);
28525      for (i = 0; i < n; i++) flippedPoints.push([ points[i][0], -points[i][1] ]);
28526      var upper = d3_geom_hullUpper(points), lower = d3_geom_hullUpper(flippedPoints);
28527      var skipLeft = lower[0] === upper[0], skipRight = lower[lower.length - 1] === upper[upper.length - 1], pol
vendor: 30,787 bytes, lines 28527-29429
28527ygon = [];
28528      for (i = upper.length - 1; i >= 0; --i) polygon.push(data[points[upper[i]][2]]);
28529      for (i = +skipLeft; i < lower.length - skipRight; ++i) polygon.push(data[points[lower[i]][2]]);
28530      return polygon;
28531    }
28532    hull.x = function(_) {
28533      return arguments.length ? (x = _, hull) : x;
28534    };
28535    hull.y = function(_) {
28536      return arguments.length ? (y = _, hull) : y;
28537    };
28538    return hull;
28539  };
28540  function d3_geom_hullUpper(points) {
28541    var n = points.length, hull = [ 0, 1 ], hs = 2;
28542    for (var i = 2; i < n; i++) {
28543      while (hs > 1 && d3_cross2d(points[hull[hs - 2]], points[hull[hs - 1]], points[i]) <= 0) --hs;
28544      hull[hs++] = i;
28545    }
28546    return hull.slice(0, hs);
28547  }
28548  function d3_geom_hullOrder(a, b) {
28549    return a[0] - b[0] || a[1] - b[1];
28550  }
28551  d3.geom.polygon = function(coordinates) {
28552    d3_subclass(coordinates, d3_geom_polygonPrototype);
28553    return coordinates;
28554  };
28555  var d3_geom_polygonPrototype = d3.geom.polygon.prototype = [];
28556  d3_geom_polygonPrototype.area = function() {
28557    var i = -1, n = this.length, a, b = this[n - 1], area = 0;
28558    while (++i < n) {
28559      a = b;
28560      b = this[i];
28561      area += a[1] * b[0] - a[0] * b[1];
28562    }
28563    return area * .5;
28564  };
28565  d3_geom_polygonPrototype.centroid = function(k) {
28566    var i = -1, n = this.length, x = 0, y = 0, a, b = this[n - 1], c;
28567    if (!arguments.length) k = -1 / (6 * this.area());
28568    while (++i < n) {
28569      a = b;
28570      b = this[i];
28571      c = a[0] * b[1] - b[0] * a[1];
28572      x += (a[0] + b[0]) * c;
28573      y += (a[1] + b[1]) * c;
28574    }
28575    return [ x * k, y * k ];
28576  };
28577  d3_geom_polygonPrototype.clip = function(subject) {
28578    var input, closed = d3_geom_polygonClosed(subject), i = -1, n = this.length - d3_geom_polygonClosed(this), j, m, a = this[n - 1], b, c, d;
28579    while (++i < n) {
28580      input = subject.slice();
28581      subject.length = 0;
28582      b = this[i];
28583      c = input[(m = input.length - closed) - 1];
28584      j = -1;
28585      while (++j < m) {
28586        d = input[j];
28587        if (d3_geom_polygonInside(d, a, b)) {
28588          if (!d3_geom_polygonInside(c, a, b)) {
28589            subject.push(d3_geom_polygonIntersect(c, d, a, b));
28590          }
28591          subject.push(d);
28592        } else if (d3_geom_polygonInside(c, a, b)) {
28593          subject.push(d3_geom_polygonIntersect(c, d, a, b));
28594        }
28595        c = d;
28596      }
28597      if (closed) subject.push(subject[0]);
28598      a = b;
28599    }
28600    return subject;
28601  };
28602  function d3_geom_polygonInside(p, a, b) {
28603    return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]);
28604  }
28605  function d3_geom_polygonIntersect(c, d, a, b) {
28606    var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21);
28607    return [ x1 + ua * x21, y1 + ua * y21 ];
28608  }
28609  function d3_geom_polygonClosed(coordinates) {
28610    var a = coordinates[0], b = coordinates[coordinates.length - 1];
28611    return !(a[0] - b[0] || a[1] - b[1]);
28612  }
28613  var d3_geom_voronoiEdges, d3_geom_voronoiCells, d3_geom_voronoiBeaches, d3_geom_voronoiBeachPool = [], d3_geom_voronoiFirstCircle, d3_geom_voronoiCircles, d3_geom_voronoiCirclePool = [];
28614  function d3_geom_voronoiBeach() {
28615    d3_geom_voronoiRedBlackNode(this);
28616    this.edge = this.site = this.circle = null;
28617  }
28618  function d3_geom_voronoiCreateBeach(site) {
28619    var beach = d3_geom_voronoiBeachPool.pop() || new d3_geom_voronoiBeach();
28620    beach.site = site;
28621    return beach;
28622  }
28623  function d3_geom_voronoiDetachBeach(beach) {
28624    d3_geom_voronoiDetachCircle(beach);
28625    d3_geom_voronoiBeaches.remove(beach);
28626    d3_geom_voronoiBeachPool.push(beach);
28627    d3_geom_voronoiRedBlackNode(beach);
28628  }
28629  function d3_geom_voronoiRemoveBeach(beach) {
28630    var circle = beach.circle, x = circle.x, y = circle.cy, vertex = {
28631      x: x,
28632      y: y
28633    }, previous = beach.P, next = beach.N, disappearing = [ beach ];
28634    d3_geom_voronoiDetachBeach(beach);
28635    var lArc = previous;
28636    while (lArc.circle && abs(x - lArc.circle.x) < ε && abs(y - lArc.circle.cy) < ε) {
28637      previous = lArc.P;
28638      disappearing.unshift(lArc);
28639      d3_geom_voronoiDetachBeach(lArc);
28640      lArc = previous;
28641    }
28642    disappearing.unshift(lArc);
28643    d3_geom_voronoiDetachCircle(lArc);
28644    var rArc = next;
28645    while (rArc.circle && abs(x - rArc.circle.x) < ε && abs(y - rArc.circle.cy) < ε) {
28646      next = rArc.N;
28647      disappearing.push(rArc);
28648      d3_geom_voronoiDetachBeach(rArc);
28649      rArc = next;
28650    }
28651    disappearing.push(rArc);
28652    d3_geom_voronoiDetachCircle(rArc);
28653    var nArcs = disappearing.length, iArc;
28654    for (iArc = 1; iArc < nArcs; ++iArc) {
28655      rArc = disappearing[iArc];
28656      lArc = disappearing[iArc - 1];
28657      d3_geom_voronoiSetEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex);
28658    }
28659    lArc = disappearing[0];
28660    rArc = disappearing[nArcs - 1];
28661    rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, rArc.site, null, vertex);
28662    d3_geom_voronoiAttachCircle(lArc);
28663    d3_geom_voronoiAttachCircle(rArc);
28664  }
28665  function d3_geom_voronoiAddBeach(site) {
28666    var x = site.x, directrix = site.y, lArc, rArc, dxl, dxr, node = d3_geom_voronoiBeaches._;
28667    while (node) {
28668      dxl = d3_geom_voronoiLeftBreakPoint(node, directrix) - x;
28669      if (dxl > ε) node = node.L; else {
28670        dxr = x - d3_geom_voronoiRightBreakPoint(node, directrix);
28671        if (dxr > ε) {
28672          if (!node.R) {
28673            lArc = node;
28674            break;
28675          }
28676          node = node.R;
28677        } else {
28678          if (dxl > -ε) {
28679            lArc = node.P;
28680            rArc = node;
28681          } else if (dxr > -ε) {
28682            lArc = node;
28683            rArc = node.N;
28684          } else {
28685            lArc = rArc = node;
28686          }
28687          break;
28688        }
28689      }
28690    }
28691    var newArc = d3_geom_voronoiCreateBeach(site);
28692    d3_geom_voronoiBeaches.insert(lArc, newArc);
28693    if (!lArc && !rArc) return;
28694    if (lArc === rArc) {
28695      d3_geom_voronoiDetachCircle(lArc);
28696      rArc = d3_geom_voronoiCreateBeach(lArc.site);
28697      d3_geom_voronoiBeaches.insert(newArc, rArc);
28698      newArc.edge = rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site);
28699      d3_geom_voronoiAttachCircle(lArc);
28700      d3_geom_voronoiAttachCircle(rArc);
28701      return;
28702    }
28703    if (!rArc) {
28704      newArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site);
28705      return;
28706    }
28707    d3_geom_voronoiDetachCircle(lArc);
28708    d3_geom_voronoiDetachCircle(rArc);
28709    var lSite = lArc.site, ax = lSite.x, ay = lSite.y, bx = site.x - ax, by = site.y - ay, rSite = rArc.site, cx = rSite.x - ax, cy = rSite.y - ay, d = 2 * (bx * cy - by * cx), hb = bx * bx + by * by, hc = cx * cx + cy * cy, vertex = {
28710      x: (cy * hb - by * hc) / d + ax,
28711      y: (bx * hc - cx * hb) / d + ay
28712    };
28713    d3_geom_voronoiSetEdgeEnd(rArc.edge, lSite, rSite, vertex);
28714    newArc.edge = d3_geom_voronoiCreateEdge(lSite, site, null, vertex);
28715    rArc.edge = d3_geom_voronoiCreateEdge(site, rSite, null, vertex);
28716    d3_geom_voronoiAttachCircle(lArc);
28717    d3_geom_voronoiAttachCircle(rArc);
28718  }
28719  function d3_geom_voronoiLeftBreakPoint(arc, directrix) {
28720    var site = arc.site, rfocx = site.x, rfocy = site.y, pby2 = rfocy - directrix;
28721    if (!pby2) return rfocx;
28722    var lArc = arc.P;
28723    if (!lArc) return -Infinity;
28724    site = lArc.site;
28725    var lfocx = site.x, lfocy = site.y, plby2 = lfocy - directrix;
28726    if (!plby2) return lfocx;
28727    var hl = lfocx - rfocx, aby2 = 1 / pby2 - 1 / plby2, b = hl / plby2;
28728    if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx;
28729    return (rfocx + lfocx) / 2;
28730  }
28731  function d3_geom_voronoiRightBreakPoint(arc, directrix) {
28732    var rArc = arc.N;
28733    if (rArc) return d3_geom_voronoiLeftBreakPoint(rArc, directrix);
28734    var site = arc.site;
28735    return site.y === directrix ? site.x : Infinity;
28736  }
28737  function d3_geom_voronoiCell(site) {
28738    this.site = site;
28739    this.edges = [];
28740  }
28741  d3_geom_voronoiCell.prototype.prepare = function() {
28742    var halfEdges = this.edges, iHalfEdge = halfEdges.length, edge;
28743    while (iHalfEdge--) {
28744      edge = halfEdges[iHalfEdge].edge;
28745      if (!edge.b || !edge.a) halfEdges.splice(iHalfEdge, 1);
28746    }
28747    halfEdges.sort(d3_geom_voronoiHalfEdgeOrder);
28748    return halfEdges.length;
28749  };
28750  function d3_geom_voronoiCloseCells(extent) {
28751    var x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], x2, y2, x3, y3, cells = d3_geom_voronoiCells, iCell = cells.length, cell, iHalfEdge, halfEdges, nHalfEdges, start, end;
28752    while (iCell--) {
28753      cell = cells[iCell];
28754      if (!cell || !cell.prepare()) continue;
28755      halfEdges = cell.edges;
28756      nHalfEdges = halfEdges.length;
28757      iHalfEdge = 0;
28758      while (iHalfEdge < nHalfEdges) {
28759        end = halfEdges[iHalfEdge].end(), x3 = end.x, y3 = end.y;
28760        start = halfEdges[++iHalfEdge % nHalfEdges].start(), x2 = start.x, y2 = start.y;
28761        if (abs(x3 - x2) > ε || abs(y3 - y2) > ε) {
28762          halfEdges.splice(iHalfEdge, 0, new d3_geom_voronoiHalfEdge(d3_geom_voronoiCreateBorderEdge(cell.site, end, abs(x3 - x0) < ε && y1 - y3 > ε ? {
28763            x: x0,
28764            y: abs(x2 - x0) < ε ? y2 : y1
28765          } : abs(y3 - y1) < ε && x1 - x3 > ε ? {
28766            x: abs(y2 - y1) < ε ? x2 : x1,
28767            y: y1
28768          } : abs(x3 - x1) < ε && y3 - y0 > ε ? {
28769            x: x1,
28770            y: abs(x2 - x1) < ε ? y2 : y0
28771          } : abs(y3 - y0) < ε && x3 - x0 > ε ? {
28772            x: abs(y2 - y0) < ε ? x2 : x0,
28773            y: y0
28774          } : null), cell.site, null));
28775          ++nHalfEdges;
28776        }
28777      }
28778    }
28779  }
28780  function d3_geom_voronoiHalfEdgeOrder(a, b) {
28781    return b.angle - a.angle;
28782  }
28783  function d3_geom_voronoiCircle() {
28784    d3_geom_voronoiRedBlackNode(this);
28785    this.x = this.y = this.arc = this.site = this.cy = null;
28786  }
28787  function d3_geom_voronoiAttachCircle(arc) {
28788    var lArc = arc.P, rArc = arc.N;
28789    if (!lArc || !rArc) return;
28790    var lSite = lArc.site, cSite = arc.site, rSite = rArc.site;
28791    if (lSite === rSite) return;
28792    var bx = cSite.x, by = cSite.y, ax = lSite.x - bx, ay = lSite.y - by, cx = rSite.x - bx, cy = rSite.y - by;
28793    var d = 2 * (ax * cy - ay * cx);
28794    if (d >= -ε2) return;
28795    var ha = ax * ax + ay * ay, hc = cx * cx + cy * cy, x = (cy * ha - ay * hc) / d, y = (ax * hc - cx * ha) / d, cy = y + by;
28796    var circle = d3_geom_voronoiCirclePool.pop() || new d3_geom_voronoiCircle();
28797    circle.arc = arc;
28798    circle.site = cSite;
28799    circle.x = x + bx;
28800    circle.y = cy + Math.sqrt(x * x + y * y);
28801    circle.cy = cy;
28802    arc.circle = circle;
28803    var before = null, node = d3_geom_voronoiCircles._;
28804    while (node) {
28805      if (circle.y < node.y || circle.y === node.y && circle.x <= node.x) {
28806        if (node.L) node = node.L; else {
28807          before = node.P;
28808          break;
28809        }
28810      } else {
28811        if (node.R) node = node.R; else {
28812          before = node;
28813          break;
28814        }
28815      }
28816    }
28817    d3_geom_voronoiCircles.insert(before, circle);
28818    if (!before) d3_geom_voronoiFirstCircle = circle;
28819  }
28820  function d3_geom_voronoiDetachCircle(arc) {
28821    var circle = arc.circle;
28822    if (circle) {
28823      if (!circle.P) d3_geom_voronoiFirstCircle = circle.N;
28824      d3_geom_voronoiCircles.remove(circle);
28825      d3_geom_voronoiCirclePool.push(circle);
28826      d3_geom_voronoiRedBlackNode(circle);
28827      arc.circle = null;
28828    }
28829  }
28830  function d3_geom_voronoiClipEdges(extent) {
28831    var edges = d3_geom_voronoiEdges, clip = d3_geom_clipLine(extent[0][0], extent[0][1], extent[1][0], extent[1][1]), i = edges.length, e;
28832    while (i--) {
28833      e = edges[i];
28834      if (!d3_geom_voronoiConnectEdge(e, extent) || !clip(e) || abs(e.a.x - e.b.x) < ε && abs(e.a.y - e.b.y) < ε) {
28835        e.a = e.b = null;
28836        edges.splice(i, 1);
28837      }
28838    }
28839  }
28840  function d3_geom_voronoiConnectEdge(edge, extent) {
28841    var vb = edge.b;
28842    if (vb) return true;
28843    var va = edge.a, x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], lSite = edge.l, rSite = edge.r, lx = lSite.x, ly = lSite.y, rx = rSite.x, ry = rSite.y, fx = (lx + rx) / 2, fy = (ly + ry) / 2, fm, fb;
28844    if (ry === ly) {
28845      if (fx < x0 || fx >= x1) return;
28846      if (lx > rx) {
28847        if (!va) va = {
28848          x: fx,
28849          y: y0
28850        }; else if (va.y >= y1) return;
28851        vb = {
28852          x: fx,
28853          y: y1
28854        };
28855      } else {
28856        if (!va) va = {
28857          x: fx,
28858          y: y1
28859        }; else if (va.y < y0) return;
28860        vb = {
28861          x: fx,
28862          y: y0
28863        };
28864      }
28865    } else {
28866      fm = (lx - rx) / (ry - ly);
28867      fb = fy - fm * fx;
28868      if (fm < -1 || fm > 1) {
28869        if (lx > rx) {
28870          if (!va) va = {
28871            x: (y0 - fb) / fm,
28872            y: y0
28873          }; else if (va.y >= y1) return;
28874          vb = {
28875            x: (y1 - fb) / fm,
28876            y: y1
28877          };
28878        } else {
28879          if (!va) va = {
28880            x: (y1 - fb) / fm,
28881            y: y1
28882          }; else if (va.y < y0) return;
28883          vb = {
28884            x: (y0 - fb) / fm,
28885            y: y0
28886          };
28887        }
28888      } else {
28889        if (ly < ry) {
28890          if (!va) va = {
28891            x: x0,
28892            y: fm * x0 + fb
28893          }; else if (va.x >= x1) return;
28894          vb = {
28895            x: x1,
28896            y: fm * x1 + fb
28897          };
28898        } else {
28899          if (!va) va = {
28900            x: x1,
28901            y: fm * x1 + fb
28902          }; else if (va.x < x0) return;
28903          vb = {
28904            x: x0,
28905            y: fm * x0 + fb
28906          };
28907        }
28908      }
28909    }
28910    edge.a = va;
28911    edge.b = vb;
28912    return true;
28913  }
28914  function d3_geom_voronoiEdge(lSite, rSite) {
28915    this.l = lSite;
28916    this.r = rSite;
28917    this.a = this.b = null;
28918  }
28919  function d3_geom_voronoiCreateEdge(lSite, rSite, va, vb) {
28920    var edge = new d3_geom_voronoiEdge(lSite, rSite);
28921    d3_geom_voronoiEdges.push(edge);
28922    if (va) d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, va);
28923    if (vb) d3_geom_voronoiSetEdgeEnd(edge, rSite, lSite, vb);
28924    d3_geom_voronoiCells[lSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, lSite, rSite));
28925    d3_geom_voronoiCells[rSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, rSite, lSite));
28926    return edge;
28927  }
28928  function d3_geom_voronoiCreateBorderEdge(lSite, va, vb) {
28929    var edge = new d3_geom_voronoiEdge(lSite, null);
28930    edge.a = va;
28931    edge.b = vb;
28932    d3_geom_voronoiEdges.push(edge);
28933    return edge;
28934  }
28935  function d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, vertex) {
28936    if (!edge.a && !edge.b) {
28937      edge.a = vertex;
28938      edge.l = lSite;
28939      edge.r = rSite;
28940    } else if (edge.l === rSite) {
28941      edge.b = vertex;
28942    } else {
28943      edge.a = vertex;
28944    }
28945  }
28946  function d3_geom_voronoiHalfEdge(edge, lSite, rSite) {
28947    var va = edge.a, vb = edge.b;
28948    this.edge = edge;
28949    this.site = lSite;
28950    this.angle = rSite ? Math.atan2(rSite.y - lSite.y, rSite.x - lSite.x) : edge.l === lSite ? Math.atan2(vb.x - va.x, va.y - vb.y) : Math.atan2(va.x - vb.x, vb.y - va.y);
28951  }
28952  d3_geom_voronoiHalfEdge.prototype = {
28953    start: function() {
28954      return this.edge.l === this.site ? this.edge.a : this.edge.b;
28955    },
28956    end: function() {
28957      return this.edge.l === this.site ? this.edge.b : this.edge.a;
28958    }
28959  };
28960  function d3_geom_voronoiRedBlackTree() {
28961    this._ = null;
28962  }
28963  function d3_geom_voronoiRedBlackNode(node) {
28964    node.U = node.C = node.L = node.R = node.P = node.N = null;
28965  }
28966  d3_geom_voronoiRedBlackTree.prototype = {
28967    insert: function(after, node) {
28968      var parent, grandpa, uncle;
28969      if (after) {
28970        node.P = after;
28971        node.N = after.N;
28972        if (after.N) after.N.P = node;
28973        after.N = node;
28974        if (after.R) {
28975          after = after.R;
28976          while (after.L) after = after.L;
28977          after.L = node;
28978        } else {
28979          after.R = node;
28980        }
28981        parent = after;
28982      } else if (this._) {
28983        after = d3_geom_voronoiRedBlackFirst(this._);
28984        node.P = null;
28985        node.N = after;
28986        after.P = after.L = node;
28987        parent = after;
28988      } else {
28989        node.P = node.N = null;
28990        this._ = node;
28991        parent = null;
28992      }
28993      node.L = node.R = null;
28994      node.U = parent;
28995      node.C = true;
28996      after = node;
28997      while (parent && parent.C) {
28998        grandpa = parent.U;
28999        if (parent === grandpa.L) {
29000          uncle = grandpa.R;
29001          if (uncle && uncle.C) {
29002            parent.C = uncle.C = false;
29003            grandpa.C = true;
29004            after = grandpa;
29005          } else {
29006            if (after === parent.R) {
29007              d3_geom_voronoiRedBlackRotateLeft(this, parent);
29008              after = parent;
29009              parent = after.U;
29010            }
29011            parent.C = false;
29012            grandpa.C = true;
29013            d3_geom_voronoiRedBlackRotateRight(this, grandpa);
29014          }
29015        } else {
29016          uncle = grandpa.L;
29017          if (uncle && uncle.C) {
29018            parent.C = uncle.C = false;
29019            grandpa.C = true;
29020            after = grandpa;
29021          } else {
29022            if (after === parent.L) {
29023              d3_geom_voronoiRedBlackRotateRight(this, parent);
29024              after = parent;
29025              parent = after.U;
29026            }
29027            parent.C = false;
29028            grandpa.C = true;
29029            d3_geom_voronoiRedBlackRotateLeft(this, grandpa);
29030          }
29031        }
29032        parent = after.U;
29033      }
29034      this._.C = false;
29035    },
29036    remove: function(node) {
29037      if (node.N) node.N.P = node.P;
29038      if (node.P) node.P.N = node.N;
29039      node.N = node.P = null;
29040      var parent = node.U, sibling, left = node.L, right = node.R, next, red;
29041      if (!left) next = right; else if (!right) next = left; else next = d3_geom_voronoiRedBlackFirst(right);
29042      if (parent) {
29043        if (parent.L === node) parent.L = next; else parent.R = next;
29044      } else {
29045        this._ = next;
29046      }
29047      if (left && right) {
29048        red = next.C;
29049        next.C = node.C;
29050        next.L = left;
29051        left.U = next;
29052        if (next !== right) {
29053          parent = next.U;
29054          next.U = node.U;
29055          node = next.R;
29056          parent.L = node;
29057          next.R = right;
29058          right.U = next;
29059        } else {
29060          next.U = parent;
29061          parent = next;
29062          node = next.R;
29063        }
29064      } else {
29065        red = node.C;
29066        node = next;
29067      }
29068      if (node) node.U = parent;
29069      if (red) return;
29070      if (node && node.C) {
29071        node.C = false;
29072        return;
29073      }
29074      do {
29075        if (node === this._) break;
29076        if (node === parent.L) {
29077          sibling = parent.R;
29078          if (sibling.C) {
29079            sibling.C = false;
29080            parent.C = true;
29081            d3_geom_voronoiRedBlackRotateLeft(this, parent);
29082            sibling = parent.R;
29083          }
29084          if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) {
29085            if (!sibling.R || !sibling.R.C) {
29086              sibling.L.C = false;
29087              sibling.C = true;
29088              d3_geom_voronoiRedBlackRotateRight(this, sibling);
29089              sibling = parent.R;
29090            }
29091            sibling.C = parent.C;
29092            parent.C = sibling.R.C = false;
29093            d3_geom_voronoiRedBlackRotateLeft(this, parent);
29094            node = this._;
29095            break;
29096          }
29097        } else {
29098          sibling = parent.L;
29099          if (sibling.C) {
29100            sibling.C = false;
29101            parent.C = true;
29102            d3_geom_voronoiRedBlackRotateRight(this, parent);
29103            sibling = parent.L;
29104          }
29105          if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) {
29106            if (!sibling.L || !sibling.L.C) {
29107              sibling.R.C = false;
29108              sibling.C = true;
29109              d3_geom_voronoiRedBlackRotateLeft(this, sibling);
29110              sibling = parent.L;
29111            }
29112            sibling.C = parent.C;
29113            parent.C = sibling.L.C = false;
29114            d3_geom_voronoiRedBlackRotateRight(this, parent);
29115            node = this._;
29116            break;
29117          }
29118        }
29119        sibling.C = true;
29120        node = parent;
29121        parent = parent.U;
29122      } while (!node.C);
29123      if (node) node.C = false;
29124    }
29125  };
29126  function d3_geom_voronoiRedBlackRotateLeft(tree, node) {
29127    var p = node, q = node.R, parent = p.U;
29128    if (parent) {
29129      if (parent.L === p) parent.L = q; else parent.R = q;
29130    } else {
29131      tree._ = q;
29132    }
29133    q.U = parent;
29134    p.U = q;
29135    p.R = q.L;
29136    if (p.R) p.R.U = p;
29137    q.L = p;
29138  }
29139  function d3_geom_voronoiRedBlackRotateRight(tree, node) {
29140    var p = node, q = node.L, parent = p.U;
29141    if (parent) {
29142      if (parent.L === p) parent.L = q; else parent.R = q;
29143    } else {
29144      tree._ = q;
29145    }
29146    q.U = parent;
29147    p.U = q;
29148    p.L = q.R;
29149    if (p.L) p.L.U = p;
29150    q.R = p;
29151  }
29152  function d3_geom_voronoiRedBlackFirst(node) {
29153    while (node.L) node = node.L;
29154    return node;
29155  }
29156  function d3_geom_voronoi(sites, bbox) {
29157    var site = sites.sort(d3_geom_voronoiVertexOrder).pop(), x0, y0, circle;
29158    d3_geom_voronoiEdges = [];
29159    d3_geom_voronoiCells = new Array(sites.length);
29160    d3_geom_voronoiBeaches = new d3_geom_voronoiRedBlackTree();
29161    d3_geom_voronoiCircles = new d3_geom_voronoiRedBlackTree();
29162    while (true) {
29163      circle = d3_geom_voronoiFirstCircle;
29164      if (site && (!circle || site.y < circle.y || site.y === circle.y && site.x < circle.x)) {
29165        if (site.x !== x0 || site.y !== y0) {
29166          d3_geom_voronoiCells[site.i] = new d3_geom_voronoiCell(site);
29167          d3_geom_voronoiAddBeach(site);
29168          x0 = site.x, y0 = site.y;
29169        }
29170        site = sites.pop();
29171      } else if (circle) {
29172        d3_geom_voronoiRemoveBeach(circle.arc);
29173      } else {
29174        break;
29175      }
29176    }
29177    if (bbox) d3_geom_voronoiClipEdges(bbox), d3_geom_voronoiCloseCells(bbox);
29178    var diagram = {
29179      cells: d3_geom_voronoiCells,
29180      edges: d3_geom_voronoiEdges
29181    };
29182    d3_geom_voronoiBeaches = d3_geom_voronoiCircles = d3_geom_voronoiEdges = d3_geom_voronoiCells = null;
29183    return diagram;
29184  }
29185  function d3_geom_voronoiVertexOrder(a, b) {
29186    return b.y - a.y || b.x - a.x;
29187  }
29188  d3.geom.voronoi = function(points) {
29189    var x = d3_geom_pointX, y = d3_geom_pointY, fx = x, fy = y, clipExtent = d3_geom_voronoiClipExtent;
29190    if (points) return voronoi(points);
29191    function voronoi(data) {
29192      var polygons = new Array(data.length), x0 = clipExtent[0][0], y0 = clipExtent[0][1], x1 = clipExtent[1][0], y1 = clipExtent[1][1];
29193      d3_geom_voronoi(sites(data), clipExtent).cells.forEach(function(cell, i) {
29194        var edges = cell.edges, site = cell.site, polygon = polygons[i] = edges.length ? edges.map(function(e) {
29195          var s = e.start();
29196          return [ s.x, s.y ];
29197        }) : site.x >= x0 && site.x <= x1 && site.y >= y0 && site.y <= y1 ? [ [ x0, y1 ], [ x1, y1 ], [ x1, y0 ], [ x0, y0 ] ] : [];
29198        polygon.point = data[i];
29199      });
29200      return polygons;
29201    }
29202    function sites(data) {
29203      return data.map(function(d, i) {
29204        return {
29205          x: Math.round(fx(d, i) / ε) * ε,
29206          y: Math.round(fy(d, i) / ε) * ε,
29207          i: i
29208        };
29209      });
29210    }
29211    voronoi.links = function(data) {
29212      return d3_geom_voronoi(sites(data)).edges.filter(function(edge) {
29213        return edge.l && edge.r;
29214      }).map(function(edge) {
29215        return {
29216          source: data[edge.l.i],
29217          target: data[edge.r.i]
29218        };
29219      });
29220    };
29221    voronoi.triangles = function(data) {
29222      var triangles = [];
29223      d3_geom_voronoi(sites(data)).cells.forEach(function(cell, i) {
29224        var site = cell.site, edges = cell.edges.sort(d3_geom_voronoiHalfEdgeOrder), j = -1, m = edges.length, e0, s0, e1 = edges[m - 1].edge, s1 = e1.l === site ? e1.r : e1.l;
29225        while (++j < m) {
29226          e0 = e1;
29227          s0 = s1;
29228          e1 = edges[j].edge;
29229          s1 = e1.l === site ? e1.r : e1.l;
29230          if (i < s0.i && i < s1.i && d3_geom_voronoiTriangleArea(site, s0, s1) < 0) {
29231            triangles.push([ data[i], data[s0.i], data[s1.i] ]);
29232          }
29233        }
29234      });
29235      return triangles;
29236    };
29237    voronoi.x = function(_) {
29238      return arguments.length ? (fx = d3_functor(x = _), voronoi) : x;
29239    };
29240    voronoi.y = function(_) {
29241      return arguments.length ? (fy = d3_functor(y = _), voronoi) : y;
29242    };
29243    voronoi.clipExtent = function(_) {
29244      if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent;
29245      clipExtent = _ == null ? d3_geom_voronoiClipExtent : _;
29246      return voronoi;
29247    };
29248    voronoi.size = function(_) {
29249      if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent && clipExtent[1];
29250      return voronoi.clipExtent(_ && [ [ 0, 0 ], _ ]);
29251    };
29252    return voronoi;
29253  };
29254  var d3_geom_voronoiClipExtent = [ [ -1e6, -1e6 ], [ 1e6, 1e6 ] ];
29255  function d3_geom_voronoiTriangleArea(a, b, c) {
29256    return (a.x - c.x) * (b.y - a.y) - (a.x - b.x) * (c.y - a.y);
29257  }
29258  d3.geom.delaunay = function(vertices) {
29259    return d3.geom.voronoi().triangles(vertices);
29260  };
29261  d3.geom.quadtree = function(points, x1, y1, x2, y2) {
29262    var x = d3_geom_pointX, y = d3_geom_pointY, compat;
29263    if (compat = arguments.length) {
29264      x = d3_geom_quadtreeCompatX;
29265      y = d3_geom_quadtreeCompatY;
29266      if (compat === 3) {
29267        y2 = y1;
29268        x2 = x1;
29269        y1 = x1 = 0;
29270      }
29271      return quadtree(points);
29272    }
29273    function quadtree(data) {
29274      var d, fx = d3_functor(x), fy = d3_functor(y), xs, ys, i, n, x1_, y1_, x2_, y2_;
29275      if (x1 != null) {
29276        x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2;
29277      } else {
29278        x2_ = y2_ = -(x1_ = y1_ = Infinity);
29279        xs = [], ys = [];
29280        n = data.length;
29281        if (compat) for (i = 0; i < n; ++i) {
29282          d = data[i];
29283          if (d.x < x1_) x1_ = d.x;
29284          if (d.y < y1_) y1_ = d.y;
29285          if (d.x > x2_) x2_ = d.x;
29286          if (d.y > y2_) y2_ = d.y;
29287          xs.push(d.x);
29288          ys.push(d.y);
29289        } else for (i = 0; i < n; ++i) {
29290          var x_ = +fx(d = data[i], i), y_ = +fy(d, i);
29291          if (x_ < x1_) x1_ = x_;
29292          if (y_ < y1_) y1_ = y_;
29293          if (x_ > x2_) x2_ = x_;
29294          if (y_ > y2_) y2_ = y_;
29295          xs.push(x_);
29296          ys.push(y_);
29297        }
29298      }
29299      var dx = x2_ - x1_, dy = y2_ - y1_;
29300      if (dx > dy) y2_ = y1_ + dx; else x2_ = x1_ + dy;
29301      function insert(n, d, x, y, x1, y1, x2, y2) {
29302        if (isNaN(x) || isNaN(y)) return;
29303        if (n.leaf) {
29304          var nx = n.x, ny = n.y;
29305          if (nx != null) {
29306            if (abs(nx - x) + abs(ny - y) < .01) {
29307              insertChild(n, d, x, y, x1, y1, x2, y2);
29308            } else {
29309              var nPoint = n.point;
29310              n.x = n.y = n.point = null;
29311              insertChild(n, nPoint, nx, ny, x1, y1, x2, y2);
29312              insertChild(n, d, x, y, x1, y1, x2, y2);
29313            }
29314          } else {
29315            n.x = x, n.y = y, n.point = d;
29316          }
29317        } else {
29318          insertChild(n, d, x, y, x1, y1, x2, y2);
29319        }
29320      }
29321      function insertChild(n, d, x, y, x1, y1, x2, y2) {
29322        var xm = (x1 + x2) * .5, ym = (y1 + y2) * .5, right = x >= xm, below = y >= ym, i = below << 1 | right;
29323        n.leaf = false;
29324        n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode());
29325        if (right) x1 = xm; else x2 = xm;
29326        if (below) y1 = ym; else y2 = ym;
29327        insert(n, d, x, y, x1, y1, x2, y2);
29328      }
29329      var root = d3_geom_quadtreeNode();
29330      root.add = function(d) {
29331        insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_);
29332      };
29333      root.visit = function(f) {
29334        d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_);
29335      };
29336      root.find = function(point) {
29337        return d3_geom_quadtreeFind(root, point[0], point[1], x1_, y1_, x2_, y2_);
29338      };
29339      i = -1;
29340      if (x1 == null) {
29341        while (++i < n) {
29342          insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_);
29343        }
29344        --i;
29345      } else data.forEach(root.add);
29346      xs = ys = data = d = null;
29347      return root;
29348    }
29349    quadtree.x = function(_) {
29350      return arguments.length ? (x = _, quadtree) : x;
29351    };
29352    quadtree.y = function(_) {
29353      return arguments.length ? (y = _, quadtree) : y;
29354    };
29355    quadtree.extent = function(_) {
29356      if (!arguments.length) return x1 == null ? null : [ [ x1, y1 ], [ x2, y2 ] ];
29357      if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], 
29358      y2 = +_[1][1];
29359      return quadtree;
29360    };
29361    quadtree.size = function(_) {
29362      if (!arguments.length) return x1 == null ? null : [ x2 - x1, y2 - y1 ];
29363      if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = y1 = 0, x2 = +_[0], y2 = +_[1];
29364      return quadtree;
29365    };
29366    return quadtree;
29367  };
29368  function d3_geom_quadtreeCompatX(d) {
29369    return d.x;
29370  }
29371  function d3_geom_quadtreeCompatY(d) {
29372    return d.y;
29373  }
29374  function d3_geom_quadtreeNode() {
29375    return {
29376      leaf: true,
29377      nodes: [],
29378      point: null,
29379      x: null,
29380      y: null
29381    };
29382  }
29383  function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) {
29384    if (!f(node, x1, y1, x2, y2)) {
29385      var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes;
29386      if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy);
29387      if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy);
29388      if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2);
29389      if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2);
29390    }
29391  }
29392  function d3_geom_quadtreeFind(root, x, y, x0, y0, x3, y3) {
29393    var minDistance2 = Infinity, closestPoint;
29394    (function find(node, x1, y1, x2, y2) {
29395      if (x1 > x3 || y1 > y3 || x2 < x0 || y2 < y0) return;
29396      if (point = node.point) {
29397        var point, dx = x - node.x, dy = y - node.y, distance2 = dx * dx + dy * dy;
29398        if (distance2 < minDistance2) {
29399          var distance = Math.sqrt(minDistance2 = distance2);
29400          x0 = x - distance, y0 = y - distance;
29401          x3 = x + distance, y3 = y + distance;
29402          closestPoint = point;
29403        }
29404      }
29405      var children = node.nodes, xm = (x1 + x2) * .5, ym = (y1 + y2) * .5, right = x >= xm, below = y >= ym;
29406      for (var i = below << 1 | right, j = i + 4; i < j; ++i) {
29407        if (node = children[i & 3]) switch (i & 3) {
29408         case 0:
29409          find(node, x1, y1, xm, ym);
29410          break;
29411
29412         case 1:
29413          find(node, xm, y1, x2, ym);
29414          break;
29415
29416         case 2:
29417          find(node, x1, ym, xm, y2);
29418          break;
29419
29420         case 3:
29421          find(node, xm, ym, x2, y2);
29422          break;
29423        }
29424      }
29425    })(root, x0, y0, x3, y3);
29426    return closestPoint;
29427  }
29428  d3.interpolateRgb = d3_interpolateRgb;
29429  function d3_interpolateRgb(a, b) {
vendor: 13,311 bytes, lines 29430-29863
29430    a = d3.rgb(a);
29431    b = d3.rgb(b);
29432    var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab;
29433    return function(t) {
29434      return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t));
29435    };
29436  }
29437  d3.interpolateObject = d3_interpolateObject;
29438  function d3_interpolateObject(a, b) {
29439    var i = {}, c = {}, k;
29440    for (k in a) {
29441      if (k in b) {
29442        i[k] = d3_interpolate(a[k], b[k]);
29443      } else {
29444        c[k] = a[k];
29445      }
29446    }
29447    for (k in b) {
29448      if (!(k in a)) {
29449        c[k] = b[k];
29450      }
29451    }
29452    return function(t) {
29453      for (k in i) c[k] = i[k](t);
29454      return c;
29455    };
29456  }
29457  d3.interpolateNumber = d3_interpolateNumber;
29458  function d3_interpolateNumber(a, b) {
29459    a = +a, b = +b;
29460    return function(t) {
29461      return a * (1 - t) + b * t;
29462    };
29463  }
29464  d3.interpolateString = d3_interpolateString;
29465  function d3_interpolateString(a, b) {
29466    var bi = d3_interpolate_numberA.lastIndex = d3_interpolate_numberB.lastIndex = 0, am, bm, bs, i = -1, s = [], q = [];
29467    a = a + "", b = b + "";
29468    while ((am = d3_interpolate_numberA.exec(a)) && (bm = d3_interpolate_numberB.exec(b))) {
29469      if ((bs = bm.index) > bi) {
29470        bs = b.slice(bi, bs);
29471        if (s[i]) s[i] += bs; else s[++i] = bs;
29472      }
29473      if ((am = am[0]) === (bm = bm[0])) {
29474        if (s[i]) s[i] += bm; else s[++i] = bm;
29475      } else {
29476        s[++i] = null;
29477        q.push({
29478          i: i,
29479          x: d3_interpolateNumber(am, bm)
29480        });
29481      }
29482      bi = d3_interpolate_numberB.lastIndex;
29483    }
29484    if (bi < b.length) {
29485      bs = b.slice(bi);
29486      if (s[i]) s[i] += bs; else s[++i] = bs;
29487    }
29488    return s.length < 2 ? q[0] ? (b = q[0].x, function(t) {
29489      return b(t) + "";
29490    }) : function() {
29491      return b;
29492    } : (b = q.length, function(t) {
29493      for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
29494      return s.join("");
29495    });
29496  }
29497  var d3_interpolate_numberA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, d3_interpolate_numberB = new RegExp(d3_interpolate_numberA.source, "g");
29498  d3.interpolate = d3_interpolate;
29499  function d3_interpolate(a, b) {
29500    var i = d3.interpolators.length, f;
29501    while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ;
29502    return f;
29503  }
29504  d3.interpolators = [ function(a, b) {
29505    var t = typeof b;
29506    return (t === "string" ? d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_color ? d3_interpolateRgb : Array.isArray(b) ? d3_interpolateArray : t === "object" && isNaN(b) ? d3_interpolateObject : d3_interpolateNumber)(a, b);
29507  } ];
29508  d3.interpolateArray = d3_interpolateArray;
29509  function d3_interpolateArray(a, b) {
29510    var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i;
29511    for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i]));
29512    for (;i < na; ++i) c[i] = a[i];
29513    for (;i < nb; ++i) c[i] = b[i];
29514    return function(t) {
29515      for (i = 0; i < n0; ++i) c[i] = x[i](t);
29516      return c;
29517    };
29518  }
29519  var d3_ease_default = function() {
29520    return d3_identity;
29521  };
29522  var d3_ease = d3.map({
29523    linear: d3_ease_default,
29524    poly: d3_ease_poly,
29525    quad: function() {
29526      return d3_ease_quad;
29527    },
29528    cubic: function() {
29529      return d3_ease_cubic;
29530    },
29531    sin: function() {
29532      return d3_ease_sin;
29533    },
29534    exp: function() {
29535      return d3_ease_exp;
29536    },
29537    circle: function() {
29538      return d3_ease_circle;
29539    },
29540    elastic: d3_ease_elastic,
29541    back: d3_ease_back,
29542    bounce: function() {
29543      return d3_ease_bounce;
29544    }
29545  });
29546  var d3_ease_mode = d3.map({
29547    "in": d3_identity,
29548    out: d3_ease_reverse,
29549    "in-out": d3_ease_reflect,
29550    "out-in": function(f) {
29551      return d3_ease_reflect(d3_ease_reverse(f));
29552    }
29553  });
29554  d3.ease = function(name) {
29555    var i = name.indexOf("-"), t = i >= 0 ? name.slice(0, i) : name, m = i >= 0 ? name.slice(i + 1) : "in";
29556    t = d3_ease.get(t) || d3_ease_default;
29557    m = d3_ease_mode.get(m) || d3_identity;
29558    return d3_ease_clamp(m(t.apply(null, d3_arraySlice.call(arguments, 1))));
29559  };
29560  function d3_ease_clamp(f) {
29561    return function(t) {
29562      return t <= 0 ? 0 : t >= 1 ? 1 : f(t);
29563    };
29564  }
29565  function d3_ease_reverse(f) {
29566    return function(t) {
29567      return 1 - f(1 - t);
29568    };
29569  }
29570  function d3_ease_reflect(f) {
29571    return function(t) {
29572      return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t));
29573    };
29574  }
29575  function d3_ease_quad(t) {
29576    return t * t;
29577  }
29578  function d3_ease_cubic(t) {
29579    return t * t * t;
29580  }
29581  function d3_ease_cubicInOut(t) {
29582    if (t <= 0) return 0;
29583    if (t >= 1) return 1;
29584    var t2 = t * t, t3 = t2 * t;
29585    return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75);
29586  }
29587  function d3_ease_poly(e) {
29588    return function(t) {
29589      return Math.pow(t, e);
29590    };
29591  }
29592  function d3_ease_sin(t) {
29593    return 1 - Math.cos(t * halfπ);
29594  }
29595  function d3_ease_exp(t) {
29596    return Math.pow(2, 10 * (t - 1));
29597  }
29598  function d3_ease_circle(t) {
29599    return 1 - Math.sqrt(1 - t * t);
29600  }
29601  function d3_ease_elastic(a, p) {
29602    var s;
29603    if (arguments.length < 2) p = .45;
29604    if (arguments.length) s = p / τ * Math.asin(1 / a); else a = 1, s = p / 4;
29605    return function(t) {
29606      return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * τ / p);
29607    };
29608  }
29609  function d3_ease_back(s) {
29610    if (!s) s = 1.70158;
29611    return function(t) {
29612      return t * t * ((s + 1) * t - s);
29613    };
29614  }
29615  function d3_ease_bounce(t) {
29616    return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
29617  }
29618  d3.interpolateHcl = d3_interpolateHcl;
29619  function d3_interpolateHcl(a, b) {
29620    a = d3.hcl(a);
29621    b = d3.hcl(b);
29622    var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al;
29623    if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac;
29624    if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360;
29625    return function(t) {
29626      return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + "";
29627    };
29628  }
29629  d3.interpolateHsl = d3_interpolateHsl;
29630  function d3_interpolateHsl(a, b) {
29631    a = d3.hsl(a);
29632    b = d3.hsl(b);
29633    var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al;
29634    if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as;
29635    if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360;
29636    return function(t) {
29637      return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + "";
29638    };
29639  }
29640  d3.interpolateLab = d3_interpolateLab;
29641  function d3_interpolateLab(a, b) {
29642    a = d3.lab(a);
29643    b = d3.lab(b);
29644    var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab;
29645    return function(t) {
29646      return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + "";
29647    };
29648  }
29649  d3.interpolateRound = d3_interpolateRound;
29650  function d3_interpolateRound(a, b) {
29651    b -= a;
29652    return function(t) {
29653      return Math.round(a + b * t);
29654    };
29655  }
29656  d3.transform = function(string) {
29657    var g = d3_document.createElementNS(d3.ns.prefix.svg, "g");
29658    return (d3.transform = function(string) {
29659      if (string != null) {
29660        g.setAttribute("transform", string);
29661        var t = g.transform.baseVal.consolidate();
29662      }
29663      return new d3_transform(t ? t.matrix : d3_transformIdentity);
29664    })(string);
29665  };
29666  function d3_transform(m) {
29667    var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0;
29668    if (r0[0] * r1[1] < r1[0] * r0[1]) {
29669      r0[0] *= -1;
29670      r0[1] *= -1;
29671      kx *= -1;
29672      kz *= -1;
29673    }
29674    this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees;
29675    this.translate = [ m.e, m.f ];
29676    this.scale = [ kx, ky ];
29677    this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0;
29678  }
29679  d3_transform.prototype.toString = function() {
29680    return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")";
29681  };
29682  function d3_transformDot(a, b) {
29683    return a[0] * b[0] + a[1] * b[1];
29684  }
29685  function d3_transformNormalize(a) {
29686    var k = Math.sqrt(d3_transformDot(a, a));
29687    if (k) {
29688      a[0] /= k;
29689      a[1] /= k;
29690    }
29691    return k;
29692  }
29693  function d3_transformCombine(a, b, k) {
29694    a[0] += k * b[0];
29695    a[1] += k * b[1];
29696    return a;
29697  }
29698  var d3_transformIdentity = {
29699    a: 1,
29700    b: 0,
29701    c: 0,
29702    d: 1,
29703    e: 0,
29704    f: 0
29705  };
29706  d3.interpolateTransform = d3_interpolateTransform;
29707  function d3_interpolateTransform(a, b) {
29708    var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale;
29709    if (ta[0] != tb[0] || ta[1] != tb[1]) {
29710      s.push("translate(", null, ",", null, ")");
29711      q.push({
29712        i: 1,
29713        x: d3_interpolateNumber(ta[0], tb[0])
29714      }, {
29715        i: 3,
29716        x: d3_interpolateNumber(ta[1], tb[1])
29717      });
29718    } else if (tb[0] || tb[1]) {
29719      s.push("translate(" + tb + ")");
29720    } else {
29721      s.push("");
29722    }
29723    if (ra != rb) {
29724      if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360;
29725      q.push({
29726        i: s.push(s.pop() + "rotate(", null, ")") - 2,
29727        x: d3_interpolateNumber(ra, rb)
29728      });
29729    } else if (rb) {
29730      s.push(s.pop() + "rotate(" + rb + ")");
29731    }
29732    if (wa != wb) {
29733      q.push({
29734        i: s.push(s.pop() + "skewX(", null, ")") - 2,
29735        x: d3_interpolateNumber(wa, wb)
29736      });
29737    } else if (wb) {
29738      s.push(s.pop() + "skewX(" + wb + ")");
29739    }
29740    if (ka[0] != kb[0] || ka[1] != kb[1]) {
29741      n = s.push(s.pop() + "scale(", null, ",", null, ")");
29742      q.push({
29743        i: n - 4,
29744        x: d3_interpolateNumber(ka[0], kb[0])
29745      }, {
29746        i: n - 2,
29747        x: d3_interpolateNumber(ka[1], kb[1])
29748      });
29749    } else if (kb[0] != 1 || kb[1] != 1) {
29750      s.push(s.pop() + "scale(" + kb + ")");
29751    }
29752    n = q.length;
29753    return function(t) {
29754      var i = -1, o;
29755      while (++i < n) s[(o = q[i]).i] = o.x(t);
29756      return s.join("");
29757    };
29758  }
29759  function d3_uninterpolateNumber(a, b) {
29760    b = (b -= a = +a) || 1 / b;
29761    return function(x) {
29762      return (x - a) / b;
29763    };
29764  }
29765  function d3_uninterpolateClamp(a, b) {
29766    b = (b -= a = +a) || 1 / b;
29767    return function(x) {
29768      return Math.max(0, Math.min(1, (x - a) / b));
29769    };
29770  }
29771  d3.layout = {};
29772  d3.layout.bundle = function() {
29773    return function(links) {
29774      var paths = [], i = -1, n = links.length;
29775      while (++i < n) paths.push(d3_layout_bundlePath(links[i]));
29776      return paths;
29777    };
29778  };
29779  function d3_layout_bundlePath(link) {
29780    var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ];
29781    while (start !== lca) {
29782      start = start.parent;
29783      points.push(start);
29784    }
29785    var k = points.length;
29786    while (end !== lca) {
29787      points.splice(k, 0, end);
29788      end = end.parent;
29789    }
29790    return points;
29791  }
29792  function d3_layout_bundleAncestors(node) {
29793    var ancestors = [], parent = node.parent;
29794    while (parent != null) {
29795      ancestors.push(node);
29796      node = parent;
29797      parent = parent.parent;
29798    }
29799    ancestors.push(node);
29800    return ancestors;
29801  }
29802  function d3_layout_bundleLeastCommonAncestor(a, b) {
29803    if (a === b) return a;
29804    var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null;
29805    while (aNode === bNode) {
29806      sharedNode = aNode;
29807      aNode = aNodes.pop();
29808      bNode = bNodes.pop();
29809    }
29810    return sharedNode;
29811  }
29812  d3.layout.chord = function() {
29813    var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords;
29814    function relayout() {
29815      var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j;
29816      chords = [];
29817      groups = [];
29818      k = 0, i = -1;
29819      while (++i < n) {
29820        x = 0, j = -1;
29821        while (++j < n) {
29822          x += matrix[i][j];
29823        }
29824        groupSums.push(x);
29825        subgroupIndex.push(d3.range(n));
29826        k += x;
29827      }
29828      if (sortGroups) {
29829        groupIndex.sort(function(a, b) {
29830          return sortGroups(groupSums[a], groupSums[b]);
29831        });
29832      }
29833      if (sortSubgroups) {
29834        subgroupIndex.forEach(function(d, i) {
29835          d.sort(function(a, b) {
29836            return sortSubgroups(matrix[i][a], matrix[i][b]);
29837          });
29838        });
29839      }
29840      k = (τ - padding * n) / k;
29841      x = 0, i = -1;
29842      while (++i < n) {
29843        x0 = x, j = -1;
29844        while (++j < n) {
29845          var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k;
29846          subgroups[di + "-" + dj] = {
29847            index: di,
29848            subindex: dj,
29849            startAngle: a0,
29850            endAngle: a1,
29851            value: v
29852          };
29853        }
29854        groups[di] = {
29855          index: di,
29856          startAngle: x0,
29857          endAngle: x,
29858          value: (x - x0) / k
29859        };
29860        x += padding;
29861      }
29862      i = -1;
29863      while (++i < n) {
vendor: 3,724 bytes, lines 29864-29984
29864        j = i - 1;
29865        while (++j < n) {
29866          var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i];
29867          if (source.value || target.value) {
29868            chords.push(source.value < target.value ? {
29869              source: target,
29870              target: source
29871            } : {
29872              source: source,
29873              target: target
29874            });
29875          }
29876        }
29877      }
29878      if (sortChords) resort();
29879    }
29880    function resort() {
29881      chords.sort(function(a, b) {
29882        return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2);
29883      });
29884    }
29885    chord.matrix = function(x) {
29886      if (!arguments.length) return matrix;
29887      n = (matrix = x) && matrix.length;
29888      chords = groups = null;
29889      return chord;
29890    };
29891    chord.padding = function(x) {
29892      if (!arguments.length) return padding;
29893      padding = x;
29894      chords = groups = null;
29895      return chord;
29896    };
29897    chord.sortGroups = function(x) {
29898      if (!arguments.length) return sortGroups;
29899      sortGroups = x;
29900      chords = groups = null;
29901      return chord;
29902    };
29903    chord.sortSubgroups = function(x) {
29904      if (!arguments.length) return sortSubgroups;
29905      sortSubgroups = x;
29906      chords = null;
29907      return chord;
29908    };
29909    chord.sortChords = function(x) {
29910      if (!arguments.length) return sortChords;
29911      sortChords = x;
29912      if (chords) resort();
29913      return chord;
29914    };
29915    chord.chords = function() {
29916      if (!chords) relayout();
29917      return chords;
29918    };
29919    chord.groups = function() {
29920      if (!groups) relayout();
29921      return groups;
29922    };
29923    return chord;
29924  };
29925  d3.layout.force = function() {
29926    var force = {}, event = d3.dispatch("start", "tick", "end"), size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, chargeDistance2 = d3_layout_forceChargeDistance2, gravity = .1, theta2 = .64, nodes = [], links = [], distances, strengths, charges;
29927    function repulse(node) {
29928      return function(quad, x1, _, x2) {
29929        if (quad.point !== node) {
29930          var dx = quad.cx - node.x, dy = quad.cy - node.y, dw = x2 - x1, dn = dx * dx + dy * dy;
29931          if (dw * dw / theta2 < dn) {
29932            if (dn < chargeDistance2) {
29933              var k = quad.charge / dn;
29934              node.px -= dx * k;
29935              node.py -= dy * k;
29936            }
29937            return true;
29938          }
29939          if (quad.point && dn && dn < chargeDistance2) {
29940            var k = quad.pointCharge / dn;
29941            node.px -= dx * k;
29942            node.py -= dy * k;
29943          }
29944        }
29945        return !quad.charge;
29946      };
29947    }
29948    force.tick = function() {
29949      if ((alpha *= .99) < .005) {
29950        event.end({
29951          type: "end",
29952          alpha: alpha = 0
29953        });
29954        return true;
29955      }
29956      var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y;
29957      for (i = 0; i < m; ++i) {
29958        o = links[i];
29959        s = o.source;
29960        t = o.target;
29961        x = t.x - s.x;
29962        y = t.y - s.y;
29963        if (l = x * x + y * y) {
29964          l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l;
29965          x *= l;
29966          y *= l;
29967          t.x -= x * (k = s.weight / (t.weight + s.weight));
29968          t.y -= y * k;
29969          s.x += x * (k = 1 - k);
29970          s.y += y * k;
29971        }
29972      }
29973      if (k = alpha * gravity) {
29974        x = size[0] / 2;
29975        y = size[1] / 2;
29976        i = -1;
29977        if (k) while (++i < n) {
29978          o = nodes[i];
29979          o.x += (x - o.x) * k;
29980          o.y += (y - o.y) * k;
29981        }
29982      }
29983      if (charge) {
29984        d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alph
vendor: 11,084 bytes, lines 29984-30323
29984a, charges);
29985        i = -1;
29986        while (++i < n) {
29987          if (!(o = nodes[i]).fixed) {
29988            q.visit(repulse(o));
29989          }
29990        }
29991      }
29992      i = -1;
29993      while (++i < n) {
29994        o = nodes[i];
29995        if (o.fixed) {
29996          o.x = o.px;
29997          o.y = o.py;
29998        } else {
29999          o.x -= (o.px - (o.px = o.x)) * friction;
30000          o.y -= (o.py - (o.py = o.y)) * friction;
30001        }
30002      }
30003      event.tick({
30004        type: "tick",
30005        alpha: alpha
30006      });
30007    };
30008    force.nodes = function(x) {
30009      if (!arguments.length) return nodes;
30010      nodes = x;
30011      return force;
30012    };
30013    force.links = function(x) {
30014      if (!arguments.length) return links;
30015      links = x;
30016      return force;
30017    };
30018    force.size = function(x) {
30019      if (!arguments.length) return size;
30020      size = x;
30021      return force;
30022    };
30023    force.linkDistance = function(x) {
30024      if (!arguments.length) return linkDistance;
30025      linkDistance = typeof x === "function" ? x : +x;
30026      return force;
30027    };
30028    force.distance = force.linkDistance;
30029    force.linkStrength = function(x) {
30030      if (!arguments.length) return linkStrength;
30031      linkStrength = typeof x === "function" ? x : +x;
30032      return force;
30033    };
30034    force.friction = function(x) {
30035      if (!arguments.length) return friction;
30036      friction = +x;
30037      return force;
30038    };
30039    force.charge = function(x) {
30040      if (!arguments.length) return charge;
30041      charge = typeof x === "function" ? x : +x;
30042      return force;
30043    };
30044    force.chargeDistance = function(x) {
30045      if (!arguments.length) return Math.sqrt(chargeDistance2);
30046      chargeDistance2 = x * x;
30047      return force;
30048    };
30049    force.gravity = function(x) {
30050      if (!arguments.length) return gravity;
30051      gravity = +x;
30052      return force;
30053    };
30054    force.theta = function(x) {
30055      if (!arguments.length) return Math.sqrt(theta2);
30056      theta2 = x * x;
30057      return force;
30058    };
30059    force.alpha = function(x) {
30060      if (!arguments.length) return alpha;
30061      x = +x;
30062      if (alpha) {
30063        if (x > 0) alpha = x; else alpha = 0;
30064      } else if (x > 0) {
30065        event.start({
30066          type: "start",
30067          alpha: alpha = x
30068        });
30069        d3.timer(force.tick);
30070      }
30071      return force;
30072    };
30073    force.start = function() {
30074      var i, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o;
30075      for (i = 0; i < n; ++i) {
30076        (o = nodes[i]).index = i;
30077        o.weight = 0;
30078      }
30079      for (i = 0; i < m; ++i) {
30080        o = links[i];
30081        if (typeof o.source == "number") o.source = nodes[o.source];
30082        if (typeof o.target == "number") o.target = nodes[o.target];
30083        ++o.source.weight;
30084        ++o.target.weight;
30085      }
30086      for (i = 0; i < n; ++i) {
30087        o = nodes[i];
30088        if (isNaN(o.x)) o.x = position("x", w);
30089        if (isNaN(o.y)) o.y = position("y", h);
30090        if (isNaN(o.px)) o.px = o.x;
30091        if (isNaN(o.py)) o.py = o.y;
30092      }
30093      distances = [];
30094      if (typeof linkDistance === "function") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); else for (i = 0; i < m; ++i) distances[i] = linkDistance;
30095      strengths = [];
30096      if (typeof linkStrength === "function") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); else for (i = 0; i < m; ++i) strengths[i] = linkStrength;
30097      charges = [];
30098      if (typeof charge === "function") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); else for (i = 0; i < n; ++i) charges[i] = charge;
30099      function position(dimension, size) {
30100        if (!neighbors) {
30101          neighbors = new Array(n);
30102          for (j = 0; j < n; ++j) {
30103            neighbors[j] = [];
30104          }
30105          for (j = 0; j < m; ++j) {
30106            var o = links[j];
30107            neighbors[o.source.index].push(o.target);
30108            neighbors[o.target.index].push(o.source);
30109          }
30110        }
30111        var candidates = neighbors[i], j = -1, l = candidates.length, x;
30112        while (++j < l) if (!isNaN(x = candidates[j][dimension])) return x;
30113        return Math.random() * size;
30114      }
30115      return force.resume();
30116    };
30117    force.resume = function() {
30118      return force.alpha(.1);
30119    };
30120    force.stop = function() {
30121      return force.alpha(0);
30122    };
30123    force.drag = function() {
30124      if (!drag) drag = d3.behavior.drag().origin(d3_identity).on("dragstart.force", d3_layout_forceDragstart).on("drag.force", dragmove).on("dragend.force", d3_layout_forceDragend);
30125      if (!arguments.length) return drag;
30126      this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag);
30127    };
30128    function dragmove(d) {
30129      d.px = d3.event.x, d.py = d3.event.y;
30130      force.resume();
30131    }
30132    return d3.rebind(force, event, "on");
30133  };
30134  function d3_layout_forceDragstart(d) {
30135    d.fixed |= 2;
30136  }
30137  function d3_layout_forceDragend(d) {
30138    d.fixed &= ~6;
30139  }
30140  function d3_layout_forceMouseover(d) {
30141    d.fixed |= 4;
30142    d.px = d.x, d.py = d.y;
30143  }
30144  function d3_layout_forceMouseout(d) {
30145    d.fixed &= ~4;
30146  }
30147  function d3_layout_forceAccumulate(quad, alpha, charges) {
30148    var cx = 0, cy = 0;
30149    quad.charge = 0;
30150    if (!quad.leaf) {
30151      var nodes = quad.nodes, n = nodes.length, i = -1, c;
30152      while (++i < n) {
30153        c = nodes[i];
30154        if (c == null) continue;
30155        d3_layout_forceAccumulate(c, alpha, charges);
30156        quad.charge += c.charge;
30157        cx += c.charge * c.cx;
30158        cy += c.charge * c.cy;
30159      }
30160    }
30161    if (quad.point) {
30162      if (!quad.leaf) {
30163        quad.point.x += Math.random() - .5;
30164        quad.point.y += Math.random() - .5;
30165      }
30166      var k = alpha * charges[quad.point.index];
30167      quad.charge += quad.pointCharge = k;
30168      cx += k * quad.point.x;
30169      cy += k * quad.point.y;
30170    }
30171    quad.cx = cx / quad.charge;
30172    quad.cy = cy / quad.charge;
30173  }
30174  var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1, d3_layout_forceChargeDistance2 = Infinity;
30175  d3.layout.hierarchy = function() {
30176    var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue;
30177    function hierarchy(root) {
30178      var stack = [ root ], nodes = [], node;
30179      root.depth = 0;
30180      while ((node = stack.pop()) != null) {
30181        nodes.push(node);
30182        if ((childs = children.call(hierarchy, node, node.depth)) && (n = childs.length)) {
30183          var n, childs, child;
30184          while (--n >= 0) {
30185            stack.push(child = childs[n]);
30186            child.parent = node;
30187            child.depth = node.depth + 1;
30188          }
30189          if (value) node.value = 0;
30190          node.children = childs;
30191        } else {
30192          if (value) node.value = +value.call(hierarchy, node, node.depth) || 0;
30193          delete node.children;
30194        }
30195      }
30196      d3_layout_hierarchyVisitAfter(root, function(node) {
30197        var childs, parent;
30198        if (sort && (childs = node.children)) childs.sort(sort);
30199        if (value && (parent = node.parent)) parent.value += node.value;
30200      });
30201      return nodes;
30202    }
30203    hierarchy.sort = function(x) {
30204      if (!arguments.length) return sort;
30205      sort = x;
30206      return hierarchy;
30207    };
30208    hierarchy.children = function(x) {
30209      if (!arguments.length) return children;
30210      children = x;
30211      return hierarchy;
30212    };
30213    hierarchy.value = function(x) {
30214      if (!arguments.length) return value;
30215      value = x;
30216      return hierarchy;
30217    };
30218    hierarchy.revalue = function(root) {
30219      if (value) {
30220        d3_layout_hierarchyVisitBefore(root, function(node) {
30221          if (node.children) node.value = 0;
30222        });
30223        d3_layout_hierarchyVisitAfter(root, function(node) {
30224          var parent;
30225          if (!node.children) node.value = +value.call(hierarchy, node, node.depth) || 0;
30226          if (parent = node.parent) parent.value += node.value;
30227        });
30228      }
30229      return root;
30230    };
30231    return hierarchy;
30232  };
30233  function d3_layout_hierarchyRebind(object, hierarchy) {
30234    d3.rebind(object, hierarchy, "sort", "children", "value");
30235    object.nodes = object;
30236    object.links = d3_layout_hierarchyLinks;
30237    return object;
30238  }
30239  function d3_layout_hierarchyVisitBefore(node, callback) {
30240    var nodes = [ node ];
30241    while ((node = nodes.pop()) != null) {
30242      callback(node);
30243      if ((children = node.children) && (n = children.length)) {
30244        var n, children;
30245        while (--n >= 0) nodes.push(children[n]);
30246      }
30247    }
30248  }
30249  function d3_layout_hierarchyVisitAfter(node, callback) {
30250    var nodes = [ node ], nodes2 = [];
30251    while ((node = nodes.pop()) != null) {
30252      nodes2.push(node);
30253      if ((children = node.children) && (n = children.length)) {
30254        var i = -1, n, children;
30255        while (++i < n) nodes.push(children[i]);
30256      }
30257    }
30258    while ((node = nodes2.pop()) != null) {
30259      callback(node);
30260    }
30261  }
30262  function d3_layout_hierarchyChildren(d) {
30263    return d.children;
30264  }
30265  function d3_layout_hierarchyValue(d) {
30266    return d.value;
30267  }
30268  function d3_layout_hierarchySort(a, b) {
30269    return b.value - a.value;
30270  }
30271  function d3_layout_hierarchyLinks(nodes) {
30272    return d3.merge(nodes.map(function(parent) {
30273      return (parent.children || []).map(function(child) {
30274        return {
30275          source: parent,
30276          target: child
30277        };
30278      });
30279    }));
30280  }
30281  d3.layout.partition = function() {
30282    var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ];
30283    function position(node, x, dx, dy) {
30284      var children = node.children;
30285      node.x = x;
30286      node.y = node.depth * dy;
30287      node.dx = dx;
30288      node.dy = dy;
30289      if (children && (n = children.length)) {
30290        var i = -1, n, c, d;
30291        dx = node.value ? dx / node.value : 0;
30292        while (++i < n) {
30293          position(c = children[i], x, d = c.value * dx, dy);
30294          x += d;
30295        }
30296      }
30297    }
30298    function depth(node) {
30299      var children = node.children, d = 0;
30300      if (children && (n = children.length)) {
30301        var i = -1, n;
30302        while (++i < n) d = Math.max(d, depth(children[i]));
30303      }
30304      return 1 + d;
30305    }
30306    function partition(d, i) {
30307      var nodes = hierarchy.call(this, d, i);
30308      position(nodes[0], 0, size[0], size[1] / depth(nodes[0]));
30309      return nodes;
30310    }
30311    partition.size = function(x) {
30312      if (!arguments.length) return size;
30313      size = x;
30314      return partition;
30315    };
30316    return d3_layout_hierarchyRebind(partition, hierarchy);
30317  };
30318  d3.layout.pie = function() {
30319    var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = τ, padAngle = 0;
30320    function pie(data) {
30321      var n = data.length, values = data.map(function(d, i) {
30322        return +value.call(pie, d, i);
30323      }), a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle), da = (typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a, p = Math.min(Math.abs(da) / n, +(typeof padAngle === "function" ? padAngle.apply(this, arguments) : padAngle)), pa = p * (da < 0 ? -1 : 1), k = (d
vendor: 22,440 bytes, lines 30323-30989
30323a - n * pa) / d3.sum(values), index = d3.range(n), arcs = [], v;
30324      if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) {
30325        return values[j] - values[i];
30326      } : function(i, j) {
30327        return sort(data[i], data[j]);
30328      });
30329      index.forEach(function(i) {
30330        arcs[i] = {
30331          data: data[i],
30332          value: v = values[i],
30333          startAngle: a,
30334          endAngle: a += v * k + pa,
30335          padAngle: p
30336        };
30337      });
30338      return arcs;
30339    }
30340    pie.value = function(_) {
30341      if (!arguments.length) return value;
30342      value = _;
30343      return pie;
30344    };
30345    pie.sort = function(_) {
30346      if (!arguments.length) return sort;
30347      sort = _;
30348      return pie;
30349    };
30350    pie.startAngle = function(_) {
30351      if (!arguments.length) return startAngle;
30352      startAngle = _;
30353      return pie;
30354    };
30355    pie.endAngle = function(_) {
30356      if (!arguments.length) return endAngle;
30357      endAngle = _;
30358      return pie;
30359    };
30360    pie.padAngle = function(_) {
30361      if (!arguments.length) return padAngle;
30362      padAngle = _;
30363      return pie;
30364    };
30365    return pie;
30366  };
30367  var d3_layout_pieSortByValue = {};
30368  d3.layout.stack = function() {
30369    var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY;
30370    function stack(data, index) {
30371      if (!(n = data.length)) return data;
30372      var series = data.map(function(d, i) {
30373        return values.call(stack, d, i);
30374      });
30375      var points = series.map(function(d) {
30376        return d.map(function(v, i) {
30377          return [ x.call(stack, v, i), y.call(stack, v, i) ];
30378        });
30379      });
30380      var orders = order.call(stack, points, index);
30381      series = d3.permute(series, orders);
30382      points = d3.permute(points, orders);
30383      var offsets = offset.call(stack, points, index);
30384      var m = series[0].length, n, i, j, o;
30385      for (j = 0; j < m; ++j) {
30386        out.call(stack, series[0][j], o = offsets[j], points[0][j][1]);
30387        for (i = 1; i < n; ++i) {
30388          out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]);
30389        }
30390      }
30391      return data;
30392    }
30393    stack.values = function(x) {
30394      if (!arguments.length) return values;
30395      values = x;
30396      return stack;
30397    };
30398    stack.order = function(x) {
30399      if (!arguments.length) return order;
30400      order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault;
30401      return stack;
30402    };
30403    stack.offset = function(x) {
30404      if (!arguments.length) return offset;
30405      offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero;
30406      return stack;
30407    };
30408    stack.x = function(z) {
30409      if (!arguments.length) return x;
30410      x = z;
30411      return stack;
30412    };
30413    stack.y = function(z) {
30414      if (!arguments.length) return y;
30415      y = z;
30416      return stack;
30417    };
30418    stack.out = function(z) {
30419      if (!arguments.length) return out;
30420      out = z;
30421      return stack;
30422    };
30423    return stack;
30424  };
30425  function d3_layout_stackX(d) {
30426    return d.x;
30427  }
30428  function d3_layout_stackY(d) {
30429    return d.y;
30430  }
30431  function d3_layout_stackOut(d, y0, y) {
30432    d.y0 = y0;
30433    d.y = y;
30434  }
30435  var d3_layout_stackOrders = d3.map({
30436    "inside-out": function(data) {
30437      var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) {
30438        return max[a] - max[b];
30439      }), top = 0, bottom = 0, tops = [], bottoms = [];
30440      for (i = 0; i < n; ++i) {
30441        j = index[i];
30442        if (top < bottom) {
30443          top += sums[j];
30444          tops.push(j);
30445        } else {
30446          bottom += sums[j];
30447          bottoms.push(j);
30448        }
30449      }
30450      return bottoms.reverse().concat(tops);
30451    },
30452    reverse: function(data) {
30453      return d3.range(data.length).reverse();
30454    },
30455    "default": d3_layout_stackOrderDefault
30456  });
30457  var d3_layout_stackOffsets = d3.map({
30458    silhouette: function(data) {
30459      var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = [];
30460      for (j = 0; j < m; ++j) {
30461        for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
30462        if (o > max) max = o;
30463        sums.push(o);
30464      }
30465      for (j = 0; j < m; ++j) {
30466        y0[j] = (max - sums[j]) / 2;
30467      }
30468      return y0;
30469    },
30470    wiggle: function(data) {
30471      var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = [];
30472      y0[0] = o = o0 = 0;
30473      for (j = 1; j < m; ++j) {
30474        for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1];
30475        for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) {
30476          for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) {
30477            s3 += (data[k][j][1] - data[k][j - 1][1]) / dx;
30478          }
30479          s2 += s3 * data[i][j][1];
30480        }
30481        y0[j] = o -= s1 ? s2 / s1 * dx : 0;
30482        if (o < o0) o0 = o;
30483      }
30484      for (j = 0; j < m; ++j) y0[j] -= o0;
30485      return y0;
30486    },
30487    expand: function(data) {
30488      var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = [];
30489      for (j = 0; j < m; ++j) {
30490        for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
30491        if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k;
30492      }
30493      for (j = 0; j < m; ++j) y0[j] = 0;
30494      return y0;
30495    },
30496    zero: d3_layout_stackOffsetZero
30497  });
30498  function d3_layout_stackOrderDefault(data) {
30499    return d3.range(data.length);
30500  }
30501  function d3_layout_stackOffsetZero(data) {
30502    var j = -1, m = data[0].length, y0 = [];
30503    while (++j < m) y0[j] = 0;
30504    return y0;
30505  }
30506  function d3_layout_stackMaxIndex(array) {
30507    var i = 1, j = 0, v = array[0][1], k, n = array.length;
30508    for (;i < n; ++i) {
30509      if ((k = array[i][1]) > v) {
30510        j = i;
30511        v = k;
30512      }
30513    }
30514    return j;
30515  }
30516  function d3_layout_stackReduceSum(d) {
30517    return d.reduce(d3_layout_stackSum, 0);
30518  }
30519  function d3_layout_stackSum(p, d) {
30520    return p + d[1];
30521  }
30522  d3.layout.histogram = function() {
30523    var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges;
30524    function histogram(data, i) {
30525      var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x;
30526      while (++i < m) {
30527        bin = bins[i] = [];
30528        bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]);
30529        bin.y = 0;
30530      }
30531      if (m > 0) {
30532        i = -1;
30533        while (++i < n) {
30534          x = values[i];
30535          if (x >= range[0] && x <= range[1]) {
30536            bin = bins[d3.bisect(thresholds, x, 1, m) - 1];
30537            bin.y += k;
30538            bin.push(data[i]);
30539          }
30540        }
30541      }
30542      return bins;
30543    }
30544    histogram.value = function(x) {
30545      if (!arguments.length) return valuer;
30546      valuer = x;
30547      return histogram;
30548    };
30549    histogram.range = function(x) {
30550      if (!arguments.length) return ranger;
30551      ranger = d3_functor(x);
30552      return histogram;
30553    };
30554    histogram.bins = function(x) {
30555      if (!arguments.length) return binner;
30556      binner = typeof x === "number" ? function(range) {
30557        return d3_layout_histogramBinFixed(range, x);
30558      } : d3_functor(x);
30559      return histogram;
30560    };
30561    histogram.frequency = function(x) {
30562      if (!arguments.length) return frequency;
30563      frequency = !!x;
30564      return histogram;
30565    };
30566    return histogram;
30567  };
30568  function d3_layout_histogramBinSturges(range, values) {
30569    return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1));
30570  }
30571  function d3_layout_histogramBinFixed(range, n) {
30572    var x = -1, b = +range[0], m = (range[1] - b) / n, f = [];
30573    while (++x <= n) f[x] = m * x + b;
30574    return f;
30575  }
30576  function d3_layout_histogramRange(values) {
30577    return [ d3.min(values), d3.max(values) ];
30578  }
30579  d3.layout.pack = function() {
30580    var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius;
30581    function pack(d, i) {
30582      var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() {
30583        return radius;
30584      };
30585      root.x = root.y = 0;
30586      d3_layout_hierarchyVisitAfter(root, function(d) {
30587        d.r = +r(d.value);
30588      });
30589      d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings);
30590      if (padding) {
30591        var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2;
30592        d3_layout_hierarchyVisitAfter(root, function(d) {
30593          d.r += dr;
30594        });
30595        d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings);
30596        d3_layout_hierarchyVisitAfter(root, function(d) {
30597          d.r -= dr;
30598        });
30599      }
30600      d3_layout_packTransform(root, w / 2, h / 2, radius ? 1 : 1 / Math.max(2 * root.r / w, 2 * root.r / h));
30601      return nodes;
30602    }
30603    pack.size = function(_) {
30604      if (!arguments.length) return size;
30605      size = _;
30606      return pack;
30607    };
30608    pack.radius = function(_) {
30609      if (!arguments.length) return radius;
30610      radius = _ == null || typeof _ === "function" ? _ : +_;
30611      return pack;
30612    };
30613    pack.padding = function(_) {
30614      if (!arguments.length) return padding;
30615      padding = +_;
30616      return pack;
30617    };
30618    return d3_layout_hierarchyRebind(pack, hierarchy);
30619  };
30620  function d3_layout_packSort(a, b) {
30621    return a.value - b.value;
30622  }
30623  function d3_layout_packInsert(a, b) {
30624    var c = a._pack_next;
30625    a._pack_next = b;
30626    b._pack_prev = a;
30627    b._pack_next = c;
30628    c._pack_prev = b;
30629  }
30630  function d3_layout_packSplice(a, b) {
30631    a._pack_next = b;
30632    b._pack_prev = a;
30633  }
30634  function d3_layout_packIntersects(a, b) {
30635    var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r;
30636    return .999 * dr * dr > dx * dx + dy * dy;
30637  }
30638  function d3_layout_packSiblings(node) {
30639    if (!(nodes = node.children) || !(n = nodes.length)) return;
30640    var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n;
30641    function bound(node) {
30642      xMin = Math.min(node.x - node.r, xMin);
30643      xMax = Math.max(node.x + node.r, xMax);
30644      yMin = Math.min(node.y - node.r, yMin);
30645      yMax = Math.max(node.y + node.r, yMax);
30646    }
30647    nodes.forEach(d3_layout_packLink);
30648    a = nodes[0];
30649    a.x = -a.r;
30650    a.y = 0;
30651    bound(a);
30652    if (n > 1) {
30653      b = nodes[1];
30654      b.x = b.r;
30655      b.y = 0;
30656      bound(b);
30657      if (n > 2) {
30658        c = nodes[2];
30659        d3_layout_packPlace(a, b, c);
30660        bound(c);
30661        d3_layout_packInsert(a, c);
30662        a._pack_prev = c;
30663        d3_layout_packInsert(c, b);
30664        b = a._pack_next;
30665        for (i = 3; i < n; i++) {
30666          d3_layout_packPlace(a, b, c = nodes[i]);
30667          var isect = 0, s1 = 1, s2 = 1;
30668          for (j = b._pack_next; j !== b; j = j._pack_next, s1++) {
30669            if (d3_layout_packIntersects(j, c)) {
30670              isect = 1;
30671              break;
30672            }
30673          }
30674          if (isect == 1) {
30675            for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) {
30676              if (d3_layout_packIntersects(k, c)) {
30677                break;
30678              }
30679            }
30680          }
30681          if (isect) {
30682            if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b);
30683            i--;
30684          } else {
30685            d3_layout_packInsert(a, c);
30686            b = c;
30687            bound(c);
30688          }
30689        }
30690      }
30691    }
30692    var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0;
30693    for (i = 0; i < n; i++) {
30694      c = nodes[i];
30695      c.x -= cx;
30696      c.y -= cy;
30697      cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y));
30698    }
30699    node.r = cr;
30700    nodes.forEach(d3_layout_packUnlink);
30701  }
30702  function d3_layout_packLink(node) {
30703    node._pack_next = node._pack_prev = node;
30704  }
30705  function d3_layout_packUnlink(node) {
30706    delete node._pack_next;
30707    delete node._pack_prev;
30708  }
30709  function d3_layout_packTransform(node, x, y, k) {
30710    var children = node.children;
30711    node.x = x += k * node.x;
30712    node.y = y += k * node.y;
30713    node.r *= k;
30714    if (children) {
30715      var i = -1, n = children.length;
30716      while (++i < n) d3_layout_packTransform(children[i], x, y, k);
30717    }
30718  }
30719  function d3_layout_packPlace(a, b, c) {
30720    var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y;
30721    if (db && (dx || dy)) {
30722      var da = b.r + c.r, dc = dx * dx + dy * dy;
30723      da *= da;
30724      db *= db;
30725      var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);
30726      c.x = a.x + x * dx + y * dy;
30727      c.y = a.y + x * dy - y * dx;
30728    } else {
30729      c.x = a.x + db;
30730      c.y = a.y;
30731    }
30732  }
30733  d3.layout.tree = function() {
30734    var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = null;
30735    function tree(d, i) {
30736      var nodes = hierarchy.call(this, d, i), root0 = nodes[0], root1 = wrapTree(root0);
30737      d3_layout_hierarchyVisitAfter(root1, firstWalk), root1.parent.m = -root1.z;
30738      d3_layout_hierarchyVisitBefore(root1, secondWalk);
30739      if (nodeSize) d3_layout_hierarchyVisitBefore(root0, sizeNode); else {
30740        var left = root0, right = root0, bottom = root0;
30741        d3_layout_hierarchyVisitBefore(root0, function(node) {
30742          if (node.x < left.x) left = node;
30743          if (node.x > right.x) right = node;
30744          if (node.depth > bottom.depth) bottom = node;
30745        });
30746        var tx = separation(left, right) / 2 - left.x, kx = size[0] / (right.x + separation(right, left) / 2 + tx), ky = size[1] / (bottom.depth || 1);
30747        d3_layout_hierarchyVisitBefore(root0, function(node) {
30748          node.x = (node.x + tx) * kx;
30749          node.y = node.depth * ky;
30750        });
30751      }
30752      return nodes;
30753    }
30754    function wrapTree(root0) {
30755      var root1 = {
30756        A: null,
30757        children: [ root0 ]
30758      }, queue = [ root1 ], node1;
30759      while ((node1 = queue.pop()) != null) {
30760        for (var children = node1.children, child, i = 0, n = children.length; i < n; ++i) {
30761          queue.push((children[i] = child = {
30762            _: children[i],
30763            parent: node1,
30764            children: (child = children[i].children) && child.slice() || [],
30765            A: null,
30766            a: null,
30767            z: 0,
30768            m: 0,
30769            c: 0,
30770            s: 0,
30771            t: null,
30772            i: i
30773          }).a = child);
30774        }
30775      }
30776      return root1.children[0];
30777    }
30778    function firstWalk(v) {
30779      var children = v.children, siblings = v.parent.children, w = v.i ? siblings[v.i - 1] : null;
30780      if (children.length) {
30781        d3_layout_treeShift(v);
30782        var midpoint = (children[0].z + children[children.length - 1].z) / 2;
30783        if (w) {
30784          v.z = w.z + separation(v._, w._);
30785          v.m = v.z - midpoint;
30786        } else {
30787          v.z = midpoint;
30788        }
30789      } else if (w) {
30790        v.z = w.z + separation(v._, w._);
30791      }
30792      v.parent.A = apportion(v, w, v.parent.A || siblings[0]);
30793    }
30794    function secondWalk(v) {
30795      v._.x = v.z + v.parent.m;
30796      v.m += v.parent.m;
30797    }
30798    function apportion(v, w, ancestor) {
30799      if (w) {
30800        var vip = v, vop = v, vim = w, vom = vip.parent.children[0], sip = vip.m, sop = vop.m, sim = vim.m, som = vom.m, shift;
30801        while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) {
30802          vom = d3_layout_treeLeft(vom);
30803          vop = d3_layout_treeRight(vop);
30804          vop.a = v;
30805          shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);
30806          if (shift > 0) {
30807            d3_layout_treeMove(d3_layout_treeAncestor(vim, v, ancestor), v, shift);
30808            sip += shift;
30809            sop += shift;
30810          }
30811          sim += vim.m;
30812          sip += vip.m;
30813          som += vom.m;
30814          sop += vop.m;
30815        }
30816        if (vim && !d3_layout_treeRight(vop)) {
30817          vop.t = vim;
30818          vop.m += sim - sop;
30819        }
30820        if (vip && !d3_layout_treeLeft(vom)) {
30821          vom.t = vip;
30822          vom.m += sip - som;
30823          ancestor = v;
30824        }
30825      }
30826      return ancestor;
30827    }
30828    function sizeNode(node) {
30829      node.x *= size[0];
30830      node.y = node.depth * size[1];
30831    }
30832    tree.separation = function(x) {
30833      if (!arguments.length) return separation;
30834      separation = x;
30835      return tree;
30836    };
30837    tree.size = function(x) {
30838      if (!arguments.length) return nodeSize ? null : size;
30839      nodeSize = (size = x) == null ? sizeNode : null;
30840      return tree;
30841    };
30842    tree.nodeSize = function(x) {
30843      if (!arguments.length) return nodeSize ? size : null;
30844      nodeSize = (size = x) == null ? null : sizeNode;
30845      return tree;
30846    };
30847    return d3_layout_hierarchyRebind(tree, hierarchy);
30848  };
30849  function d3_layout_treeSeparation(a, b) {
30850    return a.parent == b.parent ? 1 : 2;
30851  }
30852  function d3_layout_treeLeft(v) {
30853    var children = v.children;
30854    return children.length ? children[0] : v.t;
30855  }
30856  function d3_layout_treeRight(v) {
30857    var children = v.children, n;
30858    return (n = children.length) ? children[n - 1] : v.t;
30859  }
30860  function d3_layout_treeMove(wm, wp, shift) {
30861    var change = shift / (wp.i - wm.i);
30862    wp.c -= change;
30863    wp.s += shift;
30864    wm.c += change;
30865    wp.z += shift;
30866    wp.m += shift;
30867  }
30868  function d3_layout_treeShift(v) {
30869    var shift = 0, change = 0, children = v.children, i = children.length, w;
30870    while (--i >= 0) {
30871      w = children[i];
30872      w.z += shift;
30873      w.m += shift;
30874      shift += w.s + (change += w.c);
30875    }
30876  }
30877  function d3_layout_treeAncestor(vim, v, ancestor) {
30878    return vim.a.parent === v.parent ? vim.a : ancestor;
30879  }
30880  d3.layout.cluster = function() {
30881    var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false;
30882    function cluster(d, i) {
30883      var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0;
30884      d3_layout_hierarchyVisitAfter(root, function(node) {
30885        var children = node.children;
30886        if (children && children.length) {
30887          node.x = d3_layout_clusterX(children);
30888          node.y = d3_layout_clusterY(children);
30889        } else {
30890          node.x = previousNode ? x += separation(node, previousNode) : 0;
30891          node.y = 0;
30892          previousNode = node;
30893        }
30894      });
30895      var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2;
30896      d3_layout_hierarchyVisitAfter(root, nodeSize ? function(node) {
30897        node.x = (node.x - root.x) * size[0];
30898        node.y = (root.y - node.y) * size[1];
30899      } : function(node) {
30900        node.x = (node.x - x0) / (x1 - x0) * size[0];
30901        node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1];
30902      });
30903      return nodes;
30904    }
30905    cluster.separation = function(x) {
30906      if (!arguments.length) return separation;
30907      separation = x;
30908      return cluster;
30909    };
30910    cluster.size = function(x) {
30911      if (!arguments.length) return nodeSize ? null : size;
30912      nodeSize = (size = x) == null;
30913      return cluster;
30914    };
30915    cluster.nodeSize = function(x) {
30916      if (!arguments.length) return nodeSize ? size : null;
30917      nodeSize = (size = x) != null;
30918      return cluster;
30919    };
30920    return d3_layout_hierarchyRebind(cluster, hierarchy);
30921  };
30922  function d3_layout_clusterY(children) {
30923    return 1 + d3.max(children, function(child) {
30924      return child.y;
30925    });
30926  }
30927  function d3_layout_clusterX(children) {
30928    return children.reduce(function(x, child) {
30929      return x + child.x;
30930    }, 0) / children.length;
30931  }
30932  function d3_layout_clusterLeft(node) {
30933    var children = node.children;
30934    return children && children.length ? d3_layout_clusterLeft(children[0]) : node;
30935  }
30936  function d3_layout_clusterRight(node) {
30937    var children = node.children, n;
30938    return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node;
30939  }
30940  d3.layout.treemap = function() {
30941    var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = "squarify", ratio = .5 * (1 + Math.sqrt(5));
30942    function scale(children, k) {
30943      var i = -1, n = children.length, child, area;
30944      while (++i < n) {
30945        area = (child = children[i]).value * (k < 0 ? 0 : k);
30946        child.area = isNaN(area) || area <= 0 ? 0 : area;
30947      }
30948    }
30949    function squarify(node) {
30950      var children = node.children;
30951      if (children && children.length) {
30952        var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === "slice" ? rect.dx : mode === "dice" ? rect.dy : mode === "slice-dice" ? node.depth & 1 ? rect.dy : rect.dx : Math.min(rect.dx, rect.dy), n;
30953        scale(remaining, rect.dx * rect.dy / node.value);
30954        row.area = 0;
30955        while ((n = remaining.length) > 0) {
30956          row.push(child = remaining[n - 1]);
30957          row.area += child.area;
30958          if (mode !== "squarify" || (score = worst(row, u)) <= best) {
30959            remaining.pop();
30960            best = score;
30961          } else {
30962            row.area -= row.pop().area;
30963            position(row, u, rect, false);
30964            u = Math.min(rect.dx, rect.dy);
30965            row.length = row.area = 0;
30966            best = Infinity;
30967          }
30968        }
30969        if (row.length) {
30970          position(row, u, rect, true);
30971          row.length = row.area = 0;
30972        }
30973        children.forEach(squarify);
30974      }
30975    }
30976    function stickify(node) {
30977      var children = node.children;
30978      if (children && children.length) {
30979        var rect = pad(node), remaining = children.slice(), child, row = [];
30980        scale(remaining, rect.dx * rect.dy / node.value);
30981        row.area = 0;
30982        while (child = remaining.pop()) {
30983          row.push(child);
30984          row.area += child.area;
30985          if (child.z != null) {
30986            position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length);
30987            row.length = row.area = 0;
30988          }
30989        }
vendor: 6,641 bytes, lines 30990-31210
30990        children.forEach(stickify);
30991      }
30992    }
30993    function worst(row, u) {
30994      var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length;
30995      while (++i < n) {
30996        if (!(r = row[i].area)) continue;
30997        if (r < rmin) rmin = r;
30998        if (r > rmax) rmax = r;
30999      }
31000      s *= s;
31001      u *= u;
31002      return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity;
31003    }
31004    function position(row, u, rect, flush) {
31005      var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o;
31006      if (u == rect.dx) {
31007        if (flush || v > rect.dy) v = rect.dy;
31008        while (++i < n) {
31009          o = row[i];
31010          o.x = x;
31011          o.y = y;
31012          o.dy = v;
31013          x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0);
31014        }
31015        o.z = true;
31016        o.dx += rect.x + rect.dx - x;
31017        rect.y += v;
31018        rect.dy -= v;
31019      } else {
31020        if (flush || v > rect.dx) v = rect.dx;
31021        while (++i < n) {
31022          o = row[i];
31023          o.x = x;
31024          o.y = y;
31025          o.dx = v;
31026          y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0);
31027        }
31028        o.z = false;
31029        o.dy += rect.y + rect.dy - y;
31030        rect.x += v;
31031        rect.dx -= v;
31032      }
31033    }
31034    function treemap(d) {
31035      var nodes = stickies || hierarchy(d), root = nodes[0];
31036      root.x = 0;
31037      root.y = 0;
31038      root.dx = size[0];
31039      root.dy = size[1];
31040      if (stickies) hierarchy.revalue(root);
31041      scale([ root ], root.dx * root.dy / root.value);
31042      (stickies ? stickify : squarify)(root);
31043      if (sticky) stickies = nodes;
31044      return nodes;
31045    }
31046    treemap.size = function(x) {
31047      if (!arguments.length) return size;
31048      size = x;
31049      return treemap;
31050    };
31051    treemap.padding = function(x) {
31052      if (!arguments.length) return padding;
31053      function padFunction(node) {
31054        var p = x.call(treemap, node, node.depth);
31055        return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === "number" ? [ p, p, p, p ] : p);
31056      }
31057      function padConstant(node) {
31058        return d3_layout_treemapPad(node, x);
31059      }
31060      var type;
31061      pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === "function" ? padFunction : type === "number" ? (x = [ x, x, x, x ], 
31062      padConstant) : padConstant;
31063      return treemap;
31064    };
31065    treemap.round = function(x) {
31066      if (!arguments.length) return round != Number;
31067      round = x ? Math.round : Number;
31068      return treemap;
31069    };
31070    treemap.sticky = function(x) {
31071      if (!arguments.length) return sticky;
31072      sticky = x;
31073      stickies = null;
31074      return treemap;
31075    };
31076    treemap.ratio = function(x) {
31077      if (!arguments.length) return ratio;
31078      ratio = x;
31079      return treemap;
31080    };
31081    treemap.mode = function(x) {
31082      if (!arguments.length) return mode;
31083      mode = x + "";
31084      return treemap;
31085    };
31086    return d3_layout_hierarchyRebind(treemap, hierarchy);
31087  };
31088  function d3_layout_treemapPadNull(node) {
31089    return {
31090      x: node.x,
31091      y: node.y,
31092      dx: node.dx,
31093      dy: node.dy
31094    };
31095  }
31096  function d3_layout_treemapPad(node, padding) {
31097    var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2];
31098    if (dx < 0) {
31099      x += dx / 2;
31100      dx = 0;
31101    }
31102    if (dy < 0) {
31103      y += dy / 2;
31104      dy = 0;
31105    }
31106    return {
31107      x: x,
31108      y: y,
31109      dx: dx,
31110      dy: dy
31111    };
31112  }
31113  d3.random = {
31114    normal: function(µ, σ) {
31115      var n = arguments.length;
31116      if (n < 2) σ = 1;
31117      if (n < 1) µ = 0;
31118      return function() {
31119        var x, y, r;
31120        do {
31121          x = Math.random() * 2 - 1;
31122          y = Math.random() * 2 - 1;
31123          r = x * x + y * y;
31124        } while (!r || r > 1);
31125        return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r);
31126      };
31127    },
31128    logNormal: function() {
31129      var random = d3.random.normal.apply(d3, arguments);
31130      return function() {
31131        return Math.exp(random());
31132      };
31133    },
31134    bates: function(m) {
31135      var random = d3.random.irwinHall(m);
31136      return function() {
31137        return random() / m;
31138      };
31139    },
31140    irwinHall: function(m) {
31141      return function() {
31142        for (var s = 0, j = 0; j < m; j++) s += Math.random();
31143        return s;
31144      };
31145    }
31146  };
31147  d3.scale = {};
31148  function d3_scaleExtent(domain) {
31149    var start = domain[0], stop = domain[domain.length - 1];
31150    return start < stop ? [ start, stop ] : [ stop, start ];
31151  }
31152  function d3_scaleRange(scale) {
31153    return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range());
31154  }
31155  function d3_scale_bilinear(domain, range, uninterpolate, interpolate) {
31156    var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]);
31157    return function(x) {
31158      return i(u(x));
31159    };
31160  }
31161  function d3_scale_nice(domain, nice) {
31162    var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx;
31163    if (x1 < x0) {
31164      dx = i0, i0 = i1, i1 = dx;
31165      dx = x0, x0 = x1, x1 = dx;
31166    }
31167    domain[i0] = nice.floor(x0);
31168    domain[i1] = nice.ceil(x1);
31169    return domain;
31170  }
31171  function d3_scale_niceStep(step) {
31172    return step ? {
31173      floor: function(x) {
31174        return Math.floor(x / step) * step;
31175      },
31176      ceil: function(x) {
31177        return Math.ceil(x / step) * step;
31178      }
31179    } : d3_scale_niceIdentity;
31180  }
31181  var d3_scale_niceIdentity = {
31182    floor: d3_identity,
31183    ceil: d3_identity
31184  };
31185  function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
31186    var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1;
31187    if (domain[k] < domain[0]) {
31188      domain = domain.slice().reverse();
31189      range = range.slice().reverse();
31190    }
31191    while (++j <= k) {
31192      u.push(uninterpolate(domain[j - 1], domain[j]));
31193      i.push(interpolate(range[j - 1], range[j]));
31194    }
31195    return function(x) {
31196      var j = d3.bisect(domain, x, 1, k) - 1;
31197      return i[j](u[j](x));
31198    };
31199  }
31200  d3.scale.linear = function() {
31201    return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3_interpolate, false);
31202  };
31203  function d3_scale_linear(domain, range, interpolate, clamp) {
31204    var output, input;
31205    function rescale() {
31206      var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber;
31207      output = linear(domain, range, uninterpolate, interpolate);
31208      input = linear(range, domain, uninterpolate, d3_interpolate);
31209      return scale;
31210    }
31211    function scale(x) {
31212      return output(x);
31213    }
31214    scale.invert = function(y) {
31215      return input(y);
31216    };
31217    scale.domain = function(x) {
31218      if (!arguments.length) return domain;
31219      domain = x.map(Number);
31220      return rescale();
31221    };
31222    scale.range = function(x) {
31223      if (!arguments.length) return range;
31224      range = x;
31225      return rescale();
31226    };
31227    scale.rangeRound = function(x) {
31228      return scale.range(x).interpolate(d3_interpolateRound);
31229    };
31230    scale.clamp = function(x) {
31231      if (!arguments.length) return clamp;
31232      clamp = x;
31233      return rescale();
31234    };
31235    scale.interpolate = function(x) {
31236      if (!arguments.length) return interpolate;
31237      interpolate = x;
31238      return rescale();
31239    };
31240    scale.ticks = function(m) {
31241      return d3_scale_linearTicks(domain, m);
31242    };
31243    scale.tickFormat = function(m, format) {
31244      return d3_scale_linearTickFormat(domain, m, format);
31245    };
31246    scale.nice = function(m) {
31247      d3_scale_linearNice(domain, m);
31248      return rescale();
31249    };
31250    scale.copy = function() {
31251      return d3_scale_linear(domain, range, interpolate, clamp);
31252    };
31253    return rescale();
31254  }
31255  function d3_scale_linearRebind(scale, linear) {
31256    return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp");
31257  }
31258  function d3_scale_linearNice(domain, m) {
31259    return d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2]));
31260  }
31261  function d3_scale_linearTickRange(domain, m) {
31262    if (m == null) m = 10;
31263    var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step;
31264    if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2;
31265    extent[0] = Math.ceil(extent[0] / step) * step;
31266    extent[1] = Math.floor(extent[1] / step) * step + step * .5;
31267    extent[2] = step;
31268    return extent;
31269  }
31270  function d3_scale_linearTicks(domain, m) {
31271    return d3.range.apply(d3, d3_scale_linearTickRange(domain, m));
31272  }
31273  function d3_scale_linearTickFormat(domain, m, format) {
31274    var range = d3_scale_linearTickRange(domain, m);
31275    if (format) {
31276      var match = d3_format_re.exec(format);
31277      match.shift();
31278      if (match[8] === "s") {
31279        var prefix = d3.formatPrefix(Math.max(abs(range[0]), abs(range[1])));
31280        if (!match[7]) match[7] = "." + d3_scale_linearPrecision(prefix.scale(range[2]));
31281        match[8] = "f";
31282        format = d3.format(match.join(""));
31283        return function(d) {
31284          return format(prefix.scale(d)) + prefix.symbol;
31285        };
31286      }
31287      if (!match[7]) match[7] = "." + d3_scale_linearFormatPrecision(match[8], range);
31288      format = match.join("");
31289    } else {
31290      format = ",." + d3_scale_linearPrecision(range[2]) + "f";
31291    }
31292    return d3.format(format);
31293  }
31294  var d3_scale_linearFormatSignificant = {
31295    s: 1,
31296    g: 1,
31297    p: 1,
31298    r: 1,
31299    e: 1
31300  };
31301  function d3_scale_linearPrecision(value) {
31302    return -Math.floor(Math.log(value) / Math.LN10 + .01);
31303  }
31304  function d3_scale_linearFormatPrecision(type, range) {
31305    var p = d3_scale_linearPrecision(range[2]);
31306    return type in d3_scale_linearFormatSignificant ? Math.abs(p - d3_scale_linearPrecision(Math.max(abs(range[0]), abs(range[1])))) + +(type !== "e") : p - (type === "%") * 2;
31307  }
31308  d3.scale.log = function() {
31309    return d3_scale_log(d3.scale.linear().domain([ 0, 1 ]), 10, true, [ 1, 10 ]);
31310  };
31311  function d3_scale_log(linear, base, positive, domain) {
31312    function log(x) {
31313      return (positive ? Math.log(x < 0 ? 0 : x) : -Math.log(x > 0 ? 0 : -x)) / Math.log(base);
31314    }
31315    function pow(x) {
31316      return positive ? Math.pow(base, x) : -Math.pow(base, -x);
31317    }
31318    function scale(x) {
31319      return linear(log(x));
31320    }
31321    scale.invert = function(x) {
31322      return pow(linear.invert(x));
31323    };
31324    scale.domain = function(x) {
31325      if (!arguments.length) return domain;
31326      positive = x[0] >= 0;
31327      linear.domain((domain = x.map(Number)).map(log));
31328      return scale;
31329    };
31330    scale.base = function(_) {
31331      if (!arguments.length) return base;
31332      base = +_;
31333      linear.domain(domain.map(log));
31334      return scale;
31335    };
31336    scale.nice = function() {
31337      var niced = d3_scale_nice(domain.map(log), positive ? Math : d3_scale_logNiceNegative);
31338      linear.domain(niced);
31339      domain = niced.map(pow);
31340      return scale;
31341    };
31342    scale.ticks = function() {
31343      var extent = d3_scaleExtent(domain), ticks = [], u = extent[0], v = extent[1], i = Math.floor(log(u)), j = Math.ceil(log(v)), n = base % 1 ? 2 : base;
31344      if (isFinite(j - i)) {
31345        if (positive) {
31346          for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(pow(i) * k);
31347          ticks.push(pow(i));
31348        } else {
31349          ticks.push(pow(i));
31350          for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(pow(i) * k);
31351        }
31352        for (i = 0; ticks[i] < u; i++) {}
31353        for (j = ticks.length; ticks[j - 1] > v; j--) {}
31354        ticks = ticks.slice(i, j);
31355      }
31356      return ticks;
31357    };
31358    scale.tickFormat = function(n, format) {
31359      if (!arguments.length) return d3_scale_logFormat;
31360      if (arguments.length < 2) format = d3_scale_logFormat; else if (typeof format !== "function") format = d3.format(format);
31361      var k = Math.max(.1, n / scale.ticks().length), f = positive ? (e = 1e-12, Math.ceil) : (e = -1e-12, 
31362      Math.floor), e;
31363      return function(d) {
31364        return d / pow(f(log(d) + e)) <= k ? format(d) : "";
31365      };
31366    };
31367    scale.copy = function() {
31368      return d3_scale_log(linear.copy(), base, positive, domain);
31369    };
31370    return d3_scale_linearRebind(scale, linear);
31371  }
31372  var d3_scale_logFormat = d3.format(".0e"), d3_scale_logNiceNegative = {
31373    floor: function(x) {
31374      return -Math.ceil(-x);
31375    },
31376    ceil: function(x) {
31377      return -Math.floor(-x);
31378    }
31379  };
31380  d3.scale.pow = function() {
31381    return d3_scale_pow(d3.scale.linear(), 1, [ 0, 1 ]);
31382  };
31383  function d3_scale_pow(linear, exponent, domain) {
31384    var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent);
vendor: 45,711 bytes, lines 31385-32585
31385    function scale(x) {
31386      return linear(powp(x));
31387    }
31388    scale.invert = function(x) {
31389      return powb(linear.invert(x));
31390    };
31391    scale.domain = function(x) {
31392      if (!arguments.length) return domain;
31393      linear.domain((domain = x.map(Number)).map(powp));
31394      return scale;
31395    };
31396    scale.ticks = function(m) {
31397      return d3_scale_linearTicks(domain, m);
31398    };
31399    scale.tickFormat = function(m, format) {
31400      return d3_scale_linearTickFormat(domain, m, format);
31401    };
31402    scale.nice = function(m) {
31403      return scale.domain(d3_scale_linearNice(domain, m));
31404    };
31405    scale.exponent = function(x) {
31406      if (!arguments.length) return exponent;
31407      powp = d3_scale_powPow(exponent = x);
31408      powb = d3_scale_powPow(1 / exponent);
31409      linear.domain(domain.map(powp));
31410      return scale;
31411    };
31412    scale.copy = function() {
31413      return d3_scale_pow(linear.copy(), exponent, domain);
31414    };
31415    return d3_scale_linearRebind(scale, linear);
31416  }
31417  function d3_scale_powPow(e) {
31418    return function(x) {
31419      return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e);
31420    };
31421  }
31422  d3.scale.sqrt = function() {
31423    return d3.scale.pow().exponent(.5);
31424  };
31425  d3.scale.ordinal = function() {
31426    return d3_scale_ordinal([], {
31427      t: "range",
31428      a: [ [] ]
31429    });
31430  };
31431  function d3_scale_ordinal(domain, ranger) {
31432    var index, range, rangeBand;
31433    function scale(x) {
31434      return range[((index.get(x) || (ranger.t === "range" ? index.set(x, domain.push(x)) : NaN)) - 1) % range.length];
31435    }
31436    function steps(start, step) {
31437      return d3.range(domain.length).map(function(i) {
31438        return start + step * i;
31439      });
31440    }
31441    scale.domain = function(x) {
31442      if (!arguments.length) return domain;
31443      domain = [];
31444      index = new d3_Map();
31445      var i = -1, n = x.length, xi;
31446      while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi));
31447      return scale[ranger.t].apply(scale, ranger.a);
31448    };
31449    scale.range = function(x) {
31450      if (!arguments.length) return range;
31451      range = x;
31452      rangeBand = 0;
31453      ranger = {
31454        t: "range",
31455        a: arguments
31456      };
31457      return scale;
31458    };
31459    scale.rangePoints = function(x, padding) {
31460      if (arguments.length < 2) padding = 0;
31461      var start = x[0], stop = x[1], step = domain.length < 2 ? (start = (start + stop) / 2, 
31462      0) : (stop - start) / (domain.length - 1 + padding);
31463      range = steps(start + step * padding / 2, step);
31464      rangeBand = 0;
31465      ranger = {
31466        t: "rangePoints",
31467        a: arguments
31468      };
31469      return scale;
31470    };
31471    scale.rangeRoundPoints = function(x, padding) {
31472      if (arguments.length < 2) padding = 0;
31473      var start = x[0], stop = x[1], step = domain.length < 2 ? (start = stop = Math.round((start + stop) / 2), 
31474      0) : (stop - start) / (domain.length - 1 + padding) | 0;
31475      range = steps(start + Math.round(step * padding / 2 + (stop - start - (domain.length - 1 + padding) * step) / 2), step);
31476      rangeBand = 0;
31477      ranger = {
31478        t: "rangeRoundPoints",
31479        a: arguments
31480      };
31481      return scale;
31482    };
31483    scale.rangeBands = function(x, padding, outerPadding) {
31484      if (arguments.length < 2) padding = 0;
31485      if (arguments.length < 3) outerPadding = padding;
31486      var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding);
31487      range = steps(start + step * outerPadding, step);
31488      if (reverse) range.reverse();
31489      rangeBand = step * (1 - padding);
31490      ranger = {
31491        t: "rangeBands",
31492        a: arguments
31493      };
31494      return scale;
31495    };
31496    scale.rangeRoundBands = function(x, padding, outerPadding) {
31497      if (arguments.length < 2) padding = 0;
31498      if (arguments.length < 3) outerPadding = padding;
31499      var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding));
31500      range = steps(start + Math.round((stop - start - (domain.length - padding) * step) / 2), step);
31501      if (reverse) range.reverse();
31502      rangeBand = Math.round(step * (1 - padding));
31503      ranger = {
31504        t: "rangeRoundBands",
31505        a: arguments
31506      };
31507      return scale;
31508    };
31509    scale.rangeBand = function() {
31510      return rangeBand;
31511    };
31512    scale.rangeExtent = function() {
31513      return d3_scaleExtent(ranger.a[0]);
31514    };
31515    scale.copy = function() {
31516      return d3_scale_ordinal(domain, ranger);
31517    };
31518    return scale.domain(domain);
31519  }
31520  d3.scale.category10 = function() {
31521    return d3.scale.ordinal().range(d3_category10);
31522  };
31523  d3.scale.category20 = function() {
31524    return d3.scale.ordinal().range(d3_category20);
31525  };
31526  d3.scale.category20b = function() {
31527    return d3.scale.ordinal().range(d3_category20b);
31528  };
31529  d3.scale.category20c = function() {
31530    return d3.scale.ordinal().range(d3_category20c);
31531  };
31532  var d3_category10 = [ 2062260, 16744206, 2924588, 14034728, 9725885, 9197131, 14907330, 8355711, 12369186, 1556175 ].map(d3_rgbString);
31533  var d3_category20 = [ 2062260, 11454440, 16744206, 16759672, 2924588, 10018698, 14034728, 16750742, 9725885, 12955861, 9197131, 12885140, 14907330, 16234194, 8355711, 13092807, 12369186, 14408589, 1556175, 10410725 ].map(d3_rgbString);
31534  var d3_category20b = [ 3750777, 5395619, 7040719, 10264286, 6519097, 9216594, 11915115, 13556636, 9202993, 12426809, 15186514, 15190932, 8666169, 11356490, 14049643, 15177372, 8077683, 10834324, 13528509, 14589654 ].map(d3_rgbString);
31535  var d3_category20c = [ 3244733, 7057110, 10406625, 13032431, 15095053, 16616764, 16625259, 16634018, 3253076, 7652470, 10607003, 13101504, 7695281, 10394312, 12369372, 14342891, 6513507, 9868950, 12434877, 14277081 ].map(d3_rgbString);
31536  d3.scale.quantile = function() {
31537    return d3_scale_quantile([], []);
31538  };
31539  function d3_scale_quantile(domain, range) {
31540    var thresholds;
31541    function rescale() {
31542      var k = 0, q = range.length;
31543      thresholds = [];
31544      while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q);
31545      return scale;
31546    }
31547    function scale(x) {
31548      if (!isNaN(x = +x)) return range[d3.bisect(thresholds, x)];
31549    }
31550    scale.domain = function(x) {
31551      if (!arguments.length) return domain;
31552      domain = x.map(d3_number).filter(d3_numeric).sort(d3_ascending);
31553      return rescale();
31554    };
31555    scale.range = function(x) {
31556      if (!arguments.length) return range;
31557      range = x;
31558      return rescale();
31559    };
31560    scale.quantiles = function() {
31561      return thresholds;
31562    };
31563    scale.invertExtent = function(y) {
31564      y = range.indexOf(y);
31565      return y < 0 ? [ NaN, NaN ] : [ y > 0 ? thresholds[y - 1] : domain[0], y < thresholds.length ? thresholds[y] : domain[domain.length - 1] ];
31566    };
31567    scale.copy = function() {
31568      return d3_scale_quantile(domain, range);
31569    };
31570    return rescale();
31571  }
31572  d3.scale.quantize = function() {
31573    return d3_scale_quantize(0, 1, [ 0, 1 ]);
31574  };
31575  function d3_scale_quantize(x0, x1, range) {
31576    var kx, i;
31577    function scale(x) {
31578      return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))];
31579    }
31580    function rescale() {
31581      kx = range.length / (x1 - x0);
31582      i = range.length - 1;
31583      return scale;
31584    }
31585    scale.domain = function(x) {
31586      if (!arguments.length) return [ x0, x1 ];
31587      x0 = +x[0];
31588      x1 = +x[x.length - 1];
31589      return rescale();
31590    };
31591    scale.range = function(x) {
31592      if (!arguments.length) return range;
31593      range = x;
31594      return rescale();
31595    };
31596    scale.invertExtent = function(y) {
31597      y = range.indexOf(y);
31598      y = y < 0 ? NaN : y / kx + x0;
31599      return [ y, y + 1 / kx ];
31600    };
31601    scale.copy = function() {
31602      return d3_scale_quantize(x0, x1, range);
31603    };
31604    return rescale();
31605  }
31606  d3.scale.threshold = function() {
31607    return d3_scale_threshold([ .5 ], [ 0, 1 ]);
31608  };
31609  function d3_scale_threshold(domain, range) {
31610    function scale(x) {
31611      if (x <= x) return range[d3.bisect(domain, x)];
31612    }
31613    scale.domain = function(_) {
31614      if (!arguments.length) return domain;
31615      domain = _;
31616      return scale;
31617    };
31618    scale.range = function(_) {
31619      if (!arguments.length) return range;
31620      range = _;
31621      return scale;
31622    };
31623    scale.invertExtent = function(y) {
31624      y = range.indexOf(y);
31625      return [ domain[y - 1], domain[y] ];
31626    };
31627    scale.copy = function() {
31628      return d3_scale_threshold(domain, range);
31629    };
31630    return scale;
31631  }
31632  d3.scale.identity = function() {
31633    return d3_scale_identity([ 0, 1 ]);
31634  };
31635  function d3_scale_identity(domain) {
31636    function identity(x) {
31637      return +x;
31638    }
31639    identity.invert = identity;
31640    identity.domain = identity.range = function(x) {
31641      if (!arguments.length) return domain;
31642      domain = x.map(identity);
31643      return identity;
31644    };
31645    identity.ticks = function(m) {
31646      return d3_scale_linearTicks(domain, m);
31647    };
31648    identity.tickFormat = function(m, format) {
31649      return d3_scale_linearTickFormat(domain, m, format);
31650    };
31651    identity.copy = function() {
31652      return d3_scale_identity(domain);
31653    };
31654    return identity;
31655  }
31656  d3.svg = {};
31657  function d3_zero() {
31658    return 0;
31659  }
31660  d3.svg.arc = function() {
31661    var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, cornerRadius = d3_zero, padRadius = d3_svg_arcAuto, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle, padAngle = d3_svg_arcPadAngle;
31662    function arc() {
31663      var r0 = Math.max(0, +innerRadius.apply(this, arguments)), r1 = Math.max(0, +outerRadius.apply(this, arguments)), a0 = startAngle.apply(this, arguments) - halfπ, a1 = endAngle.apply(this, arguments) - halfπ, da = Math.abs(a1 - a0), cw = a0 > a1 ? 0 : 1;
31664      if (r1 < r0) rc = r1, r1 = r0, r0 = rc;
31665      if (da >= τε) return circleSegment(r1, cw) + (r0 ? circleSegment(r0, 1 - cw) : "") + "Z";
31666      var rc, cr, rp, ap, p0 = 0, p1 = 0, x0, y0, x1, y1, x2, y2, x3, y3, path = [];
31667      if (ap = (+padAngle.apply(this, arguments) || 0) / 2) {
31668        rp = padRadius === d3_svg_arcAuto ? Math.sqrt(r0 * r0 + r1 * r1) : +padRadius.apply(this, arguments);
31669        if (!cw) p1 *= -1;
31670        if (r1) p1 = d3_asin(rp / r1 * Math.sin(ap));
31671        if (r0) p0 = d3_asin(rp / r0 * Math.sin(ap));
31672      }
31673      if (r1) {
31674        x0 = r1 * Math.cos(a0 + p1);
31675        y0 = r1 * Math.sin(a0 + p1);
31676        x1 = r1 * Math.cos(a1 - p1);
31677        y1 = r1 * Math.sin(a1 - p1);
31678        var l1 = Math.abs(a1 - a0 - 2 * p1) <= π ? 0 : 1;
31679        if (p1 && d3_svg_arcSweep(x0, y0, x1, y1) === cw ^ l1) {
31680          var h1 = (a0 + a1) / 2;
31681          x0 = r1 * Math.cos(h1);
31682          y0 = r1 * Math.sin(h1);
31683          x1 = y1 = null;
31684        }
31685      } else {
31686        x0 = y0 = 0;
31687      }
31688      if (r0) {
31689        x2 = r0 * Math.cos(a1 - p0);
31690        y2 = r0 * Math.sin(a1 - p0);
31691        x3 = r0 * Math.cos(a0 + p0);
31692        y3 = r0 * Math.sin(a0 + p0);
31693        var l0 = Math.abs(a0 - a1 + 2 * p0) <= π ? 0 : 1;
31694        if (p0 && d3_svg_arcSweep(x2, y2, x3, y3) === 1 - cw ^ l0) {
31695          var h0 = (a0 + a1) / 2;
31696          x2 = r0 * Math.cos(h0);
31697          y2 = r0 * Math.sin(h0);
31698          x3 = y3 = null;
31699        }
31700      } else {
31701        x2 = y2 = 0;
31702      }
31703      if ((rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments))) > .001) {
31704        cr = r0 < r1 ^ cw ? 0 : 1;
31705        var oc = x3 == null ? [ x2, y2 ] : x1 == null ? [ x0, y0 ] : d3_geom_polygonIntersect([ x0, y0 ], [ x3, y3 ], [ x1, y1 ], [ x2, y2 ]), ax = x0 - oc[0], ay = y0 - oc[1], bx = x1 - oc[0], by = y1 - oc[1], kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2), lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]);
31706        if (x1 != null) {
31707          var rc1 = Math.min(rc, (r1 - lc) / (kc + 1)), t30 = d3_svg_arcCornerTangents(x3 == null ? [ x2, y2 ] : [ x3, y3 ], [ x0, y0 ], r1, rc1, cw), t12 = d3_svg_arcCornerTangents([ x1, y1 ], [ x2, y2 ], r1, rc1, cw);
31708          if (rc === rc1) {
31709            path.push("M", t30[0], "A", rc1, ",", rc1, " 0 0,", cr, " ", t30[1], "A", r1, ",", r1, " 0 ", 1 - cw ^ d3_svg_arcSweep(t30[1][0], t30[1][1], t12[1][0], t12[1][1]), ",", cw, " ", t12[1], "A", rc1, ",", rc1, " 0 0,", cr, " ", t12[0]);
31710          } else {
31711            path.push("M", t30[0], "A", rc1, ",", rc1, " 0 1,", cr, " ", t12[0]);
31712          }
31713        } else {
31714          path.push("M", x0, ",", y0);
31715        }
31716        if (x3 != null) {
31717          var rc0 = Math.min(rc, (r0 - lc) / (kc - 1)), t03 = d3_svg_arcCornerTangents([ x0, y0 ], [ x3, y3 ], r0, -rc0, cw), t21 = d3_svg_arcCornerTangents([ x2, y2 ], x1 == null ? [ x0, y0 ] : [ x1, y1 ], r0, -rc0, cw);
31718          if (rc === rc0) {
31719            path.push("L", t21[0], "A", rc0, ",", rc0, " 0 0,", cr, " ", t21[1], "A", r0, ",", r0, " 0 ", cw ^ d3_svg_arcSweep(t21[1][0], t21[1][1], t03[1][0], t03[1][1]), ",", 1 - cw, " ", t03[1], "A", rc0, ",", rc0, " 0 0,", cr, " ", t03[0]);
31720          } else {
31721            path.push("L", t21[0], "A", rc0, ",", rc0, " 0 0,", cr, " ", t03[0]);
31722          }
31723        } else {
31724          path.push("L", x2, ",", y2);
31725        }
31726      } else {
31727        path.push("M", x0, ",", y0);
31728        if (x1 != null) path.push("A", r1, ",", r1, " 0 ", l1, ",", cw, " ", x1, ",", y1);
31729        path.push("L", x2, ",", y2);
31730        if (x3 != null) path.push("A", r0, ",", r0, " 0 ", l0, ",", 1 - cw, " ", x3, ",", y3);
31731      }
31732      path.push("Z");
31733      return path.join("");
31734    }
31735    function circleSegment(r1, cw) {
31736      return "M0," + r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + -r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + r1;
31737    }
31738    arc.innerRadius = function(v) {
31739      if (!arguments.length) return innerRadius;
31740      innerRadius = d3_functor(v);
31741      return arc;
31742    };
31743    arc.outerRadius = function(v) {
31744      if (!arguments.length) return outerRadius;
31745      outerRadius = d3_functor(v);
31746      return arc;
31747    };
31748    arc.cornerRadius = function(v) {
31749      if (!arguments.length) return cornerRadius;
31750      cornerRadius = d3_functor(v);
31751      return arc;
31752    };
31753    arc.padRadius = function(v) {
31754      if (!arguments.length) return padRadius;
31755      padRadius = v == d3_svg_arcAuto ? d3_svg_arcAuto : d3_functor(v);
31756      return arc;
31757    };
31758    arc.startAngle = function(v) {
31759      if (!arguments.length) return startAngle;
31760      startAngle = d3_functor(v);
31761      return arc;
31762    };
31763    arc.endAngle = function(v) {
31764      if (!arguments.length) return endAngle;
31765      endAngle = d3_functor(v);
31766      return arc;
31767    };
31768    arc.padAngle = function(v) {
31769      if (!arguments.length) return padAngle;
31770      padAngle = d3_functor(v);
31771      return arc;
31772    };
31773    arc.centroid = function() {
31774      var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - halfπ;
31775      return [ Math.cos(a) * r, Math.sin(a) * r ];
31776    };
31777    return arc;
31778  };
31779  var d3_svg_arcAuto = "auto";
31780  function d3_svg_arcInnerRadius(d) {
31781    return d.innerRadius;
31782  }
31783  function d3_svg_arcOuterRadius(d) {
31784    return d.outerRadius;
31785  }
31786  function d3_svg_arcStartAngle(d) {
31787    return d.startAngle;
31788  }
31789  function d3_svg_arcEndAngle(d) {
31790    return d.endAngle;
31791  }
31792  function d3_svg_arcPadAngle(d) {
31793    return d && d.padAngle;
31794  }
31795  function d3_svg_arcSweep(x0, y0, x1, y1) {
31796    return (x0 - x1) * y0 - (y0 - y1) * x0 > 0 ? 0 : 1;
31797  }
31798  function d3_svg_arcCornerTangents(p0, p1, r1, rc, cw) {
31799    var x01 = p0[0] - p1[0], y01 = p0[1] - p1[1], lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01), ox = lo * y01, oy = -lo * x01, x1 = p0[0] + ox, y1 = p0[1] + oy, x2 = p1[0] + ox, y2 = p1[1] + oy, x3 = (x1 + x2) / 2, y3 = (y1 + y2) / 2, dx = x2 - x1, dy = y2 - y1, d2 = dx * dx + dy * dy, r = r1 - rc, D = x1 * y2 - x2 * y1, d = (dy < 0 ? -1 : 1) * Math.sqrt(r * r * d2 - D * D), cx0 = (D * dy - dx * d) / d2, cy0 = (-D * dx - dy * d) / d2, cx1 = (D * dy + dx * d) / d2, cy1 = (-D * dx + dy * d) / d2, dx0 = cx0 - x3, dy0 = cy0 - y3, dx1 = cx1 - x3, dy1 = cy1 - y3;
31800    if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
31801    return [ [ cx0 - ox, cy0 - oy ], [ cx0 * r1 / r, cy0 * r1 / r ] ];
31802  }
31803  function d3_svg_line(projection) {
31804    var x = d3_geom_pointX, y = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7;
31805    function line(data) {
31806      var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y);
31807      function segment() {
31808        segments.push("M", interpolate(projection(points), tension));
31809      }
31810      while (++i < n) {
31811        if (defined.call(this, d = data[i], i)) {
31812          points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]);
31813        } else if (points.length) {
31814          segment();
31815          points = [];
31816        }
31817      }
31818      if (points.length) segment();
31819      return segments.length ? segments.join("") : null;
31820    }
31821    line.x = function(_) {
31822      if (!arguments.length) return x;
31823      x = _;
31824      return line;
31825    };
31826    line.y = function(_) {
31827      if (!arguments.length) return y;
31828      y = _;
31829      return line;
31830    };
31831    line.defined = function(_) {
31832      if (!arguments.length) return defined;
31833      defined = _;
31834      return line;
31835    };
31836    line.interpolate = function(_) {
31837      if (!arguments.length) return interpolateKey;
31838      if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key;
31839      return line;
31840    };
31841    line.tension = function(_) {
31842      if (!arguments.length) return tension;
31843      tension = _;
31844      return line;
31845    };
31846    return line;
31847  }
31848  d3.svg.line = function() {
31849    return d3_svg_line(d3_identity);
31850  };
31851  var d3_svg_lineInterpolators = d3.map({
31852    linear: d3_svg_lineLinear,
31853    "linear-closed": d3_svg_lineLinearClosed,
31854    step: d3_svg_lineStep,
31855    "step-before": d3_svg_lineStepBefore,
31856    "step-after": d3_svg_lineStepAfter,
31857    basis: d3_svg_lineBasis,
31858    "basis-open": d3_svg_lineBasisOpen,
31859    "basis-closed": d3_svg_lineBasisClosed,
31860    bundle: d3_svg_lineBundle,
31861    cardinal: d3_svg_lineCardinal,
31862    "cardinal-open": d3_svg_lineCardinalOpen,
31863    "cardinal-closed": d3_svg_lineCardinalClosed,
31864    monotone: d3_svg_lineMonotone
31865  });
31866  d3_svg_lineInterpolators.forEach(function(key, value) {
31867    value.key = key;
31868    value.closed = /-closed$/.test(key);
31869  });
31870  function d3_svg_lineLinear(points) {
31871    return points.join("L");
31872  }
31873  function d3_svg_lineLinearClosed(points) {
31874    return d3_svg_lineLinear(points) + "Z";
31875  }
31876  function d3_svg_lineStep(points) {
31877    var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ];
31878    while (++i < n) path.push("H", (p[0] + (p = points[i])[0]) / 2, "V", p[1]);
31879    if (n > 1) path.push("H", p[0]);
31880    return path.join("");
31881  }
31882  function d3_svg_lineStepBefore(points) {
31883    var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ];
31884    while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]);
31885    return path.join("");
31886  }
31887  function d3_svg_lineStepAfter(points) {
31888    var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ];
31889    while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]);
31890    return path.join("");
31891  }
31892  function d3_svg_lineCardinalOpen(points, tension) {
31893    return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, -1), d3_svg_lineCardinalTangents(points, tension));
31894  }
31895  function d3_svg_lineCardinalClosed(points, tension) {
31896    return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), 
31897    points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension));
31898  }
31899  function d3_svg_lineCardinal(points, tension) {
31900    return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension));
31901  }
31902  function d3_svg_lineHermite(points, tangents) {
31903    if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) {
31904      return d3_svg_lineLinear(points);
31905    }
31906    var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1;
31907    if (quad) {
31908      path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1];
31909      p0 = points[1];
31910      pi = 2;
31911    }
31912    if (tangents.length > 1) {
31913      t = tangents[1];
31914      p = points[pi];
31915      pi++;
31916      path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1];
31917      for (var i = 2; i < tangents.length; i++, pi++) {
31918        p = points[pi];
31919        t = tangents[i];
31920        path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1];
31921      }
31922    }
31923    if (quad) {
31924      var lp = points[pi];
31925      path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1];
31926    }
31927    return path;
31928  }
31929  function d3_svg_lineCardinalTangents(points, tension) {
31930    var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length;
31931    while (++i < n) {
31932      p0 = p1;
31933      p1 = p2;
31934      p2 = points[i];
31935      tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]);
31936    }
31937    return tangents;
31938  }
31939  function d3_svg_lineBasis(points) {
31940    if (points.length < 3) return d3_svg_lineLinear(points);
31941    var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0, "L", d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ];
31942    points.push(points[n - 1]);
31943    while (++i <= n) {
31944      pi = points[i];
31945      px.shift();
31946      px.push(pi[0]);
31947      py.shift();
31948      py.push(pi[1]);
31949      d3_svg_lineBasisBezier(path, px, py);
31950    }
31951    points.pop();
31952    path.push("L", pi);
31953    return path.join("");
31954  }
31955  function d3_svg_lineBasisOpen(points) {
31956    if (points.length < 4) return d3_svg_lineLinear(points);
31957    var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ];
31958    while (++i < 3) {
31959      pi = points[i];
31960      px.push(pi[0]);
31961      py.push(pi[1]);
31962    }
31963    path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py));
31964    --i;
31965    while (++i < n) {
31966      pi = points[i];
31967      px.shift();
31968      px.push(pi[0]);
31969      py.shift();
31970      py.push(pi[1]);
31971      d3_svg_lineBasisBezier(path, px, py);
31972    }
31973    return path.join("");
31974  }
31975  function d3_svg_lineBasisClosed(points) {
31976    var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = [];
31977    while (++i < 4) {
31978      pi = points[i % n];
31979      px.push(pi[0]);
31980      py.push(pi[1]);
31981    }
31982    path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ];
31983    --i;
31984    while (++i < m) {
31985      pi = points[i % n];
31986      px.shift();
31987      px.push(pi[0]);
31988      py.shift();
31989      py.push(pi[1]);
31990      d3_svg_lineBasisBezier(path, px, py);
31991    }
31992    return path.join("");
31993  }
31994  function d3_svg_lineBundle(points, tension) {
31995    var n = points.length - 1;
31996    if (n) {
31997      var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t;
31998      while (++i <= n) {
31999        p = points[i];
32000        t = i / n;
32001        p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx);
32002        p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy);
32003      }
32004    }
32005    return d3_svg_lineBasis(points);
32006  }
32007  function d3_svg_lineDot4(a, b) {
32008    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
32009  }
32010  var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ];
32011  function d3_svg_lineBasisBezier(path, x, y) {
32012    path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y));
32013  }
32014  function d3_svg_lineSlope(p0, p1) {
32015    return (p1[1] - p0[1]) / (p1[0] - p0[0]);
32016  }
32017  function d3_svg_lineFiniteDifferences(points) {
32018    var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1);
32019    while (++i < j) {
32020      m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2;
32021    }
32022    m[i] = d;
32023    return m;
32024  }
32025  function d3_svg_lineMonotoneTangents(points) {
32026    var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1;
32027    while (++i < j) {
32028      d = d3_svg_lineSlope(points[i], points[i + 1]);
32029      if (abs(d) < ε) {
32030        m[i] = m[i + 1] = 0;
32031      } else {
32032        a = m[i] / d;
32033        b = m[i + 1] / d;
32034        s = a * a + b * b;
32035        if (s > 9) {
32036          s = d * 3 / Math.sqrt(s);
32037          m[i] = s * a;
32038          m[i + 1] = s * b;
32039        }
32040      }
32041    }
32042    i = -1;
32043    while (++i <= j) {
32044      s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i]));
32045      tangents.push([ s || 0, m[i] * s || 0 ]);
32046    }
32047    return tangents;
32048  }
32049  function d3_svg_lineMonotone(points) {
32050    return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points));
32051  }
32052  d3.svg.line.radial = function() {
32053    var line = d3_svg_line(d3_svg_lineRadial);
32054    line.radius = line.x, delete line.x;
32055    line.angle = line.y, delete line.y;
32056    return line;
32057  };
32058  function d3_svg_lineRadial(points) {
32059    var point, i = -1, n = points.length, r, a;
32060    while (++i < n) {
32061      point = points[i];
32062      r = point[0];
32063      a = point[1] - halfπ;
32064      point[0] = r * Math.cos(a);
32065      point[1] = r * Math.sin(a);
32066    }
32067    return points;
32068  }
32069  function d3_svg_area(projection) {
32070    var x0 = d3_geom_pointX, x1 = d3_geom_pointX, y0 = 0, y1 = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7;
32071    function area(data) {
32072      var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() {
32073        return x;
32074      } : d3_functor(x1), fy1 = y0 === y1 ? function() {
32075        return y;
32076      } : d3_functor(y1), x, y;
32077      function segment() {
32078        segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z");
32079      }
32080      while (++i < n) {
32081        if (defined.call(this, d = data[i], i)) {
32082          points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]);
32083          points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]);
32084        } else if (points0.length) {
32085          segment();
32086          points0 = [];
32087          points1 = [];
32088        }
32089      }
32090      if (points0.length) segment();
32091      return segments.length ? segments.join("") : null;
32092    }
32093    area.x = function(_) {
32094      if (!arguments.length) return x1;
32095      x0 = x1 = _;
32096      return area;
32097    };
32098    area.x0 = function(_) {
32099      if (!arguments.length) return x0;
32100      x0 = _;
32101      return area;
32102    };
32103    area.x1 = function(_) {
32104      if (!arguments.length) return x1;
32105      x1 = _;
32106      return area;
32107    };
32108    area.y = function(_) {
32109      if (!arguments.length) return y1;
32110      y0 = y1 = _;
32111      return area;
32112    };
32113    area.y0 = function(_) {
32114      if (!arguments.length) return y0;
32115      y0 = _;
32116      return area;
32117    };
32118    area.y1 = function(_) {
32119      if (!arguments.length) return y1;
32120      y1 = _;
32121      return area;
32122    };
32123    area.defined = function(_) {
32124      if (!arguments.length) return defined;
32125      defined = _;
32126      return area;
32127    };
32128    area.interpolate = function(_) {
32129      if (!arguments.length) return interpolateKey;
32130      if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key;
32131      interpolateReverse = interpolate.reverse || interpolate;
32132      L = interpolate.closed ? "M" : "L";
32133      return area;
32134    };
32135    area.tension = function(_) {
32136      if (!arguments.length) return tension;
32137      tension = _;
32138      return area;
32139    };
32140    return area;
32141  }
32142  d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter;
32143  d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore;
32144  d3.svg.area = function() {
32145    return d3_svg_area(d3_identity);
32146  };
32147  d3.svg.area.radial = function() {
32148    var area = d3_svg_area(d3_svg_lineRadial);
32149    area.radius = area.x, delete area.x;
32150    area.innerRadius = area.x0, delete area.x0;
32151    area.outerRadius = area.x1, delete area.x1;
32152    area.angle = area.y, delete area.y;
32153    area.startAngle = area.y0, delete area.y0;
32154    area.endAngle = area.y1, delete area.y1;
32155    return area;
32156  };
32157  d3.svg.chord = function() {
32158    var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle;
32159    function chord(d, i) {
32160      var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i);
32161      return "M" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + "Z";
32162    }
32163    function subgroup(self, f, d, i) {
32164      var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) - halfπ, a1 = endAngle.call(self, subgroup, i) - halfπ;
32165      return {
32166        r: r,
32167        a0: a0,
32168        a1: a1,
32169        p0: [ r * Math.cos(a0), r * Math.sin(a0) ],
32170        p1: [ r * Math.cos(a1), r * Math.sin(a1) ]
32171      };
32172    }
32173    function equals(a, b) {
32174      return a.a0 == b.a0 && a.a1 == b.a1;
32175    }
32176    function arc(r, p, a) {
32177      return "A" + r + "," + r + " 0 " + +(a > π) + ",1 " + p;
32178    }
32179    function curve(r0, p0, r1, p1) {
32180      return "Q 0,0 " + p1;
32181    }
32182    chord.radius = function(v) {
32183      if (!arguments.length) return radius;
32184      radius = d3_functor(v);
32185      return chord;
32186    };
32187    chord.source = function(v) {
32188      if (!arguments.length) return source;
32189      source = d3_functor(v);
32190      return chord;
32191    };
32192    chord.target = function(v) {
32193      if (!arguments.length) return target;
32194      target = d3_functor(v);
32195      return chord;
32196    };
32197    chord.startAngle = function(v) {
32198      if (!arguments.length) return startAngle;
32199      startAngle = d3_functor(v);
32200      return chord;
32201    };
32202    chord.endAngle = function(v) {
32203      if (!arguments.length) return endAngle;
32204      endAngle = d3_functor(v);
32205      return chord;
32206    };
32207    return chord;
32208  };
32209  function d3_svg_chordRadius(d) {
32210    return d.radius;
32211  }
32212  d3.svg.diagonal = function() {
32213    var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection;
32214    function diagonal(d, i) {
32215      var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, {
32216        x: p0.x,
32217        y: m
32218      }, {
32219        x: p3.x,
32220        y: m
32221      }, p3 ];
32222      p = p.map(projection);
32223      return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3];
32224    }
32225    diagonal.source = function(x) {
32226      if (!arguments.length) return source;
32227      source = d3_functor(x);
32228      return diagonal;
32229    };
32230    diagonal.target = function(x) {
32231      if (!arguments.length) return target;
32232      target = d3_functor(x);
32233      return diagonal;
32234    };
32235    diagonal.projection = function(x) {
32236      if (!arguments.length) return projection;
32237      projection = x;
32238      return diagonal;
32239    };
32240    return diagonal;
32241  };
32242  function d3_svg_diagonalProjection(d) {
32243    return [ d.x, d.y ];
32244  }
32245  d3.svg.diagonal.radial = function() {
32246    var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection;
32247    diagonal.projection = function(x) {
32248      return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection;
32249    };
32250    return diagonal;
32251  };
32252  function d3_svg_diagonalRadialProjection(projection) {
32253    return function() {
32254      var d = projection.apply(this, arguments), r = d[0], a = d[1] - halfπ;
32255      return [ r * Math.cos(a), r * Math.sin(a) ];
32256    };
32257  }
32258  d3.svg.symbol = function() {
32259    var type = d3_svg_symbolType, size = d3_svg_symbolSize;
32260    function symbol(d, i) {
32261      return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i));
32262    }
32263    symbol.type = function(x) {
32264      if (!arguments.length) return type;
32265      type = d3_functor(x);
32266      return symbol;
32267    };
32268    symbol.size = function(x) {
32269      if (!arguments.length) return size;
32270      size = d3_functor(x);
32271      return symbol;
32272    };
32273    return symbol;
32274  };
32275  function d3_svg_symbolSize() {
32276    return 64;
32277  }
32278  function d3_svg_symbolType() {
32279    return "circle";
32280  }
32281  function d3_svg_symbolCircle(size) {
32282    var r = Math.sqrt(size / π);
32283    return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z";
32284  }
32285  var d3_svg_symbols = d3.map({
32286    circle: d3_svg_symbolCircle,
32287    cross: function(size) {
32288      var r = Math.sqrt(size / 5) / 2;
32289      return "M" + -3 * r + "," + -r + "H" + -r + "V" + -3 * r + "H" + r + "V" + -r + "H" + 3 * r + "V" + r + "H" + r + "V" + 3 * r + "H" + -r + "V" + r + "H" + -3 * r + "Z";
32290    },
32291    diamond: function(size) {
32292      var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30;
32293      return "M0," + -ry + "L" + rx + ",0" + " 0," + ry + " " + -rx + ",0" + "Z";
32294    },
32295    square: function(size) {
32296      var r = Math.sqrt(size) / 2;
32297      return "M" + -r + "," + -r + "L" + r + "," + -r + " " + r + "," + r + " " + -r + "," + r + "Z";
32298    },
32299    "triangle-down": function(size) {
32300      var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2;
32301      return "M0," + ry + "L" + rx + "," + -ry + " " + -rx + "," + -ry + "Z";
32302    },
32303    "triangle-up": function(size) {
32304      var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2;
32305      return "M0," + -ry + "L" + rx + "," + ry + " " + -rx + "," + ry + "Z";
32306    }
32307  });
32308  d3.svg.symbolTypes = d3_svg_symbols.keys();
32309  var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians);
32310  d3_selectionPrototype.transition = function(name) {
32311    var id = d3_transitionInheritId || ++d3_transitionId, ns = d3_transitionNamespace(name), subgroups = [], subgroup, node, transition = d3_transitionInherit || {
32312      time: Date.now(),
32313      ease: d3_ease_cubicInOut,
32314      delay: 0,
32315      duration: 250
32316    };
32317    for (var j = -1, m = this.length; ++j < m; ) {
32318      subgroups.push(subgroup = []);
32319      for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
32320        if (node = group[i]) d3_transitionNode(node, i, ns, id, transition);
32321        subgroup.push(node);
32322      }
32323    }
32324    return d3_transition(subgroups, ns, id);
32325  };
32326  d3_selectionPrototype.interrupt = function(name) {
32327    return this.each(name == null ? d3_selection_interrupt : d3_selection_interruptNS(d3_transitionNamespace(name)));
32328  };
32329  var d3_selection_interrupt = d3_selection_interruptNS(d3_transitionNamespace());
32330  function d3_selection_interruptNS(ns) {
32331    return function() {
32332      var lock, active;
32333      if ((lock = this[ns]) && (active = lock[lock.active])) {
32334        if (--lock.count) delete lock[lock.active]; else delete this[ns];
32335        lock.active += .5;
32336        active.event && active.event.interrupt.call(this, this.__data__, active.index);
32337      }
32338    };
32339  }
32340  function d3_transition(groups, ns, id) {
32341    d3_subclass(groups, d3_transitionPrototype);
32342    groups.namespace = ns;
32343    groups.id = id;
32344    return groups;
32345  }
32346  var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit;
32347  d3_transitionPrototype.call = d3_selectionPrototype.call;
32348  d3_transitionPrototype.empty = d3_selectionPrototype.empty;
32349  d3_transitionPrototype.node = d3_selectionPrototype.node;
32350  d3_transitionPrototype.size = d3_selectionPrototype.size;
32351  d3.transition = function(selection, name) {
32352    return selection && selection.transition ? d3_transitionInheritId ? selection.transition(name) : selection : d3.selection().transition(selection);
32353  };
32354  d3.transition.prototype = d3_transitionPrototype;
32355  d3_transitionPrototype.select = function(selector) {
32356    var id = this.id, ns = this.namespace, subgroups = [], subgroup, subnode, node;
32357    selector = d3_selection_selector(selector);
32358    for (var j = -1, m = this.length; ++j < m; ) {
32359      subgroups.push(subgroup = []);
32360      for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
32361        if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i, j))) {
32362          if ("__data__" in node) subnode.__data__ = node.__data__;
32363          d3_transitionNode(subnode, i, ns, id, node[ns][id]);
32364          subgroup.push(subnode);
32365        } else {
32366          subgroup.push(null);
32367        }
32368      }
32369    }
32370    return d3_transition(subgroups, ns, id);
32371  };
32372  d3_transitionPrototype.selectAll = function(selector) {
32373    var id = this.id, ns = this.namespace, subgroups = [], subgroup, subnodes, node, subnode, transition;
32374    selector = d3_selection_selectorAll(selector);
32375    for (var j = -1, m = this.length; ++j < m; ) {
32376      for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
32377        if (node = group[i]) {
32378          transition = node[ns][id];
32379          subnodes = selector.call(node, node.__data__, i, j);
32380          subgroups.push(subgroup = []);
32381          for (var k = -1, o = subnodes.length; ++k < o; ) {
32382            if (subnode = subnodes[k]) d3_transitionNode(subnode, k, ns, id, transition);
32383            subgroup.push(subnode);
32384          }
32385        }
32386      }
32387    }
32388    return d3_transition(subgroups, ns, id);
32389  };
32390  d3_transitionPrototype.filter = function(filter) {
32391    var subgroups = [], subgroup, group, node;
32392    if (typeof filter !== "function") filter = d3_selection_filter(filter);
32393    for (var j = 0, m = this.length; j < m; j++) {
32394      subgroups.push(subgroup = []);
32395      for (var group = this[j], i = 0, n = group.length; i < n; i++) {
32396        if ((node = group[i]) && filter.call(node, node.__data__, i, j)) {
32397          subgroup.push(node);
32398        }
32399      }
32400    }
32401    return d3_transition(subgroups, this.namespace, this.id);
32402  };
32403  d3_transitionPrototype.tween = function(name, tween) {
32404    var id = this.id, ns = this.namespace;
32405    if (arguments.length < 2) return this.node()[ns][id].tween.get(name);
32406    return d3_selection_each(this, tween == null ? function(node) {
32407      node[ns][id].tween.remove(name);
32408    } : function(node) {
32409      node[ns][id].tween.set(name, tween);
32410    });
32411  };
32412  function d3_transition_tween(groups, name, value, tween) {
32413    var id = groups.id, ns = groups.namespace;
32414    return d3_selection_each(groups, typeof value === "function" ? function(node, i, j) {
32415      node[ns][id].tween.set(name, tween(value.call(node, node.__data__, i, j)));
32416    } : (value = tween(value), function(node) {
32417      node[ns][id].tween.set(name, value);
32418    }));
32419  }
32420  d3_transitionPrototype.attr = function(nameNS, value) {
32421    if (arguments.length < 2) {
32422      for (value in nameNS) this.attr(value, nameNS[value]);
32423      return this;
32424    }
32425    var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS);
32426    function attrNull() {
32427      this.removeAttribute(name);
32428    }
32429    function attrNullNS() {
32430      this.removeAttributeNS(name.space, name.local);
32431    }
32432    function attrTween(b) {
32433      return b == null ? attrNull : (b += "", function() {
32434        var a = this.getAttribute(name), i;
32435        return a !== b && (i = interpolate(a, b), function(t) {
32436          this.setAttribute(name, i(t));
32437        });
32438      });
32439    }
32440    function attrTweenNS(b) {
32441      return b == null ? attrNullNS : (b += "", function() {
32442        var a = this.getAttributeNS(name.space, name.local), i;
32443        return a !== b && (i = interpolate(a, b), function(t) {
32444          this.setAttributeNS(name.space, name.local, i(t));
32445        });
32446      });
32447    }
32448    return d3_transition_tween(this, "attr." + nameNS, value, name.local ? attrTweenNS : attrTween);
32449  };
32450  d3_transitionPrototype.attrTween = function(nameNS, tween) {
32451    var name = d3.ns.qualify(nameNS);
32452    function attrTween(d, i) {
32453      var f = tween.call(this, d, i, this.getAttribute(name));
32454      return f && function(t) {
32455        this.setAttribute(name, f(t));
32456      };
32457    }
32458    function attrTweenNS(d, i) {
32459      var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local));
32460      return f && function(t) {
32461        this.setAttributeNS(name.space, name.local, f(t));
32462      };
32463    }
32464    return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween);
32465  };
32466  d3_transitionPrototype.style = function(name, value, priority) {
32467    var n = arguments.length;
32468    if (n < 3) {
32469      if (typeof name !== "string") {
32470        if (n < 2) value = "";
32471        for (priority in name) this.style(priority, name[priority], value);
32472        return this;
32473      }
32474      priority = "";
32475    }
32476    function styleNull() {
32477      this.style.removeProperty(name);
32478    }
32479    function styleString(b) {
32480      return b == null ? styleNull : (b += "", function() {
32481        var a = d3_window(this).getComputedStyle(this, null).getPropertyValue(name), i;
32482        return a !== b && (i = d3_interpolate(a, b), function(t) {
32483          this.style.setProperty(name, i(t), priority);
32484        });
32485      });
32486    }
32487    return d3_transition_tween(this, "style." + name, value, styleString);
32488  };
32489  d3_transitionPrototype.styleTween = function(name, tween, priority) {
32490    if (arguments.length < 3) priority = "";
32491    function styleTween(d, i) {
32492      var f = tween.call(this, d, i, d3_window(this).getComputedStyle(this, null).getPropertyValue(name));
32493      return f && function(t) {
32494        this.style.setProperty(name, f(t), priority);
32495      };
32496    }
32497    return this.tween("style." + name, styleTween);
32498  };
32499  d3_transitionPrototype.text = function(value) {
32500    return d3_transition_tween(this, "text", value, d3_transition_text);
32501  };
32502  function d3_transition_text(b) {
32503    if (b == null) b = "";
32504    return function() {
32505      this.textContent = b;
32506    };
32507  }
32508  d3_transitionPrototype.remove = function() {
32509    var ns = this.namespace;
32510    return this.each("end.transition", function() {
32511      var p;
32512      if (this[ns].count < 2 && (p = this.parentNode)) p.removeChild(this);
32513    });
32514  };
32515  d3_transitionPrototype.ease = function(value) {
32516    var id = this.id, ns = this.namespace;
32517    if (arguments.length < 1) return this.node()[ns][id].ease;
32518    if (typeof value !== "function") value = d3.ease.apply(d3, arguments);
32519    return d3_selection_each(this, function(node) {
32520      node[ns][id].ease = value;
32521    });
32522  };
32523  d3_transitionPrototype.delay = function(value) {
32524    var id = this.id, ns = this.namespace;
32525    if (arguments.length < 1) return this.node()[ns][id].delay;
32526    return d3_selection_each(this, typeof value === "function" ? function(node, i, j) {
32527      node[ns][id].delay = +value.call(node, node.__data__, i, j);
32528    } : (value = +value, function(node) {
32529      node[ns][id].delay = value;
32530    }));
32531  };
32532  d3_transitionPrototype.duration = function(value) {
32533    var id = this.id, ns = this.namespace;
32534    if (arguments.length < 1) return this.node()[ns][id].duration;
32535    return d3_selection_each(this, typeof value === "function" ? function(node, i, j) {
32536      node[ns][id].duration = Math.max(1, value.call(node, node.__data__, i, j));
32537    } : (value = Math.max(1, value), function(node) {
32538      node[ns][id].duration = value;
32539    }));
32540  };
32541  d3_transitionPrototype.each = function(type, listener) {
32542    var id = this.id, ns = this.namespace;
32543    if (arguments.length < 2) {
32544      var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId;
32545      try {
32546        d3_transitionInheritId = id;
32547        d3_selection_each(this, function(node, i, j) {
32548          d3_transitionInherit = node[ns][id];
32549          type.call(node, node.__data__, i, j);
32550        });
32551      } finally {
32552        d3_transitionInherit = inherit;
32553        d3_transitionInheritId = inheritId;
32554      }
32555    } else {
32556      d3_selection_each(this, function(node) {
32557        var transition = node[ns][id];
32558        (transition.event || (transition.event = d3.dispatch("start", "end", "interrupt"))).on(type, listener);
32559      });
32560    }
32561    return this;
32562  };
32563  d3_transitionPrototype.transition = function() {
32564    var id0 = this.id, id1 = ++d3_transitionId, ns = this.namespace, subgroups = [], subgroup, group, node, transition;
32565    for (var j = 0, m = this.length; j < m; j++) {
32566      subgroups.push(subgroup = []);
32567      for (var group = this[j], i = 0, n = group.length; i < n; i++) {
32568        if (node = group[i]) {
32569          transition = node[ns][id0];
32570          d3_transitionNode(node, i, ns, id1, {
32571            time: transition.time,
32572            ease: transition.ease,
32573            delay: transition.delay + transition.duration,
32574            duration: transition.duration
32575          });
32576        }
32577        subgroup.push(node);
32578      }
32579    }
32580    return d3_transition(subgroups, ns, id1);
32581  };
32582  function d3_transitionNamespace(name) {
32583    return name == null ? "__transition__" : "__transition_" + name + "__";
32584  }
32585  function d3_transitionNode(node, i, ns, id, inherit) {
vendor: 5,670 bytes, lines 32586-32713
32586    var lock = node[ns] || (node[ns] = {
32587      active: 0,
32588      count: 0
32589    }), transition = lock[id];
32590    if (!transition) {
32591      var time = inherit.time;
32592      transition = lock[id] = {
32593        tween: new d3_Map(),
32594        time: time,
32595        delay: inherit.delay,
32596        duration: inherit.duration,
32597        ease: inherit.ease,
32598        index: i
32599      };
32600      inherit = null;
32601      ++lock.count;
32602      d3.timer(function(elapsed) {
32603        var delay = transition.delay, duration, ease, timer = d3_timer_active, tweened = [];
32604        timer.t = delay + time;
32605        if (delay <= elapsed) return start(elapsed - delay);
32606        timer.c = start;
32607        function start(elapsed) {
32608          if (lock.active > id) return stop();
32609          var active = lock[lock.active];
32610          if (active) {
32611            --lock.count;
32612            delete lock[lock.active];
32613            active.event && active.event.interrupt.call(node, node.__data__, active.index);
32614          }
32615          lock.active = id;
32616          transition.event && transition.event.start.call(node, node.__data__, i);
32617          transition.tween.forEach(function(key, value) {
32618            if (value = value.call(node, node.__data__, i)) {
32619              tweened.push(value);
32620            }
32621          });
32622          ease = transition.ease;
32623          duration = transition.duration;
32624          d3.timer(function() {
32625            timer.c = tick(elapsed || 1) ? d3_true : tick;
32626            return 1;
32627          }, 0, time);
32628        }
32629        function tick(elapsed) {
32630          if (lock.active !== id) return 1;
32631          var t = elapsed / duration, e = ease(t), n = tweened.length;
32632          while (n > 0) {
32633            tweened[--n].call(node, e);
32634          }
32635          if (t >= 1) {
32636            transition.event && transition.event.end.call(node, node.__data__, i);
32637            return stop();
32638          }
32639        }
32640        function stop() {
32641          if (--lock.count) delete lock[id]; else delete node[ns];
32642          return 1;
32643        }
32644      }, 0, time);
32645    }
32646  }
32647  d3.svg.axis = function() {
32648    var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, innerTickSize = 6, outerTickSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_;
32649    function axis(g) {
32650      g.each(function() {
32651        var g = d3.select(this);
32652        var scale0 = this.__chart__ || scale, scale1 = this.__chart__ = scale.copy();
32653        var ticks = tickValues == null ? scale1.ticks ? scale1.ticks.apply(scale1, tickArguments_) : scale1.domain() : tickValues, tickFormat = tickFormat_ == null ? scale1.tickFormat ? scale1.tickFormat.apply(scale1, tickArguments_) : d3_identity : tickFormat_, tick = g.selectAll(".tick").data(ticks, scale1), tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", ε), tickExit = d3.transition(tick.exit()).style("opacity", ε).remove(), tickUpdate = d3.transition(tick.order()).style("opacity", 1), tickSpacing = Math.max(innerTickSize, 0) + tickPadding, tickTransform;
32654        var range = d3_scaleRange(scale1), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = (path.enter().append("path").attr("class", "domain"), 
32655        d3.transition(path));
32656        tickEnter.append("line");
32657        tickEnter.append("text");
32658        var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text"), sign = orient === "top" || orient === "left" ? -1 : 1, x1, x2, y1, y2;
32659        if (orient === "bottom" || orient === "top") {
32660          tickTransform = d3_svg_axisX, x1 = "x", y1 = "y", x2 = "x2", y2 = "y2";
32661          text.attr("dy", sign < 0 ? "0em" : ".71em").style("text-anchor", "middle");
32662          pathUpdate.attr("d", "M" + range[0] + "," + sign * outerTickSize + "V0H" + range[1] + "V" + sign * outerTickSize);
32663        } else {
32664          tickTransform = d3_svg_axisY, x1 = "y", y1 = "x", x2 = "y2", y2 = "x2";
32665          text.attr("dy", ".32em").style("text-anchor", sign < 0 ? "end" : "start");
32666          pathUpdate.attr("d", "M" + sign * outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + sign * outerTickSize);
32667        }
32668        lineEnter.attr(y2, sign * innerTickSize);
32669        textEnter.attr(y1, sign * tickSpacing);
32670        lineUpdate.attr(x2, 0).attr(y2, sign * innerTickSize);
32671        textUpdate.attr(x1, 0).attr(y1, sign * tickSpacing);
32672        if (scale1.rangeBand) {
32673          var x = scale1, dx = x.rangeBand() / 2;
32674          scale0 = scale1 = function(d) {
32675            return x(d) + dx;
32676          };
32677        } else if (scale0.rangeBand) {
32678          scale0 = scale1;
32679        } else {
32680          tickExit.call(tickTransform, scale1, scale0);
32681        }
32682        tickEnter.call(tickTransform, scale0, scale1);
32683        tickUpdate.call(tickTransform, scale1, scale1);
32684      });
32685    }
32686    axis.scale = function(x) {
32687      if (!arguments.length) return scale;
32688      scale = x;
32689      return axis;
32690    };
32691    axis.orient = function(x) {
32692      if (!arguments.length) return orient;
32693      orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient;
32694      return axis;
32695    };
32696    axis.ticks = function() {
32697      if (!arguments.length) return tickArguments_;
32698      tickArguments_ = arguments;
32699      return axis;
32700    };
32701    axis.tickValues = function(x) {
32702      if (!arguments.length) return tickValues;
32703      tickValues = x;
32704      return axis;
32705    };
32706    axis.tickFormat = function(x) {
32707      if (!arguments.length) return tickFormat_;
32708      tickFormat_ = x;
32709      return axis;
32710    };
32711    axis.tickSize = function(x) {
32712      var n = arguments.length;
32713      if (!n) return innerTickSize;
vendor: 7,149 bytes, lines 32714-32901
32714      innerTickSize = +x;
32715      outerTickSize = +arguments[n - 1];
32716      return axis;
32717    };
32718    axis.innerTickSize = function(x) {
32719      if (!arguments.length) return innerTickSize;
32720      innerTickSize = +x;
32721      return axis;
32722    };
32723    axis.outerTickSize = function(x) {
32724      if (!arguments.length) return outerTickSize;
32725      outerTickSize = +x;
32726      return axis;
32727    };
32728    axis.tickPadding = function(x) {
32729      if (!arguments.length) return tickPadding;
32730      tickPadding = +x;
32731      return axis;
32732    };
32733    axis.tickSubdivide = function() {
32734      return arguments.length && axis;
32735    };
32736    return axis;
32737  };
32738  var d3_svg_axisDefaultOrient = "bottom", d3_svg_axisOrients = {
32739    top: 1,
32740    right: 1,
32741    bottom: 1,
32742    left: 1
32743  };
32744  function d3_svg_axisX(selection, x0, x1) {
32745    selection.attr("transform", function(d) {
32746      var v0 = x0(d);
32747      return "translate(" + (isFinite(v0) ? v0 : x1(d)) + ",0)";
32748    });
32749  }
32750  function d3_svg_axisY(selection, y0, y1) {
32751    selection.attr("transform", function(d) {
32752      var v0 = y0(d);
32753      return "translate(0," + (isFinite(v0) ? v0 : y1(d)) + ")";
32754    });
32755  }
32756  d3.svg.brush = function() {
32757    var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), x = null, y = null, xExtent = [ 0, 0 ], yExtent = [ 0, 0 ], xExtentDomain, yExtentDomain, xClamp = true, yClamp = true, resizes = d3_svg_brushResizes[0];
32758    function brush(g) {
32759      g.each(function() {
32760        var g = d3.select(this).style("pointer-events", "all").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)").on("mousedown.brush", brushstart).on("touchstart.brush", brushstart);
32761        var background = g.selectAll(".background").data([ 0 ]);
32762        background.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair");
32763        g.selectAll(".extent").data([ 0 ]).enter().append("rect").attr("class", "extent").style("cursor", "move");
32764        var resize = g.selectAll(".resize").data(resizes, d3_identity);
32765        resize.exit().remove();
32766        resize.enter().append("g").attr("class", function(d) {
32767          return "resize " + d;
32768        }).style("cursor", function(d) {
32769          return d3_svg_brushCursor[d];
32770        }).append("rect").attr("x", function(d) {
32771          return /[ew]$/.test(d) ? -3 : null;
32772        }).attr("y", function(d) {
32773          return /^[ns]/.test(d) ? -3 : null;
32774        }).attr("width", 6).attr("height", 6).style("visibility", "hidden");
32775        resize.style("display", brush.empty() ? "none" : null);
32776        var gUpdate = d3.transition(g), backgroundUpdate = d3.transition(background), range;
32777        if (x) {
32778          range = d3_scaleRange(x);
32779          backgroundUpdate.attr("x", range[0]).attr("width", range[1] - range[0]);
32780          redrawX(gUpdate);
32781        }
32782        if (y) {
32783          range = d3_scaleRange(y);
32784          backgroundUpdate.attr("y", range[0]).attr("height", range[1] - range[0]);
32785          redrawY(gUpdate);
32786        }
32787        redraw(gUpdate);
32788      });
32789    }
32790    brush.event = function(g) {
32791      g.each(function() {
32792        var event_ = event.of(this, arguments), extent1 = {
32793          x: xExtent,
32794          y: yExtent,
32795          i: xExtentDomain,
32796          j: yExtentDomain
32797        }, extent0 = this.__chart__ || extent1;
32798        this.__chart__ = extent1;
32799        if (d3_transitionInheritId) {
32800          d3.select(this).transition().each("start.brush", function() {
32801            xExtentDomain = extent0.i;
32802            yExtentDomain = extent0.j;
32803            xExtent = extent0.x;
32804            yExtent = extent0.y;
32805            event_({
32806              type: "brushstart"
32807            });
32808          }).tween("brush:brush", function() {
32809            var xi = d3_interpolateArray(xExtent, extent1.x), yi = d3_interpolateArray(yExtent, extent1.y);
32810            xExtentDomain = yExtentDomain = null;
32811            return function(t) {
32812              xExtent = extent1.x = xi(t);
32813              yExtent = extent1.y = yi(t);
32814              event_({
32815                type: "brush",
32816                mode: "resize"
32817              });
32818            };
32819          }).each("end.brush", function() {
32820            xExtentDomain = extent1.i;
32821            yExtentDomain = extent1.j;
32822            event_({
32823              type: "brush",
32824              mode: "resize"
32825            });
32826            event_({
32827              type: "brushend"
32828            });
32829          });
32830        } else {
32831          event_({
32832            type: "brushstart"
32833          });
32834          event_({
32835            type: "brush",
32836            mode: "resize"
32837          });
32838          event_({
32839            type: "brushend"
32840          });
32841        }
32842      });
32843    };
32844    function redraw(g) {
32845      g.selectAll(".resize").attr("transform", function(d) {
32846        return "translate(" + xExtent[+/e$/.test(d)] + "," + yExtent[+/^s/.test(d)] + ")";
32847      });
32848    }
32849    function redrawX(g) {
32850      g.select(".extent").attr("x", xExtent[0]);
32851      g.selectAll(".extent,.n>rect,.s>rect").attr("width", xExtent[1] - xExtent[0]);
32852    }
32853    function redrawY(g) {
32854      g.select(".extent").attr("y", yExtent[0]);
32855      g.selectAll(".extent,.e>rect,.w>rect").attr("height", yExtent[1] - yExtent[0]);
32856    }
32857    function brushstart() {
32858      var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), dragRestore = d3_event_dragSuppress(target), center, origin = d3.mouse(target), offset;
32859      var w = d3.select(d3_window(target)).on("keydown.brush", keydown).on("keyup.brush", keyup);
32860      if (d3.event.changedTouches) {
32861        w.on("touchmove.brush", brushmove).on("touchend.brush", brushend);
32862      } else {
32863        w.on("mousemove.brush", brushmove).on("mouseup.brush", brushend);
32864      }
32865      g.interrupt().selectAll("*").interrupt();
32866      if (dragging) {
32867        origin[0] = xExtent[0] - origin[0];
32868        origin[1] = yExtent[0] - origin[1];
32869      } else if (resizing) {
32870        var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing);
32871        offset = [ xExtent[1 - ex] - origin[0], yExtent[1 - ey] - origin[1] ];
32872        origin[0] = xExtent[ex];
32873        origin[1] = yExtent[ey];
32874      } else if (d3.event.altKey) center = origin.slice();
32875      g.style("pointer-events", "none").selectAll(".resize").style("display", null);
32876      d3.select("body").style("cursor", eventTarget.style("cursor"));
32877      event_({
32878        type: "brushstart"
32879      });
32880      brushmove();
32881      function keydown() {
32882        if (d3.event.keyCode == 32) {
32883          if (!dragging) {
32884            center = null;
32885            origin[0] -= xExtent[1];
32886            origin[1] -= yExtent[1];
32887            dragging = 2;
32888          }
32889          d3_eventPreventDefault();
32890        }
32891      }
32892      function keyup() {
32893        if (d3.event.keyCode == 32 && dragging == 2) {
32894          origin[0] += xExtent[1];
32895          origin[1] += yExtent[1];
32896          dragging = 0;
32897          d3_eventPreventDefault();
32898        }
32899      }
32900      function brushmove() {
32901        var point = d3.mouse(target), moved = false;
vendor: 6,929 bytes, lines 32902-33097
32902        if (offset) {
32903          point[0] += offset[0];
32904          point[1] += offset[1];
32905        }
32906        if (!dragging) {
32907          if (d3.event.altKey) {
32908            if (!center) center = [ (xExtent[0] + xExtent[1]) / 2, (yExtent[0] + yExtent[1]) / 2 ];
32909            origin[0] = xExtent[+(point[0] < center[0])];
32910            origin[1] = yExtent[+(point[1] < center[1])];
32911          } else center = null;
32912        }
32913        if (resizingX && move1(point, x, 0)) {
32914          redrawX(g);
32915          moved = true;
32916        }
32917        if (resizingY && move1(point, y, 1)) {
32918          redrawY(g);
32919          moved = true;
32920        }
32921        if (moved) {
32922          redraw(g);
32923          event_({
32924            type: "brush",
32925            mode: dragging ? "move" : "resize"
32926          });
32927        }
32928      }
32929      function move1(point, scale, i) {
32930        var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], extent = i ? yExtent : xExtent, size = extent[1] - extent[0], min, max;
32931        if (dragging) {
32932          r0 -= position;
32933          r1 -= size + position;
32934        }
32935        min = (i ? yClamp : xClamp) ? Math.max(r0, Math.min(r1, point[i])) : point[i];
32936        if (dragging) {
32937          max = (min += position) + size;
32938        } else {
32939          if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min));
32940          if (position < min) {
32941            max = min;
32942            min = position;
32943          } else {
32944            max = position;
32945          }
32946        }
32947        if (extent[0] != min || extent[1] != max) {
32948          if (i) yExtentDomain = null; else xExtentDomain = null;
32949          extent[0] = min;
32950          extent[1] = max;
32951          return true;
32952        }
32953      }
32954      function brushend() {
32955        brushmove();
32956        g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null);
32957        d3.select("body").style("cursor", null);
32958        w.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null);
32959        dragRestore();
32960        event_({
32961          type: "brushend"
32962        });
32963      }
32964    }
32965    brush.x = function(z) {
32966      if (!arguments.length) return x;
32967      x = z;
32968      resizes = d3_svg_brushResizes[!x << 1 | !y];
32969      return brush;
32970    };
32971    brush.y = function(z) {
32972      if (!arguments.length) return y;
32973      y = z;
32974      resizes = d3_svg_brushResizes[!x << 1 | !y];
32975      return brush;
32976    };
32977    brush.clamp = function(z) {
32978      if (!arguments.length) return x && y ? [ xClamp, yClamp ] : x ? xClamp : y ? yClamp : null;
32979      if (x && y) xClamp = !!z[0], yClamp = !!z[1]; else if (x) xClamp = !!z; else if (y) yClamp = !!z;
32980      return brush;
32981    };
32982    brush.extent = function(z) {
32983      var x0, x1, y0, y1, t;
32984      if (!arguments.length) {
32985        if (x) {
32986          if (xExtentDomain) {
32987            x0 = xExtentDomain[0], x1 = xExtentDomain[1];
32988          } else {
32989            x0 = xExtent[0], x1 = xExtent[1];
32990            if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1);
32991            if (x1 < x0) t = x0, x0 = x1, x1 = t;
32992          }
32993        }
32994        if (y) {
32995          if (yExtentDomain) {
32996            y0 = yExtentDomain[0], y1 = yExtentDomain[1];
32997          } else {
32998            y0 = yExtent[0], y1 = yExtent[1];
32999            if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1);
33000            if (y1 < y0) t = y0, y0 = y1, y1 = t;
33001          }
33002        }
33003        return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ];
33004      }
33005      if (x) {
33006        x0 = z[0], x1 = z[1];
33007        if (y) x0 = x0[0], x1 = x1[0];
33008        xExtentDomain = [ x0, x1 ];
33009        if (x.invert) x0 = x(x0), x1 = x(x1);
33010        if (x1 < x0) t = x0, x0 = x1, x1 = t;
33011        if (x0 != xExtent[0] || x1 != xExtent[1]) xExtent = [ x0, x1 ];
33012      }
33013      if (y) {
33014        y0 = z[0], y1 = z[1];
33015        if (x) y0 = y0[1], y1 = y1[1];
33016        yExtentDomain = [ y0, y1 ];
33017        if (y.invert) y0 = y(y0), y1 = y(y1);
33018        if (y1 < y0) t = y0, y0 = y1, y1 = t;
33019        if (y0 != yExtent[0] || y1 != yExtent[1]) yExtent = [ y0, y1 ];
33020      }
33021      return brush;
33022    };
33023    brush.clear = function() {
33024      if (!brush.empty()) {
33025        xExtent = [ 0, 0 ], yExtent = [ 0, 0 ];
33026        xExtentDomain = yExtentDomain = null;
33027      }
33028      return brush;
33029    };
33030    brush.empty = function() {
33031      return !!x && xExtent[0] == xExtent[1] || !!y && yExtent[0] == yExtent[1];
33032    };
33033    return d3.rebind(brush, event, "on");
33034  };
33035  var d3_svg_brushCursor = {
33036    n: "ns-resize",
33037    e: "ew-resize",
33038    s: "ns-resize",
33039    w: "ew-resize",
33040    nw: "nwse-resize",
33041    ne: "nesw-resize",
33042    se: "nwse-resize",
33043    sw: "nesw-resize"
33044  };
33045  var d3_svg_brushResizes = [ [ "n", "e", "s", "w", "nw", "ne", "se", "sw" ], [ "e", "w" ], [ "n", "s" ], [] ];
33046  var d3_time_format = d3_time.format = d3_locale_enUS.timeFormat;
33047  var d3_time_formatUtc = d3_time_format.utc;
33048  var d3_time_formatIso = d3_time_formatUtc("%Y-%m-%dT%H:%M:%S.%LZ");
33049  d3_time_format.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") ? d3_time_formatIsoNative : d3_time_formatIso;
33050  function d3_time_formatIsoNative(date) {
33051    return date.toISOString();
33052  }
33053  d3_time_formatIsoNative.parse = function(string) {
33054    var date = new Date(string);
33055    return isNaN(date) ? null : date;
33056  };
33057  d3_time_formatIsoNative.toString = d3_time_formatIso.toString;
33058  d3_time.second = d3_time_interval(function(date) {
33059    return new d3_date(Math.floor(date / 1e3) * 1e3);
33060  }, function(date, offset) {
33061    date.setTime(date.getTime() + Math.floor(offset) * 1e3);
33062  }, function(date) {
33063    return date.getSeconds();
33064  });
33065  d3_time.seconds = d3_time.second.range;
33066  d3_time.seconds.utc = d3_time.second.utc.range;
33067  d3_time.minute = d3_time_interval(function(date) {
33068    return new d3_date(Math.floor(date / 6e4) * 6e4);
33069  }, function(date, offset) {
33070    date.setTime(date.getTime() + Math.floor(offset) * 6e4);
33071  }, function(date) {
33072    return date.getMinutes();
33073  });
33074  d3_time.minutes = d3_time.minute.range;
33075  d3_time.minutes.utc = d3_time.minute.utc.range;
33076  d3_time.hour = d3_time_interval(function(date) {
33077    var timezone = date.getTimezoneOffset() / 60;
33078    return new d3_date((Math.floor(date / 36e5 - timezone) + timezone) * 36e5);
33079  }, function(date, offset) {
33080    date.setTime(date.getTime() + Math.floor(offset) * 36e5);
33081  }, function(date) {
33082    return date.getHours();
33083  });
33084  d3_time.hours = d3_time.hour.range;
33085  d3_time.hours.utc = d3_time.hour.utc.range;
33086  d3_time.month = d3_time_interval(function(date) {
33087    date = d3_time.day(date);
33088    date.setDate(1);
33089    return date;
33090  }, function(date, offset) {
33091    date.setMonth(date.getMonth() + offset);
33092  }, function(date) {
33093    return date.getMonth();
33094  });
33095  d3_time.months = d3_time.month.range;
33096  d3_time.months.utc = d3_time.month.utc.range;
33097  function d3_time_scale(linear, methods, format) {
33098    function scale(x) {
33099      return linear(x);
33100    }
33101    scale.invert = function(x) {
33102      return d3_time_scaleDate(linear.invert(x));
33103    };
33104    scale.domain = function(x) {
33105      if (!arguments.length) return linear.domain().map(d3_time_scaleDate);
33106      linear.domain(x);
33107      return scale;
33108    };
33109    function tickMethod(extent, count) {
33110      var span = extent[1] - extent[0], target = span / count, i = d3.bisect(d3_time_scaleSteps, target);
33111      return i == d3_time_scaleSteps.length ? [ methods.year, d3_scale_linearTickRange(extent.map(function(d) {
33112        return d / 31536e6;
33113      }), count)[2] ] : !i ? [ d3_time_scaleMilliseconds, d3_scale_linearTickRange(extent, count)[2] ] : methods[target / d3_time_scaleSteps[i - 1] < d3_time_scaleSteps[i] / target ? i - 1 : i];
33114    }
33115    scale.nice = function(interval, skip) {
33116      var domain = scale.domain(), extent = d3_scaleExtent(domain), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" && tickMethod(extent, interval);
33117      if (method) interval = method[0], skip = method[1];
33118      function skipped(date) {
33119        return !isNaN(date) && !interval.range(date, d3_time_scaleDate(+date + 1), skip).length;
33120      }
33121      return scale.domain(d3_scale_nice(domain, skip > 1 ? {
33122        floor: function(date) {
33123          while (skipped(date = interval.floor(date))) date = d3_time_scaleDate(date - 1);
33124          return date;
33125        },
33126        ceil: function(date) {
33127          while (skipped(date = interval.ceil(date))) date = d3_time_scaleDate(+date + 1);
33128          return date;
33129        }
33130      } : interval));
33131    };
33132    scale.ticks = function(interval, skip) {
33133      var extent = d3_scaleExtent(scale.domain()), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" ? tickMethod(extent, interval) : !interval.range && [ {
33134        range: interval
33135      }, skip ];
33136      if (method) interval = method[0], skip = method[1];
33137      return interval.range(extent[0], d3_time_scaleDate(+extent[1] + 1), skip < 1 ? 1 : skip);
33138    };
33139    scale.tickFormat = function() {
33140      return format;
33141    };
33142    scale.copy = function() {
33143      return d3_time_scale(linear.copy(), methods, format);
33144    };
33145    return d3_scale_linearRebind(scale, linear);
33146  }
33147  function d3_time_scaleDate(t) {
33148    return new Date(t);
33149  }
33150  var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ];
33151  var d3_time_scaleLocalMethods = [ [ d3_time.second, 1 ], [ d3_time.second, 5 ], [ d3_time.second, 15 ], [ d3_time.second, 30 ], [ d3_time.minute, 1 ], [ d3_time.minute, 5 ], [ d3_time.minute, 15 ], [ d3_time.minute, 30 ], [ d3_time.hour, 1 ], [ d3_time.hour, 3 ], [ d3_time.hour, 6 ], [ d3_time.hour, 12 ], [ d3_time.day, 1 ], [ d3_time.day, 2 ], [ d3_time.week, 1 ], [ d3_time.month, 1 ], [ d3_time.month, 3 ], [ d3_time.year, 1 ] ];
33152  var d3_time_scaleLocalFormat = d3_time_format.multi([ [ ".%L", function(d) {
33153    return d.getMilliseconds();
33154  } ], [ ":%S", function(d) {
33155    return d.getSeconds();
33156  } ], [ "%I:%M", function(d) {
33157    return d.getMinutes();
33158  } ], [ "%I %p", function(d) {
33159    return d.getHours();
33160  } ], [ "%a %d", function(d) {
33161    return d.getDay() && d.getDate() != 1;
33162  } ], [ "%b %d", function(d) {
33163    return d.getDate() != 1;
33164  } ], [ "%B", function(d) {
33165    return d.getMonth();
33166  } ], [ "%Y", d3_true ] ]);
33167  var d3_time_scaleMilliseconds = {
33168    range: function(start, stop, step) {
33169      return d3.range(Math.ceil(start / step) * step, +stop, step).map(d3_time_scaleDate);
33170    },
33171    floor: d3_identity,
33172    ceil: d3_identity
33173  };
33174  d3_time_scaleLocalMethods.year = d3_time.year;
33175  d3_time.scale = function() {
33176    return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat);
33177  };
33178  var d3_time_scaleUtcMethods = d3_time_scaleLocalMethods.map(function(m) {
33179    return [ m[0].utc, m[1] ];
33180  });
33181  var d3_time_scaleUtcFormat = d3_time_formatUtc.multi([ [ ".%L", function(d) {
33182    return d.getUTCMilliseconds();
33183  } ], [ ":%S", function(d) {
33184    return d.getUTCSeconds();
33185  } ], [ "%I:%M", function(d) {
33186    return d.getUTCMinutes();
33187  } ], [ "%I %p", function(d) {
33188    return d.getUTCHours();
33189  } ], [ "%a %d", function(d) {
33190    return d.getUTCDay() && d.getUTCDate() != 1;
33191  } ], [ "%b %d", function(d) {
33192    return d.getUTCDate() != 1;
33193  } ], [ "%B", function(d) {
33194    return d.getUTCMonth();
33195  } ], [ "%Y", d3_true ] ]);
33196  d3_time_scaleUtcMethods.year = d3_time.year.utc;
33197  d3_time.scale.utc = function() {
33198    return d3_time_scale(d3.scale.linear(), d3_time_scaleUtcMethods, d3_time_scaleUtcFormat);
33199  };
33200  d3.text = d3_xhrType(function(request) {
33201    return request.responseText;
33202  });
33203  d3.json = function(url, callback) {
33204    return d3_xhr(url, "application/json", d3_json, callback);
33205  };
33206  function d3_json(request) {
33207    return JSON.parse(request.responseText);
33208  }
33209  d3.html = function(url, callback) {
33210    return d3_xhr(url, "text/html", d3_html, callback);
33211  };
33212  function d3_html(request) {
33213    var range = d3_document.createRange();
33214    range.selectNode(d3_document.body);
33215    return range.createContextualFragment(request.responseText);
33216  }
33217  d3.xml = d3_xhrType(function(request) {
33218    return request.responseXML;
33219  });
33220  if (typeof define === "function" && define.amd) define(d3); else if (typeof module === "object" && module.exports) module.exports = d3;
33221  this.d3 = d3;
33222}();

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.