function ResetButtonColor(a)local T=a.Active a.Active=not T a.Active=T end function ArrowGraphic(a,T,X,F)local J=Create("\070\114\097\109\101",{Name="\065\114\114\111\119 \071\114\097\112\104\105\099";BorderSizePixel=0;Size=UDim2.new(0,a,0,a),Transparency=1})if not F then F=Instance.new("\070\114\097\109\101")F.BorderSizePixel=0 end local r if T==nil or T=="\085\112"then function r(a,T)return a,T end elseif T=="\068\111\119\110"then function r(T,X)return UDim2.new(0,T.X.Offset,0,(a-T.Y.Offset)-1),X end elseif T=="\076\101\102\116"then function r(a,T)return UDim2.new(0,a.Y.Offset,0,a.X.Offset),UDim2.new(0,T.Y.Offset,0,T.X.Offset)end elseif T=="\082\105\103\104\116"then function r(T,X)return UDim2.new(0,(a-T.Y.Offset)-1,0,T.X.Offset),UDim2.new(0,X.Y.Offset,0,X.X.Offset)end end local N if X then function N(T,X)return UDim2.new(T.X.Offset/a,0,T.Y.Offset/a,0),UDim2.new(X.X.Offset/a,0,X.Y.Offset/a,0)end else function N(a,T)return a,T end end local g=math.floor(a/4)if a%2==0 then local T=a/2-1 for a=0,T,1 do local X=F:Clone()local s,e=N(r(UDim2.new(0,T-a,0,g+a),UDim2.new(0,(a+1)*2,0,1)))X.Position=s X.Size=e X.Parent=J end else local T=(a-1)/2 for a=0,T,1 do local X=F:Clone()local s,e=N(r(UDim2.new(0,T-a,0,g+a),UDim2.new(0,a*2+1,0,1)))X.Position=s X.Size=e X.Parent=J end end if a%4>1 then local T=F:Clone()local X,s=N(r(UDim2.new(0,0,0,(a-g)-1),UDim2.new(0,a,0,1)))T.Position=X T.Size=s T.Parent=J end return J end function GripGraphic(a,T,X,F,J)local r=Create("\070\114\097\109\101",{Name="\071\114\105\112 \071\114\097\112\104\105\099";BorderSizePixel=0,Size=UDim2.new(0,a.x,0,a.y),Transparency=1})if not J then J=Instance.new("\070\114\097\109\101")J.BorderSizePixel=0 end X=X or 2 local N if F then function N(T)return UDim2.new(T.X.Offset/a.x,0,T.Y.Offset/a.y,0)end else function N(a)return a end end if T=="\086\101\114\116\105\099\097\108"then for T=0,a.x-1,X do local X=J:Clone()X.Size=N(UDim2.new(0,1,0,a.y))X.Position=N(UDim2.new(0,T,0,0))X.Parent=r end elseif T==nil or T=="\072\111\114\105\122\111\110\116\097\108"then for T=0,a.y-1,X do local X=J:Clone()X.Size=N(UDim2.new(0,a.x,0,1))X.Position=N(UDim2.new(0,0,0,T))X.Parent=r end end return r end do local a={__index={GetScrollPercent=function(a)return a.ScrollIndex/(a.TotalSpace-a.VisibleSpace)end,CanScrollDown=function(a)return a.ScrollIndex+a.VisibleSpace<a.TotalSpace end;CanScrollUp=function(a)return a.ScrollIndex>0 end;ScrollDown=function(a)a.ScrollIndex=a.ScrollIndex+a.PageIncrement a:Update()end;ScrollUp=function(a)a.ScrollIndex=a.ScrollIndex-a.PageIncrement a:Update()end;ScrollTo=function(a,T)a.ScrollIndex=T a:Update()end;SetScrollPercent=function(a,T)a.ScrollIndex=math.floor((a.TotalSpace-a.VisibleSpace)*T+.5)a:Update()end}}a.__index.CanScrollRight=a.__index.CanScrollDown a.__index.CanScrollLeft=a.__index.CanScrollUp a.__index.ScrollLeft=a.__index.ScrollUp a.__index.ScrollRight=a.__index.ScrollDown function ScrollBar(T)local X=Create("\070\114\097\109\101",{Name="\083\099\114\111\108\108\070\114\097\109\101";Position=T and UDim2_new(0,0,1,-ScrollBarWidth)or UDim2_new(1,-ScrollBarWidth,0,0);Size=T and UDim2_new(1,0,0,ScrollBarWidth)or UDim2_new(0,ScrollBarWidth,1,0);BackgroundTransparency=1;Create("\073\109\097\103\101\066\117\116\116\111\110",{Name="\083\099\114\111\108\108\068\111\119\110",Position=T and UDim2_new(1,-ScrollBarWidth,0,0)or UDim2_new(0,0,1,-ScrollBarWidth),Size=UDim2_new(0,ScrollBarWidth,0,ScrollBarWidth);BackgroundColor3=ScrollStyles.Button,BorderColor3=ScrollStyles.Border;ImageColor3=Styles.White});Create("\073\109\097\103\101\066\117\116\116\111\110",{Name="\083\099\114\111\108\108\085\112",Size=UDim2_new(0,ScrollBarWidth,0,ScrollBarWidth);BackgroundColor3=ScrollStyles.Button;BorderColor3=ScrollStyles.Border;ImageColor3=Styles.White}),Create("\073\109\097\103\101\066\117\116\116\111\110",{Name="\083\099\114\111\108\108\066\097\114",Size=T and UDim2_new(1,-ScrollBarWidth*2,1,0)or UDim2_new(1,0,1,-ScrollBarWidth*2),Position=T and UDim2_new(0,ScrollBarWidth,0,0)or UDim2_new(0,0,0,ScrollBarWidth);AutoButtonColor=false,BackgroundColor3=Color3_new(.25,.25,.25),BorderColor3=ScrollStyles.Border,Create("\073\109\097\103\101\066\117\116\116\111\110",{Name="\083\099\114\111\108\108\084\104\117\109\098";AutoButtonColor=false,Size=UDim2_new(0,ScrollBarWidth,0,ScrollBarWidth);BackgroundColor3=ScrollStyles.Button,BorderColor3=ScrollStyles.Border,ImageColor3=Styles.White})})})local F=Create("\070\114\097\109\101",{Name="\071\114\097\112\104\105\099",BorderSizePixel=0,BackgroundColor3=Color3_new(1,1,1)})local J=ScrollBarWidth/2 local r=X.ScrollDown local N=ArrowGraphic(J,T and"\082\105\103\104\116"or"\068\111\119\110",true,F)N.Position=UDim2_new(.5,-J/2,.5,-J/2)N.Parent=r local g=X.ScrollUp local s=ArrowGraphic(J,T and"\076\101\102\116"or"\085\112",true,F)s.Position=UDim2_new(.5,-J/2,.5,-J/2)s.Parent=g local e=X.ScrollBar local k=e.ScrollThumb do local a=(ScrollBarWidth*3)/8 local X=GripGraphic(Vector2_new(a,a),T and"\086\101\114\116\105\099\097\108"or"\072\111\114\105\122\111\110\116\097\108",2,F)X.Position=UDim2_new(.5,-a/2,.5,-a/2)X.Parent=k end local u=Create("\073\109\097\103\101\066\117\116\116\111\110",{Name="\077\111\117\115\101\068\114\097\103";Position=UDim2_new(-0.25,0,-0.25,0);Size=UDim2_new(1.5,0,1.5,0),Transparency=1;AutoButtonColor=false;Active=true,ZIndex=10})local I=setmetatable({GUI=X;ScrollIndex=0,VisibleSpace=0;TotalSpace=0,PageIncrement=1},a)local y if T then function y()k.Size=UDim2_new(I.VisibleSpace/I.TotalSpace,0,0,ScrollBarWidth)if k.AbsoluteSize.X<ScrollBarWidth then k.Size=UDim2_new(0,ScrollBarWidth,0,ScrollBarWidth)end local a=e.AbsoluteSize.X k.Position=UDim2_new((I:GetScrollPercent()*(a-k.AbsoluteSize.X))/a,0,0,0)end else function y()k.Size=UDim2_new(0,ScrollBarWidth,I.VisibleSpace/I.TotalSpace,0)if k.AbsoluteSize.Y<ScrollBarWidth then k.Size=UDim2_new(0,ScrollBarWidth,0,ScrollBarWidth)end local a=e.AbsoluteSize.Y k.Position=UDim2_new(0,0,(I:GetScrollPercent()*(a-k.AbsoluteSize.Y))/a,0)end end local v,o local l={BackgroundColor3=Color3_new(1,1,1),BackgroundTransparency=0}local Y={BackgroundColor3=Color3_new(1,1,1);BackgroundTransparency=.7}local function f()local a,T,X=I.TotalSpace,I.VisibleSpace,I.ScrollIndex if T<=a then if X>0 then if X+T>a then I.ScrollIndex=a-T end else I.ScrollIndex=0 end else I.ScrollIndex=0 end if I.UpdateCallback then if I.UpdateCallback(I)==false then return end end local F,J=I:CanScrollDown(),I:CanScrollUp()if F~=v then v=F r.Active=F r.AutoButtonColor=F local a,T=N:GetChildren(),F and l or Y for X=1,#a,1 do Create(a[X],T)end end if J~=o then o=J g.Active=J g.AutoButtonColor=J local a,T=s:GetChildren(),J and l or Y for X=1,#a,1 do Create(a[X],T)end end k.Visible=F or J y()end I.Update=f SetZIndexOnChanged(X)local H=0 r.MouseButton1Down:Connect(function()H=tick()local a,T=H,nil T=u.MouseButton1Up:Connect(function()H=tick()u.Parent=nil ResetButtonColor(r)T:Disconnect()drag=nil end)u.Parent=GetScreen(X)I:ScrollDown()wait(.2)while H==a do I:ScrollDown()if not I:CanScrollDown()then break end wait()end end)r.MouseButton1Up:Connect(function()H=tick()end)g.MouseButton1Down:Connect(function()H=tick()local a,T=H,nil T=u.MouseButton1Up:Connect(function()H=tick()u.Parent=nil ResetButtonColor(g)T:Disconnect()drag=nil end)u.Parent=GetScreen(X)I:ScrollUp()wait(.2)while H==a do I:ScrollUp()if not I:CanScrollUp()then break end wait()end end)g.MouseButton1Up:Connect(function()H=tick()end)if T then e.MouseButton1Down:Connect(function(a,T)H=tick()local F=H local J J=u.MouseButton1Up:Connect(function()H=tick()u.Parent=nil ResetButtonColor(g)J:Disconnect()drag=nil end)u.Parent=GetScreen(X)if a>k.AbsolutePosition.X then I:ScrollTo(I.ScrollIndex+I.VisibleSpace)wait(.2)while H==F do if a<k.AbsolutePosition.X+k.AbsoluteSize.X then break end I:ScrollTo(I.ScrollIndex+I.VisibleSpace)wait()end else I:ScrollTo(I.ScrollIndex-I.VisibleSpace)wait(.2)while H==F do if a>k.AbsolutePosition.X then break end I:ScrollTo(I.ScrollIndex-I.VisibleSpace)wait()end end end)else e.MouseButton1Down:Connect(function(a,T)H=tick()local F=H local J J=u.MouseButton1Up:Connect(function()H=tick()u.Parent=nil ResetButtonColor(g)J:Disconnect()drag=nil end)u.Parent=GetScreen(X)if T>k.AbsolutePosition.Y then I:ScrollTo(I.ScrollIndex+I.VisibleSpace)wait(.2)while H==F do if T<k.AbsolutePosition.Y+k.AbsoluteSize.Y then break end I:ScrollTo(I.ScrollIndex+I.VisibleSpace)wait()end else I:ScrollTo(I.ScrollIndex-I.VisibleSpace)wait(.2)while H==F do if T>k.AbsolutePosition.Y then break end I:ScrollTo(I.ScrollIndex-I.VisibleSpace)wait()end end end)end if T then k.MouseButton1Down:Connect(function(a,T)H=tick()local F=a-k.AbsolutePosition.X local J,r J=u.MouseMoved:Connect(function(a,T)local X=e.AbsolutePosition.X local J=e.AbsoluteSize.X-k.AbsoluteSize.X local r=X+J a=a-F a=a<X and X or a>r and r or a a=a-X I:SetScrollPercent(a/J)end)r=u.MouseButton1Up:Connect(function()H=tick()u.Parent=nil ResetButtonColor(k)J:Disconnect()J=nil r:Disconnect()drag=nil end)u.Parent=GetScreen(X)end)else k.MouseButton1Down:Connect(function(a,T)H=tick()local F=T-k.AbsolutePosition.Y local J,r J=u.MouseMoved:Connect(function(a,T)local X=e.AbsolutePosition.Y local J=e.AbsoluteSize.Y-k.AbsoluteSize.Y local r=X+J T=T-F T=T<X and X or T>r and r or T T=T-X I:SetScrollPercent(T/J)end)r=u.MouseButton1Up:Connect(function()H=tick()u.Parent=nil ResetButtonColor(k)J:Disconnect()J=nil r:Disconnect()drag=nil end)u.Parent=GetScreen(X)end)end function I.Destroy(a)X:Destroy()u:Destroy()for a in next,I do I[a]=nil end setmetatable(I,nil)end f()return I end end

