PageSourceSearch

https://www.hotelkaiserhof.de/(cms)/module/static/default/content/libs/js/vjg/vjg-2.js?v=2

js hotelkaiserhof.de collected 2026-09-26 17:00:40 UTC 105,350 bytes, 3,848 lines download raw bytes

1if ( typeof vjg2 == 'undefined' ) {
2	/**
3	 * TODO: disabled children auslagern, die ganze .length-checks laufen nun gegen die wand..
4	 * - oder inst.children auf instChildren() abaendern?
5	 */
6
7	var vjg2 = new function(){
8		this.version = '2.4.3.2';
9		this.insts = [];
10		this.timer = [];
11		this.children_state = {};
12		this.css3 = false;
13		this.ready = false;
14		this.debug = window.location.hash == '#dev';
15	};
16
17	// write protected default settings
18	vjg2.defaults = function(){
19		return {
20			mode:			'normal', // 'background'
21			random:			false,
22			resizeable:		false,
23			custom:			{},
24			container:		false,
25			type:			false, // 'html'
26			autostart:		true,
27			hoverpause:		true,
28			lightbox:		true,// 'Highslide', 'Lytebox'
29			overlay:		false,
30			overlay_container:			false,
31			resize:			false,
32			view:			'single',// multi, single
33			effect:			[ 'fade', 'none' ],// none, scroll, fly, tile (testing), rotate
34			timeout:		[ 4000, 1500 ],// [ timeout zwischen animationen, timeout nach .jump() ]
35			speed:			500,
36			children:		false,// false, object, selector
37			children_expand: '',
38			children_preload: 1,
39			links:			false,
40			scrollable:		false,
41			scrolling:		false,
42			scroller: {
43				align:		'left',// or 'right'
44				type:		'thumb',// or 'int'
45				mode:		'horizontal',
46				autoscroll:	true,
47				container:	false
48			},
49			navigation: {
50				type:		'int',// or img-path, function
51				container:	false
52			},
53			offset:			'1px',
54			currentIndex:	0,
55			inst_parent:	false,
56			inst_child:		false,
57			interactions:	{
58				hover:		false,
59				click:		false
60			},
61			dimensions: {
62				window: {
63					padding: {
64						top: 0,
65						right: 0,
66						bottom: 0,
67						left: 0
68					}
69				},
70				container: {
71					mode: null,
72					min: false,// { height: 300, width: 800 }
73					max: false,// { height: 500, width: 1200 }
74					ratio: false,
75					offset: {
76						top: 0,
77						right: 0,
78						bottom: 0,
79						left: 0
80					},
81					padding: {
82						top: 0,
83						right: 0,
84						bottom: 0,
85						left: 0
86					}
87				}
88				/*
89				 children: {
90				 [ pattern: '&wx$h', width: 500, height: 300 ],
91				 [ pattern: '&wx$h', width: 700, height: 400 ],
92				 [ pattern: '&wx$h', width: 900, height: 500 ]
93				 }
94				 */
95			},
96			jump_quiet: false
97		};
98	};
99
100	vjg2._init = function(){
101		//this.css3 = this.css3support();
102		this.dimsWindow = this.deviceDimensions();
103	};
104
105	vjg2.log = function( name, args, type ){
106		args = args || [''];
107		type = type in console ? type : 'log';
108
109		var instId = -1;
110		if ( typeof args[0] == 'number' ) {
111			instId = args[0];
112			args = jQuery( args ).slice( 1 );
113		}
114
115		if ( type in console ) {
116			if ( 'info' in console ) {
117				var style = 'color:#888;font-style:italic';
118
119				if ( instId != -1 ) {
120					name = instId + ':' + name;
121					style = 'background-color:' + [ '#eafbff', '#fef4f4', '#f4fef7', '#feffea', '#dfe4ff', '#fff1df' ][ instId % 6 ];
122				}
123
124				console[ type ]( '%c' + name, style, ( args.length ? args : '' ) );
125			}
126			else {
127				console[ type ]( name, args );
128			}
129		}
130	};
131
132	vjg2.copy = function( object, deep ) {
133		var copy = {};
134
135		jQuery.each( object, function( key, value ){
136			if ( deep && typeof value == 'object' ) {
137				copy[key] = vjg2.copy( value, deep );
138			}
139			else {
140				copy[key] = value;
141			}
142		});
143
144		return copy;
145	};
146
147	vjg2.shuffle = function (data) {
148		var copy = [];
149
150		while ( data.length ) {
151			copy.push( data.splice( Math.random() * data.length, 1 )[0] );
152		}
153
154		while ( copy.length ) {
155			data.push( copy.pop() );
156		}
157	};
158
159	vjg2.trim = function( string ) {
160		if ( vjg2.debug ) vjg2.log( 'vjg2.trim()', arguments );
161
162		return ( string ? '' + string : '' ).replace( /^\s*|\s*$/g, '' );
163	};
164
165	vjg2.bbcode = function( string ){
166		if ( typeof string != 'string' ) return string;
167
168		var search = new Array(
169				/\[b\](.*?)\[\/b\]/g,
170				/\[i\](.*?)\[\/i\]/g,
171				/\[br\]/g
172			),
173			replace = new Array(
174				"<b>$1</b>",
175				"<i>$1</i>",
176				"<br \/>"
177			);
178
179		for (var i = 0, l = search.length; i < l; i++) {
180			string = string.replace(search[i], replace[i]);
181		}
182
183		return string;
184	};
185
186	vjg2.json_encode = function( data ){
187		if ( data && 'JSON' in window ) {
188			return JSON.stringify( data );
189		}
190
191		return data;
192	};
193
194	vjg2.json_decode = function( string ){
195		if ( string && 'JSON' in window ) {
196			return JSON.parse( string );
197		}
198
199		return string;
200	};
201
202	vjg2.css3support = function(){
203		var css3prop = 'transition',
204			div = document.createElement( 'div' ),
205			browsers = [
206				{
207					prefix: '',
208					events: {
209						'animationEnd': 'animationend',
210						'transitionEnd': 'transitionend'
211					}
212				},
213				{
214					prefix: 'moz',
215					events: {
216						'animationEnd': 'animationEnd',
217						'transitionEnd': 'transitionEnd'
218					}
219				},
220				{
221					prefix: 'webkit',
222					events: {
223						'animationEnd': 'webkitAnimationEnd',
224						'transitionEnd': 'webkitTransitionEnd'
225					}
226				}
227			];
228
229		for( var i = 0, l = browsers.length; i < l; i++ ) {
230			if ( i == 1 ) {
231				css3prop = css3prop.charAt( 0 ).toUpperCase() + css3prop.slice( 1 );
232			}
233
234			if ( browsers[ i ].prefix + css3prop  in div.style ) {
235				return browsers[ i ];
236			}
237		}
238
239		return false;
240	};
241
242	vjg2.transitionDuration = function( instId, speed ) {
243		if ( vjg2.debug ) vjg2.log( 'vjg2.transitionSpeed()', arguments );
244		var inst = this.insts[instId];
245
246		if ( typeof speed == 'undefined' ) {
247			if ( !( 'speed_css3' in inst ) ) {
248				if ( inst.speed < 1000 ) {
249					inst.speed_css3 = '0.' + inst.speed;
250				}
251				else {
252					var speed_str = inst.speed.toString();
253					inst.speed_css3 = speed_str.substring( 0, speed_str.length - 3 ) + '.' + speed_str.substring( speed_str.length - 3 );
254				}
255			}
256
257			speed = inst.speed_css3;
258		}
259
260		return ( vjg2.css3.prefix ? '-' + vjg2.css3.prefix + '-' : '' ) + 'transition-duration:' + speed + 's';
261	};
262
263	vjg2.timer_add = function( instId, name, time, fn ){
264		if ( this.debug ) this.log( 'vjg2.timer_add()', arguments );
265		var inst = this.insts[ instId ];
266
267		if ( inst.inst_parent !== false || !fn ) return false;
268
269		this.timer_delete( instId, name );
270
271		time += Math.round(new Date().getTime());
272
273		// alle eintraege haben einen mindest-abstand von 500ms, auch wenn dadurch gewissen ungenauigkeiten beim abspiel-interval entstehen
274		if( this.timer.length > 0 ) {
275			for( var i = 0, l = this.timer.length; i < l; i++ ) {
276				var time_diff = Math.abs( this.timer[i].time - time );
277
278				if ( time_diff < 500 ) {
279					time += ( 500 - Math.abs( time_diff ) );
280				}
281			}
282		}
283
284		this.timer.push( { instId: instId, name: name, time: time, fn: fn } );
285		this.timer_watcher_start();
286		this.instCallback( instId, 'timer_add' );
287	};
288
289	vjg2.timer_watch = function(){
290		if( this.timer.length == 0 ) return false;
291
292		var timer = [],
293			skip = false,
294			current_time = Math.round(new Date().getTime());
295
296		for( var i = 0, l = this.timer.length; i < l; i++ ) {
297			if ( !skip && this.timer[i].time <= current_time ) {
298				this.timer[i].fn( this.timer[i].instId );
299				skip = true;
300			}
301			else {
302				timer.push( this.timer[i] );
303			}
304		}
305
306		this.timer = timer;
307	};
308
309	vjg2.timer_watcher_start = function(){
310		if ( this.debug ) this.log( 'vjg2.timer_watcher_start()', arguments );
311		if ( this.timer_watcher_running ) return;
312
313		this.timer_watcher_running = true;
314
315		this.interval = window.setInterval(function(){
316			vjg2.timer_watch();
317		}, 500 );
318	};
319
320	vjg2.timer_delete = function( instId, name ){
321		if ( this.debug ) this.log( 'vjg2.timer_delete()', arguments );
322
323		var timer = [];
324
325		if( this.timer.length > 0 ) {
326			for( var i in this.timer ) {
327				if ( typeof this.timer[i] !== 'undefined' ) {
328					if ( name ) {
329						if ( this.timer[i].instId == instId && name == this.timer[i].name ) {
330							// es kann immer nur einen eintrag des selben types (name) pro instanz geben
331						}
332						else {
333							timer.push( this.timer[i] );
334						}
335					}
336					else if ( this.timer[i].instId != instId ) {
337						timer.push( this.timer[i] );
338					}
339				}
340			}
341		}
342
343		this.timer = timer;
344	};
345
346	vjg2.option_get = function( instId, option ) {
347		if ( this.debug ) this.log( 'vjg2.option_get()', arguments );
348		var inst = this.insts[ instId ];
349
350		if ( inst.inst_parent !== false ) {
351			if ( option[ 1 ] ) {
352				return option[ 1 ];
353			}
354
355			return undefined;
356		}
357		else if ( option[ 0 ] ){
358			return option[ 0 ];
359		}
360
361		return option;
362	};
363
364	vjg2.instCallback = function( instId, name, optional ){
365		if ( this.debug ) this.log( 'vjg2.instCallback()', arguments );
366		var inst = this.insts[instId];
367
368		if ( !inst || !inst.callbacks ) {
369			return;
370		}
371
372		if ( inst.callbacks.main ) {
373			inst.callbacks.main( inst, name, optional );
374		}
375
376		if ( inst.callbacks[ name ] ) {
377			inst.callbacks[ name ]( inst, name, optional );
378		}
379	};
380
381	vjg2.instGet = function( selector ) {
382		if ( this.debug ) this.log( 'vjg2.instGet()', arguments );
383
384
385		for( var i = 0, l = this.insts.length; i < l; i++ ) {
386			var inst = this.insts[i];
387
388			if ( inst && inst.container.is( selector ) ) {
389				return inst;
390			}
391		}
392
393		return {};
394	};
395
396	vjg2.instReady = function( instId ) {
397		if ( this.debug ) this.log( 'vjg2.instReady()', arguments );
398		var inst = this.insts[instId];
399
400		if ( inst.inst_parent === false ) {
401			if ( !this.instResize( instId, true ) ) {
402				setTimeout(function(){
403					vjg2.instReady( instId );
404				}, 50 );
405				return;
406			}
407		}
408
409		if ( inst.ready ) return false;
410		inst.ready = true;
411
412		inst.container
413			.add( inst.links )
414			.bind('mouseenter', function(){
415				inst.container.addClass( 'hover' );
416				vjg2.interaction( inst.instId, 'hover', true );
417				if ( inst.hoverpause ) {
418					vjg2.pause( inst.instId );
419				}
420				vjg2.instCallback( inst.instId, 'child_mouseenter', inst.currentIndex );
421				vjg2.instCallback( inst.instId, 'mouseenter' );
422			})
423			.bind( 'mouseleave', function(){
424				inst.container.removeClass( 'hover' );
425				vjg2.interaction( inst.instId, 'hover', false );
426				if ( inst.hoverpause ) {
427					vjg2.resumePaused( inst.instId );
428				}
429				vjg2.instCallback( inst.instId, 'child_mouseleave', inst.currentIndex );
430				vjg2.instCallback( inst.instId, 'mouseleave' );
431			});
432
433		vjg2e[inst.effect[0]].init( instId );
434
435		this.markCurrent( instId );
436		this.poisRegister( instId );
437		this.instCallback( instId, 'init' );
438
439		jQuery( inst.options.container ).css( 'visibility', 'visible' );
440
441		if ( inst.inst_parent === false ) {
442			this[ inst.autostart ? 'play' : 'stop' ]( instId );
443		}
444
445		if ( typeof inst.options.scroller == 'object' && inst.options.children.length > 1 ) {
446			var options = this.copy( inst.options );
447			options.children = [];
448
449			for( var i in inst.children_copy ) {
450				var child = this.copy( inst.children_copy[i] );
451
452				if ( !( 'thumb' in child ) ) {
453					return;
454				}
455
456				child.src = child.thumb;
457				child.onclick = 'vjg2.interaction( ' + inst.instId + ', \'click\', true ); vjg2.jump( ' + inst.instId + ', ' + i + ' ); return false;';
458
459				delete child.thumb;
460				delete child.href;
461
462				options.children.push( child );
463			}
464
465			options.inst_parent = inst.instId;
466			options.currentIndex = inst.currentIndex;
467			options.effect = 'scroll';
468			options.scroller = false;
469			options.autostart = false;
470			options.navigation = false;
471			options.overlay = false;
472			options.resizeable = false;
473			options.dimensions = false;
474			options.mode = 'normal';
475
476			if ( inst.options.scroller.mode ) {
477				options.mode = inst.options.scroller.mode;
478			}
479
480			if ( inst.options.scroller.align ) {
481				options.align = inst.options.scroller.align;
482			}
483
484			inst.inst_child = this.create( inst.options.scroller.container, options );
485		}
486	};
487
488	vjg2.resizeableInit = function( instId ) {
489		if ( this.debug ) this.log( 'vjg2.resizeableInit()', arguments );
490
491		var inst = this.insts[instId];
492
493		if ( inst.dimensions && inst.dimensions.children ) {
494			var dimensionUse = inst.dimensions.children[0];
495
496			for( var i = 0, l = inst.dimensions.children.length; i < l; i++ ) {
497				var dimension = inst.dimensions.children[i];
498
499				if ( dimension.width && dimension.height ) {
500					if ( dimension.width >= this.dimsWindow.width && dimension.height >= this.dimsWindow.height ) {
501						if ( dimensionUse.width > dimension.width && dimensionUse.height > dimension.height ) {
502							dimensionUse = dimension;
503						}
504					}
505				}
506			}
507
508			inst.dimensionUse = dimensionUse;
509
510			if ( dimensionUse.width ) {
511				dimensionUse.pattern = dimensionUse.pattern.replace( /\$w/, dimensionUse.width );
512			}
513
514			if ( dimensionUse.height ) {
515				dimensionUse.pattern = dimensionUse.pattern.replace( /\$h/, dimensionUse.height );
516			}
517
518			for( var i = 0, l = inst.children.length; i < l; i++ ) {
519				inst.children[i].src = inst.children[i].src.replace( /\$size/, dimensionUse.pattern );
520			}
521		}
522	};
523
524	vjg2.instResize = function( instId, initial, tries ){
525		if ( this.debug ) this.log( 'vjg2.instResize()', arguments );
526		var inst = this.insts[ instId ],
527			instDimensions = this.instDimensions( inst.instId );
528
529		if ( instDimensions === false ) {
530			return false;
531		}
532
533		inst.dimensions_last = instDimensions;
534		inst.dimensions_last_json = this.json_encode( instDimensions );
535
536		this.containerResize( inst.instId );
537
538		if ( inst.resizeable ) {
539			this.childResize( inst.instId, inst.currentIndex );
540			this.poisMove( inst.instId );
541		}
542
543		this.instCallback( inst.instId, 'resize', instDimensions );
544
545		return true;
546	};
547
548	vjg2.resizeTimerStart = function() {
549		if ( this.debug ) this.log( 'vjg2.resizeTimerStart()', arguments );
550
551		if ( 'resizeTimer' in this ) {
552			clearTimeout( this.resizeTimer );
553		}
554
555		var resizeTimerFunction = function(){
556			var dimsWindow = vjg2.dimsWindow,
557				dimsWindowLast = 'dimsWindowLast' in vjg2 ? vjg2.dimsWindowLast : {};
558
559			if ( dimsWindow.width == dimsWindowLast.width && dimsWindow.height == dimsWindowLast.height ) {
560				return;
561			}
562
563			jQuery.each( vjg2.insts, function( i, inst ){
564				if ( inst && inst.inst_parent === false ) {
565					vjg2.instResize( inst.instId );
566				}
567			});
568
569			vjg2.dimsWindowLast = vjg2.dimsWindow;
570		};
571
572		resizeTimerFunction();
573		this.resizeTimer = setTimeout( resizeTimerFunction, 30 * this.insts.length );
574	};
575
576	vjg2.create = function(node, options) {
577		if ( this.debug ) this.log( 'vjg2.create()', arguments );
578		var instId = this.insts.length;
579
580		options.instId = instId;
581		options.container = jQuery( node );
582		options.options = this.copy( options );
583
584		if( options.container.closest('div').hasClass('vjg2') ) {
585			return false;
586		}
587
588		if ( 'mode' in options && options.mode == 'background' ) {
589			options.resizeable = true;
590		}
591
592		if ( !( options.timeout instanceof Array ) ) {
593			options.timeout = [ options.timeout ];
594		}
595
596		if ( !options.container.children( ':not(.vjg2_link)' ).length ) {
597			options.container.css( 'visibility', 'hidden' );
598		}
599
600		this.insts.push( jQuery.extend( true, this.defaults(), options ) );
601
602		this.instInit( instId );
603
604		return instId;
605	};
606
607	vjg2.destroy = function( instId ) {
608		if ( this.debug ) this.log( 'vjg2.destroy()', arguments );
609		if ( typeof instId != 'number' || instId < 0 ) return;
610
611		var inst = this.insts[ instId ],
612			inst_parent = inst.inst_parent,
613			inst_child = inst.inst_child;
614
615		this.timer_delete( instId );
616		this.insts[instId] = undefined;
617
618		if ( inst_parent !== false ) {
619			this.timer_delete( inst_parent );
620			this.insts[ inst_parent ] = undefined;
621		}
622
623		if ( inst_child !== false ) {
624			this.timer_delete( inst_child );
625			this.insts[ inst_child ] = undefined;
626		}
627	};
628
629	vjg2.instInit = function( instId ){
630		if ( this.debug ) this.log( 'vjg2.instInit()', arguments );
631		var inst = this.insts[instId];
632
633		inst.custom = this.option_get( instId, inst.custom );
634		inst.links = this.option_get( instId, inst.links );
635
636		if ( typeof inst.effect == 'string' ) {
637			inst.effect = [ inst.effect, inst.effect ];
638		}
639
640		this.resizeableInit( instId );
641
642		vjg2e[inst.effect[0]].preinit( inst.instId );
643		this.childrenInit( instId );
644		this.containerInit( instId );
645
646		if ( inst.navigation.container ) {
647			inst.navigation.container = jQuery( inst.navigation.container );
648			this.navigationInit( instId );
649		}
650
651		if ( inst.overlay ) {
652			this.overlayInit( instId );
653		}
654
655		if ( inst.links ) {
656			this.linksInit( instId );
657		}
658
659		if ( inst.type != 'html' && inst.resizeable ) {
660			this.childrenLoad( instId, inst.currentIndex, 0, function( instId ){
661				if ( vjg2.ready ) {
662					vjg2.instReady( instId );
663				}
664				else {
665					var inst = vjg2.insts[ instId ];
666
667					clearInterval( inst.timer_ready );
668					inst.timer_ready = setInterval(function(){
669						if ( vjg2.ready ) {
670							clearInterval( vjg2.insts[ this.instId ].timer_ready );
671							vjg2.instReady( this.instId );
672						}
673					}
673.bind({instId: instId}), 50 );
674				}
675			});
676		}
677		else {
678			vjg2.instReady( instId );
679		}
680	};
681
682	vjg2.instChildren = function( instId ){
683		if ( this.debug ) this.log( 'vjg2.instChildren()', arguments );
684		var inst = this.insts[instId],
685			children = inst.container.children( ':not(.vjg2_link)' );
686
687		if ( children.eq( 0 ).find( 'td' ).length ) {
688			children = children.find( 'td' ).children();
689		}
690
691		return children;
692	};
693
694	vjg2.containerInit = function( instId ){
695		if ( this.debug ) this.log( 'vjg2.containerInit()', arguments );
696		var inst = this.insts[instId],
697			container_classes = [ 'vjg2', 'vjg2_inst' + instId, 'vjg2e_' + inst.effect[0] ];
698
699		if ( inst.resizeable ) {
700			inst.container.wrap( '<div class="vjg2_wrapper" />' );
701		}
702
703		if ( this.css3 !== false ) {
704			container_classes.push( 'vjg2_css3' );
705		}
706
707		if ( inst.mode == 'background' ) {
708			var offset = inst.dimensions.container.offset,
709				style = 'position:fixed;top:' + offset.top + 'px;left:' + offset.left + 'px';
710
711			if ( offset.bottom ) {
712				style += ';height:' + ( jQuery( window ).height() - offset.top - offset.bottom ) + 'px';
713			}
714
715			if ( offset.right ) {
716				style += ';width:' + ( jQuery( window ).width() - offset.left - offset.right ) + 'px';
717			}
718
719			if ( offset.bottom || offset.right ) {
720				style += ';overflow:hidden';
721			}
722
723			inst.container.wrap( '<div class="vjg2_holder" style="' + style + '" />' );
724		}
725
726		inst.container.addClass( container_classes.join( ' ' ) );
727	};
728
729	vjg2.linksInit = function( instId ){
730		if ( this.debug ) this.log( 'vjg2.linksInit()', arguments );
731		var inst = this.insts[instId],
732			links = inst.links;
733
734		if(inst.links instanceof Array){
735			links = inst.links[0];
736		}
737
738		for ( var key in links ) {
739			links[key] = jQuery( links[key] );
740			vjg2e[inst.effect[0]].linkInit( instId, key );
741
742			if ( typeof links[key].context == 'undefined' ) {
743				links[key]
744					.addClass( 'vjg2_link' )
745					.appendTo( inst.container );
746			}
747		}
748
749		if ( inst.autostart && links.stop ) {
750			links.stop.hide();
751		}
752		else if ( links.play ) {
753			links.play.hide();
754		}
755	};
756
757	vjg2.navigationInit = function( instId ){
758		if ( this.debug ) this.log( 'vjg2.navigationInit()', arguments );
759		var inst = this.insts[instId],
760			callback = function( instId, index ){
761				var inst = vjg2.insts[instId],
762					a = '<a href="#"';
763
764				if ( index == inst.currentIndex + 1 ) {
765					a += 'class="current"';
766				}
767
768				a += '>' + index + '</a>';
769
770				return a;
771			};
772
773		inst.navigation.children = inst.navigation.container.children();
774
775		if ( typeof inst.navigation.format == 'function' ) {
776			callback = inst.navigation.format;
777		}
778
779		if ( inst.navigation.children.length == 0 ) {
780			var string = '';
781
782			jQuery.each(inst.children, function( i ){
783				if ( inst.type == 'html' || ( inst.children_copy && !inst.children_copy[ i ].disabled ) ) {
784					string += callback( instId, ( i + 1 ) );
785				}
786			});
787
788			inst.navigation.children = inst.navigation.container.append( string ).children();
789		}
790
791		inst.navigation.children
792			.bind( 'click', inst, function( event ){
793				var inst = event.data;
794
795				vjg2.jump( inst.instId, inst.navigation.children.index( this ) );
796
797				vjg2.instCallback( inst.instId, 'click', { element: this, type: 'navigation' } );
798
799				return false;
800			})
801			.bind( 'mouseenter', inst, function( event ){
802				var inst = event.data;
803
804				vjg2.interaction( inst.instId, 'hover', true );
805				vjg2.pause( inst.instId );
806
807				vjg2.instCallback( inst.instId, 'mouseenter', { element: this, type: 'navigation' } );
808			})
809			.bind( 'mouseleave', inst, function( event ){
810				var inst = event.data;
811
812				vjg2.interaction( inst.instId, 'hover', false );
813				vjg2.resumePaused( inst.instId );
814
815				vjg2.instCallback( inst.instId, 'mouseleave', { element: this, type: 'navigation' } );
816			})
817			.each(function( index ){
818				jQuery( this ).attr( 'rel', index );
819			});
820	};
821
822	vjg2.overlayInit = function( instId ){
823		if ( this.debug ) this.log( 'vjg2.overlayInit()', arguments );
824		var inst = this.insts[instId],
825			callback = function( indexId, index ){
826				return inst.children_copy[ index ].overlay;
827			};
828
829		if ( typeof inst.overlay == 'string' ) {
830			inst.overlay = jQuery( inst.overlay ).bind( 'click', function( event ){
831				vjg2.instChildren( instId ).eq( inst.currentIndex ).find('a:first').trigger( 'click' );
832			});
833
834			this.overlayUpdate( instId, inst.currentIndex );
835		}
836		else {
837			if ( typeof inst.overlay == 'function' ) {
838				callback = inst.overlay;
839			}
840
841			inst.children.each(function( index ){
842				var string = vjg2.bbcode( callback( instId, index ) );
843
844				if ( string ) {
845					jQuery( this ).append( '<div class="vjg2_overlay">' + string + '</div>' );
846				}
847			});
848		}
849	};
850
851	vjg2.overlayUpdate = function( instId, index ){
852		if ( this.debug ) this.log( 'vjg2.overlayUpdate()', arguments );
853		var inst = this.insts[instId],
854			effect = vjg2e[inst.effect[0]];
855
856		if ( 'vjg2' in effect && 'overlayUpdate' in effect.vjg2 && effect.vjg2.overlayUpdate === false ) {
857			return;
858		}
859
860		// ohne setTimeout aendert der IE8 nicht immer den inhalt des overlays.. 
861		window.setTimeout(function(){
862			vjg2.instCallback( inst.instId, 'overlayUpdate' );
863
864			if ( index in inst.children_copy && 'overlay' in inst.children_copy[index] ) {
865				jQuery( inst.overlay ).html( vjg2.bbcode( inst.children_copy[index].overlay ) );
866			}
867
868			vjg2.instCallback( inst.instId, 'overlayUpdated' );
869		}, 1 );
870	};
871
872	vjg2.interaction = function( instId, name, state ) {
873		//if ( this.debug ) this.log( 'vjg2.interaction()', arguments );
874		var inst = this.insts[ instId ];
875
876		if ( inst.inst_parent !== false ) {
877			inst = this.insts[ inst.inst_parent ];
878		}
879
880		if ( state != undefined ) {
881			inst.interactions[ name ] = state;
882		}
883		else {
884			return inst.interactions[ name ];
885		}
886	};
887
888	vjg2.play = function( instId ){
889		if ( this.debug ) this.log( 'vjg2.play()', arguments );
890		var inst = this.insts[instId];
891
892		if ( !inst || inst.children.length <= 1 || inst.stopped || inst.inst_parent !== false ) {
893			return;
894		}
895
896		if ( inst.children_copy ) {
897			var i = 0;
898			jQuery.each( inst.children_copy, function( index, child ){
899				if ( !( 'disabled' in child ) || !child.disabled ) {
900					i++;
901				}
902			});
903
904			if ( i <= 1 && inst.currentIndex < i ) {
905				return;
906			}
907		}
908
909		inst.paused = false;
910		inst.stopped = false;
911
912		if ( inst.links && inst.links.play ) {
913			inst.links.play.hide();
914		}
915
916		if ( inst.links && inst.links.stop ) {
917			inst.links.stop.show();
918		}
919
920		this.timer_add( instId, 'play', inst.timeout[0], function( instId ){
921			var inst = vjg2.insts[instId],
922				from = vjg2.childCurrent( instId ),
923				to = vjg2.childToPlay( instId ),
924				fn = function( instId, index ){
925					if ( !( index == undefined || index == to ) ) {
926						return;
927					}
928
929					if ( inst.resizeable ) {
930						vjg2.childResize( instId, to );
931					}
932
933					vjg2.markCurrent( instId, to );
934					vjg2e[inst.effect[0]].play( instId, from, to );
935
936					if ( inst.resizeable ) {
937						vjg2.poisMove( instId );
938					}
939
940					if ( inst.overlay ) {
941						vjg2.overlayUpdate( instId, to );
942					}
943
944					if ( inst.inst_child ) {
945						vjg2.jump( inst.inst_child, to );
946					}
947
948					vjg2.childrenLoad( inst.instId, to, inst.children_preload );
949
950					setTimeout(function(){
951						vjg2.play( instId );
952					}, 1 );
953					vjg2.instCallback( instId, 'play' );
954				};
955
956			if ( inst.type == false && !vjg2.childLoaded( instId, to ) ) {
957				vjg2.childrenLoad( instId, to, inst.children_preload, fn );
958			}
959			else fn( instId, to );
960		});
961	};
962
963	vjg2.childToPlay = function( instId, direction ){
964		if ( this.debug ) this.log( 'vjg2.childToPlay()', arguments );
965		var inst = this.insts[instId];
966
967		if ( inst.random ) {
968			return this.childRandom( instId );
969		}
970
971		if ( direction && direction == 'prev' ) {
972			return this.childPrev( instId );
973		}
974
975		return this.childNext( instId );
976	};
977
978	vjg2.resumePaused = function( instId ){
979		if ( this.debug ) this.log( 'vjg2.resumePaused()', arguments );
980		var inst = this.insts[instId];
981
982		if ( !inst.stopped && inst.paused && inst.inst_parent === false ) {
983			inst.paused = false;
984			this.resume( instId );
985		}
986	};
987
988	vjg2.resumeStopped = function( instId ){
989		if ( this.debug ) this.log( 'vjg2.resumeStopped()', arguments );
990		var inst = this.insts[instId];
991
992		if ( inst.stopped && inst.inst_parent === false ) {
993			inst.stopped = false;
994			inst.paused = false;
995			this.resume( instId );
996		}
997	};
998
999	vjg2.resume = function( instId ) {
1000		if ( this.debug ) this.log( 'vjg2.resume()', arguments );
1001		var inst = this.insts[instId];
1002
1003		/**
1004		 * TODO: das sollte eigentlich durch this.timer_add() gesteuert werden
1005		 */
1006		setTimeout(function(){
1007			vjg2.play( instId );
1008			vjg2.instCallback( inst.instId, 'resume' );
1009		}, inst.timeout[1]);
1010	};
1011
1012	vjg2.pause = function( instId ){
1013		if ( this.debug ) this.log( 'vjg2.pause()', arguments );
1014		var inst = this.insts[instId];
1015
1016		this.stopTimers( inst.instId );
1017
1018		// vjg2 is already paused
1019		if ( inst.paused ) {
1020			return;
1021		}
1022
1023		if ( this.interaction( instId, 'click' ) && inst.inst_parent !== false ) {
1024			return;
1025		}
1026
1027		inst.paused = true;
1028
1029		if ( inst.links && inst.links.stop ) {
1030			inst.links.stop.hide();
1031		}
1032
1033		if ( inst.links && inst.links.play ) {
1034			inst.links.play.show();
1035		}
1036
1037		this.instCallback( inst.instId, 'pause' );
1038	};
1039
1040	vjg2.stop = function( instId ){
1041		if ( this.debug ) this.log( 'vjg2.stop()', arguments );
1042		var inst = this.insts[instId];
1043
1044		if ( inst.inst_parent !== false || inst.stopped ) {
1045			return;
1046		}
1047
1048		this.stopTimers( instId );
1049
1050		inst.stopped = true;
1051
1052		if ( inst.links && inst.links.stop ) {
1053			inst.links.stop.hide();
1054		}
1055
1056		if ( inst.links && inst.links.play ) {
1057			inst.links.play.show();
1058		}
1059
1060		this.instCallback( inst.instId, 'stop' );
1061	};
1062
1063	vjg2.stopTimers = function( instId ){
1064		if ( this.debug ) this.log( 'vjg2.stopTimers()', arguments );
1065		this.timer_delete( instId );
1066
1067		/*
1068		 window.clearTimeout( inst.pauseTimer );
1069		 window.clearTimeout( inst.effectTimer );
1070		 */
1071	};
1072
1073	vjg2.jump = function( instId, index, direction, quiet ){
1074		if ( this.debug ) this.log( 'vjg2.jump()', arguments );
1075		var inst = this.insts[instId];
1076		inst.playDirection = direction || 'next';
1077		inst.jump_quiet = !!quiet;
1078
1079		this.pause( instId );
1080		this.markCurrent( instId, index );
1081		
1082		if ( inst.type == 'html' ) {
1083			vjg2.jump_run( instId, index );
1084		}
1085		else {
1086			this.childrenLoad( instId, index, undefined, vjg2.jump_run );
1087			this.childrenLoad( instId, this.childNext( instId ), inst.children_preload );
1088		}
1089	};
1090
1091	vjg2.jump_run = function( instId, index ){
1092		if ( this.debug ) this.log( 'vjg2.jump_run()', arguments );
1093		var inst = this.insts[instId];
1094
1095		if ( inst.resizeable ) {
1096			this.childResize( instId, index );
1097		}
1098
1099		if ( !inst.jump_quiet ) {
1100			vjg2e[inst.effect[1]].jump( instId, index );
1101		}
1102
1103		inst.currentIndex = index;
1104
1105		if ( inst.resizeable ) {
1106			this.poisMove( instId, index );
1107		}
1108
1109		if ( inst.overlay ) {
1110			this.overlayUpdate( instId, index );
1111		}
1112
1113		if ( inst.inst_parent !== false && this.insts[ inst.inst_parent ].currentIndex != index ) {
1114			this.jump( inst.inst_parent, index );
1115		}
1116
1117		if ( inst.inst_child !== false && this.insts[ inst.inst_child ].currentIndex != index ) {
1118			this.jump( inst.inst_child, index );
1119		}
1120
1121		this.resumePaused( instId );
1122		this.instCallback( inst.instId, 'jump' );
1123	};
1124
1125	vjg2.effectDone = function( instId ){
1126		if ( this.debug ) this.log( 'vjg2.effectDone()', arguments );
1127		var inst = this.insts[instId];
1128
1129		if ( inst && inst.autostart ) {
1130			this.play( instId );
1131		}
1132	};
1133
1134	vjg2.childCreate = function( instId, index ){
1135		//if ( vjg2.debug ) vjg2.log( 'vjg2.childCreate()', arguments );
1136		var inst = this.insts[instId];
1137
1138		var div = '<div rel="' + index + '"',
1139			a = '<a style="display:block;font-size:0"',
1140			img = '<img style="position:relative"',
1141			classes = [ 'vjg2_item' ],
1142			child = inst.children_copy[index || 0],
1143			style_string = vjg2e[inst.effect[0]].defaultChildrenStyle( instId, index );
1144
1145		if ( !child.src ) {
1146			return false;
1147		}
1148
1149		if ( index == 0 ) {
1150			classes.push( 'first' );
1151		}
1152		else if ( index == inst.children.length - 1 ) {
1153			classes.push( 'last' );
1154		}
1155
1156		div += ' class="' + classes.join( ' ' ) + '"';
1157
1158		if ( child.onclick && child.onclick != 'return false' && typeof child.onclick != 'boolean' ) {
1159			a += ' onclick="' + child.onclick.replace(/\"/g, "'") + '"';
1160		}
1161		else {
1162			if ( child.onclick === false || child.onclick == 'return false' ) {
1163				a += ' onclick="return false;"';
1164			}
1165			else if ( typeof hs != 'undefined' ) {
1166				a += ' onclick="return hs.expand( this, {numberPosition: \'caption\', slideshowGroup: \'vjgInst' + instId + '\', wrapperClassName: \'in-page controls-in-heading\'});"';
1167			}
1168		}
1169
1170		if ( child.style )	style_string += child.style;
1171		if ( child.href )	a += ' href="' + child.href + '"';
1172		if ( child.thumb )	a += ' thumb="' + child.thumb + '"';
1173		if ( child.rel )	a += ' rel="' + child.rel + '"';
1174		if ( child.title )	a += ' title="' + child.title + '"';
1175		if ( child.alt )	a += ' alt="' + child.alt + '"';
1176		if ( child.title )	img += ' alt="' + child.title + '"';
1177		if ( inst.type == 'html' ) img += ' src="' + child.src + '"';
1178		else {
1179			if ( child.alt_img ) img += ' alt="' + child.alt_img + '"';
1180			if ( index == this.insts[instId].currentIndex ) img += ' src="' + child.src + '"';
1181			else img += ' rev="' + child.src + '"';
1182		}
1183
1184		div += ' style="' + style_string + '">' + a + '>
1184' + img + '></a>';
1185
1186
1187		if ( child.highslide ) {
1188			div += '<div class="highslide-caption">' + child.highslide + '</div>';
1189		}
1190
1191		div += inst.children_expand + '</div>';
1192
1193		return div;
1194	};
1195
1196	vjg2.childUpdate = function( instId, index ){
1197		if ( this.debug ) this.log( 'vjg2.childUpdate()', arguments );
1198		var inst = this.insts[instId];
1199
1200		var div = this.instChildren( instId ).eq( index ).attr( 'rel', index ),
1201			a = div.is( 'a' ) ? div : div.find( 'a:first' ),
1202			classes = [ 'vjg2_item' ],
1203			img = a.find( 'img:first' ),
1204			child = inst.children_copy[index || 0],
1205			style_string = vjg2e[inst.effect[0]].defaultChildrenStyle( instId, index );
1206
1207		a.bind( 'mouseenter mouseleave', {instId: instId, index: index}, function( event ){
1208			vjg2.instCallback( event.data.instId, "child_" + event.type, event.data.index );
1209		});
1210
1211		if ( index == 0 ) {
1212			classes.push( 'first' );
1213		}
1214		else if ( index == inst.children.length - 1 ) {
1215			classes.push( 'last' );
1216		}
1217
1218		a.addClass( classes.join( ' ' ) );
1219
1220		if ( child.onclick && typeof child.onclick != 'boolean' && child.onclick.substring(0, 10) != 'return hs.' ) {
1221			a.attr( 'onclick', child.onclick.replace(/\"/g, "'") );
1222		}
1223		else {
1224			if ( child.onclick === false ) {
1225				a.attr( 'onclick', 'return false;' );
1226			}
1227			else if ( typeof hs != 'undefined' ) {
1228				var hs_settings = {
1229					numberPosition: 'caption',
1230					slideshowGroup: 'vjgInst' + instId,
1231					wrapperClassName: 'in-page controls-in-heading'
1232				};
1233
1234				if ( child.onclick && child.onclick.substring(0, 10) == 'return hs.' ) {
1235					hs_settings = eval('(' + child.onclick.match(/\{(.*)\}/)[0] + ')');
1236				}
1237
1238				a[0].onclick = function(){
1239					return hs.expand( this, hs_settings );
1240				};
1241			}
1242		}
1243
1244		if ( child.style )	style_string += child.style;
1245		if ( style_string )	a.attr( 'style', style_string );
1246		if ( child.href )	a.attr( 'href', child.href );
1247		if ( child.thumb )	a.attr( 'thumb', child.thumb );
1248		if ( child.rel )	a.attr( 'rel', child.rel );
1249		if ( child.title )	a.attr( 'title', child.title );
1250		if ( child.alt )	a.attr( 'alt', child.alt );
1251		if ( child.alt_img )img.attr( 'alt', child.alt_img );
1252		else if ( child.title )	img.attr( 'alt', child.title );
1253		if ( child.highslide ) {
1254			a.append( '<div class="highslide-caption">' + child.highslide + '</div>' );
1255		}
1256	};
1257
1258	vjg2.childCurrent = function( instId ){
1259		if ( this.debug ) this.log( 'vjg2.childCurrent()', arguments );
1260		var inst = this.insts[instId];
1261
1262		return inst.currentIndex;
1263	};
1264
1265	vjg2.childRandom = function( instId, currentIndex ){
1266		if ( this.debug ) this.log( 'vjg2.childRandom()', arguments );
1267		var inst = this.insts[instId],
1268			index = currentIndex || inst.currentIndex;
1269
1270		index = Math.floor( Math.random() * inst.children.length - 1 ) + 1;
1271
1272		if ( index == inst.currentIndex || ( inst.children_copy && index in inst.children_copy && inst.children_copy[ index ].disabled ) ) {
1273			index = this.childRandom( instId, index );
1274		}
1275
1276		return index;
1277	};
1278
1279	vjg2.childNextUnloaded = function( instId ){
1280		if ( this.debug ) this.log( 'vjg2.childNextUnloaded()', arguments );
1281		var inst = this.insts[instId];
1282
1283		return inst.children.index( inst.children.find( 'img[rev]:first' ).parent() );
1284	};
1285
1286	vjg2.childNext = function( instId, start ){
1287		if ( this.debug ) this.log( 'vjg2.childNext()', arguments );
1288		var inst = this.insts[instId],
1289			index = typeof start == 'number' ? start : inst.currentIndex;
1290
1291		index++;
1292
1293		if ( index >= inst.children.length ) {
1294			index = index - inst.children.length;
1295		}
1296
1297		if ( inst.children_copy && index in inst.children_copy && inst.children_copy[ index ].disabled ) {
1298			index = this.childNext( instId, index );
1299		}
1300
1301		return index;
1302	};
1303
1304	vjg2.childPrev = function( instId, start ){
1305		if ( this.debug ) this.log( 'vjg2.childPrev()', arguments );
1306		var inst = this.insts[instId],
1307			index = start || inst.currentIndex;
1308
1309		index--;
1310
1311		if ( index < 0 ) {
1312			index = ( inst.children.length - 1 );
1313		}
1314
1315		if ( inst.children_copy && inst.children_copy[ index ].disabled ) {
1316			index = this.childPrev( instId, index );
1317		}
1318
1319		return index;
1320	};
1321
1322	vjg2.childrenInit = function( instId ){
1323		if ( this.debug ) this.log( 'vjg2.childrenInit()', arguments );
1324		var inst = this.insts[instId];
1325
1326		if ( typeof inst.children == 'object' ) {
1327			inst.children_copy = this.copy( inst.children );
1328			this.childrenAppend( instId );
1329		}
1330		else {
1331			inst.children = this.instChildren( instId );
1332			inst.children.each(function( i ){
1333				inst.children.eq( i ).attr( 'style', vjg2e[inst.effect[0]].defaultChildrenStyle( inst.instId, i ) );
1334			});
1335		}
1336
1337		this.instChildren( instId ).each(function( index ){
1338			jQuery( this ).attr( 'rel', index );
1339		});
1340
1341		// iOS versteht onclick="return false" nicht immer und oeffnet bei ca. jedem dritten click trotzdem den hinterlegten href
1342		if ( navigator.userAgent.match( /(iPhone|iPad)/ ) && inst.children_copy ) {
1343			inst.children.each(function(i){
1344				if ( i in inst.children_copy && 'onclick' in inst.children_copy[i] ) {
1345					var onclick = inst.children_copy[i].onclick;
1346
1347					if ( !onclick || onclick == 'return false' ) {
1348						inst.children.eq( i ).bind( 'click', function(){
1349							return false;
1350						});
1351					}
1352				}
1353			});
1354		}
1355	};
1356
1357	vjg2.childrenInited = function( instId ) {
1358		if ( this.debug ) this.log( 'vjg2.childrenInited()', arguments );
1359		var inst = this.insts[instId];
1360
1361		if ( inst.type != 'html' && instId + '_' + inst.currentIndex in vjg2.children_state && vjg2.children_state[ instId + '_' + inst.currentIndex ].complete ) {
1362			window.setTimeout(function(){
1363				vjg2.childrenInited( instId );
1364			}, 50 );
1365		}
1366		else {
1367			if ( inst.type == 'html' ) {
1368				this.instChildren( instId ).addClass( 'vjg2_item' );
1369			}
1370		}
1371	};
1372
1373	vjg2.childrenAppend = function( instId ){
1374		if ( this.debug ) this.log( 'vjg2.childrenAppend()', arguments );
1375		var string = '',
1376			inst = this.insts[instId];
1377
1378		var skip = this.instChildren( instId ).length;
1379
1380		for( var i = 0; i < inst.children.length; i++ ) {
1381			if ( i < skip ) {
1382				// wenn vor dem vjg2-aufruf schon ein element mit der position "i" im container existiert, dieses an die settings anpassen
1383				this.childUpdate( instId, i );
1384			}
1385			else {
1386				string += this.childCreate( instId, i );
1387			}
1388		}
1389
1390		inst.container.append( string );
1391		inst.children = this.instChildren( instId );
1392	};
1393
1394	vjg2.childrenPrepare = function( instId ){
1395		if ( this.debug ) this.log( 'vjg2.childrenPrepare()', arguments );
1396	};
1397
1398	vjg2.childrenLoad = function( instId, start, amount, fn ){
1399		if ( this.debug ) this.log( 'vjg2.childrenLoad()', arguments );
1400		if ( typeof start != 'number' ) return;
1401
1402		var inst = this.insts[instId],
1403			callback = function( instId, index, fn){
1404				var inst = vjg2.insts[instId];
1405
1406				if ( typeof fn == 'function' ) {
1407					fn.apply( vjg2, [ instId, index ] );
1408				}
1409
1410				vjg2e[inst.effect[0]].childLoaded( instId, index );
1411			};
1412
1413		switch( inst.type ) {
1414			case 'html':
1415				callback( instId, start, fn );
1416				break;
1417
1418			default:
1419				inst.children
1420					.slice( start, start + ( amount ? amount + 1 : 1 ) )
1421					.find( 'img' )
1422					.each(function(pos){
1423						var index = start + pos,
1424							image = jQuery( this ),
1425							rev = image.attr( 'rev' ),
1426							loaded = false;
1427
1428						if ( instId + '_' + index in vjg2.children_state ) {
1429							loaded = vjg2.children_state[ instId + '_' + index ].complete;
1430						}
1431						else if ( !image.attr( 'rev' ) ) {
1432							loaded = this.complete;
1433						}
1434
1435						if ( loaded ) {
1436							callback( instId, index, fn );
1437						}
1438						else {
1439							if ( !( instId + '_' + index in vjg2.children_state ) ) {
1440								vjg2.children_state[ instId + '_' + index ] = {
1441									complete: false
1442								};
1443
1444								var image_copy = new Image();
1445								image_copy.onload = function(){
1446									if ( image.attr( 'src' ) != rev ) {
1447										image.attr( 'src', rev );
1448										image.removeAttr( 'rev' );
1449									}
1450
1451									callback( instId, index, fn );
1452									vjg2.children_state[ instId + '_' + index ].complete = true;
1453								};
1454								image_copy.src = image.attr( 'rev' ) || image.attr( 'src' );
1455							}
1456						}
1457					});
1458				break;
1459		}
1460	};
1461
1462	vjg2.childLoaded = function( instId, index ){
1463		if ( this.debug ) this.log( 'vjg2.childLoaded()', arguments );
1464		var inst = this.insts[instId],
1465			image = inst.children.eq( index ).find( 'img' );
1466
1467		return inst.type == 'html' || ( instId + '_' + index in vjg2.children_state && vjg2.children_state[ instId + '_' + index ].complete );
1468	};
1469
1470	vjg2.containerResize = function( instId ){
1471		if ( this.debug ) this.log( 'vjg2.containerResize()', arguments );
1472		var inst = this.insts[instId],
1473			dimensions = inst.dimensions_last,
1474			container =  inst.container,
1475			parent = container.parent(),
1476			dimsWindow = dimensions.window,
1477			dimsContainer = dimensions.container,
1478			offset = inst.dimensions.container.offset;
1479
1480		if ( inst.resizeable || inst.dimensions.container.min && inst.dimensions.container.max ) {
1481			container
1482				.height( dimsContainer.height - offset.top - offset.bottom )
1483				.width( dimsContainer.width - offset.left - offset.right );
1484		}
1485
1486		if ( inst.mode == 'background' ) {
1487			var containerHeight = dimsWindow.height,
1488				containerWidth = dimsWindow.width;
1489
1490			container
1491				.parent()
1492				.height( containerHeight - offset.top - offset.bottom )
1493				.width( containerWidth - offset.left - offset.right );
1494		}
1495	};
1496
1497	vjg2.childResize = function( instId, index ){
1498		if ( this.debug ) this.log( 'vjg2.childResize()', arguments );
1499
1500		var inst = this.insts[instId];
1501		if ( typeof index == 'undefined' ) index = inst.currentIndex;
1502
1503		var dimensions = inst.dimensions_last,
1504			dimsContainerInner = dimensions.containerInner,
1505			dimsChildren = dimensions.children,
1506			padding = inst.dimensions.container.padding,
1507			offset = inst.dimensions.container.offset;
1508
1509		inst.children
1510			.eq( index )
1511			.css( 'top', padding.top + 'px' )
1512			.css( 'left', padding.left + 'px' )
1513			.height( dimsContainerInner.height )
1514			.width( dimsContainerInner.width );
1515
1516		if ( inst.type != 'html' ) {
1517			inst.children
1518				.children( ':not([class*="vpoi"])' )
1519				.find( 'img' )
1520				.css( 'top', '-' + dimsChildren.top + 'px' )
1521				.css( 'left', '-' + dimsChildren.left + 'px' )
1522				.height( dimsChildren.height )
1523				.width( dimsChildren.width );
1524		}
1525	};
1526
1527	vjg2.poisRegister = function( instId ) {
1528		if ( this.debug ) this.log( 'vjg2.poisRegister()', arguments );
1529		var inst = this.insts[instId];
1530
1531		if ('children_copy' in inst ) {
1532			var pois_found = false;
1533			for( var i in inst.children_copy ) {
1534				var child = this.copy( inst.children_copy[i] );
1535
1536				if ( !( 'poi' in child ) ) continue;
1537
1538				for( var j in child.poi ) {
1539					child.poi[j].vjg2 = instId;
1540					child.poi[j].instId = vpoi.register( inst.children.eq( i ), this.copy( child.poi[j] ) );
1541				}
1542
1543				pois_found = true;
1544			}
1545
1546			if ( pois_found ) {
1547				this.poisMove( instId );
1548			}
1549		}
1550	};
1551
1552	vjg2.poisMove = function( instId, index ) {
1553		if ( this.debug ) this.log( 'vjg2.poisMove()', arguments );
1554
1555		var inst = this.insts[instId];
1556		if ( typeof index == 'undefined' ) index = inst.currentIndex;
1557
1558		if ( !inst.dimensions_last ) return;
1559
1560		if ( !( 'children_copy' in inst ) ) return;
1561
1562		var child = inst.children_copy[ index ];
1563		if ( !child || !( 'poi' in child ) ) return;
1564
1565		var dimensions = inst.dimensions_last,
1566			dimsWindow = dimensions.window,
1567			dimsContainerInner = dimensions.containerInner,
1568			dimsChildren = dimensions.children,
1569			dimsChildCurrent = dimensions.childCurrent;
1570
1571		for( var i in child.poi ) {
1572			var poi = this.poiCalculate( instId, child.poi[i] );
1573
1574			if ( !( 'instId' in poi ) ) continue;
1575
1576			var poi_element = jQuery( jQuery( vpoi.insts[ poi.instId ].link || vpoi.insts[ poi.instId ].content ).get( 0 ) ),
1577				poiOffset = poi.dimensions.offset,
1578				top = 0,
1579				left = 0;
1580
1581			if ( !poi_element ) continue;// wie kann das auftreten?
1582
1583			if ( poi.mode == 'flexible' ) {
1584				if ( poi_element.is( 'img' ) ) {
1585					var img = poi_element.get( 0 ),
1586						height = dimsChildren.height / dimsChildCurrent.height * img.naturalHeight,
1587						width = dimsChildren.width / dimsChildCurrent.width * img.naturalWidth;
1588				}
1589				else {
1590					var height = poi_element.outerHeight(),
1591						width = poi_element.outerWidth();
1592				}
1593
1594				top = parseInt( poi.top - dimsChildren.top - ( height / 2 ), 10 );
1595				left = parseInt( poi.left - dimsChildren.left - ( width / 2 ), 10 );
1596
1597				if ( top < poiOffset.top ) {
1598					top = poiOffset.top;
1599				}
1600				else if ( top + height > dimsContainerInner.height - poiOffset.bottom ) {
1601					top = dimsContainerInner.height - height - poiOffset.top;
1602				}
1603
1604				if ( left < poi.dimensions.offset.left ) {
1605					left = poi.dimensions.offset.left;
1606				}
1607				else if ( left + width > dimsContainerInner.width - poiOffset.right ) {
1608					left = dimsContainerInner.width - width - poiOffset.left;
1609				}
1610
1611				poi_element
1612					.css( 'height', height )
1613					.css( 'width', width );
1614			}
1615			else {
1616				var height = poi_element.outerHeight(),
1617					width = poi_element.outerWidth();
1618
1619				top = parseInt( poi.top - dimsChildren.top - ( height / 2 ), 10 );
1620				left = parseInt( poi.left - dimsChildren.left - ( width / 2 ), 10 );
1621			}
1622
1623			if ( left < 0 || ( left + width ) > dimsContainerInner.width ) {
1624				poi_element.hide();
1625			}
1626			else if ( top < 0 || ( top + height ) > dimsContainerInner.height ) {
1627				poi_element.hide();
1628			}
1629			else {
1630				poi_element
1631					.css( 'top', top )
1632					.css( 'left', left );
1633
1634				vpoi.restore( poi.instId );
1635			}
1636		}
1637	};
1638
1639	vjg2.poiCalculate = function( instId, poi ) {
1640		if ( this.debug ) this.log( 'vjg2.poiCalculate()', arguments );
1641		if ( !( 'original' in poi ) ) {
1642			poi.original = {
1643				left: poi.left,
1644				top: poi.top
1645			};
1646		}
1647
1648		var inst = this.insts[instId],
1649			dimsChildren = inst.dimensions_last.children;
1650
1651		poi.left = parseInt( ( poi.original.left / poi.media.width ) * dimsChildren.width, 10 );
1652		poi.top = parseInt( ( poi.original.top / poi.media.height ) * dimsChildren.height, 10 );
1653
1654		if ( !( 'mode' in poi ) ) {
1655			poi.mode = 'normal';
1656		}
1657
1658		if ( !( 'dimensions' in poi ) ) {
1659			poi.dimensions = {};
1660		}
1661
1662		poi.dimensions = jQuery.extend( { offset: { top: 0, right: 0, bottom: 0, left: 0 } }, poi.dimensions )
1663
1664		return poi;
1665	};
1666
1667	vjg2.deviceDimensions = function( ) {
1668		if ( this.debug ) this.log( 'vjg2.deviceDimensions()', arguments );
1669
1670		var width, height;
1671
1672		if ( 'vmf' in window && navigator.userAgent.match( /(iPhone)/ ) ) {
1673			width = 320;
1674			height = 420;
1675		}
1676		else {
1677			try {
1678				width = jQuery( window ).width();
1679				height = jQuery( window ).height();
1680			} catch(e) {
1681				width = window.innerWidth;
1682				height = window.innerHeight;
1683			}
1684		}
1685		var ios_fix = navigator.userAgent.match( /OS ([0-9]+)/ );
1686		if ( ios_fix && ios_fix[1] > 7 ) {
1687			height = height + 65;
1688		}
1689		return {
1690			width: width,
1691			height: height,
1692			ratio: width / height
1693		};
1694	};
1695
1696	// please, be careful! ;-)
1697	vjg2.instDimensions = function( instId ) {
1698		if ( this.debug ) this.log( 'vjg2.instDimensions()', arguments );
1699		var inst = this.insts[instId],
1700			dims = inst.dimensions,
1701			dimsContainer = dims.container,
1702			dimsWindowPadding = dims.window.padding,
1703			padding = dimsContainer.padding,
1704			offset = dimsContainer.offset,
1705			dimsWindow = {
1706				width: this.dimsWindow.width - dimsWindowPadding.left - dimsWindowPadding.right,
1707				height: this.dimsWindow.height - dimsWindowPadding.top - dimsWindowPadding.bottom
1708			},
1709			child = jQuery( inst.children[ inst.currentIndex ] );
1710
1711		if ( 'children_copy' in inst && inst.type != 'html' && inst.currentIndex in inst.children_copy ) {
1712			var childSettings = inst.children_copy[ inst.currentIndex ];
1713
1714			if ( !( 'node' in childSettings ) ) {
1715				childSettings.node = jQuery( document.createElement( 'img' ) ).attr( 'src', childSettings.src ).css( 'display', 'none' ).appendTo( 'body' );
1716			}
1717
1718			child = jQuery( childSettings.node );
1719		}
1720
1721		var propName = [ 'width', 'height', 'top', 'left', 'bottom', 'right' ],
1722			propOperator = [ '/', '*' ],
1723			propFunc = {
1724				'/': function( a, b ) { return a / b; },
1725				'*': function( a, b ) { return a * b; }
1726			},
1727			childCurrent = {
1728				width:  child.width(),
1729				height: child.height()
1730			};
1731
1732		if ( !parseInt( childCurrent.width, 10 ) || !parseInt( childCurrent.height ) ) {
1733			return false;
1734		}
1735
1736		var children = this.copy( childCurrent ),
1737			container = this.copy( childCurrent );
1738
1739		if ( dimsContainer.mode == 'flex' ) {
1740			container.height = inst.container.parent().height();
1741			container.width = inst.container.parent().width();
1742		}
1743
1744		var containerInner = {
1745				width: container.width - padding.left - padding.right - offset.left - offset.right,
1746				height: container.height - padding.top - padding.bottom - offset.top - offset.bottom
1747			},
1748			viewport = {
1749				top: offset.top + padding.top,
1750				left: offset.left + padding.left
1751			};
1752
1753		if ( !children.width || !children.height ) {
1754			if ( dimsContainer.mode == 'flex' ) {
1755				children.height = inst.container.parent().height();
1756				children.width = inst.container.parent().width();
1757			}
1758			else {
1759				children.width = inst.container.width();
1760				children.height = inst.container.height();
1761			}
1762		}
1763
1764		childCurrent.ratio = ( childCurrent.width / childCurrent.height );
1765
1766		if( childCurrent.ratio < 1 ){
1767			propName = [ 'height', 'width', 'left', 'top', 'right', 'bottom' ];
1768			propOperator = [ '*', '/' ];
1769		}
1770
1771		if ( inst.resizeable ) {
1772			if ( 'dimensionUse' in inst ) {
1773				for( var i = 0; i < 2; i++ ) {
1774					if ( propName[i] in inst.dimensionUse ) {
1775						children[ propName[i] ] = inst.dimensionUse[ propName[i] ];
1776					}
1777				}
1778			}
1779		}
1780
1781		if ( dimsContainer.mode == 'flex' ) {
1782			container.height = childCurrent.height = container.width / dimsContainer.ratio;
1783			container.width = childCurrent.width = childCurrent.height * childCurrent.ratio;
1784
1785			var parent_height = parseInt( inst.container.css( 'min-height' ), 10 ),
1786				parent_width = parseInt( inst.container.css( 'min-width' ), 10 );
1787
1788			if ( parent_height && container.height < parent_height ) {
1789				container.height = parent_height;
1790				container.minHeight = true;
1791			}
1792
1793			if ( parent_width && container.width < parent_width ) {
1794				container.width = parent_width;
1795				container.minWidth = true;
1796			}
1797		}
1798		else if ( dimsContainer.ratio == false ) {
1799			container[ propName[0] ] = dimsWindow[ propName[0] ];
1800			container[ propName[1] ] = dimsWindow[ propName[1] ];
1801		}
1802
1803		if ( dimsContainer.min ) {
1804			if ( dimsWindow.height < dimsContainer.min.height ) {
1805				container.height = dimsContainer.min.height;
1806				container.minHeight = true;
1807			}
1808			if ( dimsWindow.width < dimsContainer.min.width ) {
1809				container.width = dimsContainer.min.width;
1810				container.minWidth = true;
1811			}
1812		}
1813
1814		if ( dimsContainer.max ) {
1815			if ( dimsWindow.height > dimsContainer.max.height ) {
1816				container.height = dimsContainer.max.height;
1817				container.maxHeight = true;
1818			}
1819			if ( dimsWindow.width > dimsContainer.max.width ) {
1820				container.width = dimsContainer.max.width;
1821				container.maxWidth = true;
1822			}
1823		}
1824
1825		if ( dimsContainer.ratio ) {
1826			if ( 'width' in dimsContainer ) {
1827				container.height = container.width / dimsContainer.ratio;
1828			}
1829			else if ( 'height' in dimsContainer ) {
1830				container.width = container.height * dimsContainer.ratio;
1831			}
1832		}
1833
1834		containerInner[ propName[1] ] = container[ propName[1] ] - padding[ propName[2] ] - padding[ propName[4] ] - offset[ propName[2] ] - offset[ propName[4] ];
1835		containerInner[ propName[0] ] = container[ propName[0] ] - padding[ propName[3] ] - padding[ propName[5] ] - offset[ propName[3] ] - offset[ propName[5] ];
1836
1837		/**
1838		 * TODO: das muesste man irgendwie in den effect auslagern..
1839		 */
1840		if ( inst.effect[0] == 'scroll' ) {
1841			var containerParent = inst.container.parent();
1842
1843			viewport[ propName[4] ] = viewport[ propName[2] ] + containerParent[ propName[1] ]();
1844			viewport[ propName[5] ] = viewport[ propName[3] ] + containerParent[ propName[0] ]();
1845		}
1846		else {
1847			viewport[ propName[4] ] = viewport[ propName[2] ] + containerInner[ propName[1] ];
1848			viewport[ propName[5] ] = viewport[ propName[3] ] + containerInner[ propName[0] ];
1849		}
1850
1851		if ( inst.dimensionUse && inst.dimensionUse.crop ) {
1852			children[ propName[0] ] = inst.dimensionUse[ propName[0] ];
1853			children[ propName[1] ] = propFunc[ propOperator[0] ]( children[ propName[0] ], childCurrent.ratio );
1854		}
1855		else {
1856			children[ propName[0] ] = containerInner[ propName[0] ];
1857			children[ propName[1] ] = propFunc[ propOperator[0] ]( children[ propName[0] ], childCurrent.ratio );
1858		}
1859
1860		if ( children[ propName[1] ] < containerInner[ propName[1] ] ) {
1861			children[ propName[1] ] = containerInner[ propName[1] ];
1862			children[ propName[0] ] = propFunc[ propOperator[1] ]( children[ propName[1] ], childCurrent.ratio );
1863		}
1864
1865		children[ propName[2] ] = ( children[ propName[1] ] - containerInner[ propName[1] ] ) / 2;
1866		children[ propName[3] ] = ( children[ propName[0] ] - containerInner[ propName[0] ] ) / 2;
1867
1868		if ( this.debug && 'group' in console ) {
1869			console.group( 'dimensions' );
1870			console.log( 'window', dimsWindow );
1871			console.log( 'container', container );
1872			console.log( 'containerInner', containerInner );
1873			console.log( 'children', children );
1874			console.log( 'childCurrent', childCurrent );
1875			console.log( 'viewport', viewport );
1876			console.log( 'dimensionUse', inst.dimensionUse );
1877			console.groupEnd( 'dimensions' );
1878		}
1879
1880		return {
1881			window: dimsWindow,
1882			container: container,
1883			containerInner: containerInner,
1884			children: children,
1885			childCurrent: childCurrent,
1886			viewport: viewport
1887		};
1888	};
1889
1890	vjg2.markCurrent = function( instId, index ){
1891		if ( this.debug ) this.log( 'vjg2.markCurrent()', arguments );
1892		var inst = this.insts[instId];
1893
1894		if ( typeof index != 'number' ) {
1895			index = inst.currentIndex;
1896		}
1897
1898		this.instChildren( instId )
1899			.filter( '.current' )
1900			.removeClass( 'current' )
1901			.end()
1902			.filter( '[rel="' + index + '"]' )
1903			.addClass( 'current' );
1904
1905		if ( inst.navigation.children ) {
1906			inst.navigation.children
1907				.filter( '.current' )
1908				.removeClass( 'current' )
1909				.end()
1910				.filter( '[rel="' + index + '"]' )
1911				.addClass( 'current' );
1912		}
1913	};
1914
1915	vjg2.dom_ready = function(){
1916		if ( this.debug ) this.log( 'vjg2.dom_ready()', arguments );
1917		/**
1918		 * TODO: das mousemove event macht einen zuverlaessigeren eindruck, nur ist das ewig rechnerei.. */
1919		/*
1920		 jQuery( 'body' ).bind( 'mousemove', function( event ){
1921		 jQuery.each(vjg2.insts, function(i, inst ){
1922		 var viewport;
1923
1924		 if ( inst.mode == 'background' ) {
1925		 return true;
1926		 }
1927
1928		 if ( 'dimensions_last' in inst ) {
1929		 viewport = inst.dimensions_last.viewport;
1930		 }
1931		 else {
1932		 var containerOffset = inst.effect[0] == 'scroll' ? inst.container.parent().offset() : inst.container.offset();
1933		 viewport = {
1934		 left: containerOffset.left,
1935		 top: containerOffset.top,
1936		 right: containerOffset.left + inst.container.width(),
1937		 bottom: containerOffset.top + inst.container.height()
1938		 };
1939		 }
1940
1941		 var instId = inst.instId,
1942		 isHover = vjg2.interaction( instId, 'hover' ),
1943		 mouseenter = ( event.clientX >= viewport.left && event.clientX <= viewport.right ) && ( event.clientY >= viewport.top && event.clientY <= viewport.bottom );
1944
1945		 if ( !isHover && mouseenter ) {
1946		 inst.container.addClass( 'hover' );
1947		 vjg2.interaction( instId, 'hover', true );
1948		 vjg2.pause( instId );
1949		 vjg2.instCallback( instId, 'child_mouseenter', inst.currentIndex );
1950		 vjg2.instCallback( instId, 'mouseenter' );
1951		 }
1952
1953		 if ( isHover && !mouseenter ) {
1954		 inst.container.removeClass( 'hover' );
1955		 vjg2.interaction( instId, 'hover', false );
1956		 vjg2.resumePaused( instId );
1957		 vjg2.instCallback( instId, 'child_mouseleave', inst.currentIndex );
1958		 vjg2.instCallback( instId, 'mouseleave' );
1959		 }
1960		 });
1961		 });
1962		 */
1963
1964		this.ready = true;
1965		this.dimsWindow = this.deviceDimensions();
1966
1967		for( var i = 0, l = this.insts.length; i < l; i++ ) {
1968			var inst = this.insts[i];
1969
1970			if ( inst.type == 'html' || ( inst.ready && this.childLoaded( inst.instId, inst.currentIndex ) ) ) {
1971				this.instReady( inst.instId );
1972			}
1973		}
1974
1975		setTimeout(function(){
1976			jQuery( window ).trigger( 'resize' );
1977		}, 300 );
1978	};
1979
1980	var vjg2e = {};
1981
1982	vjg2e.effect = function() {
1983		return {
1984			preinit: function() {},
1985			init: function(){},
1986			play: function(){},
1987			stop: function(){},
1988			jump: function(){},
1989			effect: function(){},
1990			childLoaded: function(){},
1991			defaultChildrenStyle: function(){},
1992			linkInit: function(){}
1993		};
1994	};
1995
1996	vjg2e.none = new vjg2e.effect;
1997	vjg2e.none.jump = function( instId, index, to, fn ){
1998		if ( vjg2.debug ) vjg2.log( 'vjg2e.none.jump()', arguments );
1999
2000		var inst = vjg2.insts[instId],
2001			from = vjg2.childCurrent( instId );
2002
2003		to = !isNaN( index ) ? index : vjg2.childNext( instId );
2004
2005		if ( from == to ) return;
2006
2007		inst.children
2008			.css( 'opacity', 0 )
2009			.css( 'display', 'none' )
2010			.eq( to )
2011			.css( 'position', 'absolute' )
2012			.css( 'display', 'block' )
2013			.css( 'opacity', 1 );
2014
2015		if ( typeof fn == 'function' ) {
2016			fn( instId );
2017		}
2018
2019		if ( inst.type == false ) {
2020			vjg2.childrenLoad( instId, to, inst.children_preload );
2021		}
2022	};
2023
2024	vjg2e.fade = new vjg2e.effect;
2025	vjg2e.fade.init = function( instId ){
2026		if ( vjg2.debug ) vjg2.log( 'vjg2e.fade.init()', arguments );
2027		var inst = vjg2.insts[instId];
2028
2029		inst.container
2030			.css( 'position', 'relative' )
2031			.css( 'overflow', 'hidden' );
2032
2033		if ( 'ontouchstart' in document.documentElement ) {
2034			var touch_position = {},
2035				touch_position_last = {},
2036				touch_direction = '';
2037
2038			inst.container
2039				.bind( 'touchstart', function( event ){
2040					touch_position = {
2041						pageX: event.originalEvent.pageX,
2042						pageY: event.originalEvent.pageY
2043					};
2044
2045					var instChildren = vjg2.instChildren( inst.instId ),
2046						dimsContainerInner = inst.dimensions_last.containerInner;
2047
2048					if ( touch_direction ) {
2049						var childCurrent = instChildren.eq( inst.currentIndex ),
2050							childLeft = instChildren.eq( vjg2.childPrev( inst.instId ) ),
2051							childRight = instChildren.eq( vjg2.childNext( inst.instId ) );
2052
2053						instChildren.stop();
2054
2055						if ( touch_direction == 'next' ) {
2056							childRight.css( 'left', '0px' );
2057							childLeft.hide();
2058							childCurrent.css( 'left',  '-' + dimsContainerInner.width + 'px' );
2059						}
2060						else if ( touch_direction == 'prev' ) {
2061							childRight.hide();
2062							childLeft.css( 'left', '0px' );
2063							childCurrent.css( 'left',  '+' + dimsContainerInner.width + 'px' );
2064						}
2065					}
2066
2067					childRight = vjg2.childNext( inst.instId );
2068					childLeft = vjg2.childPrev( inst.instId );
2069
2070					if ( inst.type == false && !vjg2.childLoaded( instId, childRight ) && inst.inst_parent === false ) {
2071						vjg2.childrenLoad( inst.instId, childRight, 0 );
2072					}
2073
2074					if ( inst.type == false && !vjg2.childLoaded( instId, childLeft ) && inst.inst_parent === false ) {
2075						vjg2.childrenLoad( inst.instId, childLeft, 0 );
2076					}
2077
2078					if ( inst.resizeable ) {
2079						vjg2.childResize( inst.instId, childRight );
2080						vjg2.childResize( inst.instId, childLeft );
2081					}
2082				})
2083				.bind( 'touchend', function( event ){
2084					if ( 'pageX' in touch_position_last ) {
2085						var childFrom = vjg2.instChildren( inst.instId ).eq( inst.currentIndex ),
2086							childToIndex = touch_direction == 'next' ? vjg2.childNext( inst.instId ) : vjg2.childPrev( inst.instId ),
2087							childTo = vjg2.instChildren( inst.instId ).eq( childToIndex ),
2088							dimsContainerInner = inst.dimensions_last.containerInner;
2089
2090						childTo.animate(
2091							{
2092								left: 0
2093							},
2094							{
2095								duration: 350,
2096								queue: true,
2097								step: function (x, t, b, c, d) {
2098									if ( touch_direction == 'next' ) {
2099										childFrom.css( 'left', x - dimsContainerInner.width + 'px' );
2100									}
2101									else {
2102										childFrom.css( 'left', x + dimsContainerInner.width + 'px' );
2103									}
2104
2105									return x;
2106								},
2107								complete: function(){
2108									childTo.siblings( '.vjg2_item' ).css( 'display', 'none' );
2109									vjg2.jump( inst.instId, childToIndex, touch_direction, true );
2110									vjg2.childrenLoad( inst.instId, childToIndex, 0 );
2111									touch_direction = '';
2112								}
2113							}
2114						);
2115
2116						touch_position = {};
2117						touch_position_last = {};
2118						event.preventDefault();
2119					}
2120				})
2121				.bind( 'touchmove', function( event ){
2122					var touch_position_current = {
2123						pageX: event.originalEvent.pageX,
2124						pageY: event.originalEvent.pageY
2125					};
2126
2127					if ( Math.abs( touch_position_current.pageY - touch_position.pageY ) < Math.abs( touch_position_current.pageX - touch_position.pageX ) ) {
2128						touch_position_last = touch_position_current;
2129						touch_direction = touch_position.pageX > touch_position_last.pageX ? 'next' : 'prev'
2130
2131						var touchOffset = Math.abs( touch_position.pageX - touch_position_last.pageX ),
2132							childCurrent = vjg2.instChildren( inst.instId ).eq( inst.currentIndex ),
2133							childLeft = vjg2.instChildren( inst.instId ).eq( vjg2.childPrev( inst.instId ) ),
2134							childRight = vjg2.instChildren( inst.instId ).eq( vjg2.childNext( inst.instId ) ),
2135							childCurrentLeft = parseInt( childCurrent.css( 'left' ), 10 ),
2136							dimsContainerInner = 'containerInner' in inst.dimensions_last ? inst.dimensions_last.containerInner : {
2137								width: inst.container.width()
2138							};
2139
2140						childCurrentLeft = touch_direction == 'next' ? childCurrentLeft - touchOffset : childCurrentLeft + touchOffset;
2141						childCurrent.css( 'left', childCurrentLeft + 'px' );
2142
2143						childLeft
2144							.css( 'position', 'absolute' )
2145							.css( 'opacity', 1 )
2146							.css( 'display', 'block' )
2147							.css( 'left', childCurrentLeft - dimsContainerInner.width + 'px' );
2148
2149						childRight
2150							.css( 'position', 'absolute' )
2151							.css( 'opacity', 1 )
2152							.css( 'display', 'block' )
2153							.css( 'left', childCurrentLeft + dimsContainerInner.width + 'px' );
2154
2155						event.preventDefault();
2156					}
2157
2158					touch_position = {
2159						pageX: touch_position_last.pageX,
2160						pageY: touch_position_last.pageY
2161					};
2162				});
2163		}
2164
2165		if ( vjg2.css3 !== false ) {
2166			inst.children.eq( inst.currentIndex ).addClass( 'rotatein' );
2167
2168			jQuery( 'head' ).append( '<style type="text/css">' +
2169				'.vjg2_inst' + instId + '.vjg2e_fade .vjg2_item.fadein,' +
2170				'.vjg2_inst' + instId + '.vjg2e_fade .vjg2_item.fadeout {' +
2171				vjg2.transitionDuration( instId ) +
2172				'} ' +
2173				'</style>')
2174
2175		}
2176
2177		vjg2.childrenLoad( instId, inst.currentIndex, 0, function(){
2178			vjg2.childrenLoad( instId, vjg2.childNext( instId ) );
2179		});
2180	};
2181
2182	vjg2e.fade.play = function( instId, from, to ){
2183		if ( vjg2.debug ) vjg2.log( 'vjg2e.fade.play()', arguments );
2184		var inst = vjg2.insts[instId],
2185			callback = function( instId ){
2186				vjg2.effectDone( instId );
2187			};
2188
2189		if ( typeof to != 'number' ) {
2190			to = vjg2.childToPlay( instId );
2191		}
2192
2193		vjg2e[inst.effect[0]][ vjg2.css3 !== false ? 'css3effect' : 'effect' ]( instId, from, to, callback );
2194	};
2195
2196	vjg2e.fade.jump = function( instId, index, to, fn ){
2197		if ( vjg2.debug ) vjg2.log( 'vjg2e.fade.jump()', arguments );
2198
2199		var inst = vjg2.insts[instId],
2200			from = vjg2.childCurrent( instId );
2201
2202		to = !isNaN( index ) ? index : vjg2.childNext( instId );
2203
2204		if ( from == to ) return;
2205
2206		inst.children
2207			.stop()
2208			.eq( from )
2209			.show()
2210			.fadeOut(function(){
2211				jQuery( this ).css( 'display', 'none' )
2212			})
2213			.end()
2214			.eq( to )
2215			.css( 'position', 'absolute' )
2216			.css( 'display', 'block' )
2217			.css( 'opacity', 0 )
2218			.animate( { opacity: 1 }, inst.speed, "linear" );
2219
2220		if ( typeof fn == 'function' ) {
2221			fn( instId );
2222		}
2223
2224		if ( inst.type == false ) {
2225			vjg2.childrenLoad( instId, to, inst.children_preload );
2226		}
2227	};
2228
2229	vjg2e.fade.effect = function( instId, from, to, fn ){
2230		if ( vjg2.debug ) vjg2.log( 'vjg2e.fade.effect()', arguments );
2231		var inst = vjg2.insts[instId];
2232
2233		inst.currentIndex = to;
2234		inst.children.stop( true, true );
2235
2236		// the last image fades out (fix for ie8)
2237		if ( from == inst.children.length - 1 || to < from ) {
2238			inst.children
2239				.eq( to )
2240				.css( 'position', 'absolute' )
2241				.css( 'display', 'block' )
2242				.css( 'opacity', 1 )
2243				.css( 'left', 0 )
2244				.end()
2245				.eq( from )
2246				.css( 'position', 'relative' )
2247				.animate( { opacity: 0 }, inst.speed, "linear", function(){
2248					inst.children
2249						.eq( from )
2250						.css( 'display', 'none' );
2251
2252					if ( typeof fn == 'function' ) {
2253						fn( instId );
2254					}
2255				});
2256		}
2257		else {
2258			inst.children
2259				.eq( from )
2260				.css( 'position', 'absolute' )
2261				.css( 'display', 'block' )
2262				.end()
2263				.eq( to )
2264				.css( 'position', 'relative' )
2265				.css( 'display', 'block' )
2266				.css( 'opacity', 0 )
2267				.css( 'left', 0 )
2268				.animate( { opacity: 1 }, inst.speed, "linear", function(){
2269					inst.children
2270						.eq( from )
2271						.css( 'opacity', 0 )
2272						.css( 'display', 'none' );
2273
2274					if ( typeof fn == 'function' ) {
2275						fn( inst.instId );
2276					}
2277				});
2278		}
2279	};
2280
2281	vjg2e.fade.css3effect = function( instId, from, to, fn ){
2282		if ( vjg2.debug ) vjg2.log( 'vjg2e.fade.css3effect()', arguments );
2283		var inst = vjg2.insts[instId];
2284
2285		inst.currentIndex = to;
2286		inst.children
2287			.eq( to )
2288			.removeClass( 'fadeout' )
2289			.addClass( 'fadein' )
2290			.end()
2291			.eq( from )
2292			.removeClass( 'fadein' )
2293			.addClass( 'fadeout' )
2294			.one( vjg2.css3.events.transitionEnd, function(){
2295				jQuery( this ).removeClass( 'fadeout' );
2296				fn( instId );
2297			});
2298	};
2299
2300	vjg2e.fade.defaultChildrenStyle = function( instId, index ){
2301		//if ( vjg2.debug ) vjg2.log( 'vjg2e.fade.defaultChildrenStyle()', arguments );
2302		var inst = vjg2.insts[instId],
2303			style = 'position: absolute; left: 0; top: 0; height: ' + inst.container.css( 'height' ) +'; width: ' + inst.container.css( 'width' ) + ';';
2304
2305		if ( index == inst.currentIndex ) {
2306			if ( vjg2.css3 === false ) style += 'display: block;';
2307			style += 'opacity: 1;';
2308		}
2309		else {
2310			if ( vjg2.css3 === false ) style += 'display: none;';
2311			style += 'opacity: 0;';
2312		}
2313
2314		return style;
2315	};
2316
2317	vjg2e.fade.linkInit = function( instId, type ) {
2318		if ( vjg2.debug ) vjg2.log( 'vjg2e.fade.linkInit()', arguments );
2319		var inst = vjg2.insts[instId];
2320
2321		inst.links[type].bind( 'click', inst, function( event ){
2322			var inst = event.data;
2323
2324			switch( type ) {
2325				case 'next':
2326					vjg2.interaction( inst.instId, 'click', true );
2327					vjg2.jump( inst.instId, vjg2.childNext( inst.instId ), type );
2328					break;
2329
2330				case 'prev':
2331					vjg2.interaction( inst.instId, 'click', true );
2332					vjg2.jump( inst.instId, vjg2.childPrev( inst.instId ), type );
2333					break;
2334
2335				case 'play':
2336					vjg2.interaction( inst.instId, 'click', true );
2337					vjg2.resumeStopped( inst.instId );
2338					break;
2339
2340				case 'stop':
2341					vjg2.interaction( inst.instId, 'click', true );
2342					vjg2.stop( inst.instId );
2343					break;
2344
2345				case 'zoom':
2346					vjg2.instChildren( inst.instId ).eq( inst.currentIndex ).trigger( 'click' );
2347					break;
2348			}
2349
2350			vjg2.instCallback( inst.instId, 'links.' + type );
2351
2352			return false;
2353		});
2354	};
2355
2356	vjg2e.rotate = new vjg2e.effect;
2357	vjg2e.rotate.init = function( instId ){
2358		if ( vjg2.debug ) vjg2.log( 'vjg2e.rotate.init()', arguments );
2359		var inst = vjg2.insts[instId],
2360			dimsContainer = inst.dimensions_last.container;
2361
2362		inst.container
2363			.css( 'position', 'relative' )
2364			.css( 'overflow', 'hidden' );
2365
2366		if ( vjg2.css3 !== false ) {
2367			inst.children.eq( inst.currentIndex ).addClass( 'rotatein' );
2368
2369			jQuery( 'head' ).append( '<style type="text/css">' +
2370				// form left to right
2371				'.vjg2_inst' + instId + '.vjg2e_rotate .vjg2_item {' +
2372				'left: ' + dimsContainer.width + 'px;' +
2373				vjg2.transitionDuration( instId, 0 ) + ';' +
2374				'}' +
2375				'.vjg2_inst' + instId + '.vjg2e_rotate .vjg2_item.rotatein {' +
2376				'left: 0;' +
2377				vjg2.transitionDuration( instId ) + ';' +
2378				'}' +
2379				'.vjg2_inst' + instId + '.vjg2e_rotate .vjg2_item.rotateout {' +
2380				'left: -' + dimsContainer.width + 'px;' +
2381				vjg2.transitionDuration( instId ) + ';' +
2382				'}' +
2383				// form right to left
2384				'.vjg2_inst' + instId + '.vjg2e_rotate.vjg2_back .vjg2_item {' +
2385				'left: ' + dimsContainer.width + 'px;' +
2386				vjg2.transitionDuration( instId, 0 ) + ';' +
2387				'}' +
2388				'.vjg2_inst' + instId + '.vjg2e_rotate.vjg2_back .vjg2_item.rotateout {' +
2389				'left: ' + dimsContainer.width + 'px;' +
2390				'}' +
2391				// stop running transition
2392				'.vjg2_inst' + instId + '.vjg2e_rotate .vjg2_item.rotatein.stop,' +
2393				'.vjg2_inst' + instId + '.vjg2e_rotate.vjg2_back .vjg2_item.rotatein.stop {' +
2394				'left: ' + dimsContainer.width + 'px;' +
2395				vjg2.transitionDuration( instId, 0 ) + ';' +
2396				'}' +
2397				'.vjg2_inst' + instId + '.vjg2e_rotate .vjg2_item.rotateout.stop,' +
2398				'.vjg2_inst' + instId + '.vjg2e_rotate.vjg2_back .vjg2_item.rotateout.stop {' +
2399				'left: -' + dimsContainer.width + 'px;' +
2400				vjg2.transitionDuration( instId, 0 ) + ';' +
2401				'} ' +
2402				'</style>')
2403		}
2404
2405		vjg2.childrenLoad( instId, inst.currentIndex, inst.children_preload );
2406	};
2407
2408	vjg2e.rotate.play = function( instId, from, to ){
2409		if ( vjg2.debug ) vjg2.log( 'vjg2e.rotate.play()', arguments );
2410		var inst = vjg2.insts[instId],
2411			callback = function( instId ){
2412				vjg2.effectDone( instId );
2413			};
2414
2415		if ( typeof to != 'number' ) {
2416			to = vjg2.childToPlay( instId );
2417		}
2418
2419		vjg2e[inst.effect[0]][ vjg2.css3 !== false ? 'css3effect' : 'effect' ]( instId, from, to, callback );
2420	};
2421
2422	vjg2e.rotate.jump = function( instId, index, to, fn ){
2423		if ( vjg2.debug ) vjg2.log( 'vjg2e.rotate.jump()', arguments );
2424
2425		var inst = vjg2.insts[instId],
2426			from = vjg2.childCurrent( instId );
2427
2428		to = !isNaN( index ) ? index : vjg2.childNext( instId );
2429
2430		if ( from == to ) return;
2431
2432		this[ vjg2.css3 !== false ? 'css3effect' : 'effect' ]( instId, from, to, fn );
2433
2434		if ( inst.type == false ) {
2435			vjg2.childrenLoad( instId, to, inst.children_preload );
2436		}
2437	};
2438
2439	vjg2e.rotate.effect = function( instId, from, to, fn ){
2440		if ( vjg2.debug ) vjg2.log( 'vjg2e.rotate.effect()', arguments );
2441		var inst = vjg2.insts[instId],
2442			dimsContainer = inst.dimensions_last.container;
2443
2444		inst.currentIndex = to;
2445		inst.children.stop( true, true );
2446
2447		var childTo = inst.children.eq( to ),
2448			childFrom = inst.children.eq( from ),
2449			childFromLeft = parseInt( childFrom.css( 'left' ), 10 ),
2450			animationFunc = 'rotate' in inst && 'animation' in inst.rotate ? inst.rotate.animation : function (x, t, b, c, d) {
2451				return c*(t/=d)*t*t*t*t + b;
2452			};
2453
2454		childFrom.animate(
2455			{
2456				left: inst.playDirection == 'prev' ? dimsContainer.width : '-' + dimsContainer.width
2457			},
2458			{
2459				duration: inst.speed,
2460				queue: false,
2461				step: animationFunc,
2462				complete: function(){
2463					jQuery( this ).css( 'display', 'none' );
2464				}
2465			}
2466		);
2467
2468		childTo
2469			.css( 'left', ( inst.playDirection == 'prev' ? '-' + dimsContainer.width : dimsContainer.width ) + 'px' )
2470			.css( 'display', 'block' )
2471			.css( 'opacity', 1 )
2472			.animate(
2473			{
2474				left: 0
2475			},
2476			{
2477				duration: inst.speed,
2478				queue: false,
2479				step: animationFunc
2480			}
2481		);
2482	};
2483
2484	vjg2e.rotate.css3effect = function( instId, from, to, fn ){
2485		if ( vjg2.debug ) vjg2.log( 'vjg2e.rotate.css3effect()', arguments );
2486		var inst = vjg2.insts[instId];
2487
2488		inst.currentIndex = to;
2489
2490		inst.children
2491			.unbind( vjg2.css3.events.transitionEnd )
2492			.addClass( 'stop' )
2493			.removeClass( 'rotatein rotateout stop' )
2494			.eq( to )
2495			.addClass( 'rotatein' )
2496			.end()
2497			.eq( from )
2498			.addClass( 'rotateout' )
2499			.one( vjg2.css3.events.transitionEnd, function(){
2500				if ( typeof fn == 'function' ) {
2501					fn( instId );
2502				}
2503			});
2504	};
2505
2506	vjg2e.rotate.defaultChildrenStyle = function( instId, index ){
2507		//if ( vjg2.debug ) vjg2.log( 'vjg2e.rotate.defaultChildrenStyle()', arguments );
2508		var inst = vjg2.insts[instId],
2509			style = 'height: ' + inst.container.css( 'height' ) +'; width: ' + inst.container.css( 'width' ) + '; position: absolute;';
2510
2511		if ( index != inst.currentIndex ) {
2512			style += 'left:-' + inst.container.width() + 'px; display: none;';
2513		}
2514
2515		return style;
2516	};
2517
2518	vjg2e.rotate.linkInit = function( instId, type ) {
2519		if ( vjg2.debug ) vjg2.log( 'vjg2e.rotate.linkInit()', arguments );
2520		var inst = vjg2.insts[instId];
2521
2522		inst.links[type].bind( 'click', inst, function( event ){
2523			var inst = event.data;
2524
2525			switch( type ) {
2526				case 'next':
2527					vjg2.interaction( inst.instId, 'click', true );
2528					vjg2.jump( inst.instId, vjg2.childNext( inst.instId ), type );
2529					break;
2530
2531				case 'prev':
2532					vjg2.interaction( inst.instId, 'click', true );
2533					vjg2.jump( inst.instId, vjg2.childPrev( inst.instId ), type );
2534					break;
2535
2536				case 'play':
2537					vjg2.interaction( inst.instId, 'click', true );
2538					vjg2.resumeStopped( inst.instId );
2539					break;
2540
2541				case 'stop':
2542					vjg2.interaction( inst.instId, 'click', true );
2543					vjg2.stop( inst.instId );
2544					break;
2545
2546				case 'zoom':
2547					inst.children.eq( inst.currentIndex ).trigger( 'click' );
2548					break;
2549			}
2550
2551			vjg2.instCallback( inst.instId, 'links.' + type );
2552
2553			return false;
2554		});
2555	};
2556
2557	vjg2e.fly = new vjg2e.effect;
2558	vjg2e.fly.classNames = [ 'visible', '	next visible', 'next2 visible' ];
2559	vjg2e.fly.preinit = function( instId ) {
2560		if ( vjg2.debug ) vjg2.log( 'vjg2e.fly.preinit()', arguments );
2561		var inst = vjg2.insts[instId];
2562
2563		inst.children_preload = 3;
2564		inst.containerHeight = parseInt( inst.container.css( 'height' ), 10 );
2565		inst.containerWidth = parseInt( inst.container.css( 'width' ), 10 );
2566
2567		if ( !inst.fly ) inst.fly = {};
2568		if ( !inst.fly.directions ) inst.fly.directions = {};
2569		if ( !inst.fly.directions.left && !inst.fly.directions.right ) {
2570			inst.fly.directions.right = inst.containerWidth * -1;
2571		}
2572		if ( !inst.fly.directions.top && !inst.fly.directions.bottom ) {
2573			inst.fly.directions.top = inst.containerHeight * -1;
2574		}
2575
2576		inst.fly.directions_back = {};
2577		for( var key in inst.fly.directions ) {
2578			inst.fly.directions_back[ key ] = 0;
2579		}
2580	};
2581
2582	vjg2e.fly.init = function( instId ){
2583		if ( vjg2.debug ) vjg2.log( 'vjg2e.fly.init()', arguments );
2584		var inst = vjg2.insts[instId];
2585
2586		inst.container.css( 'position', 'relative' );
2587		inst.container.parent().css( 'overflow', 'visible' );
2588
2589		inst.children.bind( 'click', function(){
2590			vjg2.jump( inst.instId, vjg2.childNext( inst.instId ) );
2591			return false;
2592		});
2593
2594		var classIndex = 0;
2595		vjg2.childrenLoad( instId, inst.currentIndex, inst.children_preload, function( instId, index ){
2596			vjg2.insts[ instId ].children.eq( index ).addClass( vjg2e.fly.classNames[ classIndex++ ] );
2597		});
2598	};
2599
2600	vjg2e.fly.play = function( instId, from, to ){
2601		if ( vjg2.debug ) vjg2.log( 'vjg2e.fly.play()', arguments );
2602		var inst = vjg2.insts[instId],
2603			callback = function( instId ){
2604				vjg2.effectDone( instId );
2605			};
2606
2607		if ( typeof to != 'number' ) {
2608			to = vjg2.childToPlay( instId );
2609		}
2610
2611		vjg2e[inst.effect[0]].effect( instId, from, to, callback );
2612	};
2613
2614	vjg2e.fly.jump = function( instId, index, to, fn ){
2615		if ( vjg2.debug ) vjg2.log( 'vjg2e.fly.jump()', arguments );
2616
2617		var inst = vjg2.insts[instId],
2618			from = vjg2.childCurrent( instId ),
2619			animateParams = vjg2.copy( inst.fly.directions );
2620
2621		to = !isNaN( index ) ? index : vjg2.childNext( instId );
2622
2623		if ( from == to ) return;
2624
2625		// das animierte bild darf nicht ueber die window-breite hinaus gehen, sonst gibt es scrollbars
2626		if ( animateParams.right ) {
2627			var containerOffset = inst.container.offset(),
2628				containerWidth = inst.container.width(),
2629				animationWidth = ( jQuery( window ).width() - ( containerOffset.left + containerWidth ) ) * -1;
2630
2631			if ( animationWidth > inst.fly.directions.right ) {
2632				animateParams.right = animationWidth;
2633			}
2634		}
2635
2636		inst.children
2637			.eq( from )
2638			.addClass( 'flying' )
2639			.animate(
2640			animateParams,
2641			{
2642				queue: false,
2643				duration: ( inst.speed / 10 ) * 4,
2644				step: function (x, t, b, c, d) {
2645					if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
2646					return c/2*((t-=2)*t*t*t*t + 2) + b;
2647				},
2648				complete: function(){
2649					var zIndex = inst.children.length - ( inst.children.length - inst.currentIndex );
2650
2651					inst.children.each(function(index){
2652						var link = jQuery( this );
2653
2654						if ( zIndex == 0 ) {
2655							zIndex = inst.children.length;
2656						}
2657
2658						link.css( 'z-index', zIndex-- );
2659					});
2660
2661					jQuery( this )
2662						.removeClass( 'flying' )
2663						.animate(
2664						inst.fly.directions_back,
2665						{
2666							queue: false,
2667							duration: ( inst.speed / 10 ) * 6,
2668							step: function (x, t, b, c, d) {
2669								if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
2670								return c/2*((t-=2)*t*t*t*t + 2) + b;
2671							},
2672							complete: function(){
2673								inst.children.removeClass( 'next next2 visible' );
2674
2675								var length = inst.children.length;
2676
2677								var childIndex = to;
2678								for( var i = 0; i < length; i++ ) {
2679									if ( !( i in vjg2e.fly.classNames ) ) break;
2680
2681									if ( childIndex == inst.children.length ) {
2682										childIndex = 0;
2683									}
2684
2685									inst.children.eq( childIndex++ ).addClass( vjg2e.fly.classNames[ i ] );
2686								}
2687
2688								if ( typeof fn == 'function' ) {
2689									fn( instId );
2690								}
2691							}
2692						}
2693					);
2694				}
2695			});
2696
2697		if ( inst.type == false ) {
2698			vjg2.childrenLoad( instId, to, inst.children_preload );
2699		}
2700	};
2701
2702	vjg2e.fly.defaultChildrenStyle = function( instId, index ){
2703		//if ( vjg2.debug ) vjg2.log( 'vjg2e.fly.defaultChildrenStyle()', arguments );
2704		var inst = vjg2.insts[instId],
2705			style = 'position: absolute;opacity: 1;';
2706
2707		style += 'z-index:' + ( inst.children.length - index ) + ';';
2708		style += ( inst.fly.directions.right ? 'right' : 'left' ) + ': 0;';
2709		style += ( inst.fly.directions.top ? 'top' : 'bottom' ) + ': 0;';
2710
2711		return style;
2712	};
2713
2714	vjg2e.fly.linkInit = function( instId, type ) {
2715		if ( vjg2.debug ) vjg2.log( 'vjg2e.fly.linkInit()', arguments );
2716		var inst = vjg2.insts[instId];
2717
2718		inst.links[type].bind( 'click', inst, function( event ){
2719			var inst = event.data;
2720
2721			switch( type ) {
2722				case 'next':
2723					vjg2.interaction( inst.instId, 'click', true );
2724					vjg2.jump( inst.instId, vjg2.childNext( inst.instId ), type );
2725					break;
2726
2727				case 'prev':
2728					vjg2.interaction( inst.instId, 'click', true );
2729					vjg2.jump( inst.instId, vjg2.childPrev( inst.instId ), type );
2730					break;
2731
2732				case 'play':
2733					vjg2.interaction( inst.instId, 'click', true );
2734					vjg2.resumeStopped( inst.instId );
2735					break;
2736
2737				case 'stop':
2738					vjg2.interaction( inst.instId, 'click', true );
2739					vjg2.stop( inst.instId );
2740					break;
2741
2742				case 'zoom':
2743					inst.children.eq( inst.currentIndex ).trigger( 'click' );
2744					break;
2745			}
2746
2747			vjg2.instCallback( inst.instId, 'links.' + type );
2748
2749			return false;
2750		});
2751	};
2752
2753	/**
2754	 * TODO: support fuer disabled children hinzufuegen
2755	 */
2756	vjg2e.scroll = new vjg2e.effect;
2757	vjg2e.scroll.init = function( instId ){
2758		if ( vjg2.debug ) vjg2.log( 'vjg2e.scroll.init()', arguments );
2759
2760		var inst = vjg2.insts[instId],
2761			container = inst.container,
2762			containerDims = {
2763				Height: parseInt( container.css( 'height' ), 10 ),
2764				Width: parseInt( container.css( 'width' ), 10 )
2765			},
2766			table, table_content;
2767
2768		inst.effect = [ 'scroll', 'scroll' ];
2769
2770		if ( isNaN( parseInt( containerDims[ 'Height' ], 10 ) ) ) {
2771			containerDims[ 'Height' ] = container.height();
2772		}
2773
2774		if ( isNaN( parseInt( containerDims[ 'Width' ], 10 ) ) ) {
2775			containerDims[ 'Width' ] = container.outerWidth();
2776		}
2777
2778		container
2779			.css( 'position', 'relative' )
2780			.css( 'overflow', 'hidden' );
2781
2782		table = jQuery( '<table cellpadding="0" cellspacing="0" style="position:absolute;white-space:nowrap;top:0px;' + inst.options.align + ':0px;" />' );
2783
2784		if ( inst.mode == 'vertical' ) {
2785			table_content = inst.children
2786				.addClass( 'vjg2_item' )
2787				.wrap( '<tr><td valign="top" /></tr>' )
2788				.parent()
2789				.parent();
2790		}
2791		else {
2792			table_content = vjg2.instChildren( instId )
2793				.addClass( 'vjg2_item' )
2794				.wrapAll( '<tr />' )
2795				.wrap( '<td valign="top" />' )
2796				.parent()
2797				.parent();
2798		}
2799
2800		table
2801			.html( table_content )
2802			.appendTo( inst.container );
2803
2804		inst.container = table;
2805
2806		if ( 'ontouchstart' in document.documentElement ) {
2807			var touch_position,
2808				touch_position_first,
2809				touch_position_last,
2810				touch_direction;
2811
2812			inst.container
2813				.bind( 'touchstart', function( event ){
2814					touch_position_first = {
2815						pageX: event.originalEvent.pageX,
2816						pageY: event.originalEvent.pageY
2817					};
2818					touch_position = {
2819						pageX: event.originalEvent.pageX,
2820						pageY: event.originalEvent.pageY
2821					};
2822				})
2823				.bind( 'touchend', function( event ){
2824					var index = inst.currentIndex;
2825
2826					if ( touch_direction == 'prev' ) {
2827						index = inst.currentIndex <= 0 ? 0 : vjg2.childPrev( inst.instId );
2828					}
2829					else if ( touch_direction == 'next' ) {
2830						index = inst.currentIndex >= inst.children.length - 1 ? inst.children.length - 1 : vjg2.childNext( inst.instId );
2831					}
2832
2833					vjg2.jump( inst.instId, index );
2834
2835					touch_position_first = {};
2836					touch_position_last = {};
2837				})
2838				.bind( 'touchmove', function( event ){
2839					touch_position_last = {
2840						pageX: event.originalEvent.pageX,
2841						pageY: event.originalEvent.pageY
2842					};
2843
2844					if (  Math.abs( touch_position_last.pageY - touch_position_first.pageY ) < 10 ) {
2845						return;
2846					}
2847
2848					if ( Math.abs( touch_position_last.pageY - touch_position_first.pageY ) < Math.abs( touch_position_last.pageX - touch_position_first.pageX ) ) {
2849						var left = parseInt( inst.container.css( 'left' ), 10 ) || 0;
2850
2851						if ( touch_position.pageX > touch_position_last.pageX ) {
2852							touch_direction = 'next';
2853							left = left - Math.abs( touch_position.pageX - touch_position_last.pageX );
2854						}
2855						else {
2856							touch_direction = 'prev';
2857							left = left + Math.abs( touch_position.pageX - touch_position_last.pageX );
2858						}
2859
2860						inst.container.css( 'left',  left + 'px' );
2861						event.preventDefault();
2862					}
2863
2864					touch_position = {
2865						pageX: touch_position_last.pageX,
2866						pageY: touch_position_last.pageY
2867					};
2868				});
2869		}
2870
2871		if ( inst.type == false ) {
2872			inst.tmp = {
2873				last: 0,
2874				count: inst.children.length,
2875				func: function( ){
2876					if ( inst.tmp.last < inst.tmp.count ) {
2877						vjg2.childrenLoad( instId, inst.tmp.last, undefined, function( instId, index ){
2878							inst.tmp.last++;
2879							window.setTimeout(function(){
2880								if( typeof inst.tmp !== 'undefined' ) {
2881									inst.tmp.func();
2882								}
2883							}, 200 );
2884						}, true );
2885					}
2886					else {
2887						delete inst.tmp;
2888					}
2889				}
2890			};
2891
2892			inst.tmp.func( );
2893		}
2894	};
2895
2896	vjg2e.scroll.play = function( instId, from, to ){
2897		if ( vjg2.debug ) vjg2.log( 'vjg2e.scroll.play()', arguments );
2898		var inst = vjg2.insts[instId],
2899			callback = function( instId ){
2900				vjg2.effectDone( instId );
2901			};
2902
2903		if ( vjg2.interaction( instId, 'hover' ) ) {
2904			return;
2905		}
2906
2907		if ( typeof to != 'number' ) {
2908			to = vjg2.childNext( instId, from );
2909		}
2910
2911		vjg2e[inst.effect[0]].effect( instId, to, from, callback );
2912	};
2913
2914	vjg2e.scroll.jump = function( instId, index ){
2915		if ( vjg2.debug ) vjg2.log( 'vjg2e.scroll.jump()', arguments );
2916		var inst = vjg2.insts[instId];
2917
2918		index = isNaN( index ) ? vjg2.childNext(instId) : index;
2919
2920		vjg2e[inst.effect[1]].effect( instId, index );
2921	};
2922
2923	vjg2e.scroll.childLoaded = function( instId, index ){
2924		if ( vjg2.debug ) vjg2.log( 'vjg2e.scroll.childLoaded()', arguments );
2925		var inst = vjg2.insts[instId],
2926			child = inst.children.eq( index );
2927
2928		if ( !child.is( ':visible' ) ) {
2929			child.fadeIn();
2930		}
2931	};
2932
2933	vjg2e.scroll.defaultChildrenStyle = function( instId, index, to ){
2934		//if ( vjg2.debug ) vjg2.log( 'vjg2e.scroll.defaultChildrenStyle()', arguments );
2935		var inst = vjg2.insts[instId];
2936
2937		return inst.type == 'html' ? 'display: block;' : 'display: none;';
2938	};
2939
2940	vjg2e.scroll.linkInit = function( instId, type ) {
2941		if ( vjg2.debug ) vjg2.log( 'vjg2e.scroll.linkInit()', arguments );
2942		var inst = vjg2.insts[instId];
2943
2944		switch( inst.type ) {
2945			case 'html':
2946				inst.links[type]
2947					.unbind()
2948					.bind( 'click', inst, function( event ){
2949						var inst = event.data, to;
2950						vjg2.interaction( instId, 'click', true );
2951
2952						if ( type == 'prev' ) {
2953							to = vjg2.childPrev( inst.instId );
2954						}
2955						else {
2956							to = vjg2.childNext( inst.instId );
2957						}
2958
2959						vjg2.jump( instId, to, type );
2960
2961						return false;
2962					});
2963				break;
2964
2965			default:
2966				inst.links[type]
2967					.unbind()
2968					.bind( 'mouseenter mouseleave', inst, function( event ){
2969						var inst = event.data;
2970
2971						switch( type ) {
2972							case 'next':
2973								switch( event.type ){
2974									case 'mouseenter':
2975										vjg2.pause( inst.instId );
2976										vjg2.interaction( instId, 'hover', true );
2977										inst.scrolling = type;
2978
2979										window.clearTimeout( inst.scrollingTimer );
2980										vjg2.instCallback( inst.instId, 'links.' + type );
2981										vjg2.childrenLoad( inst.instId, vjg2.childCurrent( inst.instId ), inst.children.length );
2982										vjg2e[inst.effect[1]].effect( inst.instId, type );
2983										break;
2984
2985									case 'mouseleave':
2986										vjg2.interaction( instId, 'hover', false );
2987
2988										inst.scrolling = false;
2989										inst.container.stop();
2990										inst.currentIndex = vjg2e[inst.effect[1]].childCentered( inst.instId );
2991
2992										vjg2.instCallback( inst.instId, 'links.' + type );
2993										vjg2.resumePaused( inst.instId );
2994										break;
2995								}
2996								break;
2997
2998							case 'prev':
2999								switch( event.type ){
3000									case 'mouseenter':
3001										vjg2.pause( inst.instId );
3002										vjg2.interaction( instId, 'hover', true );
3003										inst.scrolling = type;
3004
3005										window.clearTimeout( inst.scrollingTimer );
3006
3007										vjg2.instCallback( inst.instId, 'links.' + type );
3008										vjg2e[inst.effect[1]].effect( instId, type );
3009										break;
3010
3011									case 'mouseleave':
3012										vjg2.interaction( instId, 'hover', false );
3013
3014										inst.scrolling = false;
3015										inst.container.stop();
3016										inst.currentIndex = vjg2e[inst.effect[1]].childCentered( inst.instId );
3017
3018										vjg2.instCallback( inst.instId, 'links.' + type );
3019										break;
3020								}
3021								break;
3022
3023							case 'play':
3024								vjg2.instCallback( inst.instId, 'links.' + type );
3025								break;
3026
3027							case 'pause':
3028								vjg2.instCallback( inst.instId, 'links.' + type );
3029								break;
3030
3031							case 'zoom':
3032								vjg2.instCallback( inst.instId, 'links.' + type );
3033								vjg2.children.eq( inst.currentIndex ).trigger( 'click' );
3034								break;
3035						}
3036
3037						return false;
3038					});
3039				break;
3040		}
3041	};
3042
3043	vjg2e.scroll.childCentered = function( instId ) {
3044		var inst = vjg2.insts[instId],
3045			containerOffset = Math.abs( inst.container.offset().left ),
3046			childrenVisible = inst.children
3047				.filter(function(){
3048					return jQuery( this ).offset().left > containerOffset;
3049				})
3050				.eq( 0 );
3051
3052		return inst.children.index( childrenVisible );
3053	};
3054
3055	vjg2e.scroll.effect = function( instId, type, to, fn ) {
3056		if ( vjg2.debug ) vjg2.log( 'vjg2e.scroll.effect()', arguments );
3057		var inst = vjg2.insts[instId],
3058			offsetProp = inst.mode == 'vertical' ? 'top' : 'left',
3059			dimensionProp = inst.mode == 'vertical' ? 'height' : 'width',
3060			containerDimension = inst.container[ dimensionProp ](),
3061			containerWrapper = inst.container.parent(),
3062			containerWrapperDimension = containerWrapper[ dimensionProp ](),
3063			speed = inst.speed,
3064			speedPerPixel = 3,
3065			animateOptions = {},
3066			offsetPropValue = 0;
3067
3068		if ( containerDimension < inst.container.parent()[ dimensionProp ]() ) {
3069			return;
3070		}
3071
3072		if ( isNaN( to ) ) to = inst.children.length - 1;
3073
3074		if ( typeof type == 'number' ) {
3075			inst.currentIndex = type;
3076			type = 'number';
3077		}
3078
3079		if ( to && ( offset = inst.children.eq( to + 1 ).offset() ) ) {
3080			offsetPropValue = inst.container.offset()[ offsetProp ] - offset[ offsetProp ];
3081		}
3082
3083		if ( type == 'number' ) {
3084			offsetPropValue = inst.container.offset()[ offsetProp ];
3085
3086			if ( inst.currentIndex < inst.children.length ) {
3087				offsetPropValue -= inst.children.eq( inst.currentIndex ).offset()[ offsetProp ];
3088			}
3089
3090			scrollingOffset = inst.children.eq( inst.currentIndex ).offset()[ offsetProp ] - inst.container.offset()[ offsetProp ];
3091		}
3092		else {
3093			if ( type == 'prev' ) {
3094				scrollingOffset = Math.abs( parseInt( inst.container.css( offsetProp ), 0 ) );
3095				inst.currentIndex = 1;
3096				offsetPropValue = 0;
3097				speed = Math.abs( Math.abs( inst.container.offset()[ offsetProp ] ) ) * Math.abs( speedPerPixel );
3098			}
3099			else {
3100				inst.currentIndex = to;
3101
3102				scrollingOffset = inst.children.filter( ':last' ).offset()[ offsetProp ] - inst.container.offset()[ offsetProp ];
3103				offsetPropValue = Math.abs( scrollingOffset ) * -1;
3104				speed = Math.abs( scrollingOffset - Math.abs( inst.container.offset()[ offsetProp ] ) ) * Math.abs( speedPerPixel );
3105			}
3106		}
3107
3108
3109		offsetPropValue = parseInt( offsetPropValue, 10 );
3110
3111		if ( offsetPropValue > 0 ) {
3112			offsetPropValue = 0;
3113		}
3114
3115		if ( containerDimension - Math.abs( offsetPropValue ) < containerWrapperDimension ) {
3116			offsetPropValue = ( containerDimension - containerWrapperDimension ) * -1;
3117		}
3118		animateOptions[ offsetProp ] = offsetPropValue;
3119
3120		inst.container.stop();
3121		inst.container.animate(
3122			animateOptions,
3123			speed,
3124			'linear',
3125			function(){
3126				if ( vjg2.interaction( instId, 'hover' ) ) {
3127					vjg2e.scroll.effect( instId, type, to );
3128				}
3129			}
3130		);
3131	};
3132
3133	vjg2e.tile = new vjg2e.effect;
3134	vjg2e.tile.init = function( instId ){
3135		if ( vjg2.debug ) vjg2.log( 'vjg2e.tile.init()', arguments );
3136		var inst = vjg2.insts[instId];
3137
3138		inst.tile.rows = 5;
3139		inst.tile.columns = 10;
3140
3141		inst.containerHeight = parseInt( inst.container.css( 'height' ), 10 );
3142		inst.containerWidth = parseInt( inst.container.css( 'width' ), 10 );
3143
3144		inst.tile_width = Math.round( inst.containerWidth / inst.tile.columns );
3145		inst.tile_height = Math.round( inst.containerHeight / inst.tile.rows );
3146		inst.tile_columns = Math.round( inst.containerWidth / inst.tile_width );
3147		inst.tile_rows = Math.round( inst.containerHeight / inst.tile_height );
3148		inst.tile_count = inst.tile_columns * inst.tile_rows;
3149		inst.tile_timeout = 25;
3150		inst.timeout[0] = inst.timeout[0] + ( inst.tile_timeout * inst.tile_count );
3151
3152		var tiles_string = '';
3153
3154		inst.container.css('border', '1px solid black' );
3155
3156		for( var i = 0; i < inst.tile_rows; i++ ) {
3157			for( var j = 0; j < inst.tile_columns; j++ ) {
3158				tiles_string += '<div class="vjg2_tile" style="height: ' + inst.tile_height + 'px; width: ' + inst.tile_width + 'px; top: ' + ( i * inst.tile_height ) + 'px; left: ' + ( j * inst.tile_width ) + 'px; background-position: -' + ( j * inst.tile_width ) + 'px -' + ( i * inst.tile_height ) + 'px" />';
3159			}
3160		}
3161
3162		inst.container
3163			.css( 'position', 'relative' )
3164			.css( 'overflow', 'hidden' )
3165			.append( tiles_string );
3166
3167		vjg2.childrenLoad( instId, vjg2.childCurrent( instId ), 1 );
3168	};
3169
3170	vjg2e.tile.play = function( instId, from, to ){
3171		if ( vjg2.debug ) vjg2.log( 'vjg2e.tile.play()', arguments );
3172		var inst = vjg2.insts[instId],
3173			callback = function( instId ){
3174				vjg2.effectDone( instId );
3175			};
3176
3177		if ( typeof to != 'number' ) {
3178			to = vjg2.childNext( instId, from );
3179		}
3180
3181		vjg2e[inst.effect[0]].effect( instId, from, to, callback );
3182		vjg2.childrenLoad( instId, vjg2.childNext( instId ) );
3183	};
3184
3185	vjg2e.tile.jump = function( instId, index, to, fn ){
3186		if ( vjg2.debug ) vjg2.log( 'vjg2e.tile.jump()', arguments );
3187		var inst = vjg2.insts[instId],
3188			from = vjg2.childCurrent( instId ),
3189			callback = function( index ){
3190				inst.children
3191					.css( 'opacity', 0 )
3192					.eq( index )
3193					.css( 'position', 'absolute' )
3194					.css( 'display', 'block' )
3195					.css( 'opacity', 1 );
3196			};
3197
3198		to = !isNaN( index ) ? index : vjg2.childNext( instId );
3199
3200		if ( from == to ) return;
3201
3202		if ( inst.type == false && !vjg2.childLoaded( instId, to ) ) {
3203			vjg2.childrenLoad( instId, to, undefined, function( instId, index, fn ){
3204				callback( index );
3205			});
3206		}
3207		else {
3208			callback( to );
3209		}
3210
3211		if ( typeof fn == 'function' ) {
3212			fn( instId );
3213		}
3214
3215		if ( inst.type == false ) {
3216			vjg2.childrenLoad( instId, to, 1 );
3217		}
3218	};
3219
3220	vjg2e.tile.effect = function( instId, from, to, fn ){
3221		if ( vjg2.debug ) vjg2.log( 'vjg2e.tile.effect()', arguments );
3222		var inst = vjg2.insts[instId];
3223
3224		inst.currentIndex = to;
3225		inst.children.stop( true, true );
3226
3227		if ( inst.type == false && !vjg2.childLoaded( instId, inst.currentIndex ) ) {
3228			vjg2.childrenLoad( instId, inst.currentIndex );
3229		}
3230
3231		inst.tiles_visible = 0;
3232		inst.tile_order = [];
3233
3234		var effect_use = inst.tile.effect;
3235
3236		if ( effect_use == 'random' ) {
3237			var tile_effects = [ 'matrix', 'rain', 'default' ];
3238
3239			tile_effects.sort(function() {
3240				return 0.5 - Math.random();
3241			});
3242			effect_use = tile_effects[0];
3243		}
3244
3245		switch( effect_use ) {
3246			case 'matrix':
3247				var order = [];
3248				for( var i = 0; i < inst.tile_columns; i++ ) {
3249					order.push( i );
3250				}
3251				order.sort(function() {
3252					return 0.5 - Math.random();
3253				});
3254				for( var i in order ) {
3255					for( var j = 0; j < inst.tile_rows; j++ ) {
3256						var pos = ( j * inst.tile_columns ) + order[i];
3257						inst.tile_order.push( pos );
3258					}
3259				}
3260
3261				inst.tile_order.push( order );
3262				break;
3263
3264			case 'rain':
3265				var order = [];
3266				for( var i = 0; i < inst.tile_columns; i++ ) {
3267					for( var j = 0; j < inst.tile_rows; j++ ) {
3268						var pos = ( j * inst.tile_columns ) + i;
3269						order.push( pos );
3270					}
3271				}
3272
3273				inst.tile_order.push( order );
3274				break;
3275
3276			default:
3277				var order = [];
3278				for( var i = 0; i < inst.tile_count; i++ ) {
3279					order[i] = i;
3280				}
3281
3282				vjg2.shuffle( order );
3283				inst.tile_order.push( order );
3284				break;
3285		}
3286
3287		if ( effect_use == 'random' && Math.floor(Math.random()*2) ) {
3288			//inst.tile_order.reverse();
3289		}
3290
3291		for( var i in inst.tile_order ) {
3292			this._tile_show( instId, i, 0 );
3293		}
3294
3295		/*
3296		 inst.tile_timer = window.setInterval(function(){
3297		 inst.container
3298		 .children( '.vjg2_tile:eq(' + inst.tile_order[inst.tile_last_activated]  + ')' )
3299		 .css( 'background-image', 'url("' + src + '")' )
3300		 .animate({opacity: 1}, 120 );
3301
3302		 inst.tile_last_activated++;
3303
3304		 if ( inst.tile_last_activated == inst.tile_count ) {
3305		 window.clearInterval( inst.tile_timer );
3306		 }
3307		 }, inst.tile_timeout );
3308		 */
3309	};
3310
3311	vjg2e.tile._tile_show = function( instId, pos, tile ){
3312		if ( vjg2.debug ) vjg2.log( 'vjg2e.tile.effect()', arguments );
3313		var inst = vjg2.insts[instId],
3314			src = inst.children.eq( inst.currentIndex ).find( 'img:first' ).attr( 'src' );
3315
3316		inst.tiles_visible++;
3317
3318		inst.container
3319			.children( '.vjg2_tile:eq(' + inst.tile_order[pos][tile]  + ')' )
3320			.css( 'background-image', 'url("' + src + '")' )
3321			.animate({opacity: 1}, 120 );
3322
3323		if ( tile < inst.tile_order[pos].length ) {
3324			window.setTimeout( 'vjg2e.tile._tile_show( ' + instId + ', ' + pos + ', ' + ++tile + ')', inst.tile_timeout );
3325		}
3326
3327		if ( inst.tiles_visible == inst.tile_count ) {
3328			window.setTimeout(function(){
3329				inst.children
3330					.hide()
3331					.eq( inst.currentIndex )
3332					.css( 'position', 'absolute' )
3333					.css( 'display', 'block' )
3334					.css( 'opacity', 1 );
3335
3336				inst.container
3337					.find( '.vjg2_tile' )
3338					.css( 'opacity', 0 );
3339
3340				vjg2.effectDone( instId );
3341			}, 120 );
3342		}
3343	};
3344
3345	vjg2e.tile.defaultChildrenStyle = function( instId, index ){
3346		//if ( vjg2.debug ) vjg2.log( 'vjg2e.tile.defaultChildrenStyle()', arguments );
3347		var inst = vjg2.insts[instId],
3348			style = 'position: absolute; left: 0px; top: 0px; height: ' + inst.container.css( 'height' ) +'; width: ' + inst.container.css( 'width' ) + ';';
3349
3350		if ( index == inst.currentIndex ) {
3351			style += 'display: block; opacity: 1;';
3352		}
3353		else {
3354			style += 'display: none; opacity: 0;';
3355		}
3356
3357		return style;
3358	};
3359
3360	vjg2e.tile.linkInit = function( instId, type ) {
3361		if ( vjg2.debug ) vjg2.log( 'vjg2e.tile.linkInit()', arguments );
3362		var inst = vjg2.insts[instId];
3363
3364		inst.links[type]
3365			.unbind()
3366			.bind( 'click', inst, function( event ){
3367				var inst = event.data;
3368
3369				switch( type ) {
3370					case 'next':
3371						vjg2.interaction( inst.instId, 'click', true );
3372						vjg2.jump( inst.instId, vjg2.childNext( inst.instId ), type );
3373						break;
3374
3375					case 'prev':
3376						vjg2.interaction( inst.instId, 'click', true );
3377						vjg2.jump( inst.instId, vjg2.childPrev( inst.instId ), type );
3378						break;
3379
3380					case 'play':
3381						vjg2.interaction( instId, 'click', true );
3382						vjg2.resumeStopped( inst.instId );
3383						break;
3384
3385					case 'stop':
3386						vjg2.interaction( instId, 'click', true );
3387						vjg2.stop( inst.instId );
3388						break;
3389
3390					case 'zoom':
3391						inst.children.eq( inst.currentIndex ).trigger( 'click' );
3392						break;
3393				}
3394
3395				vjg2.instCallback( inst.instId, 'links.' + type );
3396
3397				return false;
3398			});
3399	};
3400
3401	vjg2e.timeline = new vjg2e.effect;
3402	vjg2e.timeline.children_show = 3;
3403	vjg2e.timeline.offset_multiplicator = 1;
3404	vjg2e.timeline.vjg2 = {
3405		overlayUpdate: false
3406	};
3407	vjg2e.timeline.init = function( instId ){
3408		if ( vjg2.debug ) vjg2.log( 'vjg2e.timeline.init()', arguments );
3409		var inst = vjg2.insts[instId];
3410
3411		inst.container
3412			.css( 'position', 'relative' )
3413			.css( 'overflow', 'hidden' );
3414
3415		var offset = ( inst.dimensions_last.containerInner.width / this.children_show ) * this.offset_multiplicator;
3416
3417		jQuery( 'head' ).append( '<style type="text/css">' +
3418			'.vjg2_inst' + instId + '.vjg2e_timeline > .vjg2_item:first-child { display: block; left: -' + 100 + '%} ' +
3419			'.vjg2_inst' + instId + '.vjg2e_timeline > .vjg2_item:first-child + div { display: block; left: 0} ' +
3420			'.vjg2_inst' + instId + '.vjg2e_timeline > .vjg2_item:first-child + div + div { display: block; left: ' + offset + 'px} ' +
3421			'.vjg2_inst' + instId + '.vjg2e_timeline > .vjg2_item:first-child + div + div + div { display: block; left: ' + ( offset * 2 ) + 'px}' +
3422			'.vjg2_inst' + instId + '.vjg2e_timeline > .vjg2_item:first-child + div + div + div + div { display: block; left: ' + inst.dimensions_last.containerInner.width + 'px}' +
3423			'</style>' );
3424
3425		vjg2.instChildren( instId )
3426			.find( '.vjg2_overlay' )
3427			.css( 'display', 'block' )
3428			.end()
3429			.filter( ':last' )
3430			.prependTo( inst.container )
3431			.siblings()
3432			.addClass( 'trigger' )
3433			.removeClass( 'trigger' );
3434
3435
3436		vjg2.childrenLoad( instId, inst.currentIndex, 4 );
3437	};
3438
3439	vjg2e.timeline.play = function( instId, from, to ){
3440		if ( vjg2.debug ) vjg2.log( 'vjg2e.timeline.play()', arguments );
3441		var inst = vjg2.insts[instId],
3442			callback = function( instId ){
3443				vjg2.effectDone( instId );
3444			};
3445
3446		if ( typeof to != 'number' ) {
3447			to = vjg2.childNext( instId );
3448		}
3449
3450		vjg2e[inst.effect[0]][ 'effect' ]( instId, from, to, callback );
3451	};
3452
3453	vjg2e.timeline.jump = function( instId, index, to, fn ){
3454		if ( vjg2.debug ) vjg2.log( 'vjg2e.timeline.jump()', arguments );
3455
3456		var inst = vjg2.insts[instId],
3457			from = vjg2.childCurrent( instId ),
3458			backward = false;
3459
3460		if ( inst.playDirection == 'prev' || index < from && !( from == inst.children.length - 1 && index == 0 ) || ( inst.currentIndex == 0 && index == inst.children.length - 1 ) ) {
3461			backward = true;
3462		}
3463
3464		if ( backward ) {
3465			vjg2.instChildren( instId )
3466				.filter( ':last' )
3467				.prependTo( inst.container );
3468
3469			if ( inst.navigation.container ) {
3470				inst.navigation.container
3471					.children()
3472					.filter( ':last' )
3473					.prependTo( inst.navigation.container );
3474			}
3475		}
3476		else {
3477			// alle children vor dem aktuell und dessen vorgaenger in der selben reihenfolge im container nach hinten verschieben :)
3478			inst.container.append(
3479				vjg2.instChildren( instId )
3480					.filter( '[rel="' + index +'"]' )
3481					.prev()
3482					.prevAll()
3483					.get()
3484					.reverse()
3485			)
3486
3487			if ( inst.navigation.container ) {
3488				inst.navigation.container.append(
3489					inst.navigation.container
3490						.children()
3491						.filter( '[rel="' + index +'"]' )
3492						.prev()
3493						.prevAll()
3494						.get()
3495						.reverse()
3496				);
3497
3498			}
3499		}
3500
3501		/* aufgrund eines bugs in webkit muessen wir eine aenderung des className's vortaeuschen, sonst werden die transitions nicht ausgefuehrt.. */
3502		vjg2.instChildren( instId )
3503			.filter( '[rel="' + index +'"]' )
3504			.siblings()
3505			.addClass( 'trigger' )
3506			.removeClass( 'trigger' );
3507
3508		if ( inst.navigation.container ) {
3509			inst.navigation.container
3510				.children()
3511				.filter( '.current' )
3512				.removeClass( 'current' )
3513				.end()
3514				.filter( '[rel="' + index +'"]' )
3515				.addClass( 'current' )
3516				.siblings()
3517				.addClass( 'trigger' )
3518				.removeClass( 'trigger' );
3519
3520		}
3521	};
3522
3523	vjg2e.timeline.effect = function( instId, from, to, fn ){
3524		if ( vjg2.debug ) vjg2.log( 'vjg2e.timeline.effect()', arguments );
3525		var inst = vjg2.insts[instId];
3526
3527	};
3528
3529	vjg2e.timeline.defaultChildrenStyle = function( instId, index ){
3530		return 'position: absolute;';
3531	};
3532
3533	vjg2e.timeline.linkInit = function( instId, type ) {
3534		if ( vjg2.debug ) vjg2.log( 'vjg2e.timeline.linkInit()', arguments );
3535		var inst = vjg2.insts[instId];
3536
3537		inst.links[type].bind( 'click', inst, function( event ){
3538			var inst = event.data;
3539
3540			switch( type ) {
3541				case 'next':
3542					if ( jQuery( this ).attr( 'active' ) != 'false' ) {
3543						jQuery( this ).attr( 'active', 'false' );
3544
3545						vjg2.interaction( inst.instId, 'click', true );
3546						vjg2.jump( inst.instId, vjg2.childNext( inst.instId ), type );
3547
3548						setTimeout(function(){
3549							jQuery( this ).attr( 'active', 'true' );
3550						}.bind(this), 500 );
3551					}
3552					break;
3553
3554				case 'prev':
3555					if ( jQuery( this ).attr( 'active' ) != 'false' ) {
3556						jQuery( this ).attr( 'active', 'false' );
3557
3558						vjg2.interaction( inst.instId, 'click', true );
3559						vjg2.jump( inst.instId, vjg2.childPrev( inst.instId ), type );
3560
3561						setTimeout(function(){
3562							jQuery( this ).attr( 'active', 'true' );
3563						}.bind(this), 500 );
3564					}
3565					break;
3566
3567				case 'play':
3568					vjg2.interaction( inst.instId, 'click', true );
3569					vjg2.resumeStopped( inst.instId );
3570					break;
3571
3572				case 'stop':
3573					vjg2.interaction( inst.instId, 'click', true );
3574					vjg2.stop( inst.instId );
3575					break;
3576
3577				case 'zoom':
3578					vjg2.instChildren( inst.instId ).eq( inst.currentIndex ).trigger( 'click' );
3579					break;
3580			}
3581
3582			vjg2.instCallback( inst.instId, 'links.' + type );
3583
3584			return false;
3585		});
3586	};
3587
3588	/*
3589	 * other possible effects
3590	 *
3591	 * tile:
3592	 * http://workshop.rs/projects/coin-slider/
3593	 * http://nivo.dev7studios.com/
3594	 *
3595	 * coverflow:
3596	 * http://www.jacksasylum.eu/ContentFlow/
3597	 *
3598	 * easing:
3599	 * http://jqueryui.com/demos/effect/easing.html
3600	 *
3601	 */
3602
3603	var vpoi = new function(){
3604		this.container = false;
3605		this.insts = [];
3606		this.timer = [];
3607		this.debug = window.location.hash == '#dev';
3608	};
3609
3610	vpoi._init = function(){
3611		jQuery.each( this.insts, function( i, inst ){
3612			vpoi.create( inst.instId );
3613		});
3614	};
3615
3616	vpoi.defaults = function(){
3617		var defaults = {
3618			open_event: 'mouseenter',
3619			vjg2Id: false,
3620			mode: 'normal',
3621			dimensions: {
3622				offset: {
3623					top: 0,
3624					right: 0,
3625					bottom: 0,
3626					left: 0
3627				}
3628			}
3629		};
3630
3631		return defaults;
3632	};
3633
3634	vpoi.register = function( element, options ){
3635		if ( vpoi.debug ) console.log( 'vpoi.register()', arguments );
3636		var instId = this.insts.length;
3637
3638		options.instId = instId;
3639		options.container = jQuery( element );
3640
3641		if ( 'link' in options ) {
3642			options.link = jQuery( options.link );
3643		}
3644		if ( 'content' in options ) {
3645			options.content = jQuery( options.content );
3646		}
3647
3648		this.insts.push( jQuery.extend( true, this.defaults(), options ) );
3649		this.create( instId );
3650
3651		return instId;
3652	};
3653
3654	vpoi.dom_ready = function() {
3655		if ( vpoi.debug ) console.log( 'vpoi.dom_ready()', arguments );
3656		jQuery.each( this.insts, function( i, inst ){
3657			if ( 'link' in inst ) {
3658				vpoi.linkMove( inst.instId );
3659			}
3660		});
3661	};
3662
3663	vpoi.create = function( instId ) {
3664		if ( vpoi.debug ) console.log( 'vpoi.create()', arguments );
3665		var inst = this.insts[instId],
3666			offset = inst.container.offset();
3667
3668		if ( 'link' in inst ) {
3669			this.linkInit( instId );
3670		}
3671
3672		if ( 'content' in inst ) {
3673			this.containerInit( instId );
3674		}
3675	};
3676
3677	vpoi.linkInit = function( instId ) {
3678		if ( vpoi.debug ) console.log( 'vpoi.linkInit()', arguments );
3679		var inst = this.insts[instId],
3680			offset = inst.container.offset();
3681
3682		inst.link
3683			.attr( 'vpoi', instId )
3684			.addClass( 'vpoi' )
3685			.appendTo( inst.container );
3686
3687		if ( 'width' in inst ) {
3688			inst.link.width( inst.width );
3689		}
3690
3691		if ( 'height' in inst ) {
3692			inst.link.height( inst.height );
3693		}
3694
3695		if ( 'link' in inst ) {
3696			inst.link
3697				.bind( 'mouseenter', function(){
3698					clearTimeout( vpoi.timer[ instId ] );
3699				})
3700				.bind( inst.open_event, function( event ){
3701					for( var i in vpoi.timer ) {
3702						vpoi.contentHide( i );
3703					}
3704
3705					if ( 'content' in inst ) {
3706						vpoi.contentShow( instId );
3707					}
3708
3709					if ( event.type == 'click' ) {
3710						return false;
3711					}
3712				});
3713		}
3714
3715		if ( this.dom_ready ) {
3716			//this.linkMove( instId );
3717		}
3718	};
3719
3720	vpoi.containerInit = function( instId ) {
3721		if ( vpoi.debug ) console.log( 'vpoi.containerInit()', arguments );
3722		var inst = this.insts[instId],
3723			offset = inst.container.offset();
3724
3725		inst.content
3726			.attr( 'vpoi', instId )
3727			.addClass( 'vpoi_content' )
3728			.css( 'top', offset.top + inst.top - inst.content.height() )
3729			.css( 'left', offset.left + inst.left - inst.content.width() )
3730			.appendTo( inst.container );
3731
3732		if ( 'link' in inst ) {
3733			inst.content
3734				.hide()
3735				.bind( 'mouseenter', function(){
3736					clearTimeout( vpoi.timer[ instId ] );
3737				})
3738				.bind( 'mouseleave', function(){
3739					clearTimeout( vpoi.timer[ instId ] );
3740
3741					vpoi.timer[ instId ] = setTimeout(function(){
3742						vpoi.contentHide( instId );
3743						delete vpoi.timer[ instId ];
3744					}, 1500 );
3745				});
3746
3747			inst.link.bind( 'mouseleave', function(){
3748				inst.content.trigger( 'mouseleave' );
3749			});
3750		}
3751		else {
3752			inst.content.show();
3753		}
3754	};
3755
3756	vpoi.linkMove = function( instId ) {
3757		if ( vpoi.debug ) console.log( 'vpoi.linkMove()', arguments );
3758		var inst = this.insts[instId],
3759			offset = inst.container.offset();
3760
3761		inst.link
3762			.css( 'top', offset.top + inst.top )
3763			.css( 'left', offset.left + inst.left );
3764	};
3765
3766	vpoi.contentShow = function( instId ) {
3767		if ( vpoi.debug ) console.log( 'vpoi.contentShow()', arguments );
3768		var inst = this.insts[instId];
3769
3770		inst.content
3771			.css( 'top', parseInt( inst.link.css( 'top' ), 10 ) + inst.link.outerHeight() )
3772			.css( 'left', parseInt( inst.link.css( 'left' ), 10 ) + inst.link.outerWidth() )
3773			.show();
3774	};
3775
3776	vpoi.contentHide = function( instId ) {
3777		if ( vpoi.debug ) console.log( 'vpoi.contentHide()', arguments );
3778		var inst = this.insts[instId];
3779
3780		inst.content.fadeOut();
3781	};
3782
3783	vpoi.restore = function( instId ) {
3784		if ( vpoi.debug ) console.log( 'vpoi.restore()', arguments );
3785		var inst = this.insts[instId];
3786
3787		if ( 'link' in inst ) {
3788			inst.link.show();
3789		}
3790		if ( 'content' in inst ) {
3791			if ( 'link' in inst ) {
3792				inst.content.hide();
3793			}
3794			else {
3795				inst.content.show();
3796			}
3797		}
3798	};
3799
3800	(function(jQuery) {
3801		vpoi._init();
3802		vjg2._init();
3803
3804		jQuery(window).bind( 'resize', function(){
3805			vjg2.dimsWindow = vjg2.deviceDimensions();
3806			vjg2.resizeTimerStart();
3807		});
3808
3809		var ios_fix = navigator.userAgent.match( /OS ([0-9]+)/ );
3810		if ( ios_fix && ios_fix[1] < 6 ) {
3811			jQuery('html,body').bind( 'scroll', function(){
3812				var scrollTop = jQuery( 'html,body' ).scrollTop();
3813
3814				jQuery.each( vjg2.insts, function( i, inst ){
3815					if ( inst.mode == 'background' ) {
3816						inst.container.css( 'top', scrollTop );
3817					}
3818				});
3819			}, 200 );
3820		}
3821
3822		jQuery(function(){
3823			vjg2.dom_ready();
3824			vpoi.dom_ready();
3825		});
3826
3827		jQuery.fn.vpoi = function( options ) {
3828			this.each(function() {
3829				vpoi.register( this, options );
3830			});
3831
3832			return this;
3833		};
3834
3835		jQuery.fn.vjg2 = function( options ) {
3836			if ( this.is( ':not(.vjg2)' ) ) {
3837				this.each(function() {
3838					vjg2.create( this, options );
3839				});
3840			}
3841
3842			return this;
3843		};
3844	})(jQuery);
3845}
3846else if ( typeof jQuery !== 'undefined' && typeof vQuery !== 'undefined' && 'vjg2' in jQuery.fn && !( 'vjg2' in vQuery.fn ) ){
3847	vQuery.fn.vjg2 = jQuery.fn.vjg2;
3848}

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.