/**
 * Skroll
 *
 * @version      0.84
 * @author       nori (norimania@gmail.com)
 * @copyright    5509 (http://5509.me/)
 * @license      The MIT License
 * @link         https://github.com/5509/skroll
 *
 * 2011-08-04 11:47
 */
;(function($, window, document, undefined) {

// CONST
var MOBILE = "ontouchstart" in window,
MOUSEWHEEL = "onmousewheel" in document ? "mousewheel" : "DOMMouseScroll",
MATRIX = "matrix(1,0,0,1,0,0)",
$document = $(document),
$html = $("html");

// jQuery plugin
$.fn.skroll = function(option) {
new Skroll(this, option);
return this;
};
// enable using Skroll methods
$.skroll = function(elm, option) {
return new Skroll($(elm), option);
};

// Skroll
function Skroll(elm, option) {
var _borderRadius = undefined,
_this = this,
_opt;
// Option
_opt = this.option = $.extend({
margin             : 0,
width              : "auto",
height             : parseInt(elm.css("height"), 10),
inSpeed            : 0.05,
outSpeed           : 0.2,
delayTime          : 0.4,
scrollBarBorder    : 1,
scrollBarWidth     : 6,
scrollBarHeight    : 6,
scrollBarSpace     : 3,
scrollBarColor     : "#000",
scrollBarZIndex    : 100,
opacity            : .5,
scrollBarBg        : false,
scrollBarBgColor   : "#666",
scrollBarBgOpacity : .5,
scrollBarGrowth    : "0 0 2px #fff",
cursor             : {
grab     : "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAMAAACeyVWkAAAACVBMVEX///8AAAD///9+749PAAAAA3RSTlP//wDXyg1BAAAASUlEQVR42qXNQQqAQAxD0cT7H3qQj/MVKi4MXb3SJscUtX0o0qTtTZHknBetHyCWHTTo1UVUDnfUqLtNUuVJRVRWYRGVv3XKf13yEgJFXOqs0wAAAABJRU5ErkJggg==') 6 6, default",
grabbing : "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAMAAACeyVWkAAAACVBMVEX///8AAAD///9+749PAAAAA3RSTlP//wDXyg1BAAAAOklEQVR42sXQMQ4AIAxCUb73P7SDDNI03YyE6S2k1eryReE0FMkl1EFYg2+lU6RZc61qMHkbo7795AZ/8gKwxSMcDgAAAABJRU5ErkJggg==') 6 6, default"
},
scrollCancel       : 80,
cubicBezier        : "cubic-bezier(0.20,0.71,0.30,0.87)",
cubicBezierBounce  : "cubic-bezier(0.11,0.74,0.15,0.80)",
cubicBezierBar     : "cubic-bazier(0.42,0,1,1)",
scrollBarHide      : true
}, option);

// 古いブラウザはcursorのdataURLは無視する
if ( !$.support.opacity ) {
_opt.cursor = {
grab: "move",
grabbing: "move"
}
}

_borderRadius = (_opt.scrollBarWidth + _opt.scrollBarBorder * 2) / 2 + "px";

this.$elm = elm;
this.$outer = $("<div class='scrollOuter'></div>");
this.$bar = $("<div class='scrollbar'></div>").css({
position           : "absolute",
borderRadius       : _borderRadius,
WebkitBorderRadius : _borderRadius,
MozBorderRadius    : _borderRadius,
cursor             : this.option.cursor.grab,
backgroundColor    : this.option.scrollBarColor,
opacity            : 0,
WebkitTransform    : MATRIX,
boxShadow          : this.option.scrollBarGrowth,
MozBoxShadow       : this.option.scrollBarGrowth,
WebkitBoxShadow    : this.option.scrollBarGrowth
});
this.$images = $("img", elm);
this.scrollingBase = { x: 0, y: 0 };
// 値を保持しておくためのやつ
this.enteringCursor = false;
this.transitioning = false;
this.dragging = false;
this.draggingX = false;
this.scrolling = false;
this.dragTop = 0;
this.innerWidth = elm.get(0).offsetWidth,
this.id = ".skrl" + (Math.floor(Math.random() * 1000) * 5);
// イベント識別子
this.mousedown = "mousedown" + this.id;
this.mousemove = "mousemove" + this.id;
this.mouseup = "mouseup" + this.id;
this.outerHeight = undefined;
this.diff = undefined;
this.scrollBarWidth = undefined;
this.scrollBarHeight = undefined;
this.innerScrollVal = undefined;
this.setUp = undefined;
this.imgLoaded = 0;
this.imgLength = 0;
this.sideScroll = false;
this.$scrollBarBg = undefined;

if ( _opt.scrollBarBg ) {
this.$scrollBarBg = $("<div class='scrollbarbg'></div>")
.css({
position           : "absolute",
borderRadius       : _borderRadius,
WebkitBorderRadius : _borderRadius,
MozBorderRadius    : _borderRadius,
backgroundColor    : _opt.scrollBarBgColor,
opacity            : _opt.scrollBarBgOpacity
});
}

elm.css("height", "auto");
this.innerHeight = elm.get(0).offsetHeight;
// Init
this.setUpSkroll();
if ( !MOBILE ) {
this.eventBind();
// Mobile init
} else {
this.evnetBindMobile();
}

if ( this.noScrollBar ) {
this.$bar.css("opacity", 0);
this.$scrollBarBg.css("opacity", 0);
} else
if ( _opt.scrollBarHide ) {
if ( MOBILE ) {
this.barFadeIn(_opt.delayTime);
setTimeout(function() {
_this.barFadeOut(0);
}, _opt.delayTime*1000);
} else {
this.$bar
.fadeIn(_opt.inSpeed*1000)
.delay(_opt.delayTime*1000)
.fadeOut(_opt.outSpeed*1000*2);
if ( _opt.scrollBarBg ) {
this.$scrollBarBg
.fadeIn(_opt.inSpeed*1000)
.delay(_opt.delayTime*1000)
.fadeOut(_opt.outSpeed*1000*2);
}
}
} else {
this.barFadeIn();
}
}
Skroll.prototype = {
refresh: function() {
var _opt = this.option;
// コンテンツの高さを取得し直す
_opt.height = parseInt(this.$elm.css("height"), 10);
this.$outer.css({
height: _opt.height
});
this.$elm.css("height", "auto");
this.innerHeight = this.$elm.get(0).offsetHeight;
// コンテンツアウターの高さを取得し直す
this.outerHeight = this.$outer.get(0).offsetHeight;
// スクロールバーの高さを取得し直す
this.scrollBarHeight = Math.pow(parseInt(this.$outer.height(), 10), 2) / this.innerHeight;
// スクロールバーが20より小さい場合は20で固定
this.scrollBarHeight = this.scrollBarHeight < 20 ? 20 : this.scrollBarHeight;
this.$bar.css({
height: this.scrollBarHeight
});
// スクロールバーの背景がある場合は高さを取得し直す
if ( this.$scrollBarBg ) {
this.$scrollBarBg.css({
height: this.outerHeight - _opt.scrollBarSpace*2
});
}
// スクロール量を更新
this.diff = this.innerHeight - this.outerHeight;
this.innerScrollVal = this.diff / (this.outerHeight - this.scrollBarHeight - this.option.scrollBarSpace*2);
// スクロールバーの有無
this.noScrollBar = this.scrollBarHeight > this.outerHeight;

this.scrollingBase = { x: 0, y: 0 };
this.innerScrolling();

if ( this.noScrollBar ) {
this.$bar.css("opacity", 0);
this.$scrollBarBg.css("opacity", 0);
} else {
this.$bar.css("opacity", _opt.opacity);
this.$scrollBarBg.css("opacity", _opt.scrollBarBgOpacity);
}
},
setUpSkroll: function() {
var _this = this,
_opt = this.option,
$elm = this.$elm,
$bar = this.$bar,
$images = this.$images,
$outer = this.$outer,
$scrollBarBg = this.$scrollBarBg,
$barX = this.$barX ? this.$barX : undefined,
_barHeight = Math.pow(parseInt(_opt.height, 10), 2) / _this.innerHeight;

// スクロールバーが20より小さい場合は20で固定する
_barHeight = _barHeight < 20 ? 20 : _barHeight;

this.$outer = $elm
.css({
margin          : 0,
height          : "auto",
overflow        : "auto",
position        : MOBILE ? "static" : "relative",
opacity         : 1,
WebkitTransform : MATRIX
})
.wrap(
$outer
.css({
margin        : _opt.margin,
width         : _opt.width,
height        : parseInt(_opt.height, 10),
position      : "relative",
overflow      : "hidden"
})
)
.parent()
.append($scrollBarBg ?
$scrollBarBg
.css({
width   : _opt.scrollBarWidth,
height  : parseInt(_opt.height, 10) - _opt.scrollBarSpace*2,
top     : _opt.scrollBarSpace,
right   : _opt.scrollBarSpace,
opacity : _opt.scrollBarBgOpacity
})
: undefined
)
.append(
$bar
.css({
width   : _opt.scrollBarWidth,
height  : _barHeight,
top     : _opt.scrollBarSpace,
right   : _opt.scrollBarSpace,
opacity : _opt.opacity,
zIndex  : _opt.scrollBarZIndex
})
);

this.scrollBarHeight = _barHeight;
this.innerHeight = $elm.get(0).offsetHeight;
this.diff = this.innerHeight - this.outerHeight;

// スクロールバーの有無
this.noScrollBar = this.scrollBarHeight > _opt.height;

// 画像がある場合は画像の読み込み完了を待つ
if ( $images.length ) {
_this.imgLength = $images.length;
$images.each(function() {
$(this).m5ImgLoad(function() {
_this.imgLoaded = _this.imgLoaded + 1;
})
});

(function() {
if ( _this.imgLoaded === _this.imgLength ) {
_this.innerHeight = $elm.get(0).offsetHeight;
return;
}
setTimeout(arguments.callee, 30);
}());
}
},
barFadeIn: function(delay) {
var _opt = this.option;
if ( this.noScrollBar ) return;
if ( !MOBILE ) {
this.$bar.stop(true, true).fadeIn(_opt.inSpeed*1000);
if ( _opt.scrollBarBg ) {
this.$scrollBarBg.stop(true, true).fadeIn(_opt.inSpeed*1000);
}
} else {
this.$bar
.css({
WebkitTransitionDuration: _opt.inSpeed + "s",
WebkitTransitionDelay: delay + "s",
WebkitTransitionProperty: "opacity",
opacity: _opt.opacity
});
if ( _opt.scrollBarBg ) {
this.$scrollBarBg
.css({
WebkitTransitionDuration: _opt.inSpeed + "s",
WebkitTransitionDelay: delay + "s",
WebkitTransitionProperty: "opacity",
opacity: _opt.scrollBarBgOpacity
});
}
}
},
barFadeOut: function(delay) {
var _opt = this.option;
if ( this.noScrollBar ) return;
if ( !_opt.scrollBarHide ) return;

if ( !MOBILE ) {
this.$bar.fadeOut(_opt.outSpeed*1000);
if ( _opt.scrollBarBg ) {
this.$scrollBarBg.fadeOut(_opt.outSpeed*1000);
}
} else {
this.$bar
.css({
WebkitTransitionDuration: _opt.outSpeed + "s",
WebkitTransitionDelay: delay + "s",
WebkitTransitionProperty: "opacity",
opacity: 0
});
if ( _opt.scrollBarBg ) {
this.$scrollBarBg
.css({
WebkitTransitionDuration: _opt.outSpeed + "s",
WebkitTransitionDelay: delay + "s",
WebkitTransitionProperty: "opacity",
opacity: 0
});
}
}
},
getCurrent: function($el) {
if ( MOBILE ) {
var _matrix =  $el.css("WebkitTransform")
.replace(/matrix\(([^\(\)]*)\)/, "$1")
.split(",");
return {
x: parseInt(_matrix[4], 10),
y: parseInt(_matrix[5], 10)
}
} else {
return {
x: parseInt($el.css("left"), 10),
y: parseInt($el.css("top"),  10)
}
}
},
// for Transition
setNext: function($el, val, bar, to) { // val: {x: valX, y: valY}
var _this = this,
_barDiff = this.outerHeight - this.scrollBarHeight - this.option.scrollBarSpace,
_defaultVal = { x: 0, y: 0 };
if ( val.y === 0 ) {
val.y = "0";
}
if ( val.x === 0 ) {
val.x = "0";
}
if ( !val.x || !val.y ) {
_defaultVal = this.getCurrent($el);
}
val.x = 0;
// モバイル環境のelmのみ
// 含む要素が多いためmatrixで移動する
if ( MOBILE && !bar ) {
$el.css({
WebkitTransform : "matrix(1,0,0,1," + (val.x || _defaultVal.x) + "," + (val.y || _defaultVal.y) + ")"
});
} else {
// barのときのみ、barが下へ移動するときはbottomで移動する
if ( to ) {
$el.css({
WebkitTransitionProperty: "height, bottom",
top: "auto",
bottom: (_barDiff + _this.option.scrollBarSpace) - val.y
});
// elmとbar共通、barは上へ移動するときのみ
} else {
$el.css({
top: val.y || _defaultVal.y,
bottom: "auto"
});
}
}
},
setUpBeforeScrolling: function(e) {
var $outer = this.$outer;
if ( this.noScrollBar ) return;
if ( !this.setUp ) {
this.setUp = true;
} else {
return;
}
this.outerHeight = $outer.height();
this.diff = this.innerHeight - this.outerHeight;
this.innerScrollVal = this.diff / (this.outerHeight - this.scrollBarHeight - this.option.scrollBarSpace*2);
this.dragTop = e ? e.clientY : 0;
this.scrolling = this.dragging ? false : true;
},
innerScrolling: function(_to) {
var _this = this,
_opt = _this.option,
_current = this.scrollingBase,
_next = {},
_innerNext = {},
_barDiff = _this.outerHeight - _this.scrollBarHeight - _opt.scrollBarSpace,
_innerScrolling = _current.y >= _barDiff,
_maxInnerTop = -_barDiff * _this.innerScrollVal,
_scrollBounceCapacity = _this.outerHeight*7/10,
_scrollBarHeight = undefined,
$bar = _this.$bar,
$elm = _this.$elm;

if ( this.noScrollBar ) return;

if ( MOBILE ) {
_next.y = _current.y <= 0
? 0 : _innerScrolling
? _barDiff : _current.y;
_innerNext.y = _current.y * _this.innerScrollVal <= -_scrollBounceCapacity
? _scrollBounceCapacity :
-_current.y * _this.innerScrollVal <= _maxInnerTop - _scrollBounceCapacity
? _maxInnerTop - _scrollBounceCapacity
: -_current.y * _this.innerScrollVal;

// スクロールバーが縮む
if ( _innerNext.y > 0 ) {
_scrollBarHeight = _this.scrollBarHeight * (1 - (_innerNext.y / 100)/2);
$bar.css({
height: _scrollBarHeight < 10 ?
10 : _scrollBarHeight
});
} else
if ( _innerNext.y < _maxInnerTop ) {
_scrollBarHeight = _this.scrollBarHeight * (1 - (-(_innerNext.y - _maxInnerTop) / 100)/2);
$bar.css({
height: _scrollBarHeight < 10 ?
10 : _scrollBarHeight
});
}

_this.setNext($bar, {
y: _next.y < 0 ? 0 :
// 一番下よりさらに下になった場合
_next.y + _opt.scrollBarSpace >= _barDiff ? _barDiff :
// 上〜下の場合
_next.y + _opt.scrollBarSpace
}, true, _innerNext.y > _opt.scrollBarSpace ? false : _innerNext.y < _maxInnerTop ? true : _to);
// 0を超えたときは常にtop、_maxInnerTop以下のときは常にbottom
} else {
if ( _current.y > _barDiff ) {
_current.y = _barDiff;
} else
if ( _opt.scrollBarSpace > _current.y ) {
_current.y = _opt.scrollBarSpace;
}
_innerNext.y = (_current.y - _opt.scrollBarSpace) * _this.innerScrollVal <= 0
? 0 :
-(_current.y - _opt.scrollBarSpace) * _this.innerScrollVal <= _maxInnerTop
? _maxInnerTop
: -(_current.y - _opt.scrollBarSpace) * _this.innerScrollVal;
_this.setNext($bar, {
y: _current.y <= _opt.scrollBarSpace
? _opt.scrollBarSpace : _innerScrolling
? _barDiff : _current.y
});
}
_this.setNext($elm, {
y: _innerNext.y
});
},
css: function(elm, styles) {
for ( var i = 0; i < elm.length; i++ ) {
elm[i].css(styles);
}
},
transioningFunc: function(callback) {
var _this = this;
this.transitioning = true;
(function() {
if ( !_this.transitioning ) return;
callback();
setTimeout(arguments.callee, 10);
}());
},
bounceEffect: function($bar, $elm) {
var _this = this,
_opt = this.option,
_barDiff = _this.outerHeight - _this.scrollBarHeight - _opt.scrollBarSpace*2,
_maxInnerTop = -_barDiff * _this.innerScrollVal,
_current = _this.scrollingBase;

// 範囲を超えた場合のボイン戻し
if ( _current.y > _barDiff ) {
_current.y = _barDiff;
_this.css([$elm, $bar], {
WebkitTransitionDuration: "0.4s",
WebkitTransitionTimingFunction: _opt.cubicBezierBounce
});
_this.setNext($elm, {
y: _maxInnerTop
});
} else
if ( 0 > _current.y ) {
_current.y = 0;
_this.css([$elm, $bar], {
WebkitTransitionDuration: "0.4s",
WebkitTransitionTimingFunction: _opt.cubicBezierBounce
});
$bar.css("height", _this.scrollBarHeight);
_this.setNext($elm, {
y: 0
});
} else {
_this.css([$elm, $bar], {
WebkitTransitionDuration: "0s",
WebkitTransitionTimingFunction: _opt.cubicBezier
});
_this.barFadeOut(_opt.delayTime);
}
$bar.css("height", _this.scrollBarHeight);
},
eventBind: function() {
var _this = this,
_opt = this.option,
$bar = this.$bar,
$outer = this.$outer;

$outer
.bind("mouseover", function() {
_this.enteringCursor = true;
_this.barFadeIn();
})
.bind("mouseleave", function() {
_this.enteringCursor = false;
if ( _this.dragging || _this.draggingX ) {
return false;
}
_this.setUp = false;
_this.scrolling = false;
if ( !_opt.scrollBarHide ) return;
_this.barFadeOut();
})
.bind(MOUSEWHEEL, function(e) {
e = e || window.event;
// detailはwheelDeltaと正負が逆になり
// 値もwheelDeltaの1/10
var _delta = Math.round(e.wheelDelta/10) || -e.detail,
_current = _this.scrollingBase;

_current.y = _this.scrollingBase.y - _delta;
if ( !_this.setUp ) _this.setUpBeforeScrolling();
_this.innerScrolling();
e.preventDefault();
});

$bar.bind(_this.mousedown, function(e) {
var _current = _this.scrollingBase;

this.dragTop = e.clientY;
//_this.setUp = false;
_this.dragging = true;
_this.scrolling = false;
if ( !_this.setUp) _this.setUpBeforeScrolling(e);

_this.css([$html, $bar], {cursor: _opt.cursor.grabbing});

$document
.bind(_this.mousemove, function(e) {
if ( _this.dragging ) {
_current.y = _current.y + (e.clientY - _this.dragTop);
_this.dragTop = e.clientY;
_this.innerScrolling();
}
return false;
})
.bind(_this.mouseup, function() {
_this.dragging = false;
_this.setUp = false;
$document
.unbind(_this.mousemove)
.unbind(_this.mouseup);
$html.css("cursor", "default");
$bar.css("cursor", _opt.cursor.grab);
if ( !_this.enteringCursor && _opt.scrollBarHide ) {
_this.barFadeOut();
}
});
return false;
});
},
evnetBindMobile: function() {
var _this = this,
_opt = this.option,
$bar = this.$bar,
$outer = this.$outer,
$elm = this.$elm,
outer = $outer.get(0),
touching = false,
touchStartPos = undefined,
touchEndPosPrev = undefined,
touchEndPos = undefined,
acceleration = undefined,
touchStartTime = undefined,
touchMoveEndTime = undefined,
touchEndTime = undefined,
touchSpeed = 0;

_this.css([$bar, $elm], {
WebkitTransitionProperty       : "all",
WebkitTransitionTimingFunction : _opt.cubicBezier,
// GPUレンダリングをONにしておく
WebkitTransformStyle           : "preserve-3d",
WebkitTransitionDuration       : "0s"
});

$("a", $outer).each(function() {
var $this = $(this),
anchor = $this.get(0);

anchor.addEventListener("touchend", function(e) {
$this.click();
e.stopPropagation();
}, true);
});
outer.addEventListener("touchstart", function(e) {
if ( e.touches[1] ) return;
var _t = e.touches[0];

this.scrolling = false;

// touchstart時のタイムスタンプ
touchStartTime = +new Date;
touching = true;
touchSpeed = 0;

_this.enteringCursor = true;
touchStartPos = {
x: _t.pageX,
y: _t.pageY
};
}, true);
outer.addEventListener("touchmove", function(e) {
if ( e.touches[1] ) return;
else if ( !touching ) return;
var _t = e.touches[0],
_diffY = undefined,
_current = _this.scrollingBase,
_to = undefined;

touchEndPosPrev = touchEndPos || touchStartPos;
touchEndPos = {
y: _t.pageY
};

// 一度折り返した場合は、touchStartPosを折り返した地点に置き換える
if ( touchEndPos.y > touchStartPos.y && touchEndPos.y < touchEndPosPrev.y
  || touchEndPos.y < touchStartPos.y && touchEndPos.y > touchEndPosPrev.y ) {
touchStartPos = touchEndPosPrev;
}
// 最後にtouchmoveしたタイムスタンプ
touchMoveEndTime = +new Date;

_diffY = (touchEndPosPrev.y - touchEndPos.y) * (1 / 5);
// 移動距離が気持ち短い方がなめらかにみえる
_current.y = _current.y + _diffY;
// 進む方向 down: true, up: false
_to = _diffY > 0;

_this.css([$elm, $bar], {
WebkitTransitionDuration       : "0s",
WebkitTransitionTimingFunction : _opt.cubicBezier
});
_this.$bar.css({
WebkitTransitionProperty: "all",
WebkitTransitionDelay: "0s",
height: _this.scrollBarHeight
});

// vertical scrolling
if ( !_this.setUp ) {
$bar.css("opacity", _opt.opacity);
if ( _opt.scrollBarBg ) {
_this.$scrollBarBg.css({
WebkitTransitionDuration: "0s",
WebkitTransitionDelay: "0s",
opacity: _opt.scrollBarBgOpacity
});
}
_this.setUpBeforeScrolling();
}
_this.innerScrolling(_to);
e.preventDefault();
}, true);
outer.addEventListener("touchend", function(e) {
if ( e.touches[1] && touching ) return;
if ( !touchEndPos ) return;
var _diffY = (touchEndPos.y - touchStartPos.y), // タッチの移動距離
_stepY = undefined, // 慣性でバーが進む距離
_nextInnerY = undefined, // 慣性でインナーが進んだ後
_barDiff = _this.outerHeight - _this.scrollBarHeight - _opt.scrollBarSpace*2,
_maxInnerTop = -_barDiff * _this.innerScrollVal,
_scrollBounceCapacity = _this.outerHeight/4,
_duration = undefined,
// 進む方向 down: false, up: true
// moveのときとは逆
_to = _diffY < 0,
_current = _this.scrollingBase;

// touchendのタイムスタンプ
touchEndTime = +new Date;

// モーメンタムスクロール
if ( _current.y > 0 // 指を離したときに最低値を下回っていなければ
  && _current.y < _barDiff // 指を離したときに最大値を上回っていなければ
  // 最後のtouchmoveとひとつ前のtouchmoveのタイムスタンプの差を確認する
  && touchEndTime - touchMoveEndTime < _opt.scrollCancel
  // ひとつ手前のtouchEndPosとの差があまりない場合のみ
  && (Math.abs(touchEndPosPrev.y - touchEndPos.y) > 15
  || Math.abs(touchEndPosPrev.x - touchEndPos.x) > 15) ) {

// スクロールする余裕がある場合
acceleration = touchEndTime - touchStartTime; // 加速度として使う

// スクロールする量と速度は
// タッチしていた時間とタッチの距離による
_stepY = -_diffY / 300 * acceleration; // 慣性でバーが進む距離
// 現在位置の更新
_current.y = _current.y + _stepY;
// 現在位置からインナーの位置を決定する
_nextInnerY = -_current.y * _this.innerScrollVal;

// スクロール速度はタッチしていた時間による
_duration = 0.7 > acceleration / 200 ? acceleration / 200 : 0.7;
_this.css([$elm, $bar], {
WebkitTransitionDuration: _duration + "s"
});

_this.setNext($elm, {
y: _nextInnerY > _scrollBounceCapacity ? _scrollBounceCapacity :
_nextInnerY < _maxInnerTop - _scrollBounceCapacity ? _maxInnerTop - _scrollBounceCapacity : _nextInnerY
});

// バーが縮むやつ
// ここはbounceのtransitionが呼ばれているときだけ
_this.transioningFunc(function() {
var __current = _this.getCurrent($elm),
__scrollBarHeight = undefined;
if ( __current.y > 0 ) {
__scrollBarHeight = _this.scrollBarHeight * (1 - (__current.y / 100)/2);
} else
if ( __current.y < _maxInnerTop ) {
__scrollBarHeight = _this.scrollBarHeight * (1 - (-(__current.y - _maxInnerTop) / 100)/2);
}
$bar.css({
height: __scrollBarHeight < 10 ?
10 : __scrollBarHeight
});
});

// 執着地点によってスクロールバーのtiming-functionが切り替わる
if ( _current.y < _opt.scrollBarSpace
  || _current.y >= _barDiff ) {
$bar.css({
WebkitTransitionTimingFunction: _opt.cubicBezierBar
});
}
// スクロールバーの最終地点
_this.setNext($bar, {
// 一番上よりさらに上になった場合
y: _current.y < _opt.scrollBarSpace ? _opt.scrollBarSpace :
// 一番下よりさらに下になった場合
_current.y >= _barDiff + _opt.scrollBarSpace ? _barDiff + _opt.scrollBarSpace :
// 上〜下の場合
_current.y
}, true, _to);

// モーメンタムスクロールなしで指を離したとき
} else {
// スクロールバーの最終地点
// 一番上（下）よりさらに上（上）になった場合
if ( _current.y < 0
  || _current.y >= _barDiff ) {
_this.bounceEffect($bar, $elm);
} else {
_this.barFadeOut(_opt.delayTime);
}
// 上〜下の場合は何もしない
}

touching = false;
touchStartPos = touchEndPos = 0;

_this.enteringCursor = false;
_this.setUp = false;
_this.scrolling = false;
e.preventDefault();
}, true);

$elm.get(0).addEventListener("webkitTransitionEnd", function() {
_this.transitioning = false;
_this.bounceEffect($bar, $elm);
$bar.css({
WebkitTransitionProperty: "all"
});
}, false);
}
};

/**
 * m5ImgLoad
 *
 * @version      0.2
 * @author       nori (norimania@gmail.com)
 * @copyright    5509 (http://5509.me/)
 * @license      The MIT License
 * @link         https://github.com/5509/m5ImgLoad
 *
 * 2011-02-08 15:41
 */
$.fn.m5ImgLoad = function(callback, interval) {
var _img = $(this).get(0),
newImg = new Image();

newImg.src = _img.src;

(function() {
if ( newImg.complete ) {
callback.call($(newImg));
return;
}
setTimeout(arguments.callee, interval || 20);
}());
return this;
};

}(jQuery, this, this.document));