function ResetButtonColor(button)
	local active = button.Active
	button.Active = not active
	button.Active = active
end

function ArrowGraphic(size,dir,scaled,template)
	local Frame = Create('Frame',{
		Name = "Arrow Graphic";
		BorderSizePixel = 0;
		Size = UDim2.new(0,size,0,size);
		Transparency = 1;
	})
	if not template then
		template = Instance.new("Frame")
		template.BorderSizePixel = 0
	end

	local transform
	if dir == nil or dir == 'Up' then
		function transform(p,s) return p,s end
	elseif dir == 'Down' then
		function transform(p,s) return UDim2.new(0,p.X.Offset,0,size-p.Y.Offset-1),s end
	elseif dir == 'Left' then
		function transform(p,s) return UDim2.new(0,p.Y.Offset,0,p.X.Offset),UDim2.new(0,s.Y.Offset,0,s.X.Offset) end
	elseif dir == 'Right' then
		function transform(p,s) return UDim2.new(0,size-p.Y.Offset-1,0,p.X.Offset),UDim2.new(0,s.Y.Offset,0,s.X.Offset) end
	end

	local scale
	if scaled then
		function scale(p,s) return UDim2.new(p.X.Offset/size,0,p.Y.Offset/size,0),UDim2.new(s.X.Offset/size,0,s.Y.Offset/size,0) end
	else
		function scale(p,s) return p,s end
	end

	local o = math.floor(size/4)
	if size%2 == 0 then
		local n = size/2-1
		for i = 0,n do
			local t = template:Clone()
			local p,s = scale(transform(
				UDim2.new(0,n-i,0,o+i),
				UDim2.new(0,(i+1)*2,0,1)
				))
			t.Position = p
			t.Size = s
			t.Parent = Frame
		end
	else
		local n = (size-1)/2
		for i = 0,n do
			local t = template:Clone()
			local p,s = scale(transform(
				UDim2.new(0,n-i,0,o+i),
				UDim2.new(0,i*2+1,0,1)
				))
			t.Position = p
			t.Size = s
			t.Parent = Frame
		end
	end
	if size%4 > 1 then
		local t = template:Clone()
		local p,s = scale(transform(
			UDim2.new(0,0,0,size-o-1),
			UDim2.new(0,size,0,1)
			))
		t.Position = p
		t.Size = s
		t.Parent = Frame
	end
	return Frame
