    var tl_scroller = function( config ) {
      var self = this,

          sliderZone,
          contentZone,

          sliderSize,
          contentSize,

          container,
          up,
          down,
          slider,
          timer;

      var isVertical        = true,
          handleScrollDown  = false,
          handleScrollUp    = false,
          disableSelection  = false,
          handleSliderMove  = false;

      var sliderData = {
        mouseBaseTop: 0,
        baseTop:      0,
        lastScroll:   0
      };

      this.getMargin = function( element ) {
        margin = element.style[marginType] || '0px';
        return parseInt( margin.replace('px', '') );
      }

      this.setMargin = function( element, margin ) {
        element.style[marginType] = margin  + 'px';
      }

      this.scrollDown = function( pixel, noforce ) {
        if ( !handleScrollDown && noforce ) return;
        newMargin = -contentZone.scrollLeft - pixel;
        if ( newMargin > 0 ) {
          newMargin = 0;
        }
        //console.log( newMargin, sliderZone.scrollWidth, contentZone.scrollWidth );
        if ( -newMargin > sliderZone.scrollWidth - sliderZone.getWidth() || -newMargin > contentZone.scrollWidth ) {
          newMargin = -(sliderZone.scrollWidth - sliderZone.getWidth());
        }
        sliderZone.scrollLeft = -newMargin;
        //self.setMargin( slider, newMargin / ratio );
        contentZone.scrollLeft = -newMargin;
        contentZone.innerHTML += ' ';
        //self.setMargin( contentZone, newMargin );
        //self.updateSlider();
      }

      this.scrollTo = function( pixel, noforce ) {
        var newMargin = pixel;

        /*if ( pixel > sliderZone.scrollWidth - sliderZone.getWidth() || pixel > contentZone.scrollWidth ) {
          newMargin = -(sliderZone.scrollWidth - sliderZone.getWidth());
        }*/

        if ( self.config.effect ) {
          if ( self.config.effect == 'sin' ) {
            var current = self.contentZone.scrollLeft;
            var step    = 0;

            var timer   = setInterval( function() {
              if ( step > ( self.config.fps || 10 ) ) {
                clearTimeout( timer );
                newPos = newMargin;
//                $$( '.bk_programs_timeline .timeline_view .channel' ).invoke('setStyle', {'border-bottom':'1px solid #F2F2F2'});
              } else {
                percent = step / ( self.config.fps || 10 );
                newPos = current + Math.round( Math.sin( ( Math.PI / 2 ) * percent ) * ( newMargin - current ) );
              } // end else
              sliderZone.scrollLeft = newPos;
              contentZone.scrollLeft = newPos;
              step++;
            }, 1000 / ( self.config.fps || 10 ) ); // end timed function

          } // end if config.effect == sin
        } else { // end config.effect
          sliderZone.scrollLeft = newMargin;
          contentZone.scrollLeft = newMargin;
          contentZone.innerHTML += ' ';
          //self.setMargin( contentZone, newMargin );
          //self.updateSlider();
        } // end else
      }

      this.scrollUp = function( pixel, noforce ) {
        if ( !handleScrollUp && noforce ) return;
        self.scrollDown( -pixel );
      }

      this.updateSlider = function() {
        contentMargin = self.getMargin( contentZone );
        self.setMargin( slider, newMargin / ratio );
      }

      this.scrollBySlider = function() {
        //sliderMargin = self.getMargin( slider );
        contentZone.scrollLeft = sliderZone.scrollLeft;
        contentZone.innerHTML += ' ';
        //console.log('yeah');
        //self.setMargin( contentZone, -sliderZone.scrollLeft)//sliderMargin * ratio );
      }

      this.handleWheel = function( event ) {
        delta = Event.wheel( event );
        if ( delta > 0 ) {
          self.scrollUp( delta * 25 );
        } else if ( delta <= 0 ) {
          self.scrollDown( delta * -25 );
        }
      }

      this.reInit = function() {
        _szs = sliderZone.getDimensions();
        isVertical          = _szs.width < _szs.height;
        self.isVertical     = isVertical;
        sliderZoneSize      = isVertical ? _szs.height : _szs.width;

        if ( self.config.contentSize ) {
          contentMaxSize  = self.config.contentSize;
        } else {
          contentMaxSize  = config.contentSize || ( isVertical ? contentZone.offsetHeight : contentZone.offsetWidth );
        }

        contentSize     = isVertical ? contentZone.up().getHeight() : contentZone.up().getWidth();

        if ( self.config.sliderSize ) {
          sliderSize    = self.config.sliderSize;
        } else {
          sliderSize    = isVertical ? slider.offsetHeight : slider.offsetWidth;
        }
        ratio         = Math.abs( ( contentMaxSize - contentSize ) / ( sliderSize - sliderZoneSize ) );

        marginType    = isVertical ? 'marginTop' : 'marginLeft';

        self.scrollRange   = sliderZone.scrollWidth - sliderZoneSize;

        self.contentRange  = contentMaxSize - contentSize;

        self.marginType    = self.isVertical ? 'marginTop' : 'marginLeft';
        self.scrollType    = self.isVertical ? 'scrollTop' : 'scrollLeft';

      }

      var init = function() {
        self.config = config;

        container   = $( config.scrollbar );
        up          = container.down('div.up');
        down        = container.down('div.down');
        slider      = container.down('div.slider');
        sliderZone  = container.down('div.area');

        contentZone = $( config.content );
        self.contentZone = contentZone;

        self.reInit();

        disableSelection = false;
        //self.updateSlider();

        if ( isVertical ) {
          contentZone.observe( 'mousewheel',     self.handleWheel, false );
          contentZone.observe( 'DOMMouseScroll', self.handleWheel, false );
        }

        if ( slider ) {
          slider.observe( 'mousedown', function( event ) {
            handleSliderMove = true;
            disableSelection = true;
            sliderData.mouseBaseTop = isVertical ? event.pointerY() : event.pointerX();
            sliderData.baseTop = sliderZone.scrollLeft//getMargin( slider );
            //slider.scrollLeft += 40;
            //console.log( slider.scrollLeft );
          });
        }

        self.contentZone.observe('scroll', function( event ) {
          //scrolled = event.element().scrollLeft - sliderData.lastScroll;
          self.scrollTo( event.element().scrollLeft );
        });

        down.observe( 'mousedown', function( event ) {
          self.scrollDown( 123, true );
          disableSelection = true;
          timer = setInterval( function(){ self.scrollDown( 123, true ) }, 100 );
        });

        down.observe( 'mouseover', function( event ) {
          handleScrollDown = true;
        });

        down.observe( 'mouseout', function( event ) {
          handleScrollDown = false;
        });

        up.observe( 'mousedown', function( event ) {
          self.scrollUp( 123, true );
          disableSelection = true;
          timer = setInterval( function(){ self.scrollUp( 123, true ) }, 100 );
        });

        up.observe( 'mouseover', function( event ) {
          handleScrollUp = true;
        });
        up.observe( 'mouseout', function( event ) {
          handleScrollUp = false;
        });

        /*sliderZone.observe('mousedown', function( event ) {
          _slider   = isVertical ? slider.cumulativeOffset().top : slider.cumulativeOffset().left;
          _pointer  = isVertical ? event.pointerY() : event.pointerX();
          if ( _slider + 15 < _pointer ) {
            self.scrollDown( 25 );
          } else if( _pointer < _slider ) {
            self.scrollUp( 25 );
          }
        });*/

        document.observe( 'mouseup', function( event ) {
          if ( timer ) clearInterval( timer );
          handleSliderMove = false;
          disableSelection = false;
        }); // end observe mouseup

        /*document.body.onselectstart = function( event ) {
          if ( disableSelection ) {
            return false;
          }
          else return true;
        }*/

        if ( Prototype.Browser.Gecko ) {
          $( document.body ).setStyle({'MozUserSelect': "none"});
        }

        document.observe( 'mousemove', function( event ) {
          // disable selection
          //event.element().style.MozUserSelect = ( Prototype.Browser.Gecko && ( handleSliderMove || handleScrollUp || handleScrollDown ) ) ? "none" : "";

          if ( handleSliderMove ) {
            mouseMovedBy = sliderData.mouseBaseTop - ( isVertical ? event.pointerY() : event.pointerX() );
            newpos = sliderData.baseTop + mouseMovedBy;

            //console.log( mouseMovedBy,newpos, self.scrollRange );
            //if ( ( newpos <= 0 && mouseMovedBy < 0 ) || ( newpos > -sliderSize + sliderZoneSize && mouseMovedBy > 0 ) ) {
            if ( newpos < 0 ) {
              newpos = 0;
            } else if( newpos > self.scrollRange ) {
              newpos = self.scrollRange;
            }
            //console.log( self.scrollRange );
            //newpos = Math.round( newpos / 123 ) * 123;
            if ( newpos != sliderZone[self.scrollType] ) {
              sliderZone[self.scrollType] = newpos;
              self.scrollBySlider();
            } // end if pos ...
          } // end if handleSliderMove
        }); // end document.observe mousemove
      }(); // end constructor
    }
