text: ( function(nsjs) {
  	var 	content,
  			viewport,
  			dir_vertical = true,
  			translate_name = 'translateY',
  			options,
  			viewport_height,
  			max, min,
  			mouse_pos, prev_mouse_pos, pos,
  			ticker_pos,
  			velocity = 0,
  			move_delta = 0,
  			relative,
  			hand_control = false,
  			started_animation = false,
  			style_name, 
  			indicator,
  			last_time,
  			inertia_starts,
  			holded = false,
  			halt_threshold = 2,
  			halt_counter = halt_threshold,
  			accumulator_ticker,
  			resizeTimeout;
  
  	/**
  	 * Handles the change of window size by periodic call of the calculate_scrolling function
  	 */
  	function resizeThrottler() {
  		if ( !resizeTimeout ) {
  			resizeTimeout = setTimeout( function() {
  				resizeTimeout = null;
  				nsjs.calculate_scrolling();
  			}, 66);
  		}
  	};
  
  	/**
  	 * Rewrites object's obj1 params with params of obj2. Used in rewriting of the default options
  	 * @param {object} obj1
  	 * @param {object} obj2
  	 * @return {object} merged object
  	 */
  	function merge_options( obj1, obj2 )
  	{
  		var obj3 = {};
  		for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
  		for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
  		return obj3;
  	};
  
  	/**
  	 * Extracts xy-position from click event object, generated by dom element
  	 * @param {event} event
  	 * @return {Number} y-postition
  	 */
  	function y_position( event ) {
  		if ( event.targetTouches && event.targetTouches.length > 0 ) {
  			return event.targetTouches[0].clientY;
  		}
  		return event.clientY;
  	};
  	function x_position( event ) {
  		if ( event.targetTouches && event.targetTouches.length > 0 ) {
  			return event.targetTouches[0].clientX;
  		}
  		return event.clientX;
  	};
  
  	/**
  	 * Scrolls content to position defined by y param. Handles the overscrolling by hard overwriting the pos variable:
  	 * just the precaution. Smooth overscrolling is handled by init_inertia function
  	 * @param {Number} y
  	 */
  	function scroll_content( new_pos ) {
  		pos = new_pos
  		content.style[ style_name ] = translate_name + '(' + (pos) + 'px)';
  		indicator.style[ style_name ] = translate_name + '(' + ( pos * relative) + 'px)';
  	};
  
  	/**
  	 * The function need to be called after every change of speed of the content: it initializes data for inertia scroll. The new 
  	 * speed - new look of the scrolling. It could not be called after every call of add_speed function or inside it
  	 * because of possible hand_control (hand_control var is true then) mode: content is not inertial
  	 * anymore and reacts momentally on every mouse movement. but behind the scenes add_speed is still working
  	 */
  	function init_inertia( ) {
  		if ( (pos + velocity ) < max && ( velocity < 0 ) ) {
  			velocity = max - pos;
  		} else if ( (pos + velocity) > min && ( velocity > 0 ) ) {
  			velocity = min - pos;
  		}
  		start_velocity = velocity;
  		start_pos = pos;
  		inertia_starts = Date.now();
  		if ( !started_animation ) 
  		{
  			requestAnimationFrame( inertia_scroll );
  			started_animation = true;
  		}
  	};
  
  	/**
  	 * The requestAnimationFrame callback. Exponentially reduce velocity and at the same rate brings closer content's pos to
  	 * start_pos + start_velocity. Halt the animation when hand_control toggles to true or when distance to the destination
  	 * is smaller than 0.5px
  	 */
  	function inertia_scroll() {
  		move_delta = start_velocity * (1 - Math.exp(-(Date.now() - inertia_starts) / options.inertion ));
  		velocity = start_velocity - move_delta;
  		if ( hand_control ) {
  			started_animation = false;
  			return;
  		}
  		if ( velocity < -0.5 || velocity > 0.5 ) {
  			requestAnimationFrame( inertia_scroll );
  			scroll_content( start_pos + move_delta );
  		} else {
  			scroll_content( start_pos + start_velocity );
  			started_animation = false;
  		}
  	};
  
  	/**
  	 * Initializes vars need to be set when user 'touches' content rectangle
  	 */
  	function touch( event ) {
  		halt_counter = halt_threshold;
  
  		if ( dir_vertical )
  			mouse_pos = viewport.getBoundingClientRect().top + y_position( event );
  		else
  			mouse_pos = viewport.getBoundingClientRect().left + x_position( event );
  		last_time = Date.now();
  		clearInterval( accumulator_ticker );
  		window.addEventListener( 'mousemove', handle_mouse_move );
  		window.addEventListener( 'mouseup', release );
  		accumulator_ticker = setInterval( track_drag, 100 );
  		prev_mouse_pos = mouse_pos;
  		ticker_pos = mouse_pos;
  		event.stopPropagation();
  		return false;
  	};
  
  	/**
  	 * Handles mouseup or touchend event
  	 */
  	function release( event ) {
  		clearInterval( accumulator_ticker );
  		window.removeEventListener( 'mousemove', handle_mouse_move );
  		window.removeEventListener( 'mouseup', release );
  		hand_control = false;
  		init_inertia();
  		event.preventDefault();
  		event.stopPropagation();
  		return false;
  	};
  
  	/**
  	 * Adds speed to the content movement. Need to call init_inertia to start actual animation
  	 * vector param - speed vector, which is then summed to the speed using standart vector sum
  	 * @param {Number} vector
  	 */
  	function add_speed( vector ) {
  		if ( vector == 0 ) 
  		{
  			if ( halt_counter == 0 ) 
  			{
  				velocity = 0;
  				halt_counter = halt_threshold;
  				hand_control = true;
  			} else 
  			{
  				halt_counter--;
  				velocity = velocity / 2.0;
  			}
  		}
  		else
  			velocity = (velocity + vector) / 2.0;
  	};
  
  	/**
  	 * Register the speed of mouse drag and adds it to speed. Fires 10 times/sec
  	 */
  	function track_drag() {
  		var now = Date.now();
  		add_speed( 1000*( mouse_pos - ticker_pos ) / ( now - last_time ) );
  		if ( !hand_control ) {
  			init_inertia();
  		}
  		ticker_pos = mouse_pos;
  		last_time = now;
  	};
  
  	/**
  	 * Handles wheel scroll while user's mouse is over the content viewport
  	 */
  	function wheel(event) {
  		var 	event = window.event || event, // old IE support
  				delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail)));
  		add_speed( delta*options.wheel_mutiplier );
  		init_inertia();
  		event.stopPropagation();
  		event.preventDefault();
  	};
  
  	function on_key( event ) {
  		event = event || window.event;
  		if ( event.keyCode >= 33 && event.keyCode <= 40 ) 
  		{
  			if ( event.keyCode == 33 ) 			// pageup
  			{
  				add_speed( viewport_height*2 );
  			} else if ( event.keyCode == 34 )	// pagedown
  			{
  				add_speed( -viewport_height*2 );
  			} else if ( event.keyCode == 37 || event.keyCode == 38 ) 	// up left
  			{
  				add_speed( options.arrows_speed );
  			} else if ( event.keyCode == 39 || event.keyCode == 40 )		// down right
  			{
  				add_speed( -options.arrows_speed );
  			} else if ( event.keyCode == 36 )	// home
  			{
  				add_speed( (min - pos)*2 );
  			} else if ( event.keyCode == 35 )	// end
  			{
  				add_speed( (max - pos )*2 );
  			}
  			init_inertia();
  			event.stopPropagation();
  			event.preventDefault();
  		}
  	};
  
  	function remove_key_listeners( event ) {
  		window.removeEventListener('keydown', on_key);
  		event.preventDefault();
  	};
  
  	function add_key_listeners( event ) {
  		window.addEventListener('keydown', on_key);
  		event.preventDefault();
  		
  	};
  
  
  	/**
  	 * Refresh mouse position even
  	 * just the precaution. Smooth overscrolling is handled by init_inertia function
  	 * @param {Number} y
  	 */
  	function handle_mouse_move(event) {
  		event = event || window.event;
  		if ( dir_vertical )
  			mouse_pos = event.clientY;
  		else
  			mouse_pos = event.clientX;
  		if ( hand_control ) {
  			scroll_content( pos + mouse_pos - prev_mouse_pos );
  			prev_mouse_pos = mouse_pos;
  		}
  		event.preventDefault();
  		event.stopPropagation();
  	};
  
  	nsjs.calculate_scrolling = function() {
  		// temporarilly turn on to calculate dimensions with inner margins
  		content.style[ 'overflow'] = 'auto';
  		if ( dir_vertical )
  		{
  			viewport_height = parseInt( getComputedStyle( content.parentNode ).height, 10 );
  			max = viewport_height - parseInt( getComputedStyle(content).height, 10 );
  			relative = (viewport_height - parseInt( getComputedStyle(indicator).height, 10 ) )/ max;
  		} else 
  		{
  			viewport_height = parseInt( getComputedStyle( content.parentNode ).width, 10 );
  			max = viewport_height - parseInt( getComputedStyle(content).width, 10 );
  			relative = (viewport_height - parseInt( getComputedStyle(indicator).width, 10 ) )/ max;
  		}
  		// turn off
  		content.style[ 'overflow'] = '';
  		if ( max > 0 ) { max = 0; }
  
  		if ( pos < max )
  		{
  			add_speed( (max - pos)*2 );
  			init_inertia();
  		}
  	};
  
  	nsjs.applyit_to = function( target, opt ) {
  		var default_options = {
  			direction: 'vertical',
  			indicator: 'indicator',
  			wheel_mutiplier: 300,
  			arrows_speed: 600,
  			inertion: 325
  		};
  
  		options = typeof opt !== 'undefined' ? merge_options( default_options, opt ) : default_options;
  
  		dir_vertical = (options.direction == 'vertical');
  		if ( !dir_vertical )
  			translate_name = 'translateX';
  
  		content = document.getElementById( target ),
  		viewport = content.parentNode,
  		indicator = document.getElementById( options.indicator );
  		velocity = 0;
  
  		if ( typeof window.ontouchstart !== 'undefined' ) {
  			viewport.addEventListener('touchstart', touch);
  		}
  		viewport.addEventListener( 'mousedown', touch );
  		viewport.addEventListener( 'mouseenter', add_key_listeners );
  		viewport.addEventListener( 'mouseleave', remove_key_listeners);
  		viewport.style.cursor = "move";
  
  
  	// mouse wheel support
  		if (viewport.addEventListener) {
  			// IE9, Chrome, Safari, Opera
  			viewport.addEventListener("mousewheel", wheel, false);
  			// Firefox
  			viewport.addEventListener("DOMMouseScroll", wheel, false);
  		}
  		else  // IE 6/7/8
  			viewport.attachEvent("onmousewheel", wheel);
  	// mouse wheel support
  
  		window.addEventListener("resize", resizeThrottler, false);
  
  		nsjs.calculate_scrolling();
  		pos = min = 0;
  		style_name = 'transform';
  		['webkit', 'Moz', 'o', 'ms'].every( function ( prefix ) {
  			var e = prefix + 'Transform';
  
  			if ( typeof content.style[e] !== 'undefined' ) {
  				style_name = e;
  				return false;
  			}
  			return true;
  		} );
  	};
  
  } )( this.noscrolljs = this.noscrolljs || {} );