end

function GripGraphic(size,dir,spacing,scaled,template)
	local Frame = Create('Frame',{
		Name = "Grip Graphic";
		BorderSizePixel = 0;
		Size = UDim2.new(0,size.x,0,size.y);
		Transparency = 1;
	})
	if not template then
		template = Instance.new("Frame")
		template.BorderSizePixel = 0
	end

	spacing = spacing or 2

	local scale
	if scaled then
		function scale(p) return UDim2.new(p.X.Offset/size.x,0,p.Y.Offset/size.y,0) end
	else
		function scale(p) return p end
	end

	if dir == 'Vertical' then
		for i=0,size.x-1,spacing do
			local t = template:Clone()
			t.Size = scale(UDim2.new(0,1,0,size.y))
			t.Position = scale(UDim2.new(0,i,0,0))
			t.Parent = Frame
		end
	elseif dir == nil or dir == 'Horizontal' then
		for i=0,size.y-1,spacing do
			local t = template:Clone()
			t.Size = scale(UDim2.new(0,size.x,0,1))
			t.Position = scale(UDim2.new(0,0,0,i))
			t.Parent = Frame
		end
	end

	return Frame
end

do
	local mt = {
		__index = {
			GetScrollPercent = function(self)
				return self.ScrollIndex/(self.TotalSpace-self.VisibleSpace)
			end;
			CanScrollDown = function(self)
				return self.ScrollIndex + self.VisibleSpace < self.TotalSpace
			end;
			CanScrollUp = function(self)
				return self.ScrollIndex > 0
			end;
			ScrollDown = function(self)
				self.ScrollIndex = self.ScrollIndex + self.PageIncrement
				self:Update()
			end;
			ScrollUp = function(self)
				self.ScrollIndex = self.ScrollIndex - self.PageIncrement
				self:Update()
			end;
			ScrollTo = function(self,index)
				self.ScrollIndex = index
				self:Update()
			end;
			SetScrollPercent = function(self,percent)
				self.ScrollIndex = math.floor((self.TotalSpace - self.VisibleSpace)*percent + 0.5)
				self:Update()
			end;
		};
	}
	mt.__index.CanScrollRight = mt.__index.CanScrollDown
	mt.__index.CanScrollLeft = mt.__index.CanScrollUp
	mt.__index.ScrollLeft = mt.__index.ScrollUp
	mt.__index.ScrollRight = mt.__index.ScrollDown

	function ScrollBar(horizontal)
		local ScrollFrame = Create('Frame',{
			Name = "ScrollFrame",
			Position = horizontal and UDim2_new(0,0,1,-ScrollBarWidth) or UDim2_new(1,-ScrollBarWidth,0,0),
			Size = horizontal and UDim2_new(1,0,0,ScrollBarWidth) or UDim2_new(0,ScrollBarWidth,1,0),
			BackgroundTransparency = 1,
			Create('ImageButton',{
				Name = "ScrollDown",
				Position = horizontal and UDim2_new(1,-ScrollBarWidth,0,0) or UDim2_new(0,0,1,-ScrollBarWidth),
				Size = UDim2_new(0, ScrollBarWidth, 0, ScrollBarWidth),
				BackgroundColor3 = ScrollStyles.Button,
				BorderColor3 = ScrollStyles.Border,
				ImageColor3 = Styles.White
			}),
			Create('ImageButton',{
				Name = "ScrollUp",
				Size = UDim2_new(0, ScrollBarWidth, 0, ScrollBarWidth),
				BackgroundColor3 = ScrollStyles.Button,
				BorderColor3 = ScrollStyles.Border,
				ImageColor3 = Styles.White
			}),
			Create('ImageButton',{
				Name = "ScrollBar",
				Size = horizontal and UDim2_new(1,-ScrollBarWidth*2,1,0) or UDim2_new(1,0,1,-ScrollBarWidth*2),
				Position = horizontal and UDim2_new(0,ScrollBarWidth,0,0) or UDim2_new(0,0,0,ScrollBarWidth),
				AutoButtonColor = false,
				BackgroundColor3 = Color3_new(1/4, 1/4, 1/4),
				BorderColor3 = ScrollStyles.Border,
				Create('ImageButton',{
					Name = "ScrollThumb",
					AutoButtonColor = false,
					Size = UDim2_new(0, ScrollBarWidth, 0, ScrollBarWidth),
					BackgroundColor3 = ScrollStyles.Button,
					BorderColor3 = ScrollStyles.Border,
					ImageColor3 = Styles.White
				})
			})
		})

		local graphicTemplate = Create('Frame',{
			Name="Graphic",
			BorderSizePixel = 0,
			BackgroundColor3 = Color3_new(1, 1, 1)
		})

		local graphicSize = ScrollBarWidth/2

		local ScrollDownFrame = ScrollFrame.ScrollDown
		local ScrollDownGraphic = ArrowGraphic(graphicSize,horizontal and 'Right' or 'Down',true,graphicTemplate)
		ScrollDownGraphic.Position = UDim2_new(.5,-graphicSize/2,.5,-graphicSize/2)
		ScrollDownGraphic.Parent = ScrollDownFrame
		local ScrollUpFrame = ScrollFrame.ScrollUp
		local ScrollUpGraphic = ArrowGraphic(graphicSize,horizontal and 'Left' or 'Up',true,graphicTemplate)
		ScrollUpGraphic.Position = UDim2_new(.5,-graphicSize/2,.5,-graphicSize/2)
		ScrollUpGraphic.Parent = ScrollUpFrame
		local ScrollBarFrame = ScrollFrame.ScrollBar
		local ScrollThumbFrame = ScrollBarFrame.ScrollThumb
		do
			local size = ScrollBarWidth*3/8
			local Decal = GripGraphic(Vector2_new(size,size),horizontal and 'Vertical' or 'Horizontal',2,graphicTemplate)
			Decal.Position = UDim2_new(.5,-size/2,.5,-size/2)
			Decal.Parent = ScrollThumbFrame
		end

		local MouseDrag = Create('ImageButton',{
			Name = "MouseDrag",
			Position = UDim2_new(-.25,0,-.25,0),
			Size = UDim2_new(1.5,0,1.5,0),
			Transparency = 1,
			AutoButtonColor = false,
			Active = true,
			ZIndex = 10
		})

		local Class = setmetatable({
			GUI = ScrollFrame,
			ScrollIndex = 0,
			VisibleSpace = 0,
			TotalSpace = 0,
			PageIncrement = 1
		},mt)

		local UpdateScrollThumb
		if horizontal then
			function UpdateScrollThumb()
				ScrollThumbFrame.Size = UDim2_new(Class.VisibleSpace/Class.TotalSpace,0,0,ScrollBarWidth)
				if ScrollThumbFrame.AbsoluteSize.X < ScrollBarWidth then
					ScrollThumbFrame.Size = UDim2_new(0,ScrollBarWidth,0,ScrollBarWidth)
				end
				local barSize = ScrollBarFrame.AbsoluteSize.X
				ScrollThumbFrame.Position = UDim2_new(Class:GetScrollPercent()*(barSize - ScrollThumbFrame.AbsoluteSize.X)/barSize,0,0,0)
			end
		else
			function UpdateScrollThumb()
				ScrollThumbFrame.Size = UDim2_new(0,ScrollBarWidth,Class.VisibleSpace/Class.TotalSpace,0)
				if ScrollThumbFrame.AbsoluteSize.Y < ScrollBarWidth then
					ScrollThumbFrame.Size = UDim2_new(0,ScrollBarWidth,0,ScrollBarWidth)
				end
				local barSize = ScrollBarFrame.AbsoluteSize.Y
				ScrollThumbFrame.Position = UDim2_new(0,0,Class:GetScrollPercent()*(barSize - ScrollThumbFrame.AbsoluteSize.Y)/barSize,0)
			end
		end

		local lastDown, lastUp
		local scrollStyle = {BackgroundColor3=Color3_new(1, 1, 1),BackgroundTransparency=0}
		local scrollStyle_ds = {BackgroundColor3=Color3_new(1, 1, 1),BackgroundTransparency=.7}

		local function Update()
			local t,v,s = Class.TotalSpace,Class.VisibleSpace,Class.ScrollIndex
			if v <= t then
				if s > 0 then
					if s + v > t then
						Class.ScrollIndex = t - v
					end
				else
					Class.ScrollIndex = 0
				end
			else
				Class.ScrollIndex = 0
			end

			if Class.UpdateCallback then
				if Class.UpdateCallback(Class) == false then
					return
				end
			end

			local down,up = Class:CanScrollDown(),Class:CanScrollUp()
			if down ~= lastDown then
				lastDown = down
				ScrollDownFrame.Active = down
				ScrollDownFrame.AutoButtonColor = down
				local children,style = ScrollDownGraphic:GetChildren(),down and scrollStyle or scrollStyle_ds
				for i = 1,#children do
					Create(children[i],style)
				end
			end
			if up ~= lastUp then
				lastUp = up
				ScrollUpFrame.Active = up
				ScrollUpFrame.AutoButtonColor = up
				local children,style = ScrollUpGraphic:GetChildren(),up and scrollStyle or scrollStyle_ds
				for i = 1,#children do
					Create(children[i],style)
				end
			end
			ScrollThumbFrame.Visible = down or up
			UpdateScrollThumb()
		end
		Class.Update = Update

		SetZIndexOnChanged(ScrollFrame)

		local scrollEventID = 0
		ScrollDownFrame.MouseButton1Down:Connect(function()
			scrollEventID = tick()
			local current,up_con = scrollEventID,nil
			up_con = MouseDrag.MouseButton1Up:Connect(function()
				scrollEventID = tick()
				MouseDrag.Parent = nil
				ResetButtonColor(ScrollDownFrame)
				up_con:Disconnect()
				drag = nil
			end)
			MouseDrag.Parent = GetScreen(ScrollFrame)
			Class:ScrollDown()
			wait(.2)
			while scrollEventID == current do
				Class:ScrollDown()
				if not Class:CanScrollDown() then break end
				wait()
			end
		end)

		ScrollDownFrame.MouseButton1Up:Connect(function()
			scrollEventID = tick()
		end)

		ScrollUpFrame.MouseButton1Down:Connect(function()
			scrollEventID = tick()
			local current,up_con = scrollEventID,nil
			up_con = MouseDrag.MouseButton1Up:Connect(function()
				scrollEventID = tick()
				MouseDrag.Parent = nil
				ResetButtonColor(ScrollUpFrame)
				up_con:Disconnect()
				drag = nil
			end)
			MouseDrag.Parent = GetScreen(ScrollFrame)
			Class:ScrollUp()
			wait(.2)
			while scrollEventID == current do
				Class:ScrollUp()
				if not Class:CanScrollUp() then break end
				wait()
			end
		end)

		ScrollUpFrame.MouseButton1Up:Connect(function()
			scrollEventID = tick()
		end)

		if horizontal then
			ScrollBarFrame.MouseButton1Down:Connect(function(x,y)
				scrollEventID = tick()
				local current = scrollEventID
				local up_con
				up_con = MouseDrag.MouseButton1Up:Connect(function()
					scrollEventID = tick()
					MouseDrag.Parent = nil
					ResetButtonColor(ScrollUpFrame)
					up_con:Disconnect()
					drag = nil
				end)
				MouseDrag.Parent = GetScreen(ScrollFrame)
				if x > ScrollThumbFrame.AbsolutePosition.X then
					Class:ScrollTo(Class.ScrollIndex + Class.VisibleSpace)
					wait(.2)
					while scrollEventID == current do
						if x < ScrollThumbFrame.AbsolutePosition.X + ScrollThumbFrame.AbsoluteSize.X then break end
						Class:ScrollTo(Class.ScrollIndex + Class.VisibleSpace)
						wait()
					end
				else
					Class:ScrollTo(Class.ScrollIndex - Class.VisibleSpace)
					wait(.2)
					while scrollEventID == current do
						if x > ScrollThumbFrame.AbsolutePosition.X then break end
						Class:ScrollTo(Class.ScrollIndex - Class.VisibleSpace)
						wait()
					end
				end
			end)
		else
			ScrollBarFrame.MouseButton1Down:Connect(function(x,y)
				scrollEventID = tick()
				local current = scrollEventID
				local up_con
				up_con = MouseDrag.MouseButton1Up:Connect(function()
					scrollEventID = tick()
					MouseDrag.Parent = nil
					ResetButtonColor(ScrollUpFrame)
					up_con:Disconnect(); drag = nil
				end)
				MouseDrag.Parent = GetScreen(ScrollFrame)
				if y > ScrollThumbFrame.AbsolutePosition.Y then
					Class:ScrollTo(Class.ScrollIndex + Class.VisibleSpace)
					wait(.2)
					while scrollEventID == current do
						if y < ScrollThumbFrame.AbsolutePosition.Y + ScrollThumbFrame.AbsoluteSize.Y then break end
						Class:ScrollTo(Class.ScrollIndex + Class.VisibleSpace)
						wait()
					end
				else
					Class:ScrollTo(Class.ScrollIndex - Class.VisibleSpace)
					wait(.2)
					while scrollEventID == current do
						if y > ScrollThumbFrame.AbsolutePosition.Y then break end
						Class:ScrollTo(Class.ScrollIndex - Class.VisibleSpace)
						wait()
					end
				end
			end)
		end

		if horizontal then
			ScrollThumbFrame.MouseButton1Down:Connect(function(x,y)
				scrollEventID = tick()
				local mouse_offset = x - ScrollThumbFrame.AbsolutePosition.X
				local drag_con,up_con
				drag_con = MouseDrag.MouseMoved:Connect(function(x,y)
					local bar_abs_pos = ScrollBarFrame.AbsolutePosition.X
					local bar_drag = ScrollBarFrame.AbsoluteSize.X - ScrollThumbFrame.AbsoluteSize.X
					local bar_abs_one = bar_abs_pos + bar_drag
					x = x - mouse_offset
					x = x < bar_abs_pos and bar_abs_pos or x > bar_abs_one and bar_abs_one or x
					x = x - bar_abs_pos
					Class:SetScrollPercent(x/(bar_drag))
				end)
				up_con = MouseDrag.MouseButton1Up:Connect(function()
					scrollEventID = tick()
					MouseDrag.Parent = nil
					ResetButtonColor(ScrollThumbFrame)
					drag_con:Disconnect(); drag_con = nil
					up_con:Disconnect(); drag = nil
				end)
				MouseDrag.Parent = GetScreen(ScrollFrame)
			end)
		else
			ScrollThumbFrame.MouseButton1Down:Connect(function(x,y)
				scrollEventID = tick()
				local mouse_offset = y - ScrollThumbFrame.AbsolutePosition.Y
				local drag_con,up_con
				drag_con = MouseDrag.MouseMoved:Connect(function(x,y)
					local bar_abs_pos = ScrollBarFrame.AbsolutePosition.Y
					local bar_drag = ScrollBarFrame.AbsoluteSize.Y - ScrollThumbFrame.AbsoluteSize.Y
					local bar_abs_one = bar_abs_pos + bar_drag
					y = y - mouse_offset
					y = y < bar_abs_pos and bar_abs_pos or y > bar_abs_one and bar_abs_one or y
					y = y - bar_abs_pos
					Class:SetScrollPercent(y/(bar_drag))
				end)
				up_con = MouseDrag.MouseButton1Up:Connect(function()
					scrollEventID = tick()
					MouseDrag.Parent = nil
					ResetButtonColor(ScrollThumbFrame)
					drag_con:Disconnect(); drag_con = nil
					up_con:Disconnect(); drag = nil
				end)
				MouseDrag.Parent = GetScreen(ScrollFrame)
			end)
		end

		function Class:Destroy()
			ScrollFrame:Destroy()
			MouseDrag:Destroy()
			for k in next, Class do
				Class[k] = nil
			end
			setmetatable(Class,nil)
		end
		Update()
		return Class
	end
end
